]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/sh/sh.md
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Hitachi / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
38
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
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;; t -- T
46 ;; x -- mac
47 ;; l -- pr
48 ;; z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
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
59 ;;
60 ;; Special predicates:
61 ;;
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
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
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)
81
82 (FPSCR_REG 151)
83
84 (PIC_REG 12)
85 (FP_REG 14)
86 (SP_REG 15)
87
88 (PR_MEDIA_REG 18)
89 (T_MEDIA_REG 19)
90
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)
106
107 (DR0_REG 64)
108 (DR2_REG 66)
109 (DR4_REG 68)
110 (FR23_REG 87)
111
112 (TR0_REG 128)
113 (TR1_REG 129)
114 (TR2_REG 130)
115
116 (XD0_REG 136)
117
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
140 ;; These are used with unspec_volatile.
141 (UNSPECV_BLOCKAGE 0)
142 (UNSPECV_ALIGN 1)
143 (UNSPECV_CONST2 2)
144 (UNSPECV_CONST4 4)
145 (UNSPECV_CONST8 6)
146 (UNSPECV_WINDOW_END 10)
147 (UNSPECV_CONST_END 11)
148 ])
149
150 ;; -------------------------------------------------------------------------
151 ;; Attributes
152 ;; -------------------------------------------------------------------------
153
154 ;; Target CPU.
155
156 (define_attr "cpu"
157 "sh1,sh2,sh3,sh3e,sh4,sh5"
158 (const (symbol_ref "sh_cpu_attr")))
159
160 (define_attr "endian" "big,little"
161 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
162 (const_string "little") (const_string "big"))))
163
164 ;; Indicate if the default fpu mode is single precision.
165 (define_attr "fpu_single" "yes,no"
166 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
167 (const_string "yes") (const_string "no"))))
168
169 (define_attr "fmovd" "yes,no"
170 (const (if_then_else (symbol_ref "TARGET_FMOVD")
171 (const_string "yes") (const_string "no"))))
172 ;; pipeline model
173 (define_attr "pipe_model" "sh1,sh4,sh5media"
174 (const
175 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
176 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
177 (const_string "sh1"))))
178
179 ;; cbranch conditional branch instructions
180 ;; jump unconditional jumps
181 ;; arith ordinary arithmetic
182 ;; arith3 a compound insn that behaves similarly to a sequence of
183 ;; three insns of type arith
184 ;; arith3b like above, but might end with a redirected branch
185 ;; load from memory
186 ;; load_si Likewise, SImode variant for general register.
187 ;; fload Likewise, but load to fp register.
188 ;; store to memory
189 ;; move general purpose register to register
190 ;; mt_group other sh4 mt instructions
191 ;; fmove register to register, floating point
192 ;; smpy word precision integer multiply
193 ;; dmpy longword or doublelongword precision integer multiply
194 ;; return rts
195 ;; pload load of pr reg, which can't be put into delay slot of rts
196 ;; prset copy register to pr reg, ditto
197 ;; pstore store of pr reg, which can't be put into delay slot of jsr
198 ;; prget copy pr to register, ditto
199 ;; pcload pc relative load of constant value
200 ;; pcfload Likewise, but load to fp register.
201 ;; pcload_si Likewise, SImode variant for general register.
202 ;; rte return from exception
203 ;; sfunc special function call with known used registers
204 ;; call function call
205 ;; fp floating point
206 ;; fdiv floating point divide (or square root)
207 ;; gp_fpul move from general purpose register to fpul
208 ;; fpul_gp move from fpul to general purpose register
209 ;; mac_gp move from mac[lh] to general purpose register
210 ;; dfp_arith, dfp_cmp,dfp_conv
211 ;; ftrc_s fix_truncsfsi2_i4
212 ;; dfdiv double precision floating point divide (or square root)
213 ;; cwb ic_invalidate_line_i
214 ;; arith_media SHmedia arithmetic, logical, and shift instructions
215 ;; cbranch_media SHmedia conditional branch instructions
216 ;; cmp_media SHmedia compare instructions
217 ;; dfdiv_media SHmedia double precision divide and square root
218 ;; dfmul_media SHmedia double precision multiply instruction
219 ;; dfparith_media SHmedia double precision floating point arithmetic
220 ;; dfpconv_media SHmedia double precision floating point conversions
221 ;; dmpy_media SHmedia longword multiply
222 ;; fcmp_media SHmedia floating point compare instructions
223 ;; fdiv_media SHmedia single precision divide and square root
224 ;; fload_media SHmedia floating point register load instructions
225 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
226 ;; fparith_media SHmedia single precision floating point arithmetic
227 ;; fpconv_media SHmedia single precision floating point conversions
228 ;; fstore_media SHmedia floating point register store instructions
229 ;; gettr_media SHmedia gettr instruction
230 ;; invalidate_line_media SHmedia invaldiate_line sequence
231 ;; jump_media SHmedia unconditional branch instructions
232 ;; load_media SHmedia general register load instructions
233 ;; pt_media SHmedia pt instruction (expanded by assembler)
234 ;; ptabs_media SHmedia ptabs instruction
235 ;; store_media SHmedia general register store instructions
236 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
237 ;; mac_media SHmedia mac-style fixed point operations
238 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
239 ;; atrans SHmedia approximate transcendential functions
240 ;; ustore_media SHmedia unaligned stores
241 ;; nil no-op move, will be deleted.
242
243 (define_attr "type"
244 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
245 (const_string "other"))
246
247 ;; We define a new attribute namely "insn_class".We use
248 ;; this for the DFA based pipeline description.
249 ;;
250 ;; mt_group SH4 "mt" group instructions.
251 ;;
252 ;; ex_group SH4 "ex" group instructions.
253 ;;
254 ;; ls_group SH4 "ls" group instructions.
255 ;;
256
257 (define_attr "insn_class"
258 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
259 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
260 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
261 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
262 (eq_attr "type" "cbranch,jump") (const_string "br_group")
263 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
264 (const_string "fe_group")
265 (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")]
266 (const_string "none")))
267 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
268 ;; so these do not belong in an insn group, although they are modeled
269 ;; with their own define_insn_reservations.
270
271 ;; Indicate what precision must be selected in fpscr for this insn, if any.
272
273 (define_attr "fp_mode" "single,double,none" (const_string "none"))
274
275 ; If a conditional branch destination is within -252..258 bytes away
276 ; from the instruction it can be 2 bytes long. Something in the
277 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
278 ; branches are initially assumed to be 16 bytes long.
279 ; In machine_dependent_reorg, we split all branches that are longer than
280 ; 2 bytes.
281
282 ;; The maximum range used for SImode constant pool entries is 1018. A final
283 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
284 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
285 ;; instruction around the pool table, 2 bytes of alignment before the table,
286 ;; and 30 bytes of alignment after the table. That gives a maximum total
287 ;; pool size of 1058 bytes.
288 ;; Worst case code/pool content size ratio is 1:2 (using asms).
289 ;; Thus, in the worst case, there is one instruction in front of a maximum
290 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
291 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
292 ;; If we have a forward branch, the initial table will be put after the
293 ;; unconditional branch.
294 ;;
295 ;; ??? We could do much better by keeping track of the actual pcloads within
296 ;; the branch range and in the pcload range in front of the branch range.
297
298 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
299 ;; inside an le.
300 (define_attr "short_cbranch_p" "no,yes"
301 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
302 (const_string "no")
303 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
304 (const_string "yes")
305 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
306 (const_string "no")
307 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
308 (const_string "yes")
309 ] (const_string "no")))
310
311 (define_attr "med_branch_p" "no,yes"
312 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
313 (const_int 1988))
314 (const_string "yes")
315 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
316 (const_string "no")
317 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
318 (const_int 8186))
319 (const_string "yes")
320 ] (const_string "no")))
321
322 (define_attr "med_cbranch_p" "no,yes"
323 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
324 (const_int 1986))
325 (const_string "yes")
326 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
327 (const_string "no")
328 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
329 (const_int 8184))
330 (const_string "yes")
331 ] (const_string "no")))
332
333 (define_attr "braf_branch_p" "no,yes"
334 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
335 (const_string "no")
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
337 (const_int 20660))
338 (const_string "yes")
339 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
340 (const_string "no")
341 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
342 (const_int 65530))
343 (const_string "yes")
344 ] (const_string "no")))
345
346 (define_attr "braf_cbranch_p" "no,yes"
347 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
348 (const_string "no")
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
350 (const_int 20658))
351 (const_string "yes")
352 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353 (const_string "no")
354 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
355 (const_int 65528))
356 (const_string "yes")
357 ] (const_string "no")))
358
359 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
360 ; For wider ranges, we need a combination of a code and a data part.
361 ; If we can get a scratch register for a long range jump, the code
362 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
363 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
364 ; long; otherwise, it must be 6 bytes long.
365
366 ; All other instructions are two bytes long by default.
367
368 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
369 ;; but getattrtab doesn't understand this.
370 (define_attr "length" ""
371 (cond [(eq_attr "type" "cbranch")
372 (cond [(eq_attr "short_cbranch_p" "yes")
373 (const_int 2)
374 (eq_attr "med_cbranch_p" "yes")
375 (const_int 6)
376 (eq_attr "braf_cbranch_p" "yes")
377 (const_int 12)
378 ;; ??? using pc is not computed transitively.
379 (ne (match_dup 0) (match_dup 0))
380 (const_int 14)
381 (ne (symbol_ref ("flag_pic")) (const_int 0))
382 (const_int 24)
383 ] (const_int 16))
384 (eq_attr "type" "jump")
385 (cond [(eq_attr "med_branch_p" "yes")
386 (const_int 2)
387 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
388 (symbol_ref "INSN"))
389 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
390 (symbol_ref "code_for_indirect_jump_scratch")))
391 (if_then_else (eq_attr "braf_branch_p" "yes")
392 (const_int 6)
393 (const_int 10))
394 (eq_attr "braf_branch_p" "yes")
395 (const_int 10)
396 ;; ??? using pc is not computed transitively.
397 (ne (match_dup 0) (match_dup 0))
398 (const_int 12)
399 (ne (symbol_ref ("flag_pic")) (const_int 0))
400 (const_int 22)
401 ] (const_int 14))
402 (eq_attr "type" "pt_media")
403 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
404 (const_int 20) (const_int 12))
405 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
406 (const_int 4)
407 (const_int 2))))
408
409 ;; (define_function_unit {name} {num-units} {n-users} {test}
410 ;; {ready-delay} {issue-delay} [{conflict-list}])
411
412 ;; Load and store instructions save a cycle if they are aligned on a
413 ;; four byte boundary. Using a function unit for stores encourages
414 ;; gcc to separate load and store instructions by one instruction,
415 ;; which makes it more likely that the linker will be able to word
416 ;; align them when relaxing.
417
418 ;; Loads have a latency of two.
419 ;; However, call insns can have a delay slot, so that we want one more
420 ;; insn to be scheduled between the load of the function address and the call.
421 ;; This is equivalent to a latency of three.
422 ;; We cannot use a conflict list for this, because we need to distinguish
423 ;; between the actual call address and the function arguments.
424 ;; ADJUST_COST can only properly handle reductions of the cost, so we
425 ;; use a latency of three here.
426 ;; We only do this for SImode loads of general registers, to make the work
427 ;; for ADJUST_COST easier.
428 (define_function_unit "memory" 1 0
429 (and (eq_attr "pipe_model" "sh1")
430 (eq_attr "type" "load_si,pcload_si"))
431 3 2)
432 (define_function_unit "memory" 1 0
433 (and (eq_attr "pipe_model" "sh1")
434 (eq_attr "type" "load,pcload,pload,store,pstore"))
435 2 2)
436
437 (define_function_unit "int" 1 0
438 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
439
440 (define_function_unit "int" 1 0
441 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
442
443 (define_function_unit "int" 1 0
444 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
445
446 ;; ??? These are approximations.
447 (define_function_unit "mpy" 1 0
448 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
449 (define_function_unit "mpy" 1 0
450 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
451
452 (define_function_unit "fp" 1 0
453 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
454 (define_function_unit "fp" 1 0
455 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
456
457
458 ;; SH-5 SHmedia scheduling
459 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
460 ;; single-issue machine. It has four pipelines, the branch unit (br),
461 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
462 ;; the floating point unit (fpu).
463 ;; Here model the instructions with a latency greater than one cycle.
464
465 ;; Every instruction on SH-5 occupies the issue resource for at least one
466 ;; cycle.
467 (define_function_unit "sh5issue" 1 0
468 (and (eq_attr "pipe_model" "sh5media")
469 (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
470
471 ;; Specify the various types of instruction which have latency > 1
472 (define_function_unit "sh5issue" 1 0
473 (and (eq_attr "pipe_model" "sh5media")
474 (eq_attr "type" "mcmp_media")) 2 1)
475
476 (define_function_unit "sh5issue" 1 0
477 (and (eq_attr "pipe_model" "sh5media")
478 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
479 ;; but see sh_adjust_cost for mac_media exception.
480
481 (define_function_unit "sh5issue" 1 0
482 (and (eq_attr "pipe_model" "sh5media")
483 (eq_attr "type" "fload_media,fmove_media")) 4 1)
484
485 (define_function_unit "sh5issue" 1 0
486 (and (eq_attr "pipe_model" "sh5media")
487 (eq_attr "type" "d2mpy_media")) 4 2)
488
489 (define_function_unit "sh5issue" 1 0
490 (and (eq_attr "pipe_model" "sh5media")
491 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
492
493 (define_function_unit "sh5issue" 1 0
494 (and (eq_attr "pipe_model" "sh5media")
495 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
496
497 (define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "invalidate_line_media")) 7 7)
500
501 (define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
503
504 (define_function_unit "sh5issue" 1 0
505 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
506
507 ;; Floating-point divide and square-root occupy an additional resource,
508 ;; which is not internally pipelined. However, other instructions
509 ;; can continue to issue.
510 (define_function_unit "sh5fds" 1 0
511 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
512
513 (define_function_unit "sh5fds" 1 0
514 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
515
516 ; Definitions for filling branch delay slots.
517
518 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
519
520 ;; ??? This should be (nil) instead of (const_int 0)
521 (define_attr "hit_stack" "yes,no"
522 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
523 (const_int 0))
524 (const_string "no")]
525 (const_string "yes")))
526
527 (define_attr "interrupt_function" "no,yes"
528 (const (symbol_ref "current_function_interrupt")))
529
530 (define_attr "in_delay_slot" "yes,no"
531 (cond [(eq_attr "type" "cbranch") (const_string "no")
532 (eq_attr "type" "pcload,pcload_si") (const_string "no")
533 (eq_attr "needs_delay_slot" "yes") (const_string "no")
534 (eq_attr "length" "2") (const_string "yes")
535 ] (const_string "no")))
536
537 (define_attr "cond_delay_slot" "yes,no"
538 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
539 ] (const_string "no")))
540
541 (define_attr "is_sfunc" ""
542 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
543
544 (define_attr "is_mac_media" ""
545 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
546
547 (define_attr "branch_zero" "yes,no"
548 (cond [(eq_attr "type" "!cbranch") (const_string "no")
549 (ne (symbol_ref "(next_active_insn (insn)\
550 == (prev_active_insn\
551 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
552 && get_attr_length (next_active_insn (insn)) == 2")
553 (const_int 0))
554 (const_string "yes")]
555 (const_string "no")))
556
557 ;; SH4 Double-precision computation with double-precision result -
558 ;; the two halves are ready at different times.
559 (define_attr "dfp_comp" "yes,no"
560 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
561 (const_string "no")))
562
563 ;; Insns for which the latency of a preceding fp insn is decreased by one.
564 (define_attr "late_fp_use" "yes,no" (const_string "no"))
565 ;; And feeding insns for which this relevant.
566 (define_attr "any_fp_comp" "yes,no"
567 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
568 (const_string "yes")]
569 (const_string "no")))
570
571 (define_attr "any_int_load" "yes,no"
572 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
573 (const_string "yes")]
574 (const_string "no")))
575
576 (define_delay
577 (eq_attr "needs_delay_slot" "yes")
578 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
579
580 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
581 ;; and thus we can't put a pop instruction in its delay slot.
582 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
583 ;; instruction can go in the delay slot.
584
585 ;; Since a normal return (rts) implicitly uses the PR register,
586 ;; we can't allow PR register loads in an rts delay slot.
587
588 (define_delay
589 (eq_attr "type" "return")
590 [(and (eq_attr "in_delay_slot" "yes")
591 (ior (and (eq_attr "interrupt_function" "no")
592 (eq_attr "type" "!pload,prset"))
593 (and (eq_attr "interrupt_function" "yes")
594 (ior
595 (ne (symbol_ref "TARGET_SH3") (const_int 0))
596 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
597
598 ;; Since a call implicitly uses the PR register, we can't allow
599 ;; a PR register store in a jsr delay slot.
600
601 (define_delay
602 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
603 [(and (eq_attr "in_delay_slot" "yes")
604 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
605
606 ;; Say that we have annulled true branches, since this gives smaller and
607 ;; faster code when branches are predicted as not taken.
608
609 (define_delay
610 (and (eq_attr "type" "cbranch")
611 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
612 [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
613 \f
614 ;; -------------------------------------------------------------------------
615 ;; SImode signed integer comparisons
616 ;; -------------------------------------------------------------------------
617
618 (define_insn ""
619 [(set (reg:SI T_REG)
620 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
621 (match_operand:SI 1 "arith_operand" "L,r"))
622 (const_int 0)))]
623 "TARGET_SH1"
624 "tst %1,%0"
625 [(set_attr "type" "mt_group")])
626
627 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
628 ;; That would still allow reload to create cmpi instructions, but would
629 ;; perhaps allow forcing the constant into a register when that is better.
630 ;; Probably should use r0 for mem/imm compares, but force constant into a
631 ;; register for pseudo/imm compares.
632
633 (define_insn "cmpeqsi_t"
634 [(set (reg:SI T_REG)
635 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
636 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
637 "TARGET_SH1"
638 "@
639 tst %0,%0
640 cmp/eq %1,%0
641 cmp/eq %1,%0"
642 [(set_attr "type" "mt_group")])
643
644 (define_insn "cmpgtsi_t"
645 [(set (reg:SI T_REG)
646 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
647 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
648 "TARGET_SH1"
649 "@
650 cmp/gt %1,%0
651 cmp/pl %0"
652 [(set_attr "type" "mt_group")])
653
654 (define_insn "cmpgesi_t"
655 [(set (reg:SI T_REG)
656 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
657 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
658 "TARGET_SH1"
659 "@
660 cmp/ge %1,%0
661 cmp/pz %0"
662 [(set_attr "type" "mt_group")])
663
664 ;; -------------------------------------------------------------------------
665 ;; SImode unsigned integer comparisons
666 ;; -------------------------------------------------------------------------
667
668 (define_insn "cmpgeusi_t"
669 [(set (reg:SI T_REG)
670 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
671 (match_operand:SI 1 "arith_reg_operand" "r")))]
672 "TARGET_SH1"
673 "cmp/hs %1,%0"
674 [(set_attr "type" "mt_group")])
675
676 (define_insn "cmpgtusi_t"
677 [(set (reg:SI T_REG)
678 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
679 (match_operand:SI 1 "arith_reg_operand" "r")))]
680 "TARGET_SH1"
681 "cmp/hi %1,%0"
682 [(set_attr "type" "mt_group")])
683
684 ;; We save the compare operands in the cmpxx patterns and use them when
685 ;; we generate the branch.
686
687 (define_expand "cmpsi"
688 [(set (reg:SI T_REG)
689 (compare (match_operand:SI 0 "arith_operand" "")
690 (match_operand:SI 1 "arith_operand" "")))]
691 "TARGET_SH1"
692 "
693 {
694 sh_compare_op0 = operands[0];
695 sh_compare_op1 = operands[1];
696 DONE;
697 }")
698 \f
699 ;; -------------------------------------------------------------------------
700 ;; DImode signed integer comparisons
701 ;; -------------------------------------------------------------------------
702
703 ;; ??? Could get better scheduling by splitting the initial test from the
704 ;; rest of the insn after reload. However, the gain would hardly justify
705 ;; the sh.md size increase necessary to do that.
706
707 (define_insn ""
708 [(set (reg:SI T_REG)
709 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
710 (match_operand:DI 1 "arith_operand" "r"))
711 (const_int 0)))]
712 "TARGET_SH1"
713 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
714 insn, operands);"
715 [(set_attr "length" "6")
716 (set_attr "type" "arith3b")])
717
718 (define_insn "cmpeqdi_t"
719 [(set (reg:SI T_REG)
720 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
722 "TARGET_SH1"
723 "@
724 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
725 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
726 [(set_attr "length" "6")
727 (set_attr "type" "arith3b")])
728
729 (define_split
730 [(set (reg:SI T_REG)
731 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
732 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
733 ;; If we applied this split when not optimizing, it would only be
734 ;; applied during the machine-dependent reorg, when no new basic blocks
735 ;; may be created.
736 "TARGET_SH1 && reload_completed && optimize"
737 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
738 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
739 (label_ref (match_dup 6))
740 (pc)))
741 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
742 (match_dup 6)]
743 "
744 {
745 operands[2]
746 = gen_rtx_REG (SImode,
747 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
748 operands[3]
749 = (operands[1] == const0_rtx
750 ? const0_rtx
751 : gen_rtx_REG (SImode,
752 true_regnum (operands[1])
753 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
754 operands[4] = gen_lowpart (SImode, operands[0]);
755 operands[5] = gen_lowpart (SImode, operands[1]);
756 operands[6] = gen_label_rtx ();
757 }")
758
759 (define_insn "cmpgtdi_t"
760 [(set (reg:SI T_REG)
761 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
762 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
763 "TARGET_SH2"
764 "@
765 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
766 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
767 [(set_attr "length" "8")
768 (set_attr "type" "arith3")])
769
770 (define_insn "cmpgedi_t"
771 [(set (reg:SI T_REG)
772 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
774 "TARGET_SH2"
775 "@
776 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
777 cmp/pz\\t%S0"
778 [(set_attr "length" "8,2")
779 (set_attr "type" "arith3,mt_group")])
780 \f
781 ;; -------------------------------------------------------------------------
782 ;; DImode unsigned integer comparisons
783 ;; -------------------------------------------------------------------------
784
785 (define_insn "cmpgeudi_t"
786 [(set (reg:SI T_REG)
787 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
788 (match_operand:DI 1 "arith_reg_operand" "r")))]
789 "TARGET_SH2"
790 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
791 [(set_attr "length" "8")
792 (set_attr "type" "arith3")])
793
794 (define_insn "cmpgtudi_t"
795 [(set (reg:SI T_REG)
796 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
797 (match_operand:DI 1 "arith_reg_operand" "r")))]
798 "TARGET_SH2"
799 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
800 [(set_attr "length" "8")
801 (set_attr "type" "arith3")])
802
803 (define_insn "cmpeqdi_media"
804 [(set (match_operand:DI 0 "register_operand" "=r")
805 (eq:DI (match_operand:DI 1 "register_operand" "%r")
806 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
807 "TARGET_SHMEDIA"
808 "cmpeq %1, %N2, %0"
809 [(set_attr "type" "cmp_media")])
810
811 (define_insn "cmpgtdi_media"
812 [(set (match_operand:DI 0 "register_operand" "=r")
813 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
814 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
815 "TARGET_SHMEDIA"
816 "cmpgt %N1, %N2, %0"
817 [(set_attr "type" "cmp_media")])
818
819 (define_insn "cmpgtudi_media"
820 [(set (match_operand:DI 0 "register_operand" "=r")
821 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
822 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
823 "TARGET_SHMEDIA"
824 "cmpgtu %N1, %N2, %0"
825 [(set_attr "type" "cmp_media")])
826
827 ;; We save the compare operands in the cmpxx patterns and use them when
828 ;; we generate the branch.
829
830 (define_expand "cmpdi"
831 [(set (reg:SI T_REG)
832 (compare (match_operand:DI 0 "arith_operand" "")
833 (match_operand:DI 1 "arith_operand" "")))]
834 "TARGET_SH2 || TARGET_SHMEDIA"
835 "
836 {
837 sh_compare_op0 = operands[0];
838 sh_compare_op1 = operands[1];
839 DONE;
840 }")
841 ;; -------------------------------------------------------------------------
842 ;; Conditional move instructions
843 ;; -------------------------------------------------------------------------
844
845 ;; The insn names may seem reversed, but note that cmveq performs the move
846 ;; if op1 == 0, and cmvne does it if op1 != 0.
847
848 (define_insn "movdicc_false"
849 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
850 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
851 (const_int 0))
852 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
853 (match_operand:DI 3 "arith_reg_operand" "0")))]
854 "TARGET_SHMEDIA"
855 "cmveq %1, %N2, %0"
856 [(set_attr "type" "arith_media")])
857
858 (define_insn "movdicc_true"
859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
860 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
861 (const_int 0))
862 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
863 (match_operand:DI 3 "arith_reg_operand" "0")))]
864 "TARGET_SHMEDIA"
865 "cmvne %1, %N2, %0"
866 [(set_attr "type" "arith_media")])
867
868 (define_expand "movdicc"
869 [(set (match_operand:DI 0 "register_operand" "")
870 (if_then_else:DI (match_operand 1 "comparison_operator" "")
871 (match_operand:DI 2 "register_operand" "")
872 (match_operand:DI 3 "register_operand" "")))]
873 "TARGET_SHMEDIA"
874 "
875 {
876 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
877 && GET_MODE (sh_compare_op0) == DImode
878 && sh_compare_op1 == const0_rtx)
879 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
880 sh_compare_op0, sh_compare_op1);
881 else
882 {
883 rtx tmp;
884
885 if (no_new_pseudos)
886 FAIL;
887
888 tmp = gen_reg_rtx (DImode);
889
890 switch (GET_CODE (operands[1]))
891 {
892 case EQ:
893 emit_insn (gen_seq (tmp));
894 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
895 break;
896
897 case NE:
898 emit_insn (gen_seq (tmp));
899 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
900 break;
901
902 case GT:
903 emit_insn (gen_sgt (tmp));
904 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
905 break;
906
907 case LT:
908 emit_insn (gen_slt (tmp));
909 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
910 break;
911
912 case GE:
913 emit_insn (gen_slt (tmp));
914 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
915 break;
916
917 case LE:
918 emit_insn (gen_sgt (tmp));
919 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
920 break;
921
922 case GTU:
923 emit_insn (gen_sgtu (tmp));
924 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
925 break;
926
927 case LTU:
928 emit_insn (gen_sltu (tmp));
929 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
930 break;
931
932 case GEU:
933 emit_insn (gen_sltu (tmp));
934 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
935 break;
936
937 case LEU:
938 emit_insn (gen_sgtu (tmp));
939 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
940 break;
941
942 case UNORDERED:
943 emit_insn (gen_sunordered (tmp));
944 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
945 break;
946
947 case ORDERED:
948 emit_insn (gen_sunordered (tmp));
949 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
950 break;
951
952 case UNEQ:
953 case UNGE:
954 case UNGT:
955 case UNLE:
956 case UNLT:
957 case LTGT:
958 FAIL;
959
960 default:
961 abort ();
962 }
963 }
964 }")
965 \f
966 ;; -------------------------------------------------------------------------
967 ;; Addition instructions
968 ;; -------------------------------------------------------------------------
969
970 (define_expand "adddi3"
971 [(set (match_operand:DI 0 "arith_reg_operand" "")
972 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
973 (match_operand:DI 2 "arith_operand" "")))]
974 ""
975 "
976 {
977 if (TARGET_SH1)
978 {
979 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
980 FAIL;
981 operands[2] = force_reg (DImode, operands[2]);
982 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
983 DONE;
984 }
985 }")
986
987 (define_insn "*adddi3_media"
988 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
989 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
990 (match_operand:DI 2 "arith_operand" "r,P")))]
991 "TARGET_SHMEDIA"
992 "@
993 add %1, %2, %0
994 addi %1, %2, %0"
995 [(set_attr "type" "arith_media")])
996
997 (define_insn "adddi3z_media"
998 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
999 (zero_extend:DI
1000 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1001 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1002 "TARGET_SHMEDIA"
1003 "addz.l %1, %N2, %0"
1004 [(set_attr "type" "arith_media")])
1005
1006 (define_insn "adddi3_compact"
1007 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1008 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1009 (match_operand:DI 2 "arith_reg_operand" "r")))
1010 (clobber (reg:SI T_REG))]
1011 "TARGET_SH1"
1012 "#"
1013 [(set_attr "length" "6")])
1014
1015 (define_split
1016 [(set (match_operand:DI 0 "arith_reg_operand" "")
1017 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1018 (match_operand:DI 2 "arith_reg_operand" "")))
1019 (clobber (reg:SI T_REG))]
1020 "TARGET_SH1 && reload_completed"
1021 [(const_int 0)]
1022 "
1023 {
1024 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1025 high0 = gen_rtx_REG (SImode,
1026 true_regnum (operands[0])
1027 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1028 high2 = gen_rtx_REG (SImode,
1029 true_regnum (operands[2])
1030 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1031 emit_insn (gen_clrt ());
1032 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1033 emit_insn (gen_addc1 (high0, high0, high2));
1034 DONE;
1035 }")
1036
1037 (define_insn "addc"
1038 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1039 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1040 (match_operand:SI 2 "arith_reg_operand" "r"))
1041 (reg:SI T_REG)))
1042 (set (reg:SI T_REG)
1043 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1044 "TARGET_SH1"
1045 "addc %2,%0"
1046 [(set_attr "type" "arith")])
1047
1048 (define_insn "addc1"
1049 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1051 (match_operand:SI 2 "arith_reg_operand" "r"))
1052 (reg:SI T_REG)))
1053 (clobber (reg:SI T_REG))]
1054 "TARGET_SH1"
1055 "addc %2,%0"
1056 [(set_attr "type" "arith")])
1057
1058 (define_expand "addsi3"
1059 [(set (match_operand:SI 0 "arith_reg_operand" "")
1060 (plus:SI (match_operand:SI 1 "arith_operand" "")
1061 (match_operand:SI 2 "arith_operand" "")))]
1062 ""
1063 "
1064 {
1065 if (TARGET_SHMEDIA)
1066 operands[1] = force_reg (SImode, operands[1]);
1067 }")
1068
1069 (define_insn "addsi3_media"
1070 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1071 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1072 (match_operand:SI 2 "arith_operand" "r,P")))]
1073 "TARGET_SHMEDIA"
1074 "@
1075 add.l %1, %2, %0
1076 addi.l %1, %2, %0"
1077 [(set_attr "type" "arith_media")])
1078
1079 (define_insn "*addsi3_compact"
1080 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1081 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1082 (match_operand:SI 2 "arith_operand" "rI")))]
1083 "TARGET_SH1"
1084 "add %2,%0"
1085 [(set_attr "type" "arith")])
1086
1087 ;; -------------------------------------------------------------------------
1088 ;; Subtraction instructions
1089 ;; -------------------------------------------------------------------------
1090
1091 (define_expand "subdi3"
1092 [(set (match_operand:DI 0 "arith_reg_operand" "")
1093 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1094 (match_operand:DI 2 "arith_reg_operand" "")))]
1095 ""
1096 "
1097 {
1098 if (TARGET_SH1)
1099 {
1100 operands[1] = force_reg (DImode, operands[1]);
1101 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1102 DONE;
1103 }
1104 }")
1105
1106 (define_insn "*subdi3_media"
1107 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1108 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1109 (match_operand:DI 2 "arith_reg_operand" "r")))]
1110 "TARGET_SHMEDIA"
1111 "sub %N1, %2, %0"
1112 [(set_attr "type" "arith_media")])
1113
1114 (define_insn "subdi3_compact"
1115 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1116 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1117 (match_operand:DI 2 "arith_reg_operand" "r")))
1118 (clobber (reg:SI T_REG))]
1119 "TARGET_SH1"
1120 "#"
1121 [(set_attr "length" "6")])
1122
1123 (define_split
1124 [(set (match_operand:DI 0 "arith_reg_operand" "")
1125 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1126 (match_operand:DI 2 "arith_reg_operand" "")))
1127 (clobber (reg:SI T_REG))]
1128 "TARGET_SH1 && reload_completed"
1129 [(const_int 0)]
1130 "
1131 {
1132 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1133 high0 = gen_rtx_REG (SImode,
1134 true_regnum (operands[0])
1135 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1136 high2 = gen_rtx_REG (SImode,
1137 true_regnum (operands[2])
1138 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1139 emit_insn (gen_clrt ());
1140 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1141 emit_insn (gen_subc1 (high0, high0, high2));
1142 DONE;
1143 }")
1144
1145 (define_insn "subc"
1146 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1147 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1148 (match_operand:SI 2 "arith_reg_operand" "r"))
1149 (reg:SI T_REG)))
1150 (set (reg:SI T_REG)
1151 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1152 "TARGET_SH1"
1153 "subc %2,%0"
1154 [(set_attr "type" "arith")])
1155
1156 (define_insn "subc1"
1157 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1158 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1159 (match_operand:SI 2 "arith_reg_operand" "r"))
1160 (reg:SI T_REG)))
1161 (clobber (reg:SI T_REG))]
1162 "TARGET_SH1"
1163 "subc %2,%0"
1164 [(set_attr "type" "arith")])
1165
1166 (define_insn "*subsi3_internal"
1167 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1169 (match_operand:SI 2 "arith_reg_operand" "r")))]
1170 "TARGET_SH1"
1171 "sub %2,%0"
1172 [(set_attr "type" "arith")])
1173
1174 (define_insn "*subsi3_media"
1175 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1176 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1177 (match_operand:SI 2 "extend_reg_operand" "r")))]
1178 "TARGET_SHMEDIA"
1179 "sub.l %N1, %2, %0"
1180 [(set_attr "type" "arith_media")])
1181
1182 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1183 ;; will sometimes save one instruction. Otherwise we might get
1184 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1185 ;; are the same.
1186
1187 (define_expand "subsi3"
1188 [(set (match_operand:SI 0 "arith_reg_operand" "")
1189 (minus:SI (match_operand:SI 1 "arith_operand" "")
1190 (match_operand:SI 2 "arith_reg_operand" "")))]
1191 ""
1192 "
1193 {
1194 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1195 {
1196 emit_insn (gen_negsi2 (operands[0], operands[2]));
1197 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1198 DONE;
1199 }
1200 if (TARGET_SHMEDIA)
1201 {
1202 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1203 FAIL;
1204 if (operands[1] != const0_rtx)
1205 operands[1] = force_reg (SImode, operands[1]);
1206 }
1207 }")
1208 \f
1209 ;; -------------------------------------------------------------------------
1210 ;; Division instructions
1211 ;; -------------------------------------------------------------------------
1212
1213 ;; We take advantage of the library routines which don't clobber as many
1214 ;; registers as a normal function call would.
1215
1216 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1217 ;; also has an effect on the register that holds the address of the sfunc.
1218 ;; To make this work, we have an extra dummy insn that shows the use
1219 ;; of this register for reorg.
1220
1221 (define_insn "use_sfunc_addr"
1222 [(set (reg:SI PR_REG)
1223 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1224 "TARGET_SH1"
1225 ""
1226 [(set_attr "length" "0")])
1227
1228 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1229 ;; hard register 0. If we used hard register 0, then the next instruction
1230 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1231 ;; gets allocated to a stack slot that needs its address reloaded, then
1232 ;; there is nothing to prevent reload from using r0 to reload the address.
1233 ;; This reload would clobber the value in r0 we are trying to store.
1234 ;; If we let reload allocate r0, then this problem can never happen.
1235
1236 (define_insn "udivsi3_i1"
1237 [(set (match_operand:SI 0 "register_operand" "=z")
1238 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1239 (clobber (reg:SI T_REG))
1240 (clobber (reg:SI PR_REG))
1241 (clobber (reg:SI R4_REG))
1242 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1243 "TARGET_SH1 && ! TARGET_SH4"
1244 "jsr @%1%#"
1245 [(set_attr "type" "sfunc")
1246 (set_attr "needs_delay_slot" "yes")])
1247
1248 ; Since shmedia-nofpu code could be linked against shcompact code, and
1249 ; the udivsi3 libcall has the same name, we must consider all registers
1250 ; clobbered that are in the union of the registers clobbered by the
1251 ; shmedia and the shcompact implementation. Note, if the shcompact
1252 ; implemenation actually used shcompact code, we'd need to clobber
1253 ; also r23 and fr23.
1254 (define_insn "udivsi3_i1_media"
1255 [(set (match_operand:SI 0 "register_operand" "=z")
1256 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1257 (clobber (reg:SI T_MEDIA_REG))
1258 (clobber (reg:SI PR_MEDIA_REG))
1259 (clobber (reg:SI R20_REG))
1260 (clobber (reg:SI R21_REG))
1261 (clobber (reg:SI R22_REG))
1262 (clobber (reg:DI TR0_REG))
1263 (clobber (reg:DI TR1_REG))
1264 (clobber (reg:DI TR2_REG))
1265 (use (match_operand:DI 1 "target_operand" "b"))]
1266 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1267 "blink %1, r18"
1268 [(set_attr "type" "sfunc")
1269 (set_attr "needs_delay_slot" "yes")])
1270
1271 (define_expand "udivsi3_i4_media"
1272 [(set (match_dup 3)
1273 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1274 (set (match_dup 4)
1275 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1276 (set (match_dup 5) (float:DF (match_dup 3)))
1277 (set (match_dup 6) (float:DF (match_dup 4)))
1278 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1279 (set (match_dup 8) (fix:DI (match_dup 7)))
1280 (set (match_operand:SI 0 "register_operand" "")
1281 (truncate:SI (match_dup 8)))]
1282 "TARGET_SHMEDIA_FPU"
1283 "
1284 {
1285 operands[3] = gen_reg_rtx (DImode);
1286 operands[4] = gen_reg_rtx (DImode);
1287 operands[5] = gen_reg_rtx (DFmode);
1288 operands[6] = gen_reg_rtx (DFmode);
1289 operands[7] = gen_reg_rtx (DFmode);
1290 operands[8] = gen_reg_rtx (DImode);
1291 }")
1292
1293 (define_insn "udivsi3_i4"
1294 [(set (match_operand:SI 0 "register_operand" "=y")
1295 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1296 (clobber (reg:SI T_REG))
1297 (clobber (reg:SI PR_REG))
1298 (clobber (reg:DF DR0_REG))
1299 (clobber (reg:DF DR2_REG))
1300 (clobber (reg:DF DR4_REG))
1301 (clobber (reg:SI R0_REG))
1302 (clobber (reg:SI R1_REG))
1303 (clobber (reg:SI R4_REG))
1304 (clobber (reg:SI R5_REG))
1305 (use (reg:PSI FPSCR_REG))
1306 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1307 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1308 "jsr @%1%#"
1309 [(set_attr "type" "sfunc")
1310 (set_attr "fp_mode" "double")
1311 (set_attr "needs_delay_slot" "yes")])
1312
1313 (define_insn "udivsi3_i4_single"
1314 [(set (match_operand:SI 0 "register_operand" "=y")
1315 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1316 (clobber (reg:SI T_REG))
1317 (clobber (reg:SI PR_REG))
1318 (clobber (reg:DF DR0_REG))
1319 (clobber (reg:DF DR2_REG))
1320 (clobber (reg:DF DR4_REG))
1321 (clobber (reg:SI R0_REG))
1322 (clobber (reg:SI R1_REG))
1323 (clobber (reg:SI R4_REG))
1324 (clobber (reg:SI R5_REG))
1325 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1326 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1327 "jsr @%1%#"
1328 [(set_attr "type" "sfunc")
1329 (set_attr "needs_delay_slot" "yes")])
1330
1331 (define_expand "udivsi3"
1332 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1333 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1334 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1335 (parallel [(set (match_operand:SI 0 "register_operand" "")
1336 (udiv:SI (reg:SI R4_REG)
1337 (reg:SI R5_REG)))
1338 (clobber (reg:SI T_REG))
1339 (clobber (reg:SI PR_REG))
1340 (clobber (reg:SI R4_REG))
1341 (use (match_dup 3))])]
1342 ""
1343 "
1344 {
1345 rtx first, last;
1346
1347 operands[3] = gen_reg_rtx (Pmode);
1348 /* Emit the move of the address to a pseudo outside of the libcall. */
1349 if (TARGET_HARD_SH4 && TARGET_SH3E)
1350 {
1351 emit_move_insn (operands[3],
1352 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1353 if (TARGET_FPU_SINGLE)
1354 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1355 else
1356 last = gen_udivsi3_i4 (operands[0], operands[3]);
1357 }
1358 else if (TARGET_SHMEDIA_FPU)
1359 {
1360 operands[1] = force_reg (SImode, operands[1]);
1361 operands[2] = force_reg (SImode, operands[2]);
1362 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1363 DONE;
1364 }
1365 else if (TARGET_SH5)
1366 {
1367 emit_move_insn (operands[3],
1368 gen_rtx_SYMBOL_REF (Pmode,
1369 (TARGET_FPU_ANY
1370 ? \"__udivsi3_i4\"
1371 : \"__udivsi3\")));
1372
1373 if (TARGET_SHMEDIA)
1374 last = gen_udivsi3_i1_media (operands[0],
1375 Pmode == DImode
1376 ? operands[3]
1377 : gen_rtx_SUBREG (DImode, operands[3],
1378 0));
1379 else if (TARGET_FPU_ANY)
1380 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1381 else
1382 last = gen_udivsi3_i1 (operands[0], operands[3]);
1383 }
1384 else
1385 {
1386 emit_move_insn (operands[3],
1387 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1388 last = gen_udivsi3_i1 (operands[0], operands[3]);
1389 }
1390 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1391 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1392 last = emit_insn (last);
1393 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1394 invariant code motion can move it. */
1395 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1396 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1397 DONE;
1398 }")
1399
1400 (define_insn "divsi3_i1"
1401 [(set (match_operand:SI 0 "register_operand" "=z")
1402 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1403 (clobber (reg:SI T_REG))
1404 (clobber (reg:SI PR_REG))
1405 (clobber (reg:SI R1_REG))
1406 (clobber (reg:SI R2_REG))
1407 (clobber (reg:SI R3_REG))
1408 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1409 "TARGET_SH1 && ! TARGET_SH4"
1410 "jsr @%1%#"
1411 [(set_attr "type" "sfunc")
1412 (set_attr "needs_delay_slot" "yes")])
1413
1414 ; Since shmedia-nofpu code could be linked against shcompact code, and
1415 ; the sdivsi3 libcall has the same name, we must consider all registers
1416 ; clobbered that are in the union of the registers clobbered by the
1417 ; shmedia and the shcompact implementation. Note, if the shcompact
1418 ; implemenation actually used shcompact code, we'd need to clobber
1419 ; also r22, r23 and fr23.
1420 (define_insn "divsi3_i1_media"
1421 [(set (match_operand:SI 0 "register_operand" "=z")
1422 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1423 (clobber (reg:SI T_MEDIA_REG))
1424 (clobber (reg:SI PR_MEDIA_REG))
1425 (clobber (reg:SI R1_REG))
1426 (clobber (reg:SI R2_REG))
1427 (clobber (reg:SI R3_REG))
1428 (clobber (reg:SI R20_REG))
1429 (clobber (reg:SI R21_REG))
1430 (clobber (reg:DI TR0_REG))
1431 (clobber (reg:DI TR1_REG))
1432 (clobber (reg:DI TR2_REG))
1433 (use (match_operand:DI 1 "target_operand" "b"))]
1434 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1435 "blink %1, r18"
1436 [(set_attr "type" "sfunc")])
1437
1438 (define_expand "divsi3_i4_media"
1439 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1440 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1441 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1442 (set (match_operand:SI 0 "register_operand" "=r")
1443 (fix:SI (match_dup 5)))]
1444 "TARGET_SHMEDIA_FPU"
1445 "
1446 {
1447 operands[3] = gen_reg_rtx (DFmode);
1448 operands[4] = gen_reg_rtx (DFmode);
1449 operands[5] = gen_reg_rtx (DFmode);
1450 }")
1451
1452 (define_insn "divsi3_i4"
1453 [(set (match_operand:SI 0 "register_operand" "=y")
1454 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1455 (clobber (reg:SI PR_REG))
1456 (clobber (reg:DF DR0_REG))
1457 (clobber (reg:DF DR2_REG))
1458 (use (reg:PSI FPSCR_REG))
1459 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1460 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1461 "jsr @%1%#"
1462 [(set_attr "type" "sfunc")
1463 (set_attr "fp_mode" "double")
1464 (set_attr "needs_delay_slot" "yes")])
1465
1466 (define_insn "divsi3_i4_single"
1467 [(set (match_operand:SI 0 "register_operand" "=y")
1468 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1469 (clobber (reg:SI PR_REG))
1470 (clobber (reg:DF DR0_REG))
1471 (clobber (reg:DF DR2_REG))
1472 (clobber (reg:SI R2_REG))
1473 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1474 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1475 "jsr @%1%#"
1476 [(set_attr "type" "sfunc")
1477 (set_attr "needs_delay_slot" "yes")])
1478
1479 (define_expand "divsi3"
1480 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1481 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1482 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1483 (parallel [(set (match_operand:SI 0 "register_operand" "")
1484 (div:SI (reg:SI R4_REG)
1485 (reg:SI R5_REG)))
1486 (clobber (reg:SI T_REG))
1487 (clobber (reg:SI PR_REG))
1488 (clobber (reg:SI R1_REG))
1489 (clobber (reg:SI R2_REG))
1490 (clobber (reg:SI R3_REG))
1491 (use (match_dup 3))])]
1492 ""
1493 "
1494 {
1495 rtx first, last;
1496
1497 operands[3] = gen_reg_rtx (Pmode);
1498 /* Emit the move of the address to a pseudo outside of the libcall. */
1499 if (TARGET_HARD_SH4 && TARGET_SH3E)
1500 {
1501 emit_move_insn (operands[3],
1502 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1503 if (TARGET_FPU_SINGLE)
1504 last = gen_divsi3_i4_single (operands[0], operands[3]);
1505 else
1506 last = gen_divsi3_i4 (operands[0], operands[3]);
1507 }
1508 else if (TARGET_SHMEDIA_FPU)
1509 {
1510 operands[1] = force_reg (SImode, operands[1]);
1511 operands[2] = force_reg (SImode, operands[2]);
1512 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1513 DONE;
1514 }
1515 else if (TARGET_SH5)
1516 {
1517 emit_move_insn (operands[3],
1518 gen_rtx_SYMBOL_REF (Pmode,
1519 (TARGET_FPU_ANY
1520 ? \"__sdivsi3_i4\"
1521 : \"__sdivsi3\")));
1522
1523 if (TARGET_SHMEDIA)
1524 last = gen_divsi3_i1_media (operands[0],
1525 Pmode == DImode
1526 ? operands[3]
1527 : gen_rtx_SUBREG (DImode, operands[3],
1528 0));
1529 else if (TARGET_FPU_ANY)
1530 last = gen_divsi3_i4_single (operands[0], operands[3]);
1531 else
1532 last = gen_divsi3_i1 (operands[0], operands[3]);
1533 }
1534 else
1535 {
1536 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1537 last = gen_divsi3_i1 (operands[0], operands[3]);
1538 }
1539 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1540 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1541 last = emit_insn (last);
1542 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1543 invariant code motion can move it. */
1544 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1545 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1546 DONE;
1547 }")
1548 \f
1549 ;; -------------------------------------------------------------------------
1550 ;; Multiplication instructions
1551 ;; -------------------------------------------------------------------------
1552
1553 (define_insn "umulhisi3_i"
1554 [(set (reg:SI MACL_REG)
1555 (mult:SI (zero_extend:SI
1556 (match_operand:HI 0 "arith_reg_operand" "r"))
1557 (zero_extend:SI
1558 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1559 "TARGET_SH1"
1560 "mulu.w %1,%0"
1561 [(set_attr "type" "smpy")])
1562
1563 (define_insn "mulhisi3_i"
1564 [(set (reg:SI MACL_REG)
1565 (mult:SI (sign_extend:SI
1566 (match_operand:HI 0 "arith_reg_operand" "r"))
1567 (sign_extend:SI
1568 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1569 "TARGET_SH1"
1570 "muls.w %1,%0"
1571 [(set_attr "type" "smpy")])
1572
1573 (define_expand "mulhisi3"
1574 [(set (reg:SI MACL_REG)
1575 (mult:SI (sign_extend:SI
1576 (match_operand:HI 1 "arith_reg_operand" ""))
1577 (sign_extend:SI
1578 (match_operand:HI 2 "arith_reg_operand" ""))))
1579 (set (match_operand:SI 0 "arith_reg_operand" "")
1580 (reg:SI MACL_REG))]
1581 "TARGET_SH1"
1582 "
1583 {
1584 rtx first, last;
1585
1586 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1587 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1588 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1589 invariant code motion can move it. */
1590 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1591 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1592 /* expand_binop can't find a suitable code in umul_widen_optab to
1593 make a REG_EQUAL note from, so make one here.
1594 See also smulsi3_highpart.
1595 ??? Alternatively, we could put this at the calling site of expand_binop,
1596 i.e. expand_expr. */
1597 REG_NOTES (last)
1598 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1599 REG_NOTES (last));
1600 DONE;
1601 }")
1602
1603 (define_expand "umulhisi3"
1604 [(set (reg:SI MACL_REG)
1605 (mult:SI (zero_extend:SI
1606 (match_operand:HI 1 "arith_reg_operand" ""))
1607 (zero_extend:SI
1608 (match_operand:HI 2 "arith_reg_operand" ""))))
1609 (set (match_operand:SI 0 "arith_reg_operand" "")
1610 (reg:SI MACL_REG))]
1611 "TARGET_SH1"
1612 "
1613 {
1614 rtx first, last;
1615
1616 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1617 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1618 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1619 invariant code motion can move it. */
1620 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1621 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1622 /* expand_binop can't find a suitable code in umul_widen_optab to
1623 make a REG_EQUAL note from, so make one here.
1624 See also smulsi3_highpart.
1625 ??? Alternatively, we could put this at the calling site of expand_binop,
1626 i.e. expand_expr. */
1627 REG_NOTES (last)
1628 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1629 REG_NOTES (last));
1630 DONE;
1631 }")
1632
1633 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1634 ;; a call to a routine which clobbers known registers.
1635
1636 (define_insn ""
1637 [(set (match_operand:SI 1 "register_operand" "=z")
1638 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1639 (clobber (reg:SI MACL_REG))
1640 (clobber (reg:SI T_REG))
1641 (clobber (reg:SI PR_REG))
1642 (clobber (reg:SI R3_REG))
1643 (clobber (reg:SI R2_REG))
1644 (clobber (reg:SI R1_REG))
1645 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1646 "TARGET_SH1"
1647 "jsr @%0%#"
1648 [(set_attr "type" "sfunc")
1649 (set_attr "needs_delay_slot" "yes")])
1650
1651 (define_expand "mulsi3_call"
1652 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1653 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1654 (parallel[(set (match_operand:SI 0 "register_operand" "")
1655 (mult:SI (reg:SI R4_REG)
1656 (reg:SI R5_REG)))
1657 (clobber (reg:SI MACL_REG))
1658 (clobber (reg:SI T_REG))
1659 (clobber (reg:SI PR_REG))
1660 (clobber (reg:SI R3_REG))
1661 (clobber (reg:SI R2_REG))
1662 (clobber (reg:SI R1_REG))
1663 (use (match_operand:SI 3 "register_operand" ""))])]
1664 "TARGET_SH1"
1665 "")
1666
1667 (define_insn "mul_l"
1668 [(set (reg:SI MACL_REG)
1669 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1670 (match_operand:SI 1 "arith_reg_operand" "r")))]
1671 "TARGET_SH2"
1672 "mul.l %1,%0"
1673 [(set_attr "type" "dmpy")])
1674
1675 (define_expand "mulsi3"
1676 [(set (reg:SI MACL_REG)
1677 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1678 (match_operand:SI 2 "arith_reg_operand" "")))
1679 (set (match_operand:SI 0 "arith_reg_operand" "")
1680 (reg:SI MACL_REG))]
1681 "TARGET_SH1"
1682 "
1683 {
1684 rtx first, last;
1685
1686 if (!TARGET_SH2)
1687 {
1688 /* The address must be set outside the libcall,
1689 since it goes into a pseudo. */
1690 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1691 rtx addr = force_reg (SImode, sym);
1692 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1693 operands[2], addr);
1694 first = insns;
1695 last = emit_insn (insns);
1696 }
1697 else
1698 {
1699 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1700
1701 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1702 /* consec_sets_giv can only recognize the first insn that sets a
1703 giv as the giv insn. So we must tag this also with a REG_EQUAL
1704 note. */
1705 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1706 }
1707 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1708 invariant code motion can move it. */
1709 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1710 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1711 DONE;
1712 }")
1713
1714 (define_insn "mulsidi3_i"
1715 [(set (reg:SI MACH_REG)
1716 (truncate:SI
1717 (lshiftrt:DI
1718 (mult:DI
1719 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1720 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1721 (const_int 32))))
1722 (set (reg:SI MACL_REG)
1723 (mult:SI (match_dup 0)
1724 (match_dup 1)))]
1725 "TARGET_SH2"
1726 "dmuls.l %1,%0"
1727 [(set_attr "type" "dmpy")])
1728
1729 (define_expand "mulsidi3"
1730 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1731 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1732 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1733 "TARGET_SH2 || TARGET_SHMEDIA"
1734 "
1735 {
1736 if (TARGET_SH2)
1737 {
1738 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1739 operands[2]));
1740 DONE;
1741 }
1742 }")
1743
1744 (define_insn "mulsidi3_media"
1745 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1746 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1747 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1748 "TARGET_SHMEDIA"
1749 "muls.l %1, %2, %0"
1750 [(set_attr "type" "dmpy_media")])
1751
1752 (define_insn "mulsidi3_compact"
1753 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1754 (mult:DI
1755 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1756 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1757 (clobber (reg:SI MACH_REG))
1758 (clobber (reg:SI MACL_REG))]
1759 "TARGET_SH2"
1760 "#")
1761
1762 (define_split
1763 [(set (match_operand:DI 0 "arith_reg_operand" "")
1764 (mult:DI
1765 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1766 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1767 (clobber (reg:SI MACH_REG))
1768 (clobber (reg:SI MACL_REG))]
1769 "TARGET_SH2"
1770 [(const_int 0)]
1771 "
1772 {
1773 rtx low_dst = gen_lowpart (SImode, operands[0]);
1774 rtx high_dst = gen_highpart (SImode, operands[0]);
1775
1776 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1777
1778 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1779 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1780 /* We need something to tag the possible REG_EQUAL notes on to. */
1781 emit_move_insn (operands[0], operands[0]);
1782 DONE;
1783 }")
1784
1785 (define_insn "umulsidi3_i"
1786 [(set (reg:SI MACH_REG)
1787 (truncate:SI
1788 (lshiftrt:DI
1789 (mult:DI
1790 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1791 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1792 (const_int 32))))
1793 (set (reg:SI MACL_REG)
1794 (mult:SI (match_dup 0)
1795 (match_dup 1)))]
1796 "TARGET_SH2"
1797 "dmulu.l %1,%0"
1798 [(set_attr "type" "dmpy")])
1799
1800 (define_expand "umulsidi3"
1801 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1802 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1803 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1804 "TARGET_SH2 || TARGET_SHMEDIA"
1805 "
1806 {
1807 if (TARGET_SH2)
1808 {
1809 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1810 operands[2]));
1811 DONE;
1812 }
1813 }")
1814
1815 (define_insn "umulsidi3_media"
1816 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1817 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1818 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1819 "TARGET_SHMEDIA"
1820 "mulu.l %1, %2, %0"
1821 [(set_attr "type" "dmpy_media")])
1822
1823 (define_insn "umulsidi3_compact"
1824 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1825 (mult:DI
1826 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1827 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1828 (clobber (reg:SI MACH_REG))
1829 (clobber (reg:SI MACL_REG))]
1830 "TARGET_SH2"
1831 "#")
1832
1833 (define_split
1834 [(set (match_operand:DI 0 "arith_reg_operand" "")
1835 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1836 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1837 (clobber (reg:SI MACH_REG))
1838 (clobber (reg:SI MACL_REG))]
1839 "TARGET_SH2"
1840 [(const_int 0)]
1841 "
1842 {
1843 rtx low_dst = gen_lowpart (SImode, operands[0]);
1844 rtx high_dst = gen_highpart (SImode, operands[0]);
1845
1846 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1847
1848 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1849 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1850 /* We need something to tag the possible REG_EQUAL notes on to. */
1851 emit_move_insn (operands[0], operands[0]);
1852 DONE;
1853 }")
1854
1855 (define_insn "smulsi3_highpart_i"
1856 [(set (reg:SI MACH_REG)
1857 (truncate:SI
1858 (lshiftrt:DI
1859 (mult:DI
1860 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1861 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1862 (const_int 32))))
1863 (clobber (reg:SI MACL_REG))]
1864 "TARGET_SH2"
1865 "dmuls.l %1,%0"
1866 [(set_attr "type" "dmpy")])
1867
1868 (define_expand "smulsi3_highpart"
1869 [(parallel
1870 [(set (reg:SI MACH_REG)
1871 (truncate:SI
1872 (lshiftrt:DI
1873 (mult:DI
1874 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1875 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1876 (const_int 32))))
1877 (clobber (reg:SI MACL_REG))])
1878 (set (match_operand:SI 0 "arith_reg_operand" "")
1879 (reg:SI MACH_REG))]
1880 "TARGET_SH2"
1881 "
1882 {
1883 rtx first, last;
1884
1885 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1886 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1887 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1888 invariant code motion can move it. */
1889 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1890 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1891 /* expand_binop can't find a suitable code in mul_highpart_optab to
1892 make a REG_EQUAL note from, so make one here.
1893 See also {,u}mulhisi.
1894 ??? Alternatively, we could put this at the calling site of expand_binop,
1895 i.e. expand_mult_highpart. */
1896 REG_NOTES (last)
1897 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1898 REG_NOTES (last));
1899 DONE;
1900 }")
1901
1902 (define_insn "umulsi3_highpart_i"
1903 [(set (reg:SI MACH_REG)
1904 (truncate:SI
1905 (lshiftrt:DI
1906 (mult:DI
1907 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1908 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1909 (const_int 32))))
1910 (clobber (reg:SI MACL_REG))]
1911 "TARGET_SH2"
1912 "dmulu.l %1,%0"
1913 [(set_attr "type" "dmpy")])
1914
1915 (define_expand "umulsi3_highpart"
1916 [(parallel
1917 [(set (reg:SI MACH_REG)
1918 (truncate:SI
1919 (lshiftrt:DI
1920 (mult:DI
1921 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1922 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1923 (const_int 32))))
1924 (clobber (reg:SI MACL_REG))])
1925 (set (match_operand:SI 0 "arith_reg_operand" "")
1926 (reg:SI MACH_REG))]
1927 "TARGET_SH2"
1928 "
1929 {
1930 rtx first, last;
1931
1932 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1933 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1934 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1935 invariant code motion can move it. */
1936 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1937 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1938 DONE;
1939 }")
1940 \f
1941 ;; -------------------------------------------------------------------------
1942 ;; Logical operations
1943 ;; -------------------------------------------------------------------------
1944
1945 (define_insn "*andsi3_compact"
1946 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1947 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1948 (match_operand:SI 2 "logical_operand" "r,L")))]
1949 "TARGET_SH1"
1950 "and %2,%0"
1951 [(set_attr "type" "arith")])
1952
1953 ;; If the constant is 255, then emit an extu.b instruction instead of an
1954 ;; and, since that will give better code.
1955
1956 (define_expand "andsi3"
1957 [(set (match_operand:SI 0 "arith_reg_operand" "")
1958 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1959 (match_operand:SI 2 "logical_operand" "")))]
1960 "TARGET_SH1"
1961 "
1962 {
1963 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1964 {
1965 emit_insn (gen_zero_extendqisi2 (operands[0],
1966 gen_lowpart (QImode, operands[1])));
1967 DONE;
1968 }
1969 }")
1970
1971 (define_insn_and_split "anddi3"
1972 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1973 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1974 (match_operand:DI 2 "and_operand" "r,P,Z")))]
1975 "TARGET_SHMEDIA"
1976 "@
1977 and %1, %2, %0
1978 andi %1, %2, %0
1979 #"
1980 "reload_completed
1981 && ! logical_operand (operands[2], DImode)"
1982 [(const_int 0)]
1983 "
1984 {
1985 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1986 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1987 else
1988 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1989 DONE;
1990 }"
1991 [(set_attr "type" "arith_media")])
1992
1993 (define_insn "andcdi3"
1994 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1995 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1996 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1997 "TARGET_SHMEDIA"
1998 "andc %1,%2,%0"
1999 [(set_attr "type" "arith_media")])
2000
2001 (define_insn "iorsi3"
2002 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2003 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2004 (match_operand:SI 2 "logical_operand" "r,L")))]
2005 "TARGET_SH1"
2006 "or %2,%0"
2007 [(set_attr "type" "arith")])
2008
2009 (define_insn "iordi3"
2010 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2011 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2012 (match_operand:DI 2 "logical_operand" "r,P")))]
2013 "TARGET_SHMEDIA"
2014 "@
2015 or %1, %2, %0
2016 ori %1, %2, %0"
2017 [(set_attr "type" "arith_media")])
2018
2019 (define_insn "xorsi3"
2020 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2021 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2022 (match_operand:SI 2 "logical_operand" "L,r")))]
2023 "TARGET_SH1"
2024 "xor %2,%0"
2025 [(set_attr "type" "arith")])
2026
2027 (define_insn "xordi3"
2028 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2029 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2030 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2031 "TARGET_SHMEDIA"
2032 "@
2033 xor %1, %2, %0
2034 xori %1, %2, %0"
2035 [(set_attr "type" "arith_media")])
2036
2037 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2038 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2039 (define_split
2040 [(set (match_operand:DI 0 "arith_reg_operand" "")
2041 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2042 [(match_operand 1 "any_register_operand" "")
2043 (match_operand 2 "any_register_operand" "")])))]
2044 "TARGET_SHMEDIA"
2045 [(set (match_dup 5) (match_dup 4))
2046 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2047 "
2048 {
2049 enum machine_mode inmode = GET_MODE (operands[1]);
2050 int regno, offset = 0;
2051
2052 if (GET_CODE (operands[0]) == SUBREG)
2053 {
2054 offset = SUBREG_BYTE (operands[0]);
2055 operands[0] = SUBREG_REG (operands[0]);
2056 }
2057 if (GET_CODE (operands[0]) != REG)
2058 abort ();
2059 if (! TARGET_LITTLE_ENDIAN)
2060 offset += 8 - GET_MODE_SIZE (inmode);
2061 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2062 }")
2063 \f
2064 ;; -------------------------------------------------------------------------
2065 ;; Shifts and rotates
2066 ;; -------------------------------------------------------------------------
2067
2068 (define_expand "rotldi3"
2069 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2070 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2071 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2072 "TARGET_SHMEDIA"
2073 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2074
2075 (define_insn "rotldi3_mextr"
2076 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2077 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2078 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2079 "TARGET_SHMEDIA"
2080 "*
2081 {
2082 static char templ[16];
2083
2084 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2085 8 - (int) (INTVAL (operands[2]) >> 3));
2086 return templ;
2087 }"
2088 [(set_attr "type" "arith_media")])
2089
2090 (define_expand "rotrdi3"
2091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2092 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2093 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2094 "TARGET_SHMEDIA"
2095 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2096
2097 (define_insn "rotrdi3_mextr"
2098 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2099 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2100 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2101 "TARGET_SHMEDIA"
2102 "*
2103 {
2104 static char templ[16];
2105
2106 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2107 return templ;
2108 }"
2109 [(set_attr "type" "arith_media")])
2110
2111 (define_insn "rotlsi3_1"
2112 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2113 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2114 (const_int 1)))
2115 (set (reg:SI T_REG)
2116 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2117 "TARGET_SH1"
2118 "rotl %0"
2119 [(set_attr "type" "arith")])
2120
2121 (define_insn "rotlsi3_31"
2122 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2123 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2124 (const_int 31)))
2125 (clobber (reg:SI T_REG))]
2126 "TARGET_SH1"
2127 "rotr %0"
2128 [(set_attr "type" "arith")])
2129
2130 (define_insn "rotlsi3_16"
2131 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2133 (const_int 16)))]
2134 "TARGET_SH1"
2135 "swap.w %1,%0"
2136 [(set_attr "type" "arith")])
2137
2138 (define_expand "rotlsi3"
2139 [(set (match_operand:SI 0 "arith_reg_operand" "")
2140 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2141 (match_operand:SI 2 "immediate_operand" "")))]
2142 "TARGET_SH1"
2143 "
2144 {
2145 static const char rot_tab[] = {
2146 000, 000, 000, 000, 000, 000, 010, 001,
2147 001, 001, 011, 013, 003, 003, 003, 003,
2148 003, 003, 003, 003, 003, 013, 012, 002,
2149 002, 002, 010, 000, 000, 000, 000, 000,
2150 };
2151
2152 int count, choice;
2153
2154 if (GET_CODE (operands[2]) != CONST_INT)
2155 FAIL;
2156 count = INTVAL (operands[2]);
2157 choice = rot_tab[count];
2158 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2159 FAIL;
2160 choice &= 7;
2161 switch (choice)
2162 {
2163 case 0:
2164 emit_move_insn (operands[0], operands[1]);
2165 count -= (count & 16) * 2;
2166 break;
2167 case 3:
2168 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2169 count -= 16;
2170 break;
2171 case 1:
2172 case 2:
2173 {
2174 rtx parts[2];
2175 parts[0] = gen_reg_rtx (SImode);
2176 parts[1] = gen_reg_rtx (SImode);
2177 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2178 parts[choice-1] = operands[1];
2179 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2180 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2181 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2182 count = (count & ~16) - 8;
2183 }
2184 }
2185
2186 for (; count > 0; count--)
2187 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2188 for (; count < 0; count++)
2189 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2190
2191 DONE;
2192 }")
2193
2194 (define_insn "*rotlhi3_8"
2195 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2196 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2197 (const_int 8)))]
2198 "TARGET_SH1"
2199 "swap.b %1,%0"
2200 [(set_attr "type" "arith")])
2201
2202 (define_expand "rotlhi3"
2203 [(set (match_operand:HI 0 "arith_reg_operand" "")
2204 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2205 (match_operand:HI 2 "immediate_operand" "")))]
2206 "TARGET_SH1"
2207 "
2208 {
2209 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2210 FAIL;
2211 }")
2212
2213 ;;
2214 ;; shift left
2215
2216 ;; This pattern is used by init_expmed for computing the costs of shift
2217 ;; insns.
2218
2219 (define_insn_and_split "ashlsi3_std"
2220 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2221 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2222 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2223 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2224 "TARGET_SH3
2225 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2226 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2227 "@
2228 shld %2,%0
2229 add %0,%0
2230 shll%O2 %0
2231 #"
2232 "TARGET_SH3
2233 && reload_completed
2234 && GET_CODE (operands[2]) == CONST_INT
2235 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2236 [(set (match_dup 3) (match_dup 2))
2237 (parallel
2238 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2239 (clobber (match_dup 4))])]
2240 "operands[4] = gen_rtx_SCRATCH (SImode);"
2241 [(set_attr "length" "*,*,*,4")
2242 (set_attr "type" "dyn_shift,arith,arith,arith")])
2243
2244 (define_insn "ashlhi3_k"
2245 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2246 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2247 (match_operand:HI 2 "const_int_operand" "M,K")))]
2248 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2249 "@
2250 add %0,%0
2251 shll%O2 %0"
2252 [(set_attr "type" "arith")])
2253
2254 (define_insn "ashlsi3_n"
2255 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2256 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2257 (match_operand:SI 2 "const_int_operand" "n")))
2258 (clobber (reg:SI T_REG))]
2259 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2260 "#"
2261 [(set (attr "length")
2262 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2263 (const_string "2")
2264 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2265 (const_string "4")
2266 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2267 (const_string "6")]
2268 (const_string "8")))
2269 (set_attr "type" "arith")])
2270
2271 (define_split
2272 [(set (match_operand:SI 0 "arith_reg_operand" "")
2273 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2274 (match_operand:SI 2 "const_int_operand" "")))
2275 (clobber (reg:SI T_REG))]
2276 "TARGET_SH1 && reload_completed"
2277 [(use (reg:SI R0_REG))]
2278 "
2279 {
2280 gen_shifty_op (ASHIFT, operands);
2281 DONE;
2282 }")
2283
2284 (define_insn "ashlsi3_media"
2285 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2286 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2287 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2288 "TARGET_SHMEDIA"
2289 "@
2290 shlld.l %1, %2, %0
2291 shlli.l %1, %2, %0"
2292 [(set_attr "type" "arith_media")])
2293
2294 (define_expand "ashlsi3"
2295 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2296 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2297 (match_operand:SI 2 "nonmemory_operand" "")))
2298 (clobber (reg:SI T_REG))])]
2299 ""
2300 "
2301 {
2302 if (TARGET_SHMEDIA)
2303 {
2304 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2305 DONE;
2306 }
2307 if (GET_CODE (operands[2]) == CONST_INT
2308 && sh_dynamicalize_shift_p (operands[2]))
2309 operands[2] = force_reg (SImode, operands[2]);
2310 if (TARGET_SH3)
2311 {
2312 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2313 DONE;
2314 }
2315 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2316 FAIL;
2317 }")
2318
2319 (define_insn "ashlhi3"
2320 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2321 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2322 (match_operand:HI 2 "const_int_operand" "n")))
2323 (clobber (reg:SI T_REG))]
2324 "TARGET_SH1"
2325 "#"
2326 [(set (attr "length")
2327 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2328 (const_string "2")
2329 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2330 (const_string "4")]
2331 (const_string "6")))
2332 (set_attr "type" "arith")])
2333
2334 (define_split
2335 [(set (match_operand:HI 0 "arith_reg_operand" "")
2336 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2337 (match_operand:HI 2 "const_int_operand" "")))
2338 (clobber (reg:SI T_REG))]
2339 "TARGET_SH1 && reload_completed"
2340 [(use (reg:SI R0_REG))]
2341 "
2342 {
2343 gen_shifty_hi_op (ASHIFT, operands);
2344 DONE;
2345 }")
2346
2347 ;
2348 ; arithmetic shift right
2349 ;
2350
2351 (define_insn "ashrsi3_k"
2352 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2353 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2354 (match_operand:SI 2 "const_int_operand" "M")))
2355 (clobber (reg:SI T_REG))]
2356 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2357 "shar %0"
2358 [(set_attr "type" "arith")])
2359
2360 ;; We can't do HImode right shifts correctly unless we start out with an
2361 ;; explicit zero / sign extension; doing that would result in worse overall
2362 ;; code, so just let the machine independent code widen the mode.
2363 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2364
2365
2366 ;; ??? This should be a define expand.
2367
2368 (define_insn "ashrsi2_16"
2369 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2370 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2371 (const_int 16)))]
2372 "TARGET_SH1"
2373 "#"
2374 [(set_attr "length" "4")])
2375
2376 (define_split
2377 [(set (match_operand:SI 0 "arith_reg_operand" "")
2378 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2379 (const_int 16)))]
2380 "TARGET_SH1"
2381 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2382 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2383 "operands[2] = gen_lowpart (HImode, operands[0]);")
2384
2385 ;; ??? This should be a define expand.
2386
2387 (define_insn "ashrsi2_31"
2388 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2390 (const_int 31)))
2391 (clobber (reg:SI T_REG))]
2392 "TARGET_SH1"
2393 "#"
2394 [(set_attr "length" "4")])
2395
2396 (define_split
2397 [(set (match_operand:SI 0 "arith_reg_operand" "")
2398 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2399 (const_int 31)))
2400 (clobber (reg:SI T_REG))]
2401 "TARGET_SH1"
2402 [(const_int 0)]
2403 "
2404 {
2405 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2406 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2407 DONE;
2408 }")
2409
2410 (define_insn "ashlsi_c"
2411 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2412 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2413 (set (reg:SI T_REG)
2414 (lt:SI (match_dup 1) (const_int 0)))]
2415 "TARGET_SH1"
2416 "shll %0"
2417 [(set_attr "type" "arith")])
2418
2419 (define_insn "ashrsi3_d"
2420 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2421 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2422 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2423 "TARGET_SH3"
2424 "shad %2,%0"
2425 [(set_attr "type" "dyn_shift")])
2426
2427 (define_insn "ashrsi3_n"
2428 [(set (reg:SI R4_REG)
2429 (ashiftrt:SI (reg:SI R4_REG)
2430 (match_operand:SI 0 "const_int_operand" "i")))
2431 (clobber (reg:SI T_REG))
2432 (clobber (reg:SI PR_REG))
2433 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2434 "TARGET_SH1"
2435 "jsr @%1%#"
2436 [(set_attr "type" "sfunc")
2437 (set_attr "needs_delay_slot" "yes")])
2438
2439 (define_insn "ashrsi3_media"
2440 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2441 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2442 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2443 "TARGET_SHMEDIA"
2444 "@
2445 shard.l %1, %2, %0
2446 shari.l %1, %2, %0"
2447 [(set_attr "type" "arith_media")])
2448
2449 (define_expand "ashrsi3"
2450 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2451 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2452 (match_operand:SI 2 "nonmemory_operand" "")))
2453 (clobber (reg:SI T_REG))])]
2454 ""
2455 "
2456 {
2457 if (TARGET_SHMEDIA)
2458 {
2459 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2460 DONE;
2461 }
2462 if (expand_ashiftrt (operands))
2463 DONE;
2464 else
2465 FAIL;
2466 }")
2467
2468 ;; logical shift right
2469
2470 (define_insn "lshrsi3_d"
2471 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2472 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2473 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2474 "TARGET_SH3"
2475 "shld %2,%0"
2476 [(set_attr "type" "dyn_shift")])
2477
2478 ;; Only the single bit shift clobbers the T bit.
2479
2480 (define_insn "lshrsi3_m"
2481 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2482 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2483 (match_operand:SI 2 "const_int_operand" "M")))
2484 (clobber (reg:SI T_REG))]
2485 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2486 "shlr %0"
2487 [(set_attr "type" "arith")])
2488
2489 (define_insn "lshrsi3_k"
2490 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2492 (match_operand:SI 2 "const_int_operand" "K")))]
2493 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2494 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2495 "shlr%O2 %0"
2496 [(set_attr "type" "arith")])
2497
2498 (define_insn "lshrsi3_n"
2499 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2500 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2501 (match_operand:SI 2 "const_int_operand" "n")))
2502 (clobber (reg:SI T_REG))]
2503 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2504 "#"
2505 [(set (attr "length")
2506 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2507 (const_string "2")
2508 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2509 (const_string "4")
2510 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2511 (const_string "6")]
2512 (const_string "8")))
2513 (set_attr "type" "arith")])
2514
2515 (define_split
2516 [(set (match_operand:SI 0 "arith_reg_operand" "")
2517 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2518 (match_operand:SI 2 "const_int_operand" "")))
2519 (clobber (reg:SI T_REG))]
2520 "TARGET_SH1 && reload_completed"
2521 [(use (reg:SI R0_REG))]
2522 "
2523 {
2524 gen_shifty_op (LSHIFTRT, operands);
2525 DONE;
2526 }")
2527
2528 (define_insn "lshrsi3_media"
2529 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2530 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2531 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2532 "TARGET_SHMEDIA"
2533 "@
2534 shlrd.l %1, %2, %0
2535 shlri.l %1, %2, %0"
2536 [(set_attr "type" "arith_media")])
2537
2538 (define_expand "lshrsi3"
2539 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2540 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2541 (match_operand:SI 2 "nonmemory_operand" "")))
2542 (clobber (reg:SI T_REG))])]
2543 ""
2544 "
2545 {
2546 if (TARGET_SHMEDIA)
2547 {
2548 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2549 DONE;
2550 }
2551 if (GET_CODE (operands[2]) == CONST_INT
2552 && sh_dynamicalize_shift_p (operands[2]))
2553 operands[2] = force_reg (SImode, operands[2]);
2554 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2555 {
2556 rtx count = copy_to_mode_reg (SImode, operands[2]);
2557 emit_insn (gen_negsi2 (count, count));
2558 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2559 DONE;
2560 }
2561 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2562 FAIL;
2563 }")
2564
2565 ;; ??? This should be a define expand.
2566
2567 (define_insn "ashldi3_k"
2568 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2569 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2570 (const_int 1)))
2571 (clobber (reg:SI T_REG))]
2572 "TARGET_SH1"
2573 "shll %R0\;rotcl %S0"
2574 [(set_attr "length" "4")
2575 (set_attr "type" "arith")])
2576
2577 (define_insn "ashldi3_media"
2578 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2579 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2580 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2581 "TARGET_SHMEDIA"
2582 "@
2583 shlld %1, %2, %0
2584 shlli %1, %2, %0"
2585 [(set_attr "type" "arith_media")])
2586
2587 (define_expand "ashldi3"
2588 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2589 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2590 (match_operand:DI 2 "immediate_operand" "")))
2591 (clobber (reg:SI T_REG))])]
2592 ""
2593 "
2594 {
2595 if (TARGET_SHMEDIA)
2596 {
2597 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2598 DONE;
2599 }
2600 if (GET_CODE (operands[2]) != CONST_INT
2601 || INTVAL (operands[2]) != 1)
2602 FAIL;
2603 }")
2604
2605 ;; ??? This should be a define expand.
2606
2607 (define_insn "lshrdi3_k"
2608 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2609 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2610 (const_int 1)))
2611 (clobber (reg:SI T_REG))]
2612 "TARGET_SH1"
2613 "shlr %S0\;rotcr %R0"
2614 [(set_attr "length" "4")
2615 (set_attr "type" "arith")])
2616
2617 (define_insn "lshrdi3_media"
2618 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2619 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2620 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2621 "TARGET_SHMEDIA"
2622 "@
2623 shlrd %1, %2, %0
2624 shlri %1, %2, %0"
2625 [(set_attr "type" "arith_media")])
2626
2627 (define_expand "lshrdi3"
2628 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2629 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2630 (match_operand:DI 2 "immediate_operand" "")))
2631 (clobber (reg:SI T_REG))])]
2632 ""
2633 "
2634 {
2635 if (TARGET_SHMEDIA)
2636 {
2637 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2638 DONE;
2639 }
2640 if (GET_CODE (operands[2]) != CONST_INT
2641 || INTVAL (operands[2]) != 1)
2642 FAIL;
2643 }")
2644
2645 ;; ??? This should be a define expand.
2646
2647 (define_insn "ashrdi3_k"
2648 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2649 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2650 (const_int 1)))
2651 (clobber (reg:SI T_REG))]
2652 "TARGET_SH1"
2653 "shar %S0\;rotcr %R0"
2654 [(set_attr "length" "4")
2655 (set_attr "type" "arith")])
2656
2657 (define_insn "ashrdi3_media"
2658 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2659 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2660 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2661 "TARGET_SHMEDIA"
2662 "@
2663 shard %1, %2, %0
2664 shari %1, %2, %0"
2665 [(set_attr "type" "arith_media")])
2666
2667 (define_expand "ashrdi3"
2668 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2669 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2670 (match_operand:DI 2 "immediate_operand" "")))
2671 (clobber (reg:SI T_REG))])]
2672 ""
2673 "
2674 {
2675 if (TARGET_SHMEDIA)
2676 {
2677 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2678 DONE;
2679 }
2680 if (GET_CODE (operands[2]) != CONST_INT
2681 || INTVAL (operands[2]) != 1)
2682 FAIL;
2683 }")
2684
2685 ;; combined left/right shift
2686
2687 (define_split
2688 [(set (match_operand:SI 0 "register_operand" "")
2689 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2690 (match_operand:SI 2 "const_int_operand" ""))
2691 (match_operand:SI 3 "const_int_operand" "")))]
2692 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2693 [(use (reg:SI R0_REG))]
2694 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2695 DONE;")
2696
2697 (define_split
2698 [(set (match_operand:SI 0 "register_operand" "")
2699 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2700 (match_operand:SI 2 "const_int_operand" ""))
2701 (match_operand:SI 3 "const_int_operand" "")))
2702 (clobber (reg:SI T_REG))]
2703 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2704 [(use (reg:SI R0_REG))]
2705 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2706 DONE;")
2707
2708 (define_insn ""
2709 [(set (match_operand:SI 0 "register_operand" "=r")
2710 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2711 (match_operand:SI 2 "const_int_operand" "n"))
2712 (match_operand:SI 3 "const_int_operand" "n")))
2713 (clobber (reg:SI T_REG))]
2714 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2715 "#"
2716 [(set (attr "length")
2717 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2718 (const_string "4")
2719 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2720 (const_string "6")
2721 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2722 (const_string "8")
2723 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2724 (const_string "10")
2725 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2726 (const_string "12")
2727 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2728 (const_string "14")
2729 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2730 (const_string "16")]
2731 (const_string "18")))
2732 (set_attr "type" "arith")])
2733
2734 (define_insn ""
2735 [(set (match_operand:SI 0 "register_operand" "=z")
2736 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2737 (match_operand:SI 2 "const_int_operand" "n"))
2738 (match_operand:SI 3 "const_int_operand" "n")))
2739 (clobber (reg:SI T_REG))]
2740 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2741 "#"
2742 [(set (attr "length")
2743 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2744 (const_string "4")
2745 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2746 (const_string "6")
2747 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2748 (const_string "8")]
2749 (const_string "10")))
2750 (set_attr "type" "arith")])
2751
2752 ;; shift left / and combination with a scratch register: The combine pass
2753 ;; does not accept the individual instructions, even though they are
2754 ;; cheap. But it needs a precise description so that it is usable after
2755 ;; reload.
2756 (define_insn "and_shl_scratch"
2757 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2758 (lshiftrt:SI
2759 (ashift:SI
2760 (and:SI
2761 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2762 (match_operand:SI 2 "const_int_operand" "N,n"))
2763 (match_operand:SI 3 "" "0,r"))
2764 (match_operand:SI 4 "const_int_operand" "n,n"))
2765 (match_operand:SI 5 "const_int_operand" "n,n")))
2766 (clobber (reg:SI T_REG))]
2767 "TARGET_SH1"
2768 "#"
2769 [(set (attr "length")
2770 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2771 (const_string "4")
2772 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2773 (const_string "6")
2774 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2775 (const_string "8")
2776 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2777 (const_string "10")]
2778 (const_string "12")))
2779 (set_attr "type" "arith")])
2780
2781 (define_split
2782 [(set (match_operand:SI 0 "register_operand" "")
2783 (lshiftrt:SI
2784 (ashift:SI
2785 (and:SI
2786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2787 (match_operand:SI 2 "const_int_operand" ""))
2788 (match_operand:SI 3 "register_operand" ""))
2789 (match_operand:SI 4 "const_int_operand" ""))
2790 (match_operand:SI 5 "const_int_operand" "")))
2791 (clobber (reg:SI T_REG))]
2792 "TARGET_SH1"
2793 [(use (reg:SI R0_REG))]
2794 "
2795 {
2796 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2797
2798 if (INTVAL (operands[2]))
2799 {
2800 gen_shifty_op (LSHIFTRT, operands);
2801 }
2802 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2803 operands[2] = operands[4];
2804 gen_shifty_op (ASHIFT, operands);
2805 if (INTVAL (operands[5]))
2806 {
2807 operands[2] = operands[5];
2808 gen_shifty_op (LSHIFTRT, operands);
2809 }
2810 DONE;
2811 }")
2812
2813 ;; signed left/right shift combination.
2814 (define_split
2815 [(set (match_operand:SI 0 "register_operand" "")
2816 (sign_extract:SI
2817 (ashift:SI (match_operand:SI 1 "register_operand" "")
2818 (match_operand:SI 2 "const_int_operand" ""))
2819 (match_operand:SI 3 "const_int_operand" "")
2820 (const_int 0)))
2821 (clobber (reg:SI T_REG))]
2822 "TARGET_SH1"
2823 [(use (reg:SI R0_REG))]
2824 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2825 DONE;")
2826
2827 (define_insn "shl_sext_ext"
2828 [(set (match_operand:SI 0 "register_operand" "=r")
2829 (sign_extract:SI
2830 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2831 (match_operand:SI 2 "const_int_operand" "n"))
2832 (match_operand:SI 3 "const_int_operand" "n")
2833 (const_int 0)))
2834 (clobber (reg:SI T_REG))]
2835 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2836 "#"
2837 [(set (attr "length")
2838 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2839 (const_string "2")
2840 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2841 (const_string "4")
2842 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2843 (const_string "6")
2844 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2845 (const_string "8")
2846 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2847 (const_string "10")
2848 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2849 (const_string "12")
2850 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2851 (const_string "14")
2852 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2853 (const_string "16")]
2854 (const_string "18")))
2855 (set_attr "type" "arith")])
2856
2857 (define_insn "shl_sext_sub"
2858 [(set (match_operand:SI 0 "register_operand" "=z")
2859 (sign_extract:SI
2860 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2861 (match_operand:SI 2 "const_int_operand" "n"))
2862 (match_operand:SI 3 "const_int_operand" "n")
2863 (const_int 0)))
2864 (clobber (reg:SI T_REG))]
2865 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2866 "#"
2867 [(set (attr "length")
2868 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2869 (const_string "6")
2870 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2871 (const_string "8")
2872 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2873 (const_string "10")
2874 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2875 (const_string "12")]
2876 (const_string "14")))
2877 (set_attr "type" "arith")])
2878
2879 ;; These patterns are found in expansions of DImode shifts by 16, and
2880 ;; allow the xtrct instruction to be generated from C source.
2881
2882 (define_insn "xtrct_left"
2883 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2884 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2885 (const_int 16))
2886 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2887 (const_int 16))))]
2888 "TARGET_SH1"
2889 "xtrct %1,%0"
2890 [(set_attr "type" "arith")])
2891
2892 (define_insn "xtrct_right"
2893 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2894 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2895 (const_int 16))
2896 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2897 (const_int 16))))]
2898 "TARGET_SH1"
2899 "xtrct %2,%0"
2900 [(set_attr "type" "arith")])
2901
2902 ;; -------------------------------------------------------------------------
2903 ;; Unary arithmetic
2904 ;; -------------------------------------------------------------------------
2905
2906 (define_insn "negc"
2907 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2908 (neg:SI (plus:SI (reg:SI T_REG)
2909 (match_operand:SI 1 "arith_reg_operand" "r"))))
2910 (set (reg:SI T_REG)
2911 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2912 (const_int 0)))]
2913 "TARGET_SH1"
2914 "negc %1,%0"
2915 [(set_attr "type" "arith")])
2916
2917 (define_insn "*negdi_media"
2918 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2919 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2920 "TARGET_SHMEDIA"
2921 "sub r63, %1, %0"
2922 [(set_attr "type" "arith_media")])
2923
2924 (define_expand "negdi2"
2925 [(set (match_operand:DI 0 "arith_reg_operand" "")
2926 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2927 ""
2928 "
2929 {
2930 if (TARGET_SH1)
2931 {
2932 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2933 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2934
2935 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2936 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2937
2938 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2939 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2940
2941 emit_insn (gen_clrt ());
2942 emit_insn (gen_negc (low_dst, low_src));
2943 emit_insn (gen_negc (high_dst, high_src));
2944 DONE;
2945 }
2946 }")
2947
2948 (define_insn "negsi2"
2949 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2950 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2951 "TARGET_SH1"
2952 "neg %1,%0"
2953 [(set_attr "type" "arith")])
2954
2955 (define_insn "one_cmplsi2"
2956 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2957 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2958 "TARGET_SH1"
2959 "not %1,%0"
2960 [(set_attr "type" "arith")])
2961
2962 (define_expand "one_cmpldi2"
2963 [(set (match_operand:DI 0 "arith_reg_operand" "")
2964 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2965 (const_int -1)))]
2966 "TARGET_SHMEDIA" "")
2967 \f
2968 ;; -------------------------------------------------------------------------
2969 ;; Zero extension instructions
2970 ;; -------------------------------------------------------------------------
2971
2972 (define_insn "zero_extendsidi2"
2973 [(set (match_operand:DI 0 "register_operand" "=r")
2974 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2975 "TARGET_SHMEDIA"
2976 "addz.l %1, r63, %0"
2977 [(set_attr "type" "arith_media")])
2978
2979 (define_insn "zero_extendhidi2"
2980 [(set (match_operand:DI 0 "register_operand" "=r,r")
2981 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2982 "TARGET_SHMEDIA"
2983 "@
2984 #
2985 ld%M1.uw %m1, %0"
2986 [(set_attr "type" "*,load_media")])
2987
2988 (define_split
2989 [(set (match_operand:DI 0 "register_operand" "")
2990 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2991 "TARGET_SHMEDIA && reload_completed"
2992 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2993 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2994 "
2995 {
2996 if (GET_CODE (operands[1]) == TRUNCATE)
2997 operands[1] = XEXP (operands[1], 0);
2998 }")
2999
3000 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3001 ;; reload the entrire truncate expression.
3002 (define_insn_and_split "*loaddi_trunc"
3003 [(set (match_operand 0 "int_gpr_dest" "=r")
3004 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3005 "TARGET_SHMEDIA && reload_completed"
3006 "#"
3007 "TARGET_SHMEDIA && reload_completed"
3008 [(set (match_dup 0) (match_dup 1))]
3009 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3010
3011 (define_insn "zero_extendqidi2"
3012 [(set (match_operand:DI 0 "register_operand" "=r,r")
3013 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3014 "TARGET_SHMEDIA"
3015 "@
3016 andi %1, 255, %0
3017 ld%M1.ub %m1, %0"
3018 [(set_attr "type" "arith_media,load_media")])
3019
3020 (define_expand "zero_extendhisi2"
3021 [(set (match_operand:SI 0 "arith_reg_operand" "")
3022 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3023 ""
3024 "
3025 {
3026 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3027 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3028 }")
3029
3030 (define_insn "*zero_extendhisi2_compact"
3031 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3032 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3033 "TARGET_SH1"
3034 "extu.w %1,%0"
3035 [(set_attr "type" "arith")])
3036
3037 (define_insn "*zero_extendhisi2_media"
3038 [(set (match_operand:SI 0 "register_operand" "=r,r")
3039 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3040 "TARGET_SHMEDIA"
3041 "@
3042 #
3043 ld%M1.uw %m1, %0"
3044 [(set_attr "type" "arith_media,load_media")])
3045
3046 (define_split
3047 [(set (match_operand:SI 0 "register_operand" "")
3048 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3049 "TARGET_SHMEDIA && reload_completed"
3050 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3051 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3052 "
3053 {
3054 if (GET_CODE (operands[1]) == TRUNCATE)
3055 operands[1] = XEXP (operands[1], 0);
3056 }")
3057
3058 (define_expand "zero_extendqisi2"
3059 [(set (match_operand:SI 0 "arith_reg_operand" "")
3060 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3061 ""
3062 "
3063 {
3064 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3065 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3066 }")
3067
3068 (define_insn "*zero_extendqisi2_compact"
3069 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3070 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3071 "TARGET_SH1"
3072 "extu.b %1,%0"
3073 [(set_attr "type" "arith")])
3074
3075 (define_insn "*zero_extendqisi2_media"
3076 [(set (match_operand:SI 0 "register_operand" "=r,r")
3077 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3078 "TARGET_SHMEDIA"
3079 "@
3080 andi %1, 255, %0
3081 ld%M1.ub %m1, %0"
3082 [(set_attr "type" "arith_media,load_media")])
3083
3084 (define_insn "zero_extendqihi2"
3085 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3086 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3087 "TARGET_SH1"
3088 "extu.b %1,%0"
3089 [(set_attr "type" "arith")])
3090
3091 ;; -------------------------------------------------------------------------
3092 ;; Sign extension instructions
3093 ;; -------------------------------------------------------------------------
3094
3095 ;; ??? This should be a define expand.
3096 ;; ??? Or perhaps it should be dropped?
3097
3098 ;; convert_move generates good code for SH[1-4].
3099 (define_insn "extendsidi2"
3100 [(set (match_operand:DI 0 "register_operand" "=r,r")
3101 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3102 "TARGET_SHMEDIA"
3103 "@
3104 add.l %1, r63, %0
3105 ld%M1.l %m1, %0"
3106 [(set_attr "type" "arith_media,load_media")])
3107
3108 (define_insn "extendhidi2"
3109 [(set (match_operand:DI 0 "register_operand" "=r,r")
3110 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3111 "TARGET_SHMEDIA"
3112 "@
3113 #
3114 ld%M1.w %m1, %0"
3115 [(set_attr "type" "*,load_media")])
3116
3117 (define_split
3118 [(set (match_operand:DI 0 "register_operand" "")
3119 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3120 "TARGET_SHMEDIA && reload_completed"
3121 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3122 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3123 "
3124 {
3125 if (GET_CODE (operands[1]) == TRUNCATE)
3126 operands[1] = XEXP (operands[1], 0);
3127 }")
3128
3129 (define_insn "extendqidi2"
3130 [(set (match_operand:DI 0 "register_operand" "=r,r")
3131 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3132 "TARGET_SHMEDIA"
3133 "@
3134 #
3135 ld%M1.b %m1, %0"
3136 [(set_attr "type" "*,load_media")])
3137
3138 (define_split
3139 [(set (match_operand:DI 0 "register_operand" "")
3140 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3141 "TARGET_SHMEDIA && reload_completed"
3142 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3143 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3144 "
3145 {
3146 if (GET_CODE (operands[1]) == TRUNCATE)
3147 operands[1] = XEXP (operands[1], 0);
3148 }")
3149
3150 (define_expand "extendhisi2"
3151 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3152 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3153 ""
3154 "")
3155
3156 (define_insn "*extendhisi2_compact"
3157 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3158 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3159 "TARGET_SH1"
3160 "@
3161 exts.w %1,%0
3162 mov.w %1,%0"
3163 [(set_attr "type" "arith,load")])
3164
3165 (define_insn "*extendhisi2_media"
3166 [(set (match_operand:SI 0 "register_operand" "=r,r")
3167 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3168 "TARGET_SHMEDIA"
3169 "@
3170 #
3171 ld%M1.w %m1, %0"
3172 [(set_attr "type" "arith_media,load_media")])
3173
3174 (define_split
3175 [(set (match_operand:SI 0 "register_operand" "")
3176 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3177 "TARGET_SHMEDIA && reload_completed"
3178 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3179 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3180 "
3181 {
3182 if (GET_CODE (operands[1]) == TRUNCATE)
3183 operands[1] = XEXP (operands[1], 0);
3184 }")
3185
3186 (define_expand "extendqisi2"
3187 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3188 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3189 ""
3190 "")
3191
3192 (define_insn "*extendqisi2_compact"
3193 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3194 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3195 "TARGET_SH1"
3196 "@
3197 exts.b %1,%0
3198 mov.b %1,%0"
3199 [(set_attr "type" "arith,load")])
3200
3201 (define_insn "*extendqisi2_media"
3202 [(set (match_operand:SI 0 "register_operand" "=r,r")
3203 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3204 "TARGET_SHMEDIA"
3205 "@
3206 #
3207 ld%M1.b %m1, %0"
3208 [(set_attr "type" "arith_media,load_media")])
3209
3210 (define_split
3211 [(set (match_operand:SI 0 "register_operand" "")
3212 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3213 "TARGET_SHMEDIA && reload_completed"
3214 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3215 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3216 "
3217 {
3218 if (GET_CODE (operands[1]) == TRUNCATE)
3219 operands[1] = XEXP (operands[1], 0);
3220 }")
3221
3222 (define_insn "extendqihi2"
3223 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3224 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3225 "TARGET_SH1"
3226 "@
3227 exts.b %1,%0
3228 mov.b %1,%0"
3229 [(set_attr "type" "arith,load")])
3230
3231 /* It would seem useful to combine the truncXi patterns into the movXi
3232 patterns, but unary operators are ignored when matching constraints,
3233 so we need separate patterns. */
3234 (define_insn "truncdisi2"
3235 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3236 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3237 "TARGET_SHMEDIA"
3238 "@
3239 add.l %1, r63, %0
3240 st%M0.l %m0, %1
3241 fst%M0.s %m0, %T1
3242 fmov.ls %1, %0
3243 fmov.sl %T1, %0
3244 fmov.s %T1, %0"
3245 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3246
3247
3248 (define_insn "truncdihi2"
3249 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3250 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3251 "TARGET_SHMEDIA"
3252 "@
3253 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3254 st%M0.w %m0, %1"
3255 [(set_attr "type" "arith_media,store_media")
3256 (set_attr "length" "8,4")])
3257
3258 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3259 ; Because we use zero extension, we can't provide signed QImode compares
3260 ; using a simple compare or conditional banch insn.
3261 (define_insn "truncdiqi2"
3262 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3263 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3264 "TARGET_SHMEDIA"
3265 "@
3266 and %1, 255, %0
3267 st%M0.b %m0, %1"
3268 [(set_attr "type" "arith_media,store")])
3269
3270 ;; -------------------------------------------------------------------------
3271 ;; Move instructions
3272 ;; -------------------------------------------------------------------------
3273
3274 ;; define push and pop so it is easy for sh.c
3275 ;; We can't use push and pop on SHcompact because the stack must always
3276 ;; be 8-byte aligned.
3277
3278 (define_expand "push"
3279 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3280 (match_operand:SI 0 "register_operand" "r,l,x"))]
3281 "TARGET_SH1 && ! TARGET_SH5"
3282 "")
3283
3284 (define_expand "pop"
3285 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3286 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3287 "TARGET_SH1 && ! TARGET_SH5"
3288 "")
3289
3290 (define_expand "push_e"
3291 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3292 (match_operand:SF 0 "" ""))
3293 (use (reg:PSI FPSCR_REG))
3294 (clobber (scratch:SI))])]
3295 "TARGET_SH1 && ! TARGET_SH5"
3296 "")
3297
3298 (define_insn "push_fpul"
3299 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3300 "TARGET_SH3E && ! TARGET_SH5"
3301 "sts.l fpul,@-r15"
3302 [(set_attr "type" "store")
3303 (set_attr "late_fp_use" "yes")
3304 (set_attr "hit_stack" "yes")])
3305
3306 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3307 ;; so use that.
3308 (define_expand "push_4"
3309 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3310 (match_operand:DF 0 "" ""))
3311 (use (reg:PSI FPSCR_REG))
3312 (clobber (scratch:SI))])]
3313 "TARGET_SH1 && ! TARGET_SH5"
3314 "")
3315
3316 (define_expand "pop_e"
3317 [(parallel [(set (match_operand:SF 0 "" "")
3318 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3319 (use (reg:PSI FPSCR_REG))
3320 (clobber (scratch:SI))])]
3321 "TARGET_SH1 && ! TARGET_SH5"
3322 "")
3323
3324 (define_insn "pop_fpul"
3325 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3326 "TARGET_SH3E && ! TARGET_SH5"
3327 "lds.l @r15+,fpul"
3328 [(set_attr "type" "load")
3329 (set_attr "hit_stack" "yes")])
3330
3331 (define_expand "pop_4"
3332 [(parallel [(set (match_operand:DF 0 "" "")
3333 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3334 (use (reg:PSI FPSCR_REG))
3335 (clobber (scratch:SI))])]
3336 "TARGET_SH1 && ! TARGET_SH5"
3337 "")
3338
3339 (define_expand "push_fpscr"
3340 [(const_int 0)]
3341 "TARGET_SH3E"
3342 "
3343 {
3344 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3345 gen_rtx (PRE_DEC, Pmode,
3346 stack_pointer_rtx)),
3347 get_fpscr_rtx ()));
3348 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3349 DONE;
3350 }")
3351
3352 (define_expand "pop_fpscr"
3353 [(const_int 0)]
3354 "TARGET_SH3E"
3355 "
3356 {
3357 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3358 gen_rtx (MEM, PSImode,
3359 gen_rtx (POST_INC, Pmode,
3360 stack_pointer_rtx))));
3361 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3362 DONE;
3363 }")
3364
3365 ;; These two patterns can happen as the result of optimization, when
3366 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3367 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3368
3369 (define_insn "clrt"
3370 [(set (reg:SI T_REG) (const_int 0))]
3371 "TARGET_SH1"
3372 "clrt")
3373
3374 (define_insn "sett"
3375 [(set (reg:SI T_REG) (const_int 1))]
3376 "TARGET_SH1"
3377 "sett")
3378
3379 ;; t/r must come after r/r, lest reload will try to reload stuff like
3380 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3381 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3382 (define_insn "movsi_i"
3383 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3384 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3385 "TARGET_SH1
3386 && ! TARGET_SH3E
3387 && (register_operand (operands[0], SImode)
3388 || register_operand (operands[1], SImode))"
3389 "@
3390 mov.l %1,%0
3391 mov %1,%0
3392 cmp/pl %1
3393 mov.l %1,%0
3394 sts %1,%0
3395 sts %1,%0
3396 movt %0
3397 mov.l %1,%0
3398 sts.l %1,%0
3399 sts.l %1,%0
3400 lds %1,%0
3401 lds %1,%0
3402 lds.l %1,%0
3403 lds.l %1,%0
3404 fake %1,%0"
3405 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3406 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3407
3408 ;; t/r must come after r/r, lest reload will try to reload stuff like
3409 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3410 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3411 ;; will require a reload.
3412 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3413 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3414 (define_insn "movsi_ie"
3415 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3416 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3417 "TARGET_SH3E
3418 && (register_operand (operands[0], SImode)
3419 || register_operand (operands[1], SImode))"
3420 "@
3421 mov.l %1,%0
3422 mov %1,%0
3423 cmp/pl %1
3424 mov.l %1,%0
3425 sts %1,%0
3426 sts %1,%0
3427 movt %0
3428 mov.l %1,%0
3429 sts.l %1,%0
3430 sts.l %1,%0
3431 lds %1,%0
3432 lds %1,%0
3433 lds.l %1,%0
3434 lds.l %1,%0
3435 lds.l %1,%0
3436 sts.l %1,%0
3437 fake %1,%0
3438 lds %1,%0
3439 sts %1,%0
3440 fsts fpul,%0
3441 flds %1,fpul
3442 fmov %1,%0
3443 ! move optimized away"
3444 [(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")
3445 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3446 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3447
3448 (define_insn "movsi_i_lowpart"
3449 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3450 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3451 "TARGET_SH1
3452 && (register_operand (operands[0], SImode)
3453 || register_operand (operands[1], SImode))"
3454 "@
3455 mov.l %1,%0
3456 mov %1,%0
3457 mov.l %1,%0
3458 sts %1,%0
3459 sts %1,%0
3460 movt %0
3461 mov.l %1,%0
3462 fake %1,%0"
3463 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3464
3465 (define_insn "*movsi_media"
3466 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3467 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,rU,m,f,rU,f,f,r,*b,T"))]
3468 "TARGET_SHMEDIA_FPU
3469 && (register_operand (operands[0], SImode)
3470 || sh_register_operand (operands[1], SImode))"
3471 "@
3472 add.l %1, r63, %0
3473 movi %1, %0
3474 #
3475 ld%M1.l %m1, %0
3476 st%M0.l %m0, %N1
3477 fld%M1.s %m1, %0
3478 fst%M0.s %m0, %1
3479 fmov.ls %N1, %0
3480 fmov.sl %1, %0
3481 fmov.s %1, %0
3482 ptabs %1, %0
3483 gettr %1, %0
3484 pt %1, %0"
3485 [(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")
3486 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3487
3488 (define_insn "*movsi_media_nofpu"
3489 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3490 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,rU,r,*b,T"))]
3491 "TARGET_SHMEDIA
3492 && (register_operand (operands[0], SImode)
3493 || sh_register_operand (operands[1], SImode))"
3494 "@
3495 add.l %1, r63, %0
3496 movi %1, %0
3497 #
3498 ld%M1.l %m1, %0
3499 st%M0.l %m0, %N1
3500 ptabs %1, %0
3501 gettr %1, %0
3502 pt %1, %0"
3503 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3504 (set_attr "length" "4,4,8,4,4,4,4,12")])
3505
3506 (define_split
3507 [(set (match_operand:SI 0 "arith_reg_operand" "")
3508 (match_operand:SI 1 "immediate_operand" ""))]
3509 "TARGET_SHMEDIA && reload_completed
3510 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3511 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3512 "
3513 {
3514 operands[2] = shallow_copy_rtx (operands[1]);
3515 PUT_MODE (operands[2], DImode);
3516 }")
3517
3518 (define_split
3519 [(set (match_operand:SI 0 "register_operand" "")
3520 (match_operand:SI 1 "immediate_operand" ""))]
3521 "TARGET_SHMEDIA && reload_completed
3522 && ((GET_CODE (operands[1]) == CONST_INT
3523 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3524 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3525 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3526
3527 (define_expand "movsi"
3528 [(set (match_operand:SI 0 "general_movdst_operand" "")
3529 (match_operand:SI 1 "general_movsrc_operand" ""))]
3530 ""
3531 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3532
3533 (define_expand "ic_invalidate_line"
3534 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3535 (match_dup 1)] UNSPEC_ICACHE)
3536 (clobber (scratch:SI))])]
3537 "TARGET_HARD_SH4 || TARGET_SH5"
3538 "
3539 {
3540 if (TARGET_SHMEDIA)
3541 {
3542 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3543 DONE;
3544 }
3545 else if (TARGET_SHCOMPACT)
3546 {
3547 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3548 operands[1] = force_reg (Pmode, operands[1]);
3549 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3550 DONE;
3551 }
3552 operands[0] = force_reg (Pmode, operands[0]);
3553 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3554 Pmode)));
3555 }")
3556
3557 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3558 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3559 ;; the requirement *1*00 for associative address writes. The alignment of
3560 ;; %0 implies that its least significant bit is cleared,
3561 ;; thus we clear the V bit of a matching entry if there is one.
3562 (define_insn "ic_invalidate_line_i"
3563 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3564 (match_operand:SI 1 "register_operand" "r")]
3565 UNSPEC_ICACHE)
3566 (clobber (match_scratch:SI 2 "=&r"))]
3567 "TARGET_HARD_SH4"
3568 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3569 [(set_attr "length" "8")
3570 (set_attr "type" "cwb")])
3571
3572 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3573 ;; an add in the code that calculates the address.
3574 (define_insn "ic_invalidate_line_media"
3575 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3576 UNSPEC_ICACHE)]
3577 "TARGET_SHMEDIA"
3578 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3579 [(set_attr "length" "16")
3580 (set_attr "type" "invalidate_line_media")])
3581
3582 (define_insn "ic_invalidate_line_compact"
3583 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3584 (match_operand:SI 1 "register_operand" "r")]
3585 UNSPEC_ICACHE)
3586 (clobber (reg:SI PR_REG))]
3587 "TARGET_SHCOMPACT"
3588 "jsr @%1%#"
3589 [(set_attr "type" "sfunc")
3590 (set_attr "needs_delay_slot" "yes")])
3591
3592 (define_expand "initialize_trampoline"
3593 [(match_operand:SI 0 "" "")
3594 (match_operand:SI 1 "" "")
3595 (match_operand:SI 2 "" "")]
3596 "TARGET_SHCOMPACT"
3597 "
3598 {
3599 rtx sfun, tramp;
3600
3601 tramp = force_reg (Pmode, operands[0]);
3602 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3603 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3604 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3605
3606 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3607 DONE;
3608 }")
3609
3610 (define_insn "initialize_trampoline_compact"
3611 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3612 (match_operand:SI 1 "register_operand" "r")
3613 (reg:SI R2_REG) (reg:SI R3_REG)]
3614 UNSPEC_INIT_TRAMP)
3615
3616 (clobber (reg:SI PR_REG))]
3617 "TARGET_SHCOMPACT"
3618 "jsr @%1%#"
3619 [(set_attr "type" "sfunc")
3620 (set_attr "needs_delay_slot" "yes")])
3621
3622 (define_insn "movqi_i"
3623 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3624 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3625 "TARGET_SH1
3626 && (arith_reg_operand (operands[0], QImode)
3627 || arith_reg_operand (operands[1], QImode))"
3628 "@
3629 mov %1,%0
3630 mov.b %1,%0
3631 mov.b %1,%0
3632 movt %0
3633 sts %1,%0
3634 lds %1,%0"
3635 [(set_attr "type" "move,load,store,move,move,move")])
3636
3637 (define_insn "*movqi_media"
3638 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3639 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,rU"))]
3640 "TARGET_SHMEDIA
3641 && (arith_reg_operand (operands[0], QImode)
3642 || arith_reg_or_0_operand (operands[1], QImode))"
3643 "@
3644 add.l %1, r63, %0
3645 movi %1, %0
3646 ld%M1.ub %m1, %0
3647 st%M0.b %m0, %N1"
3648 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3649
3650 (define_expand "movqi"
3651 [(set (match_operand:QI 0 "general_operand" "")
3652 (match_operand:QI 1 "general_operand" ""))]
3653 ""
3654 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3655
3656 (define_expand "reload_inqi"
3657 [(set (match_operand:SI 2 "" "=&r")
3658 (match_operand:QI 1 "inqhi_operand" ""))
3659 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3660 (truncate:HI (match_dup 3)))]
3661 "TARGET_SHMEDIA"
3662 "
3663 {
3664 rtx inner = XEXP (operands[1], 0);
3665 int regno = REGNO (inner);
3666
3667 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3668 operands[1] = gen_rtx_REG (SImode, regno);
3669 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3670 }")
3671
3672 (define_insn "movhi_i"
3673 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3674 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3675 "TARGET_SH1
3676 && (arith_reg_operand (operands[0], HImode)
3677 || arith_reg_operand (operands[1], HImode))"
3678 "@
3679 mov.w %1,%0
3680 mov %1,%0
3681 mov.w %1,%0
3682 movt %0
3683 mov.w %1,%0
3684 sts %1,%0
3685 lds %1,%0
3686 fake %1,%0"
3687 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3688
3689 (define_insn "*movhi_media"
3690 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3691 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,rU"))]
3692 "TARGET_SHMEDIA
3693 && (arith_reg_operand (operands[0], HImode)
3694 || arith_reg_or_0_operand (operands[1], HImode))"
3695 "@
3696 add.l %1, r63, %0
3697 movi %1, %0
3698 #
3699 ld%M1.w %m1, %0
3700 st%M0.w %m0, %N1"
3701 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3702
3703 (define_split
3704 [(set (match_operand:HI 0 "register_operand" "")
3705 (match_operand:HI 1 "immediate_operand" ""))]
3706 "TARGET_SHMEDIA && reload_completed
3707 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3708 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3709
3710 (define_expand "movhi"
3711 [(set (match_operand:HI 0 "general_movdst_operand" "")
3712 (match_operand:HI 1 "general_movsrc_operand" ""))]
3713 ""
3714 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3715
3716 (define_expand "reload_inhi"
3717 [(set (match_operand:SI 2 "" "=&r")
3718 (match_operand:HI 1 "inqhi_operand" ""))
3719 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3720 (truncate:HI (match_dup 3)))]
3721 "TARGET_SHMEDIA"
3722 "
3723 {
3724 rtx inner = XEXP (operands[1], 0);
3725 int regno = REGNO (inner);
3726
3727 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3728 operands[1] = gen_rtx_REG (SImode, regno);
3729 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3730 }")
3731
3732 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3733 ;; compiled with -m2 -ml -O3 -funroll-loops
3734 (define_insn "*movdi_i"
3735 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3736 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3737 "TARGET_SH1
3738 && (arith_reg_operand (operands[0], DImode)
3739 || arith_reg_operand (operands[1], DImode))"
3740 "* return output_movedouble (insn, operands, DImode);"
3741 [(set_attr "length" "4")
3742 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3743
3744 ;; If the output is a register and the input is memory or a register, we have
3745 ;; to be careful and see which word needs to be loaded first.
3746
3747 (define_split
3748 [(set (match_operand:DI 0 "general_movdst_operand" "")
3749 (match_operand:DI 1 "general_movsrc_operand" ""))]
3750 "TARGET_SH1 && reload_completed"
3751 [(set (match_dup 2) (match_dup 3))
3752 (set (match_dup 4) (match_dup 5))]
3753 "
3754 {
3755 int regno;
3756
3757 if ((GET_CODE (operands[0]) == MEM
3758 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3759 || (GET_CODE (operands[1]) == MEM
3760 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3761 FAIL;
3762
3763 if (GET_CODE (operands[0]) == REG)
3764 regno = REGNO (operands[0]);
3765 else if (GET_CODE (operands[0]) == SUBREG)
3766 regno = subreg_regno (operands[0]);
3767 else if (GET_CODE (operands[0]) == MEM)
3768 regno = -1;
3769 else
3770 abort ();
3771
3772 if (regno == -1
3773 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3774 {
3775 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3776 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3777 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3778 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3779 }
3780 else
3781 {
3782 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3783 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3784 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3785 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3786 }
3787
3788 if (operands[2] == 0 || operands[3] == 0
3789 || operands[4] == 0 || operands[5] == 0)
3790 FAIL;
3791 }")
3792
3793 (define_insn "*movdi_media"
3794 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3795 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rlU,m,f,rU,f,f,r,*b,T"))]
3796 "TARGET_SHMEDIA_FPU
3797 && (register_operand (operands[0], DImode)
3798 || sh_register_operand (operands[1], DImode))"
3799 "@
3800 add %1, r63, %0
3801 movi %1, %0
3802 #
3803 ld%M1.q %m1, %0
3804 st%M0.q %m0, %N1
3805 fld%M1.d %m1, %0
3806 fst%M0.d %m0, %1
3807 fmov.qd %N1, %0
3808 fmov.dq %1, %0
3809 fmov.d %1, %0
3810 ptabs %1, %0
3811 gettr %1, %0
3812 pt %1, %0"
3813 [(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")
3814 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3815
3816 (define_insn "*movdi_media_nofpu"
3817 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3818 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rlU,r,*b,T"))]
3819 "TARGET_SHMEDIA
3820 && (register_operand (operands[0], DImode)
3821 || sh_register_operand (operands[1], DImode))"
3822 "@
3823 add %1, r63, %0
3824 movi %1, %0
3825 #
3826 ld%M1.q %m1, %0
3827 st%M0.q %m0, %N1
3828 ptabs %1, %0
3829 gettr %1, %0
3830 pt %1, %0"
3831 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3832 (set_attr "length" "4,4,16,4,4,4,4,*")])
3833
3834 (define_split
3835 [(set (match_operand:DI 0 "arith_reg_operand" "")
3836 (match_operand:DI 1 "immediate_operand" ""))]
3837 "TARGET_SHMEDIA && reload_completed
3838 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3839 [(set (match_dup 0) (match_dup 1))]
3840 "
3841 {
3842 rtx insn;
3843
3844 if (TARGET_SHMEDIA64)
3845 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3846 else
3847 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3848
3849 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3850 REG_NOTES (insn));
3851
3852 DONE;
3853 }")
3854
3855 (define_expand "movdi_const"
3856 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3857 (const:DI (sign_extend:DI
3858 (truncate:HI
3859 (ashiftrt:DI
3860 (match_operand:DI 1 "immediate_operand" "s")
3861 (const_int 48))))))
3862 (set (match_dup 0)
3863 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3864 (zero_extend:DI
3865 (truncate:HI
3866 (const:DI
3867 (sign_extend:DI
3868 (truncate:HI
3869 (ashiftrt:SI
3870 (match_dup 1)
3871 (const_int 32)))))))))
3872 (set (match_dup 0)
3873 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3874 (zero_extend:DI
3875 (truncate:HI
3876 (const:DI
3877 (sign_extend:DI
3878 (truncate:HI
3879 (ashiftrt:SI
3880 (match_dup 1)
3881 (const_int 16)))))))))
3882 (set (match_dup 0)
3883 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3884 (zero_extend:DI
3885 (truncate:HI
3886 (const:DI
3887 (sign_extend:DI
3888 (truncate:HI
3889 (match_dup 1))))))))]
3890 "TARGET_SHMEDIA64 && reload_completed
3891 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3892 "
3893 {
3894 sh_mark_label (operands[1], 4);
3895 }")
3896
3897 (define_expand "movdi_const_32bit"
3898 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3899 (const:DI (sign_extend:DI
3900 (truncate:HI
3901 (ashiftrt:DI
3902 (match_operand:DI 1 "immediate_operand" "s")
3903 (const_int 16))))))
3904 (set (match_dup 0)
3905 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3906 (zero_extend:DI
3907 (truncate:HI
3908 (const:DI
3909 (sign_extend:DI
3910 (truncate:HI
3911 (match_dup 1))))))))]
3912 "TARGET_SHMEDIA32 && reload_completed
3913 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3914 "
3915 {
3916 sh_mark_label (operands[1], 2);
3917 }")
3918
3919 (define_expand "movdi_const_16bit"
3920 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3921 (const:DI (sign_extend:DI
3922 (truncate:HI
3923 (match_operand:DI 1 "immediate_operand" "s")))))]
3924 "TARGET_SHMEDIA && flag_pic && reload_completed
3925 && GET_CODE (operands[1]) == SYMBOL_REF"
3926 "")
3927
3928 (define_split
3929 [(set (match_operand:DI 0 "arith_reg_operand" "")
3930 (match_operand:DI 1 "immediate_operand" ""))]
3931 "TARGET_SHMEDIA && reload_completed
3932 && GET_CODE (operands[1]) == CONST_INT
3933 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3934 [(set (match_dup 0) (match_dup 2))
3935 (match_dup 1)]
3936 "
3937 {
3938 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3939 unsigned HOST_WIDE_INT low = val;
3940 unsigned HOST_WIDE_INT high = val;
3941 unsigned HOST_WIDE_INT sign;
3942 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3943
3944 /* Sign-extend the 16 least-significant bits. */
3945 low &= 0xffff;
3946 low ^= 0x8000;
3947 low -= 0x8000;
3948
3949 /* Arithmetic shift right the word by 16 bits. */
3950 high >>= 16;
3951 sign = 1;
3952 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3953 high ^= sign;
3954 high -= sign;
3955 do
3956 {
3957 /* If we can't generate the constant with a two-insn movi / shori
3958 sequence, try some other strategies. */
3959 if (! CONST_OK_FOR_J (high))
3960 {
3961 /* Try constant load / left shift. We know VAL != 0. */
3962 val2 = val ^ (val-1);
3963 if (val2 > 0x1ffff)
3964 {
3965 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3966
3967 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3968 || (! CONST_OK_FOR_J (high >> 16)
3969 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3970 {
3971 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3972 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3973 GEN_INT (trailing_zeroes));
3974 break;
3975 }
3976 }
3977 /* Try constant load / right shift. */
3978 val2 = (val >> 15) + 1;
3979 if (val2 == (val2 & -val2))
3980 {
3981 int shift = 49 - exact_log2 (val2);
3982
3983 val2 = trunc_int_for_mode (val << shift, DImode);
3984 if (CONST_OK_FOR_J (val2))
3985 {
3986 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3987 GEN_INT (shift));
3988 break;
3989 }
3990 }
3991 /* Try mperm.w . */
3992 val2 = val & 0xffff;
3993 if ((val >> 16 & 0xffff) == val2
3994 && (val >> 32 & 0xffff) == val2
3995 && (val >> 48 & 0xffff) == val2)
3996 {
3997 val2 = (HOST_WIDE_INT) val >> 48;
3998 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3999 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4000 break;
4001 }
4002 /* Try movi / mshflo.l */
4003 val2 = (HOST_WIDE_INT) val >> 32;
4004 if (val2 == trunc_int_for_mode (val, SImode))
4005 {
4006 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4007 operands[0]);
4008 break;
4009 }
4010 /* Try movi / mshflo.l w/ r63. */
4011 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4012 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4013 {
4014 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4015 GEN_INT (0));
4016 break;
4017 }
4018 }
4019 val2 = high;
4020 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4021 }
4022 while (0);
4023 operands[2] = GEN_INT (val2);
4024 }")
4025
4026 (define_split
4027 [(set (match_operand:DI 0 "arith_reg_operand" "")
4028 (match_operand:DI 1 "immediate_operand" ""))]
4029 "TARGET_SHMEDIA && reload_completed
4030 && GET_CODE (operands[1]) == CONST_DOUBLE"
4031 [(set (match_dup 0) (match_dup 2))
4032 (set (match_dup 0)
4033 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4034 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4035 "
4036 {
4037 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4038 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4039 unsigned HOST_WIDE_INT val = low;
4040 unsigned HOST_WIDE_INT sign;
4041
4042 /* Sign-extend the 16 least-significant bits. */
4043 val &= 0xffff;
4044 val ^= 0x8000;
4045 val -= 0x8000;
4046 operands[1] = GEN_INT (val);
4047
4048 /* Arithmetic shift right the double-word by 16 bits. */
4049 low >>= 16;
4050 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4051 high >>= 16;
4052 sign = 1;
4053 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4054 high ^= sign;
4055 high -= sign;
4056
4057 /* This will only be true if high is a sign-extension of low, i.e.,
4058 it must be either 0 or (unsigned)-1, and be zero iff the
4059 most-significant bit of low is set. */
4060 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4061 operands[2] = GEN_INT (low);
4062 else
4063 operands[2] = immed_double_const (low, high, DImode);
4064 }")
4065
4066 (define_insn "shori_media"
4067 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4068 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4069 (const_int 16))
4070 (zero_extend:DI
4071 (truncate:HI
4072 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4073 "TARGET_SHMEDIA"
4074 "@
4075 shori %u2, %0
4076 #"
4077 [(set_attr "type" "arith_media,*")])
4078
4079 (define_expand "movdi"
4080 [(set (match_operand:DI 0 "general_movdst_operand" "")
4081 (match_operand:DI 1 "general_movsrc_operand" ""))]
4082 ""
4083 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4084
4085 (define_insn "movdf_media"
4086 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4087 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,rU"))]
4088 "TARGET_SHMEDIA_FPU
4089 && (register_operand (operands[0], DFmode)
4090 || sh_register_operand (operands[1], DFmode))"
4091 "@
4092 fmov.d %1, %0
4093 fmov.qd %N1, %0
4094 fmov.dq %1, %0
4095 add %1, r63, %0
4096 #
4097 fld%M1.d %m1, %0
4098 fst%M0.d %m0, %1
4099 ld%M1.q %m1, %0
4100 st%M0.q %m0, %N1"
4101 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4102
4103 (define_insn "movdf_media_nofpu"
4104 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4105 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rU"))]
4106 "TARGET_SHMEDIA
4107 && (register_operand (operands[0], DFmode)
4108 || sh_register_operand (operands[1], DFmode))"
4109 "@
4110 add %1, r63, %0
4111 #
4112 ld%M1.q %m1, %0
4113 st%M0.q %m0, %N1"
4114 [(set_attr "type" "arith_media,*,load_media,store_media")])
4115
4116 (define_split
4117 [(set (match_operand:DF 0 "arith_reg_operand" "")
4118 (match_operand:DF 1 "immediate_operand" ""))]
4119 "TARGET_SHMEDIA && reload_completed"
4120 [(set (match_dup 3) (match_dup 2))]
4121 "
4122 {
4123 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4124 long values[2];
4125 REAL_VALUE_TYPE value;
4126
4127 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4128 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4129
4130 if (HOST_BITS_PER_WIDE_INT >= 64)
4131 operands[2] = immed_double_const ((unsigned long) values[endian]
4132 | ((HOST_WIDE_INT) values[1 - endian]
4133 << 32), 0, DImode);
4134 else if (HOST_BITS_PER_WIDE_INT == 32)
4135 operands[2] = immed_double_const (values[endian], values[1 - endian],
4136 DImode);
4137 else
4138 abort ();
4139
4140 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4141 }")
4142
4143 ;; ??? This should be a define expand.
4144
4145 (define_insn "movdf_k"
4146 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4147 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4148 "TARGET_SH1
4149 && (! TARGET_SH4 || reload_completed
4150 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4151 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4152 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4153 && (arith_reg_operand (operands[0], DFmode)
4154 || arith_reg_operand (operands[1], DFmode))"
4155 "* return output_movedouble (insn, operands, DFmode);"
4156 [(set_attr "length" "4")
4157 (set_attr "type" "move,pcload,load,store")])
4158
4159 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4160 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4161 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4162 ;; the d/m/c/X alternative, which is split later into single-precision
4163 ;; instructions. And when not optimizing, no splits are done before fixing
4164 ;; up pcloads, so we need usable length information for that.
4165 (define_insn "movdf_i4"
4166 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4167 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4168 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4169 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4170 "TARGET_SH4
4171 && (arith_reg_operand (operands[0], DFmode)
4172 || arith_reg_operand (operands[1], DFmode))"
4173 "@
4174 fmov %1,%0
4175 #
4176 #
4177 fmov.d %1,%0
4178 fmov.d %1,%0
4179 #
4180 #
4181 #
4182 #
4183 #"
4184 [(set_attr_alternative "length"
4185 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4186 (const_int 4)
4187 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4188 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4189 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4190 (const_int 4)
4191 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4192 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4193 ;; increment or decrement r15 explicitly.
4194 (if_then_else
4195 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4196 (const_int 10) (const_int 8))
4197 (if_then_else
4198 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4199 (const_int 10) (const_int 8))])
4200 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4201 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4202 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4203 (const_string "double")
4204 (const_string "none")))])
4205
4206 ;; Moving DFmode between fp/general registers through memory
4207 ;; (the top of the stack) is faster than moving through fpul even for
4208 ;; little endian. Because the type of an instruction is important for its
4209 ;; scheduling, it is beneficial to split these operations, rather than
4210 ;; emitting them in one single chunk, even if this will expose a stack
4211 ;; use that will prevent scheduling of other stack accesses beyond this
4212 ;; instruction.
4213 (define_split
4214 [(set (match_operand:DF 0 "register_operand" "")
4215 (match_operand:DF 1 "register_operand" ""))
4216 (use (match_operand:PSI 2 "fpscr_operand" ""))
4217 (clobber (match_scratch:SI 3 "=X"))]
4218 "TARGET_SH4 && reload_completed
4219 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4220 [(const_int 0)]
4221 "
4222 {
4223 rtx insn, tos;
4224
4225 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4226 {
4227 emit_move_insn (stack_pointer_rtx,
4228 plus_constant (stack_pointer_rtx, -8));
4229 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4230 }
4231 else
4232 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4233 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4234 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4235 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4236 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4237 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4238 else
4239 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4240 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4241 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4242 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4243 else
4244 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4245 DONE;
4246 }")
4247
4248 ;; local-alloc sometimes allocates scratch registers even when not required,
4249 ;; so we must be prepared to handle these.
4250
4251 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4252 (define_split
4253 [(set (match_operand:DF 0 "general_movdst_operand" "")
4254 (match_operand:DF 1 "general_movsrc_operand" ""))
4255 (use (match_operand:PSI 2 "fpscr_operand" ""))
4256 (clobber (match_scratch:SI 3 ""))]
4257 "TARGET_SH4
4258 && reload_completed
4259 && true_regnum (operands[0]) < 16
4260 && true_regnum (operands[1]) < 16"
4261 [(set (match_dup 0) (match_dup 1))]
4262 "
4263 {
4264 /* If this was a reg <-> mem operation with base + index reg addressing,
4265 we have to handle this in a special way. */
4266 rtx mem = operands[0];
4267 int store_p = 1;
4268 if (! memory_operand (mem, DFmode))
4269 {
4270 mem = operands[1];
4271 store_p = 0;
4272 }
4273 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4274 mem = SUBREG_REG (mem);
4275 if (GET_CODE (mem) == MEM)
4276 {
4277 rtx addr = XEXP (mem, 0);
4278 if (GET_CODE (addr) == PLUS
4279 && GET_CODE (XEXP (addr, 0)) == REG
4280 && GET_CODE (XEXP (addr, 1)) == REG)
4281 {
4282 int offset;
4283 rtx reg0 = gen_rtx (REG, Pmode, 0);
4284 rtx regop = operands[store_p], word0 ,word1;
4285
4286 if (GET_CODE (regop) == SUBREG)
4287 alter_subreg (&regop);
4288 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4289 offset = 2;
4290 else
4291 offset = 4;
4292 mem = copy_rtx (mem);
4293 PUT_MODE (mem, SImode);
4294 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4295 alter_subreg (&word0);
4296 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4297 alter_subreg (&word1);
4298 if (store_p || ! refers_to_regno_p (REGNO (word0),
4299 REGNO (word0) + 1, addr, 0))
4300 {
4301 emit_insn (store_p
4302 ? gen_movsi_ie (mem, word0)
4303 : gen_movsi_ie (word0, mem));
4304 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4305 mem = copy_rtx (mem);
4306 emit_insn (store_p
4307 ? gen_movsi_ie (mem, word1)
4308 : gen_movsi_ie (word1, mem));
4309 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4310 }
4311 else
4312 {
4313 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4314 emit_insn (gen_movsi_ie (word1, mem));
4315 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4316 mem = copy_rtx (mem);
4317 emit_insn (gen_movsi_ie (word0, mem));
4318 }
4319 DONE;
4320 }
4321 }
4322 }")
4323
4324 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4325 (define_split
4326 [(set (match_operand:DF 0 "register_operand" "")
4327 (match_operand:DF 1 "memory_operand" ""))
4328 (use (match_operand:PSI 2 "fpscr_operand" ""))
4329 (clobber (reg:SI R0_REG))]
4330 "TARGET_SH4 && reload_completed"
4331 [(parallel [(set (match_dup 0) (match_dup 1))
4332 (use (match_dup 2))
4333 (clobber (scratch:SI))])]
4334 "")
4335
4336 (define_expand "reload_indf"
4337 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4338 (match_operand:DF 1 "immediate_operand" "FQ"))
4339 (use (reg:PSI FPSCR_REG))
4340 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4341 "TARGET_SH1"
4342 "")
4343
4344 (define_expand "reload_outdf"
4345 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4346 (match_operand:DF 1 "register_operand" "af,r"))
4347 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4348 "TARGET_SH1"
4349 "")
4350
4351 ;; Simplify no-op moves.
4352 (define_split
4353 [(set (match_operand:SF 0 "register_operand" "")
4354 (match_operand:SF 1 "register_operand" ""))
4355 (use (match_operand:PSI 2 "fpscr_operand" ""))
4356 (clobber (match_scratch:SI 3 "X"))]
4357 "TARGET_SH3E && reload_completed
4358 && true_regnum (operands[0]) == true_regnum (operands[1])"
4359 [(set (match_dup 0) (match_dup 0))]
4360 "")
4361
4362 ;; fmovd substitute post-reload splits
4363 (define_split
4364 [(set (match_operand:DF 0 "register_operand" "")
4365 (match_operand:DF 1 "register_operand" ""))
4366 (use (match_operand:PSI 2 "fpscr_operand" ""))
4367 (clobber (match_scratch:SI 3 "X"))]
4368 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4369 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4370 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4371 [(const_int 0)]
4372 "
4373 {
4374 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4375 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4376 gen_rtx (REG, SFmode, src), operands[2]));
4377 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4378 gen_rtx (REG, SFmode, src + 1), operands[2]));
4379 DONE;
4380 }")
4381
4382 (define_split
4383 [(set (match_operand:DF 0 "register_operand" "")
4384 (mem:DF (match_operand:SI 1 "register_operand" "")))
4385 (use (match_operand:PSI 2 "fpscr_operand" ""))
4386 (clobber (match_scratch:SI 3 ""))]
4387 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4388 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4389 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4390 [(const_int 0)]
4391 "
4392 {
4393 int regno = true_regnum (operands[0]);
4394 rtx insn;
4395 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4396
4397 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4398 regno + !! TARGET_LITTLE_ENDIAN),
4399 mem2, operands[2]));
4400 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4401 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4402 regno + ! TARGET_LITTLE_ENDIAN),
4403 gen_rtx (MEM, SFmode, operands[1]),
4404 operands[2]));
4405 DONE;
4406 }")
4407
4408 (define_split
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
4411 (use (match_operand:PSI 2 "fpscr_operand" ""))
4412 (clobber (match_scratch:SI 3 ""))]
4413 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4414 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4415 [(const_int 0)]
4416 "
4417 {
4418 int regno = true_regnum (operands[0]);
4419 rtx addr, insn, adjust = NULL_RTX;
4420 rtx mem2 = copy_rtx (operands[1]);
4421 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4422 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4423
4424 PUT_MODE (mem2, SFmode);
4425 operands[1] = copy_rtx (mem2);
4426 addr = XEXP (mem2, 0);
4427 if (GET_CODE (addr) != POST_INC)
4428 {
4429 /* If we have to modify the stack pointer, the value that we have
4430 read with post-increment might be modified by an interrupt,
4431 so write it back. */
4432 if (REGNO (addr) == STACK_POINTER_REGNUM)
4433 adjust = gen_push_e (reg0);
4434 else
4435 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4436 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4437 }
4438 addr = XEXP (addr, 0);
4439 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4440 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4441 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4442 if (adjust)
4443 emit_insn (adjust);
4444 else
4445 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4446 DONE;
4447 }")
4448
4449 (define_split
4450 [(set (match_operand:DF 0 "memory_operand" "")
4451 (match_operand:DF 1 "register_operand" ""))
4452 (use (match_operand:PSI 2 "fpscr_operand" ""))
4453 (clobber (match_scratch:SI 3 ""))]
4454 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4455 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4456 [(const_int 0)]
4457 "
4458 {
4459 int regno = true_regnum (operands[1]);
4460 rtx insn, addr, adjust = NULL_RTX;
4461
4462 operands[0] = copy_rtx (operands[0]);
4463 PUT_MODE (operands[0], SFmode);
4464 insn = emit_insn (gen_movsf_ie (operands[0],
4465 gen_rtx (REG, SFmode,
4466 regno + ! TARGET_LITTLE_ENDIAN),
4467 operands[2]));
4468 operands[0] = copy_rtx (operands[0]);
4469 addr = XEXP (operands[0], 0);
4470 if (GET_CODE (addr) != PRE_DEC)
4471 {
4472 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4473 emit_insn_before (adjust, insn);
4474 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4475 }
4476 addr = XEXP (addr, 0);
4477 if (! adjust)
4478 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4479 insn = emit_insn (gen_movsf_ie (operands[0],
4480 gen_rtx (REG, SFmode,
4481 regno + !! TARGET_LITTLE_ENDIAN),
4482 operands[2]));
4483 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4484 DONE;
4485 }")
4486
4487 ;; If the output is a register and the input is memory or a register, we have
4488 ;; to be careful and see which word needs to be loaded first.
4489
4490 (define_split
4491 [(set (match_operand:DF 0 "general_movdst_operand" "")
4492 (match_operand:DF 1 "general_movsrc_operand" ""))]
4493 "TARGET_SH1 && reload_completed"
4494 [(set (match_dup 2) (match_dup 3))
4495 (set (match_dup 4) (match_dup 5))]
4496 "
4497 {
4498 int regno;
4499
4500 if ((GET_CODE (operands[0]) == MEM
4501 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4502 || (GET_CODE (operands[1]) == MEM
4503 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4504 FAIL;
4505
4506 if (GET_CODE (operands[0]) == REG)
4507 regno = REGNO (operands[0]);
4508 else if (GET_CODE (operands[0]) == SUBREG)
4509 regno = subreg_regno (operands[0]);
4510 else if (GET_CODE (operands[0]) == MEM)
4511 regno = -1;
4512 else
4513 abort ();
4514
4515 if (regno == -1
4516 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4517 {
4518 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4519 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4520 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4521 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4522 }
4523 else
4524 {
4525 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4526 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4527 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4528 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4529 }
4530
4531 if (operands[2] == 0 || operands[3] == 0
4532 || operands[4] == 0 || operands[5] == 0)
4533 FAIL;
4534 }")
4535
4536 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4537 ;; used only once, let combine add in the index again.
4538
4539 (define_split
4540 [(set (match_operand:SI 0 "register_operand" "")
4541 (match_operand:SI 1 "" ""))
4542 (clobber (match_operand 2 "register_operand" ""))]
4543 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4544 [(use (reg:SI R0_REG))]
4545 "
4546 {
4547 rtx addr, reg, const_int;
4548
4549 if (GET_CODE (operands[1]) != MEM)
4550 FAIL;
4551 addr = XEXP (operands[1], 0);
4552 if (GET_CODE (addr) != PLUS)
4553 FAIL;
4554 reg = XEXP (addr, 0);
4555 const_int = XEXP (addr, 1);
4556 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4557 && GET_CODE (const_int) == CONST_INT))
4558 FAIL;
4559 emit_move_insn (operands[2], const_int);
4560 emit_move_insn (operands[0],
4561 change_address (operands[1], VOIDmode,
4562 gen_rtx_PLUS (SImode, reg, operands[2])));
4563 DONE;
4564 }")
4565
4566 (define_split
4567 [(set (match_operand:SI 1 "" "")
4568 (match_operand:SI 0 "register_operand" ""))
4569 (clobber (match_operand 2 "register_operand" ""))]
4570 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4571 [(use (reg:SI R0_REG))]
4572 "
4573 {
4574 rtx addr, reg, const_int;
4575
4576 if (GET_CODE (operands[1]) != MEM)
4577 FAIL;
4578 addr = XEXP (operands[1], 0);
4579 if (GET_CODE (addr) != PLUS)
4580 FAIL;
4581 reg = XEXP (addr, 0);
4582 const_int = XEXP (addr, 1);
4583 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4584 && GET_CODE (const_int) == CONST_INT))
4585 FAIL;
4586 emit_move_insn (operands[2], const_int);
4587 emit_move_insn (change_address (operands[1], VOIDmode,
4588 gen_rtx_PLUS (SImode, reg, operands[2])),
4589 operands[0]);
4590 DONE;
4591 }")
4592
4593 (define_expand "movdf"
4594 [(set (match_operand:DF 0 "general_movdst_operand" "")
4595 (match_operand:DF 1 "general_movsrc_operand" ""))]
4596 ""
4597 "
4598 {
4599 if (prepare_move_operands (operands, DFmode)) DONE;
4600 if (TARGET_SHMEDIA)
4601 {
4602 if (TARGET_SHMEDIA_FPU)
4603 emit_insn (gen_movdf_media (operands[0], operands[1]));
4604 else
4605 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4606 DONE;
4607 }
4608 if (TARGET_SH4)
4609 {
4610 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4611 DONE;
4612 }
4613 }")
4614
4615 ;;This is incompatible with the way gcc uses subregs.
4616 ;;(define_insn "movv2sf_i"
4617 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4618 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4619 ;; "TARGET_SHMEDIA_FPU
4620 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4621 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4622 ;; "@
4623 ;; #
4624 ;; fld%M1.p %m1, %0
4625 ;; fst%M0.p %m0, %1"
4626 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4627
4628 (define_insn_and_split "movv2sf_i"
4629 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4630 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4631 "TARGET_SHMEDIA_FPU"
4632 "#"
4633 "TARGET_SHMEDIA_FPU && reload_completed"
4634 [(set (match_dup 0) (match_dup 1))]
4635 "
4636 {
4637 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4638 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4639 }")
4640
4641 (define_expand "movv2sf"
4642 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4643 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4644 "TARGET_SHMEDIA_FPU"
4645 "
4646 {
4647 if (prepare_move_operands (operands, V2SFmode))
4648 DONE;
4649 }")
4650
4651 (define_expand "addv2sf3"
4652 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4653 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4654 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4655 "TARGET_SHMEDIA_FPU"
4656 "
4657 {
4658 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4659 DONE;
4660 }")
4661
4662 (define_expand "subv2sf3"
4663 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4664 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4665 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4666 "TARGET_SHMEDIA_FPU"
4667 "
4668 {
4669 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4670 DONE;
4671 }")
4672
4673 (define_expand "mulv2sf3"
4674 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4675 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4676 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4677 "TARGET_SHMEDIA_FPU"
4678 "
4679 {
4680 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4681 DONE;
4682 }")
4683
4684 (define_expand "divv2sf3"
4685 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4686 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4688 "TARGET_SHMEDIA_FPU"
4689 "
4690 {
4691 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4692 DONE;
4693 }")
4694
4695 (define_insn_and_split "*movv4sf_i"
4696 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4697 (match_operand:V4SF 1 "general_operand" "fU,m,fU"))]
4698 "TARGET_SHMEDIA_FPU"
4699 "#"
4700 "&& reload_completed"
4701 [(const_int 0)]
4702 "
4703 {
4704 int i;
4705
4706 for (i = 0; i < 4/2; i++)
4707 {
4708 rtx x, y;
4709
4710 if (GET_CODE (operands[0]) == MEM)
4711 x = gen_rtx_MEM (V2SFmode,
4712 plus_constant (XEXP (operands[0], 0),
4713 i * GET_MODE_SIZE (V2SFmode)));
4714 else
4715 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4716
4717 if (GET_CODE (operands[1]) == MEM)
4718 y = gen_rtx_MEM (V2SFmode,
4719 plus_constant (XEXP (operands[1], 0),
4720 i * GET_MODE_SIZE (V2SFmode)));
4721 else
4722 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4723
4724 emit_insn (gen_movv2sf_i (x, y));
4725 }
4726
4727 DONE;
4728 }"
4729 [(set_attr "length" "8")])
4730
4731 (define_expand "movv4sf"
4732 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4733 (match_operand:V4SF 1 "general_operand" ""))]
4734 "TARGET_SHMEDIA_FPU"
4735 "
4736 {
4737 if (prepare_move_operands (operands, V4SFmode))
4738 DONE;
4739 }")
4740
4741 (define_insn_and_split "*movv16sf_i"
4742 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4743 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4744 "TARGET_SHMEDIA_FPU"
4745 "#"
4746 "&& reload_completed"
4747 [(const_int 0)]
4748 "
4749 {
4750 int i;
4751
4752 for (i = 0; i < 16/2; i++)
4753 {
4754 rtx x,y;
4755
4756 if (GET_CODE (operands[0]) == MEM)
4757 x = gen_rtx_MEM (V2SFmode,
4758 plus_constant (XEXP (operands[0], 0),
4759 i * GET_MODE_SIZE (V2SFmode)));
4760 else
4761 {
4762 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4763 alter_subreg (&x);
4764 }
4765
4766 if (GET_CODE (operands[1]) == MEM)
4767 y = gen_rtx_MEM (V2SFmode,
4768 plus_constant (XEXP (operands[1], 0),
4769 i * GET_MODE_SIZE (V2SFmode)));
4770 else
4771 {
4772 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4773 alter_subreg (&y);
4774 }
4775
4776 emit_insn (gen_movv2sf_i (x, y));
4777 }
4778
4779 DONE;
4780 }"
4781 [(set_attr "length" "32")])
4782
4783 (define_expand "movv16sf"
4784 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4785 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4786 "TARGET_SHMEDIA_FPU"
4787 "
4788 {
4789 if (prepare_move_operands (operands, V16SFmode))
4790 DONE;
4791 }")
4792
4793 (define_insn "movsf_media"
4794 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4795 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,rU"))]
4796 "TARGET_SHMEDIA_FPU
4797 && (register_operand (operands[0], SFmode)
4798 || sh_register_operand (operands[1], SFmode))"
4799 "@
4800 fmov.s %1, %0
4801 fmov.ls %N1, %0
4802 fmov.sl %1, %0
4803 add.l %1, r63, %0
4804 #
4805 fld%M1.s %m1, %0
4806 fst%M0.s %m0, %1
4807 ld%M1.l %m1, %0
4808 st%M0.l %m0, %N1"
4809 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4810
4811 (define_insn "movsf_media_nofpu"
4812 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4813 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rU"))]
4814 "TARGET_SHMEDIA
4815 && (register_operand (operands[0], SFmode)
4816 || sh_register_operand (operands[1], SFmode))"
4817 "@
4818 add.l %1, r63, %0
4819 #
4820 ld%M1.l %m1, %0
4821 st%M0.l %m0, %N1"
4822 [(set_attr "type" "arith_media,*,load_media,store_media")])
4823
4824 (define_split
4825 [(set (match_operand:SF 0 "arith_reg_operand" "")
4826 (match_operand:SF 1 "immediate_operand" ""))]
4827 "TARGET_SHMEDIA && reload_completed
4828 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4829 [(set (match_dup 3) (match_dup 2))]
4830 "
4831 {
4832 long values;
4833 REAL_VALUE_TYPE value;
4834
4835 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4836 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4837 operands[2] = GEN_INT (values);
4838
4839 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4840 }")
4841
4842 (define_insn "movsf_i"
4843 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4844 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4845 "TARGET_SH1
4846 && (! TARGET_SH3E
4847 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4848 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4849 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4850 && (arith_reg_operand (operands[0], SFmode)
4851 || arith_reg_operand (operands[1], SFmode))"
4852 "@
4853 mov %1,%0
4854 mov %1,%0
4855 mov.l %1,%0
4856 mov.l %1,%0
4857 mov.l %1,%0
4858 lds %1,%0
4859 sts %1,%0"
4860 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4861
4862 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4863 ;; update_flow_info would not know where to put REG_EQUAL notes
4864 ;; when the destination changes mode.
4865 (define_insn "movsf_ie"
4866 [(set (match_operand:SF 0 "general_movdst_operand"
4867 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4868 (match_operand:SF 1 "general_movsrc_operand"
4869 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4870 (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"))
4871 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4872
4873 "TARGET_SH3E
4874 && (arith_reg_operand (operands[0], SFmode)
4875 || arith_reg_operand (operands[1], SFmode)
4876 || arith_reg_operand (operands[3], SImode)
4877 || (fpul_operand (operands[0], SFmode)
4878 && memory_operand (operands[1], SFmode)
4879 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4880 || (fpul_operand (operands[1], SFmode)
4881 && memory_operand (operands[0], SFmode)
4882 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4883 "@
4884 fmov %1,%0
4885 mov %1,%0
4886 fldi0 %0
4887 fldi1 %0
4888 #
4889 fmov.s %1,%0
4890 fmov.s %1,%0
4891 mov.l %1,%0
4892 mov.l %1,%0
4893 mov.l %1,%0
4894 fsts fpul,%0
4895 flds %1,fpul
4896 lds.l %1,%0
4897 #
4898 sts %1,%0
4899 lds %1,%0
4900 sts.l %1,%0
4901 lds.l %1,%0
4902 ! move optimized away"
4903 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4904 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4905 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4906 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4907 (const_string "single")
4908 (const_string "none")))])
4909
4910 (define_split
4911 [(set (match_operand:SF 0 "register_operand" "")
4912 (match_operand:SF 1 "register_operand" ""))
4913 (use (match_operand:PSI 2 "fpscr_operand" ""))
4914 (clobber (reg:SI FPUL_REG))]
4915 "TARGET_SH1"
4916 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4917 (use (match_dup 2))
4918 (clobber (scratch:SI))])
4919 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4920 (use (match_dup 2))
4921 (clobber (scratch:SI))])]
4922 "")
4923
4924 (define_expand "movsf"
4925 [(set (match_operand:SF 0 "general_movdst_operand" "")
4926 (match_operand:SF 1 "general_movsrc_operand" ""))]
4927 ""
4928 "
4929 {
4930 if (prepare_move_operands (operands, SFmode))
4931 DONE;
4932 if (TARGET_SHMEDIA)
4933 {
4934 if (TARGET_SHMEDIA_FPU)
4935 emit_insn (gen_movsf_media (operands[0], operands[1]));
4936 else
4937 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4938 DONE;
4939 }
4940 if (TARGET_SH3E)
4941 {
4942 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4943 DONE;
4944 }
4945 }")
4946
4947 (define_insn "mov_nop"
4948 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4949 "TARGET_SH3E"
4950 ""
4951 [(set_attr "length" "0")
4952 (set_attr "type" "nil")])
4953
4954 (define_expand "reload_insf"
4955 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4956 (match_operand:SF 1 "immediate_operand" "FQ"))
4957 (use (reg:PSI FPSCR_REG))
4958 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4959 "TARGET_SH1"
4960 "")
4961
4962 (define_expand "reload_insi"
4963 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4964 (match_operand:SF 1 "immediate_operand" "FQ"))
4965 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4966 "TARGET_SH1"
4967 "")
4968
4969 (define_insn "*movsi_y"
4970 [(set (match_operand:SI 0 "register_operand" "=y,y")
4971 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4972 (clobber (match_scratch:SI 2 "=&z,r"))]
4973 "TARGET_SH3E
4974 && (reload_in_progress || reload_completed)"
4975 "#"
4976 [(set_attr "length" "4")
4977 (set_attr "type" "pcload,move")])
4978
4979 (define_split
4980 [(set (match_operand:SI 0 "register_operand" "")
4981 (match_operand:SI 1 "immediate_operand" ""))
4982 (clobber (match_operand:SI 2 "register_operand" ""))]
4983 "TARGET_SH1"
4984 [(set (match_dup 2) (match_dup 1))
4985 (set (match_dup 0) (match_dup 2))]
4986 "")
4987
4988 (define_split
4989 [(set (match_operand:SI 0 "register_operand" "")
4990 (match_operand:SI 1 "memory_operand" ""))
4991 (clobber (reg:SI R0_REG))]
4992 "TARGET_SH1"
4993 [(set (match_dup 0) (match_dup 1))]
4994 "")
4995 \f
4996 ;; ------------------------------------------------------------------------
4997 ;; Define the real conditional branch instructions.
4998 ;; ------------------------------------------------------------------------
4999
5000 (define_insn "branch_true"
5001 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5002 (label_ref (match_operand 0 "" ""))
5003 (pc)))]
5004 "TARGET_SH1"
5005 "* return output_branch (1, insn, operands);"
5006 [(set_attr "type" "cbranch")])
5007
5008 (define_insn "branch_false"
5009 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5010 (label_ref (match_operand 0 "" ""))
5011 (pc)))]
5012 "TARGET_SH1"
5013 "* return output_branch (0, insn, operands);"
5014 [(set_attr "type" "cbranch")])
5015
5016 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5017 ;; which destination is too far away.
5018 ;; The const_int_operand is distinct for each branch target; it avoids
5019 ;; unwanted matches with redundant_insn.
5020 (define_insn "block_branch_redirect"
5021 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5022 "TARGET_SH1"
5023 ""
5024 [(set_attr "length" "0")])
5025
5026 ;; This one has the additional purpose to record a possible scratch register
5027 ;; for the following branch.
5028 (define_insn "indirect_jump_scratch"
5029 [(set (match_operand:SI 0 "register_operand" "=r")
5030 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5031 "TARGET_SH1"
5032 ""
5033 [(set_attr "length" "0")])
5034
5035 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5036 ;; being pulled into the delay slot of a condbranch that has been made to
5037 ;; jump around the unconditional jump because it was out of range.
5038 (define_insn "stuff_delay_slot"
5039 [(set (pc)
5040 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5041 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5042 "TARGET_SH1"
5043 ""
5044 [(set_attr "length" "0")
5045 (set_attr "cond_delay_slot" "yes")])
5046 \f
5047 ;; Conditional branch insns
5048
5049 (define_expand "beq_media"
5050 [(set (pc)
5051 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5052 (match_operand:DI 2 "arith_operand" "r,O"))
5053 (label_ref:DI (match_operand 0 "" ""))
5054 (pc)))]
5055 "TARGET_SHMEDIA"
5056 "")
5057
5058 (define_insn "*beq_media_i"
5059 [(set (pc)
5060 (if_then_else (match_operator 3 "equality_comparison_operator"
5061 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5062 (match_operand:DI 2 "arith_operand" "r,O")])
5063 (match_operand:DI 0 "target_operand" "b,b")
5064 (pc)))]
5065 "TARGET_SHMEDIA"
5066 "@
5067 b%o3%' %1, %2, %0
5068 b%o3i%' %1, %2, %0"
5069 [(set_attr "type" "cbranch_media")])
5070
5071 (define_expand "bne_media"
5072 [(set (pc)
5073 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5074 (match_operand:DI 2 "arith_operand" "r,O"))
5075 (label_ref:DI (match_operand 0 "" ""))
5076 (pc)))]
5077 "TARGET_SHMEDIA"
5078 "")
5079
5080 (define_expand "bgt_media"
5081 [(set (pc)
5082 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5083 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5084 (label_ref:DI (match_operand 0 "" ""))
5085 (pc)))]
5086 "TARGET_SHMEDIA"
5087 "")
5088
5089 (define_expand "bge_media"
5090 [(set (pc)
5091 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5092 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5093 (label_ref:DI (match_operand 0 "" ""))
5094 (pc)))]
5095 "TARGET_SHMEDIA"
5096 "")
5097
5098 (define_expand "bgtu_media"
5099 [(set (pc)
5100 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5101 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5102 (label_ref:DI (match_operand 0 "" ""))
5103 (pc)))]
5104 "TARGET_SHMEDIA"
5105 "")
5106
5107 (define_expand "bgeu_media"
5108 [(set (pc)
5109 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5110 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5111 (label_ref:DI (match_operand 0 "" ""))
5112 (pc)))]
5113 "TARGET_SHMEDIA"
5114 "")
5115
5116 (define_insn "*bgt_media_i"
5117 [(set (pc)
5118 (if_then_else (match_operator 3 "greater_comparison_operator"
5119 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5120 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5121 (match_operand:DI 0 "target_operand" "b")
5122 (pc)))]
5123 "TARGET_SHMEDIA"
5124 "b%o3%' %N1, %N2, %0"
5125 [(set_attr "type" "cbranch_media")])
5126
5127 ;; These are only needed to make invert_jump() happy.
5128 (define_insn "*blt_media_i"
5129 [(set (pc)
5130 (if_then_else (match_operator 3 "less_comparison_operator"
5131 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5132 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5133 (match_operand:DI 0 "target_operand" "b")
5134 (pc)))]
5135 "TARGET_SHMEDIA"
5136 "b%o3%' %N2, %N1, %0"
5137 [(set_attr "type" "cbranch_media")])
5138
5139 (define_expand "beq"
5140 [(set (pc)
5141 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5142 (label_ref (match_operand 0 "" ""))
5143 (pc)))]
5144 ""
5145 "
5146 {
5147 if (TARGET_SHMEDIA)
5148 {
5149 if (GET_MODE (sh_compare_op0) != DImode)
5150 {
5151 rtx tmp = gen_reg_rtx (DImode);
5152
5153 emit_insn (gen_seq (tmp));
5154 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5155 DONE;
5156 }
5157
5158 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5159 emit_jump_insn (gen_beq_media (operands[0],
5160 sh_compare_op0, sh_compare_op1));
5161 DONE;
5162 }
5163
5164 from_compare (operands, EQ);
5165 }")
5166
5167 (define_expand "bne"
5168 [(set (pc)
5169 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5170 (label_ref (match_operand 0 "" ""))
5171 (pc)))]
5172 ""
5173 "
5174 {
5175 if (TARGET_SHMEDIA)
5176 {
5177 if (GET_MODE (sh_compare_op0) != DImode)
5178 {
5179 rtx tmp = gen_reg_rtx (DImode);
5180
5181 emit_insn (gen_seq (tmp));
5182 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5183 DONE;
5184 }
5185
5186 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5187 emit_jump_insn (gen_bne_media (operands[0],
5188 sh_compare_op0, sh_compare_op1));
5189 DONE;
5190 }
5191
5192 from_compare (operands, EQ);
5193 }")
5194
5195 (define_expand "bgt"
5196 [(set (pc)
5197 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5198 (label_ref (match_operand 0 "" ""))
5199 (pc)))]
5200 ""
5201 "
5202 {
5203 if (TARGET_SHMEDIA)
5204 {
5205 if (GET_MODE (sh_compare_op0) != DImode)
5206 {
5207 rtx tmp = gen_reg_rtx (DImode);
5208
5209 emit_insn (gen_sgt (tmp));
5210 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5211 DONE;
5212 }
5213
5214 if (sh_compare_op0 != const0_rtx)
5215 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5216 if (sh_compare_op1 != const0_rtx)
5217 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5218 emit_jump_insn (gen_bgt_media (operands[0],
5219 sh_compare_op0, sh_compare_op1));
5220 DONE;
5221 }
5222
5223 from_compare (operands, GT);
5224 }")
5225
5226 (define_expand "blt"
5227 [(set (pc)
5228 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5229 (label_ref (match_operand 0 "" ""))
5230 (pc)))]
5231 ""
5232 "
5233 {
5234 if (TARGET_SHMEDIA)
5235 {
5236 if (GET_MODE (sh_compare_op0) != DImode)
5237 {
5238 rtx tmp = gen_reg_rtx (DImode);
5239
5240 emit_insn (gen_slt (tmp));
5241 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5242 DONE;
5243 }
5244
5245 if (sh_compare_op0 != const0_rtx)
5246 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5247 if (sh_compare_op1 != const0_rtx)
5248 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5249 emit_jump_insn (gen_bgt_media (operands[0],
5250 sh_compare_op1, sh_compare_op0));
5251 DONE;
5252 }
5253
5254 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5255 {
5256 rtx tmp = sh_compare_op0;
5257 sh_compare_op0 = sh_compare_op1;
5258 sh_compare_op1 = tmp;
5259 emit_insn (gen_bgt (operands[0]));
5260 DONE;
5261 }
5262 from_compare (operands, GE);
5263 }")
5264
5265 (define_expand "ble"
5266 [(set (pc)
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5269 (pc)))]
5270 ""
5271 "
5272 {
5273 if (TARGET_SHMEDIA)
5274 {
5275 if (GET_MODE (sh_compare_op0) != DImode)
5276 {
5277 rtx tmp = gen_reg_rtx (DImode);
5278
5279 emit_insn (gen_sle (tmp));
5280 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5281 DONE;
5282 }
5283
5284 if (sh_compare_op0 != const0_rtx)
5285 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286 if (sh_compare_op1 != const0_rtx)
5287 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5288 emit_jump_insn (gen_bge_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5290 DONE;
5291 }
5292
5293 if (TARGET_SH3E
5294 && TARGET_IEEE
5295 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5296 {
5297 rtx tmp = sh_compare_op0;
5298 sh_compare_op0 = sh_compare_op1;
5299 sh_compare_op1 = tmp;
5300 emit_insn (gen_bge (operands[0]));
5301 DONE;
5302 }
5303 from_compare (operands, GT);
5304 }")
5305
5306 (define_expand "bge"
5307 [(set (pc)
5308 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5309 (label_ref (match_operand 0 "" ""))
5310 (pc)))]
5311 ""
5312 "
5313 {
5314 if (TARGET_SHMEDIA)
5315 {
5316 if (GET_MODE (sh_compare_op0) != DImode)
5317 {
5318 rtx tmp = gen_reg_rtx (DImode);
5319
5320 emit_insn (gen_sge (tmp));
5321 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5322 DONE;
5323 }
5324
5325 if (sh_compare_op0 != const0_rtx)
5326 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5327 if (sh_compare_op1 != const0_rtx)
5328 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5329 emit_jump_insn (gen_bge_media (operands[0],
5330 sh_compare_op0, sh_compare_op1));
5331 DONE;
5332 }
5333
5334 if (TARGET_SH3E
5335 && ! TARGET_IEEE
5336 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5337 {
5338 rtx tmp = sh_compare_op0;
5339 sh_compare_op0 = sh_compare_op1;
5340 sh_compare_op1 = tmp;
5341 emit_insn (gen_ble (operands[0]));
5342 DONE;
5343 }
5344 from_compare (operands, GE);
5345 }")
5346
5347 (define_expand "bgtu"
5348 [(set (pc)
5349 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5350 (label_ref (match_operand 0 "" ""))
5351 (pc)))]
5352 ""
5353 "
5354 {
5355 if (TARGET_SHMEDIA)
5356 {
5357 if (sh_compare_op0 != const0_rtx)
5358 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5359 if (sh_compare_op1 != const0_rtx)
5360 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5361 emit_jump_insn (gen_bgtu_media (operands[0],
5362 sh_compare_op0, sh_compare_op1));
5363 DONE;
5364 }
5365
5366 from_compare (operands, GTU);
5367 }")
5368
5369 (define_expand "bltu"
5370 [(set (pc)
5371 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5372 (label_ref (match_operand 0 "" ""))
5373 (pc)))]
5374 ""
5375 "
5376 {
5377 if (TARGET_SHMEDIA)
5378 {
5379 if (sh_compare_op0 != const0_rtx)
5380 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5381 if (sh_compare_op1 != const0_rtx)
5382 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5383 emit_jump_insn (gen_bgtu_media (operands[0],
5384 sh_compare_op1, sh_compare_op0));
5385 DONE;
5386 }
5387
5388 from_compare (operands, GEU);
5389 }")
5390
5391 (define_expand "bgeu"
5392 [(set (pc)
5393 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5394 (label_ref (match_operand 0 "" ""))
5395 (pc)))]
5396 ""
5397 "
5398 {
5399 if (TARGET_SHMEDIA)
5400 {
5401 if (sh_compare_op0 != const0_rtx)
5402 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5403 if (sh_compare_op1 != const0_rtx)
5404 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5405 emit_jump_insn (gen_bgeu_media (operands[0],
5406 sh_compare_op0, sh_compare_op1));
5407 DONE;
5408 }
5409
5410 from_compare (operands, GEU);
5411 }")
5412
5413 (define_expand "bleu"
5414 [(set (pc)
5415 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5416 (label_ref (match_operand 0 "" ""))
5417 (pc)))]
5418 ""
5419 "
5420 {
5421 if (TARGET_SHMEDIA)
5422 {
5423 if (sh_compare_op0 != const0_rtx)
5424 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5425 if (sh_compare_op1 != const0_rtx)
5426 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5427 emit_jump_insn (gen_bgeu_media (operands[0],
5428 sh_compare_op1, sh_compare_op0));
5429 DONE;
5430 }
5431
5432 from_compare (operands, GTU);
5433 }")
5434
5435 (define_expand "bunordered"
5436 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5437 (set (pc)
5438 (if_then_else (ne (match_dup 1) (const_int 0))
5439 (label_ref:DI (match_operand 0 "" ""))
5440 (pc)))]
5441 "TARGET_SHMEDIA"
5442 "
5443 {
5444 operands[1] = gen_reg_rtx (DImode);
5445 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5446 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5447 }")
5448 \f
5449 ;; ------------------------------------------------------------------------
5450 ;; Jump and linkage insns
5451 ;; ------------------------------------------------------------------------
5452
5453 (define_insn "jump_compact"
5454 [(set (pc)
5455 (label_ref (match_operand 0 "" "")))]
5456 "TARGET_SH1"
5457 "*
5458 {
5459 /* The length is 16 if the delay slot is unfilled. */
5460 if (get_attr_length(insn) > 4)
5461 return output_far_jump(insn, operands[0]);
5462 else
5463 return \"bra %l0%#\";
5464 }"
5465 [(set_attr "type" "jump")
5466 (set_attr "needs_delay_slot" "yes")])
5467
5468 (define_insn "jump_media"
5469 [(set (pc)
5470 (match_operand:DI 0 "target_operand" "b"))]
5471 "TARGET_SHMEDIA"
5472 "blink %0, r63"
5473 [(set_attr "type" "jump_media")])
5474
5475 (define_expand "jump"
5476 [(set (pc)
5477 (label_ref (match_operand 0 "" "")))]
5478 ""
5479 "
5480 {
5481 if (TARGET_SH1)
5482 emit_jump_insn (gen_jump_compact (operands[0]));
5483 else if (TARGET_SHMEDIA)
5484 {
5485 if (reload_in_progress || reload_completed)
5486 FAIL;
5487 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5488 operands[0])));
5489 }
5490 DONE;
5491 }")
5492
5493 (define_insn "force_mode_for_call"
5494 [(use (reg:PSI FPSCR_REG))]
5495 "TARGET_SHCOMPACT"
5496 ""
5497 [(set_attr "length" "0")
5498 (set (attr "fp_mode")
5499 (if_then_else (eq_attr "fpu_single" "yes")
5500 (const_string "single") (const_string "double")))])
5501
5502 (define_insn "calli"
5503 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5504 (match_operand 1 "" ""))
5505 (use (reg:PSI FPSCR_REG))
5506 (clobber (reg:SI PR_REG))]
5507 "TARGET_SH1"
5508 "jsr @%0%#"
5509 [(set_attr "type" "call")
5510 (set (attr "fp_mode")
5511 (if_then_else (eq_attr "fpu_single" "yes")
5512 (const_string "single") (const_string "double")))
5513 (set_attr "needs_delay_slot" "yes")])
5514
5515 ;; This is a pc-rel call, using bsrf, for use with PIC.
5516
5517 (define_insn "calli_pcrel"
5518 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5519 (match_operand 1 "" ""))
5520 (use (reg:PSI FPSCR_REG))
5521 (use (reg:SI PIC_REG))
5522 (use (match_operand 2 "" ""))
5523 (clobber (reg:SI PR_REG))]
5524 "TARGET_SH2"
5525 "bsrf %0\\n%O2:%#"
5526 [(set_attr "type" "call")
5527 (set (attr "fp_mode")
5528 (if_then_else (eq_attr "fpu_single" "yes")
5529 (const_string "single") (const_string "double")))
5530 (set_attr "needs_delay_slot" "yes")])
5531
5532 (define_insn_and_split "call_pcrel"
5533 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5534 (match_operand 1 "" ""))
5535 (use (reg:PSI FPSCR_REG))
5536 (use (reg:SI PIC_REG))
5537 (clobber (reg:SI PR_REG))
5538 (clobber (match_scratch:SI 2 "=r"))]
5539 "TARGET_SH2"
5540 "#"
5541 "reload_completed"
5542 [(const_int 0)]
5543 "
5544 {
5545 rtx lab = PATTERN (gen_call_site ());
5546
5547 if (SYMBOL_REF_FLAG (operands[0]))
5548 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5549 else
5550 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5551 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5552 DONE;
5553 }"
5554 [(set_attr "type" "call")
5555 (set (attr "fp_mode")
5556 (if_then_else (eq_attr "fpu_single" "yes")
5557 (const_string "single") (const_string "double")))
5558 (set_attr "needs_delay_slot" "yes")])
5559
5560 (define_insn "call_compact"
5561 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5562 (match_operand 1 "" ""))
5563 (match_operand 2 "immediate_operand" "n")
5564 (use (reg:SI R0_REG))
5565 (use (reg:SI R1_REG))
5566 (use (reg:PSI FPSCR_REG))
5567 (clobber (reg:SI PR_REG))]
5568 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5569 "jsr @%0%#"
5570 [(set_attr "type" "call")
5571 (set (attr "fp_mode")
5572 (if_then_else (eq_attr "fpu_single" "yes")
5573 (const_string "single") (const_string "double")))
5574 (set_attr "needs_delay_slot" "yes")])
5575
5576 (define_insn "call_compact_rettramp"
5577 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5578 (match_operand 1 "" ""))
5579 (match_operand 2 "immediate_operand" "n")
5580 (use (reg:SI R0_REG))
5581 (use (reg:SI R1_REG))
5582 (use (reg:PSI FPSCR_REG))
5583 (clobber (reg:SI R10_REG))
5584 (clobber (reg:SI PR_REG))]
5585 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5586 "jsr @%0%#"
5587 [(set_attr "type" "call")
5588 (set (attr "fp_mode")
5589 (if_then_else (eq_attr "fpu_single" "yes")
5590 (const_string "single") (const_string "double")))
5591 (set_attr "needs_delay_slot" "yes")])
5592
5593 (define_insn "call_media"
5594 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5595 (match_operand 1 "" ""))
5596 (clobber (reg:DI PR_MEDIA_REG))]
5597 "TARGET_SHMEDIA"
5598 "blink %0, r18"
5599 [(set_attr "type" "jump_media")])
5600
5601 (define_insn "call_valuei"
5602 [(set (match_operand 0 "" "=rf")
5603 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5604 (match_operand 2 "" "")))
5605 (use (reg:PSI FPSCR_REG))
5606 (clobber (reg:SI PR_REG))]
5607 "TARGET_SH1"
5608 "jsr @%1%#"
5609 [(set_attr "type" "call")
5610 (set (attr "fp_mode")
5611 (if_then_else (eq_attr "fpu_single" "yes")
5612 (const_string "single") (const_string "double")))
5613 (set_attr "needs_delay_slot" "yes")])
5614
5615 (define_insn "call_valuei_pcrel"
5616 [(set (match_operand 0 "" "=rf")
5617 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5618 (match_operand 2 "" "")))
5619 (use (reg:PSI FPSCR_REG))
5620 (use (reg:SI PIC_REG))
5621 (use (match_operand 3 "" ""))
5622 (clobber (reg:SI PR_REG))]
5623 "TARGET_SH2"
5624 "bsrf %1\\n%O3:%#"
5625 [(set_attr "type" "call")
5626 (set (attr "fp_mode")
5627 (if_then_else (eq_attr "fpu_single" "yes")
5628 (const_string "single") (const_string "double")))
5629 (set_attr "needs_delay_slot" "yes")])
5630
5631 (define_insn_and_split "call_value_pcrel"
5632 [(set (match_operand 0 "" "=rf")
5633 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5634 (match_operand 2 "" "")))
5635 (use (reg:PSI FPSCR_REG))
5636 (use (reg:SI PIC_REG))
5637 (clobber (reg:SI PR_REG))
5638 (clobber (match_scratch:SI 3 "=r"))]
5639 "TARGET_SH2"
5640 "#"
5641 "reload_completed"
5642 [(const_int 0)]
5643 "
5644 {
5645 rtx lab = PATTERN (gen_call_site ());
5646
5647 if (SYMBOL_REF_FLAG (operands[1]))
5648 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5649 else
5650 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5651 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5652 operands[2], lab));
5653 DONE;
5654 }"
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")])
5660
5661 (define_insn "call_value_compact"
5662 [(set (match_operand 0 "" "=rf")
5663 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5664 (match_operand 2 "" "")))
5665 (match_operand 3 "immediate_operand" "n")
5666 (use (reg:SI R0_REG))
5667 (use (reg:SI R1_REG))
5668 (use (reg:PSI FPSCR_REG))
5669 (clobber (reg:SI PR_REG))]
5670 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5671 "jsr @%1%#"
5672 [(set_attr "type" "call")
5673 (set (attr "fp_mode")
5674 (if_then_else (eq_attr "fpu_single" "yes")
5675 (const_string "single") (const_string "double")))
5676 (set_attr "needs_delay_slot" "yes")])
5677
5678 (define_insn "call_value_compact_rettramp"
5679 [(set (match_operand 0 "" "=rf")
5680 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5681 (match_operand 2 "" "")))
5682 (match_operand 3 "immediate_operand" "n")
5683 (use (reg:SI R0_REG))
5684 (use (reg:SI R1_REG))
5685 (use (reg:PSI FPSCR_REG))
5686 (clobber (reg:SI R10_REG))
5687 (clobber (reg:SI PR_REG))]
5688 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5689 "jsr @%1%#"
5690 [(set_attr "type" "call")
5691 (set (attr "fp_mode")
5692 (if_then_else (eq_attr "fpu_single" "yes")
5693 (const_string "single") (const_string "double")))
5694 (set_attr "needs_delay_slot" "yes")])
5695
5696 (define_insn "call_value_media"
5697 [(set (match_operand 0 "" "=rf")
5698 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5699 (match_operand 2 "" "")))
5700 (clobber (reg:DI PR_MEDIA_REG))]
5701 "TARGET_SHMEDIA"
5702 "blink %1, r18"
5703 [(set_attr "type" "jump_media")])
5704
5705 (define_expand "call"
5706 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5707 (match_operand 1 "" ""))
5708 (match_operand 2 "" "")
5709 (use (reg:PSI FPSCR_REG))
5710 (clobber (reg:SI PR_REG))])]
5711 ""
5712 "
5713 {
5714 if (TARGET_SHMEDIA)
5715 {
5716 operands[0] = XEXP (operands[0], 0);
5717 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5718 {
5719 if (! SYMBOL_REF_FLAG (operands[0]))
5720 {
5721 rtx reg = gen_reg_rtx (Pmode);
5722
5723 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5724 operands[0] = reg;
5725 }
5726 else
5727 {
5728 operands[0] = gen_sym2PIC (operands[0]);
5729 PUT_MODE (operands[0], Pmode);
5730 }
5731 }
5732 if (GET_MODE (operands[0]) == SImode)
5733 {
5734 if (GET_CODE (operands[0]) == REG)
5735 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5736 else if (GET_CODE (operands[0]) == SUBREG)
5737 {
5738 operands[0] = SUBREG_REG (operands[0]);
5739 if (GET_MODE (operands[0]) != DImode)
5740 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5741 }
5742 else
5743 {
5744 operands[0] = shallow_copy_rtx (operands[0]);
5745 PUT_MODE (operands[0], DImode);
5746 }
5747 }
5748 if (! target_reg_operand (operands[0], DImode))
5749 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5750 emit_call_insn (gen_call_media (operands[0], operands[1]));
5751 DONE;
5752 }
5753 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5754 {
5755 rtx cookie_rtx = operands[2];
5756 long cookie = INTVAL (cookie_rtx);
5757 rtx func = XEXP (operands[0], 0);
5758 rtx r0, r1;
5759
5760 if (flag_pic)
5761 {
5762 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5763 {
5764 rtx reg = gen_reg_rtx (Pmode);
5765
5766 emit_insn (gen_symGOTPLT2reg (reg, func));
5767 func = reg;
5768 }
5769 else
5770 func = legitimize_pic_address (func, Pmode, 0);
5771 }
5772
5773 r0 = gen_rtx_REG (SImode, R0_REG);
5774 r1 = gen_rtx_REG (SImode, R1_REG);
5775
5776 /* Since such a call function may use all call-clobbered
5777 registers, we force a mode switch earlier, so that we don't
5778 run out of registers when adjusting fpscr for the call. */
5779 emit_insn (gen_force_mode_for_call ());
5780
5781 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5782 \"__GCC_shcompact_call_trampoline\");
5783 if (flag_pic)
5784 {
5785 rtx reg = gen_reg_rtx (Pmode);
5786
5787 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5788 operands[0] = reg;
5789 }
5790 operands[0] = force_reg (SImode, operands[0]);
5791
5792 emit_move_insn (r0, func);
5793 emit_move_insn (r1, cookie_rtx);
5794
5795 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5796 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5797 operands[2]));
5798 else
5799 emit_call_insn (gen_call_compact (operands[0], operands[1],
5800 operands[2]));
5801
5802 DONE;
5803 }
5804 else if (TARGET_SHCOMPACT && flag_pic
5805 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5806 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5807 {
5808 rtx reg = gen_reg_rtx (Pmode);
5809
5810 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5811 XEXP (operands[0], 0) = reg;
5812 }
5813 if (flag_pic && TARGET_SH2
5814 && GET_CODE (operands[0]) == MEM
5815 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5816 {
5817 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5818 DONE;
5819 }
5820 else
5821 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5822
5823 emit_call_insn (gen_calli (operands[0], operands[1]));
5824 DONE;
5825 }")
5826
5827 (define_insn "call_pop_compact"
5828 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5829 (match_operand 1 "" ""))
5830 (match_operand 2 "immediate_operand" "n")
5831 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5832 (match_operand 3 "immediate_operand" "n")))
5833 (use (reg:SI R0_REG))
5834 (use (reg:SI R1_REG))
5835 (use (reg:PSI FPSCR_REG))
5836 (clobber (reg:SI PR_REG))]
5837 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5838 "jsr @%0%#"
5839 [(set_attr "type" "call")
5840 (set (attr "fp_mode")
5841 (if_then_else (eq_attr "fpu_single" "yes")
5842 (const_string "single") (const_string "double")))
5843 (set_attr "needs_delay_slot" "yes")])
5844
5845 (define_insn "call_pop_compact_rettramp"
5846 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5847 (match_operand 1 "" ""))
5848 (match_operand 2 "immediate_operand" "n")
5849 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5850 (match_operand 3 "immediate_operand" "n")))
5851 (use (reg:SI R0_REG))
5852 (use (reg:SI R1_REG))
5853 (use (reg:PSI FPSCR_REG))
5854 (clobber (reg:SI R10_REG))
5855 (clobber (reg:SI PR_REG))]
5856 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5857 "jsr @%0%#"
5858 [(set_attr "type" "call")
5859 (set (attr "fp_mode")
5860 (if_then_else (eq_attr "fpu_single" "yes")
5861 (const_string "single") (const_string "double")))
5862 (set_attr "needs_delay_slot" "yes")])
5863
5864 (define_expand "call_pop"
5865 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5866 (match_operand 1 "" ""))
5867 (match_operand 2 "" "")
5868 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5869 (match_operand 3 "" "")))])]
5870 "TARGET_SHCOMPACT"
5871 "
5872 {
5873 if (operands[2] && INTVAL (operands[2]))
5874 {
5875 rtx cookie_rtx = operands[2];
5876 long cookie = INTVAL (cookie_rtx);
5877 rtx func = XEXP (operands[0], 0);
5878 rtx r0, r1;
5879
5880 if (flag_pic)
5881 {
5882 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5883 {
5884 rtx reg = gen_reg_rtx (Pmode);
5885
5886 emit_insn (gen_symGOTPLT2reg (reg, func));
5887 func = reg;
5888 }
5889 else
5890 func = legitimize_pic_address (func, Pmode, 0);
5891 }
5892
5893 r0 = gen_rtx_REG (SImode, R0_REG);
5894 r1 = gen_rtx_REG (SImode, R1_REG);
5895
5896 /* Since such a call function may use all call-clobbered
5897 registers, we force a mode switch earlier, so that we don't
5898 run out of registers when adjusting fpscr for the call. */
5899 emit_insn (gen_force_mode_for_call ());
5900
5901 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5902 \"__GCC_shcompact_call_trampoline\");
5903 if (flag_pic)
5904 {
5905 rtx reg = gen_reg_rtx (Pmode);
5906
5907 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5908 operands[0] = reg;
5909 }
5910 operands[0] = force_reg (SImode, operands[0]);
5911
5912 emit_move_insn (r0, func);
5913 emit_move_insn (r1, cookie_rtx);
5914
5915 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5916 emit_call_insn (gen_call_pop_compact_rettramp
5917 (operands[0], operands[1], operands[2], operands[3]));
5918 else
5919 emit_call_insn (gen_call_pop_compact
5920 (operands[0], operands[1], operands[2], operands[3]));
5921
5922 DONE;
5923 }
5924
5925 abort ();
5926 }")
5927
5928 (define_expand "call_value"
5929 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5930 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5931 (match_operand 2 "" "")))
5932 (match_operand 3 "" "")
5933 (use (reg:PSI FPSCR_REG))
5934 (clobber (reg:SI PR_REG))])]
5935 ""
5936 "
5937 {
5938 if (TARGET_SHMEDIA)
5939 {
5940 operands[1] = XEXP (operands[1], 0);
5941 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5942 {
5943 if (! SYMBOL_REF_FLAG (operands[1]))
5944 {
5945 rtx reg = gen_reg_rtx (Pmode);
5946
5947 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5948 operands[1] = reg;
5949 }
5950 else
5951 {
5952 operands[1] = gen_sym2PIC (operands[1]);
5953 PUT_MODE (operands[1], Pmode);
5954 }
5955 }
5956 if (GET_MODE (operands[1]) == SImode)
5957 {
5958 if (GET_CODE (operands[1]) == REG)
5959 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5960 else if (GET_CODE (operands[1]) == SUBREG)
5961 {
5962 operands[1] = SUBREG_REG (operands[1]);
5963 if (GET_MODE (operands[1]) != DImode)
5964 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5965 }
5966 else
5967 {
5968 operands[1] = shallow_copy_rtx (operands[1]);
5969 PUT_MODE (operands[1], DImode);
5970 }
5971 }
5972 if (! target_reg_operand (operands[1], DImode))
5973 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5974 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5975 operands[2]));
5976 DONE;
5977 }
5978 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5979 {
5980 rtx cookie_rtx = operands[3];
5981 long cookie = INTVAL (cookie_rtx);
5982 rtx func = XEXP (operands[1], 0);
5983 rtx r0, r1;
5984
5985 if (flag_pic)
5986 {
5987 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5988 {
5989 rtx reg = gen_reg_rtx (Pmode);
5990
5991 emit_insn (gen_symGOTPLT2reg (reg, func));
5992 func = reg;
5993 }
5994 else
5995 func = legitimize_pic_address (func, Pmode, 0);
5996 }
5997
5998 r0 = gen_rtx_REG (SImode, R0_REG);
5999 r1 = gen_rtx_REG (SImode, R1_REG);
6000
6001 /* Since such a call function may use all call-clobbered
6002 registers, we force a mode switch earlier, so that we don't
6003 run out of registers when adjusting fpscr for the call. */
6004 emit_insn (gen_force_mode_for_call ());
6005
6006 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6007 \"__GCC_shcompact_call_trampoline\");
6008 if (flag_pic)
6009 {
6010 rtx reg = gen_reg_rtx (Pmode);
6011
6012 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6013 operands[1] = reg;
6014 }
6015 operands[1] = force_reg (SImode, operands[1]);
6016
6017 emit_move_insn (r0, func);
6018 emit_move_insn (r1, cookie_rtx);
6019
6020 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6021 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6022 operands[1],
6023 operands[2],
6024 operands[3]));
6025 else
6026 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6027 operands[2], operands[3]));
6028
6029 DONE;
6030 }
6031 else if (TARGET_SHCOMPACT && flag_pic
6032 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6033 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6034 {
6035 rtx reg = gen_reg_rtx (Pmode);
6036
6037 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6038 XEXP (operands[1], 0) = reg;
6039 }
6040 if (flag_pic && TARGET_SH2
6041 && GET_CODE (operands[1]) == MEM
6042 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6043 {
6044 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6045 operands[2]));
6046 DONE;
6047 }
6048 else
6049 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6050
6051 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6052 DONE;
6053 }")
6054
6055 (define_insn "sibcalli"
6056 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6057 (match_operand 1 "" ""))
6058 (use (reg:PSI FPSCR_REG))
6059 (return)]
6060 "TARGET_SH1"
6061 "jmp @%0%#"
6062 [(set_attr "needs_delay_slot" "yes")
6063 (set (attr "fp_mode")
6064 (if_then_else (eq_attr "fpu_single" "yes")
6065 (const_string "single") (const_string "double")))
6066 (set_attr "type" "jump_ind")])
6067
6068 (define_insn "sibcalli_pcrel"
6069 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6070 (match_operand 1 "" ""))
6071 (use (match_operand 2 "" ""))
6072 (use (reg:PSI FPSCR_REG))
6073 (return)]
6074 "TARGET_SH2"
6075 "braf %0\\n%O2:%#"
6076 [(set_attr "needs_delay_slot" "yes")
6077 (set (attr "fp_mode")
6078 (if_then_else (eq_attr "fpu_single" "yes")
6079 (const_string "single") (const_string "double")))
6080 (set_attr "type" "jump_ind")])
6081
6082 (define_insn_and_split "sibcall_pcrel"
6083 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6084 (match_operand 1 "" ""))
6085 (use (reg:PSI FPSCR_REG))
6086 (clobber (match_scratch:SI 2 "=k"))
6087 (return)]
6088 "TARGET_SH2"
6089 "#"
6090 "reload_completed"
6091 [(const_int 0)]
6092 "
6093 {
6094 rtx lab = PATTERN (gen_call_site ());
6095 rtx call_insn;
6096
6097 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6098 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6099 lab));
6100 SIBLING_CALL_P (call_insn) = 1;
6101 DONE;
6102 }"
6103 [(set_attr "needs_delay_slot" "yes")
6104 (set (attr "fp_mode")
6105 (if_then_else (eq_attr "fpu_single" "yes")
6106 (const_string "single") (const_string "double")))
6107 (set_attr "type" "jump_ind")])
6108
6109 (define_insn "sibcall_compact"
6110 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6111 (match_operand 1 "" ""))
6112 (return)
6113 (use (match_operand:SI 2 "register_operand" "z,x"))
6114 (use (reg:SI R1_REG))
6115 (use (reg:PSI FPSCR_REG))
6116 ;; We want to make sure the `x' above will only match MACH_REG
6117 ;; because sibcall_epilogue may clobber MACL_REG.
6118 (clobber (reg:SI MACL_REG))]
6119 "TARGET_SHCOMPACT"
6120 "@
6121 jmp @%0%#
6122 jmp @%0\\n sts %2, r0"
6123 [(set_attr "needs_delay_slot" "yes,no")
6124 (set_attr "length" "2,4")
6125 (set (attr "fp_mode") (const_string "single"))
6126 (set_attr "type" "jump_ind")])
6127
6128 (define_insn "sibcall_media"
6129 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6130 (match_operand 1 "" ""))
6131 (return)]
6132 "TARGET_SHMEDIA"
6133 "blink %0, r63"
6134 [(set_attr "type" "jump_media")])
6135
6136 (define_expand "sibcall"
6137 [(parallel
6138 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6139 (match_operand 1 "" ""))
6140 (match_operand 2 "" "")
6141 (use (reg:PSI FPSCR_REG))
6142 (return)])]
6143 ""
6144 "
6145 {
6146 if (TARGET_SHMEDIA)
6147 {
6148 operands[0] = XEXP (operands[0], 0);
6149 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6150 {
6151 if (! SYMBOL_REF_FLAG (operands[0]))
6152 {
6153 rtx reg = gen_reg_rtx (Pmode);
6154
6155 /* We must not use GOTPLT for sibcalls, because PIC_REG
6156 must be restored before the PLT code gets to run. */
6157 emit_insn (gen_symGOT2reg (reg, operands[0]));
6158 operands[0] = reg;
6159 }
6160 else
6161 {
6162 operands[0] = gen_sym2PIC (operands[0]);
6163 PUT_MODE (operands[0], Pmode);
6164 }
6165 }
6166 if (GET_MODE (operands[0]) == SImode)
6167 {
6168 if (GET_CODE (operands[0]) == REG)
6169 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6170 else if (GET_CODE (operands[0]) == SUBREG)
6171 {
6172 operands[0] = SUBREG_REG (operands[0]);
6173 if (GET_MODE (operands[0]) != DImode)
6174 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6175 }
6176 else
6177 {
6178 operands[0] = shallow_copy_rtx (operands[0]);
6179 PUT_MODE (operands[0], DImode);
6180 }
6181 }
6182 if (! target_reg_operand (operands[0], DImode))
6183 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6184 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6185 DONE;
6186 }
6187 else if (TARGET_SHCOMPACT && operands[2]
6188 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6189 {
6190 rtx cookie_rtx = operands[2];
6191 long cookie = INTVAL (cookie_rtx);
6192 rtx func = XEXP (operands[0], 0);
6193 rtx mach, r1;
6194
6195 if (flag_pic)
6196 {
6197 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6198 {
6199 rtx reg = gen_reg_rtx (Pmode);
6200
6201 emit_insn (gen_symGOT2reg (reg, func));
6202 func = reg;
6203 }
6204 else
6205 func = legitimize_pic_address (func, Pmode, 0);
6206 }
6207
6208 /* FIXME: if we could tell whether all argument registers are
6209 already taken, we could decide whether to force the use of
6210 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6211 simple way to tell. We could use the CALL_COOKIE, but we
6212 can't currently tell a register used for regular argument
6213 passing from one that is unused. If we leave it up to reload
6214 to decide which register to use, it seems to always choose
6215 R0_REG, which leaves no available registers in SIBCALL_REGS
6216 to hold the address of the trampoline. */
6217 mach = gen_rtx_REG (SImode, MACH_REG);
6218 r1 = gen_rtx_REG (SImode, R1_REG);
6219
6220 /* Since such a call function may use all call-clobbered
6221 registers, we force a mode switch earlier, so that we don't
6222 run out of registers when adjusting fpscr for the call. */
6223 emit_insn (gen_force_mode_for_call ());
6224
6225 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6226 \"__GCC_shcompact_call_trampoline\");
6227 if (flag_pic)
6228 {
6229 rtx reg = gen_reg_rtx (Pmode);
6230
6231 emit_insn (gen_symGOT2reg (reg, operands[0]));
6232 operands[0] = reg;
6233 }
6234 operands[0] = force_reg (SImode, operands[0]);
6235
6236 /* We don't need a return trampoline, since the callee will
6237 return directly to the upper caller. */
6238 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6239 {
6240 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6241 cookie_rtx = GEN_INT (cookie);
6242 }
6243
6244 emit_move_insn (mach, func);
6245 emit_move_insn (r1, cookie_rtx);
6246
6247 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6248 DONE;
6249 }
6250 else if (TARGET_SHCOMPACT && flag_pic
6251 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6252 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6253 {
6254 rtx reg = gen_reg_rtx (Pmode);
6255
6256 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6257 XEXP (operands[0], 0) = reg;
6258 }
6259 if (flag_pic && TARGET_SH2
6260 && GET_CODE (operands[0]) == MEM
6261 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6262 /* The PLT needs the PIC register, but the epilogue would have
6263 to restore it, so we can only use PC-relative PIC calls for
6264 static functions. */
6265 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6266 {
6267 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6268 DONE;
6269 }
6270 else
6271 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6272
6273 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6274 DONE;
6275 }")
6276
6277 (define_expand "sibcall_value"
6278 [(set (match_operand 0 "" "")
6279 (call (match_operand 1 "" "")
6280 (match_operand 2 "" "")))
6281 (match_operand 3 "" "")]
6282 ""
6283 "
6284 {
6285 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6286 DONE;
6287 }")
6288
6289 (define_insn "call_value_pop_compact"
6290 [(set (match_operand 0 "" "=rf")
6291 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6292 (match_operand 2 "" "")))
6293 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6294 (match_operand 4 "immediate_operand" "n")))
6295 (match_operand 3 "immediate_operand" "n")
6296 (use (reg:SI R0_REG))
6297 (use (reg:SI R1_REG))
6298 (use (reg:PSI FPSCR_REG))
6299 (clobber (reg:SI PR_REG))]
6300 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6301 "jsr @%1%#"
6302 [(set_attr "type" "call")
6303 (set (attr "fp_mode")
6304 (if_then_else (eq_attr "fpu_single" "yes")
6305 (const_string "single") (const_string "double")))
6306 (set_attr "needs_delay_slot" "yes")])
6307
6308 (define_insn "call_value_pop_compact_rettramp"
6309 [(set (match_operand 0 "" "=rf")
6310 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6311 (match_operand 2 "" "")))
6312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6313 (match_operand 4 "immediate_operand" "n")))
6314 (match_operand 3 "immediate_operand" "n")
6315 (use (reg:SI R0_REG))
6316 (use (reg:SI R1_REG))
6317 (use (reg:PSI FPSCR_REG))
6318 (clobber (reg:SI R10_REG))
6319 (clobber (reg:SI PR_REG))]
6320 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6321 "jsr @%1%#"
6322 [(set_attr "type" "call")
6323 (set (attr "fp_mode")
6324 (if_then_else (eq_attr "fpu_single" "yes")
6325 (const_string "single") (const_string "double")))
6326 (set_attr "needs_delay_slot" "yes")])
6327
6328 (define_expand "call_value_pop"
6329 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6330 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6331 (match_operand 2 "" "")))
6332 (match_operand 3 "" "")
6333 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6334 (match_operand 4 "" "")))])]
6335 "TARGET_SHCOMPACT"
6336 "
6337 {
6338 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6339 {
6340 rtx cookie_rtx = operands[3];
6341 long cookie = INTVAL (cookie_rtx);
6342 rtx func = XEXP (operands[1], 0);
6343 rtx r0, r1;
6344
6345 if (flag_pic)
6346 {
6347 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6348 {
6349 rtx reg = gen_reg_rtx (Pmode);
6350
6351 emit_insn (gen_symGOTPLT2reg (reg, func));
6352 func = reg;
6353 }
6354 else
6355 func = legitimize_pic_address (func, Pmode, 0);
6356 }
6357
6358 r0 = gen_rtx_REG (SImode, R0_REG);
6359 r1 = gen_rtx_REG (SImode, R1_REG);
6360
6361 /* Since such a call function may use all call-clobbered
6362 registers, we force a mode switch earlier, so that we don't
6363 run out of registers when adjusting fpscr for the call. */
6364 emit_insn (gen_force_mode_for_call ());
6365
6366 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6367 \"__GCC_shcompact_call_trampoline\");
6368 if (flag_pic)
6369 {
6370 rtx reg = gen_reg_rtx (Pmode);
6371
6372 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6373 operands[1] = reg;
6374 }
6375 operands[1] = force_reg (SImode, operands[1]);
6376
6377 emit_move_insn (r0, func);
6378 emit_move_insn (r1, cookie_rtx);
6379
6380 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6381 emit_call_insn (gen_call_value_pop_compact_rettramp
6382 (operands[0], operands[1], operands[2],
6383 operands[3], operands[4]));
6384 else
6385 emit_call_insn (gen_call_value_pop_compact
6386 (operands[0], operands[1], operands[2],
6387 operands[3], operands[4]));
6388
6389 DONE;
6390 }
6391
6392 abort ();
6393 }")
6394
6395 (define_expand "sibcall_epilogue"
6396 [(return)]
6397 ""
6398 "
6399 {
6400 sh_expand_epilogue ();
6401 if (TARGET_SHCOMPACT)
6402 {
6403 rtx insn, set;
6404
6405 /* If epilogue clobbers r0, preserve it in macl. */
6406 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6407 if ((set = single_set (insn))
6408 && GET_CODE (SET_DEST (set)) == REG
6409 && REGNO (SET_DEST (set)) == R0_REG)
6410 {
6411 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6412 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6413 rtx i;
6414
6415 /* We can't tell at this point whether the sibcall is a
6416 sibcall_compact and, if it is, whether it uses r0 or
6417 mach as operand 2, so let the instructions that
6418 preserve r0 be optimized away if r0 turns out to be
6419 dead. */
6420 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6421 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6422 REG_NOTES (i));
6423 i = emit_move_insn (r0, tmp);
6424 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6425 REG_NOTES (i));
6426 break;
6427 }
6428 }
6429 DONE;
6430 }")
6431
6432 (define_insn "indirect_jump_compact"
6433 [(set (pc)
6434 (match_operand:SI 0 "arith_reg_operand" "r"))]
6435 "TARGET_SH1"
6436 "jmp @%0%#"
6437 [(set_attr "needs_delay_slot" "yes")
6438 (set_attr "type" "jump_ind")])
6439
6440 (define_expand "indirect_jump"
6441 [(set (pc)
6442 (match_operand 0 "register_operand" ""))]
6443 ""
6444 "
6445 {
6446 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6448 }")
6449
6450 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6451 ;; which can be present in structured code from indirect jumps which can not
6452 ;; be present in structured code. This allows -fprofile-arcs to work.
6453
6454 ;; For SH1 processors.
6455 (define_insn "casesi_jump_1"
6456 [(set (pc)
6457 (match_operand:SI 0 "register_operand" "r"))
6458 (use (label_ref (match_operand 1 "" "")))]
6459 "TARGET_SH1"
6460 "jmp @%0%#"
6461 [(set_attr "needs_delay_slot" "yes")
6462 (set_attr "type" "jump_ind")])
6463
6464 ;; For all later processors.
6465 (define_insn "casesi_jump_2"
6466 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6467 (label_ref (match_operand 1 "" ""))))
6468 (use (label_ref (match_operand 2 "" "")))]
6469 "TARGET_SH2
6470 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6471 "braf %0%#"
6472 [(set_attr "needs_delay_slot" "yes")
6473 (set_attr "type" "jump_ind")])
6474
6475 (define_insn "casesi_jump_media"
6476 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6477 (use (label_ref (match_operand 1 "" "")))]
6478 "TARGET_SHMEDIA"
6479 "blink %0, r63"
6480 [(set_attr "type" "jump_media")])
6481
6482 ;; Call subroutine returning any type.
6483 ;; ??? This probably doesn't work.
6484
6485 (define_expand "untyped_call"
6486 [(parallel [(call (match_operand 0 "" "")
6487 (const_int 0))
6488 (match_operand 1 "" "")
6489 (match_operand 2 "" "")])]
6490 "TARGET_SH3E || TARGET_SHMEDIA"
6491 "
6492 {
6493 int i;
6494
6495 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6496
6497 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6498 {
6499 rtx set = XVECEXP (operands[2], 0, i);
6500 emit_move_insn (SET_DEST (set), SET_SRC (set));
6501 }
6502
6503 /* The optimizer does not know that the call sets the function value
6504 registers we stored in the result block. We avoid problems by
6505 claiming that all hard registers are used and clobbered at this
6506 point. */
6507 emit_insn (gen_blockage ());
6508
6509 DONE;
6510 }")
6511 \f
6512 ;; ------------------------------------------------------------------------
6513 ;; Misc insns
6514 ;; ------------------------------------------------------------------------
6515
6516 (define_insn "dect"
6517 [(set (reg:SI T_REG)
6518 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6519 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6520 "TARGET_SH2"
6521 "dt %0"
6522 [(set_attr "type" "arith")])
6523
6524 (define_insn "nop"
6525 [(const_int 0)]
6526 ""
6527 "nop")
6528
6529 ;; Load address of a label. This is only generated by the casesi expand,
6530 ;; and by machine_dependent_reorg (fixing up fp moves).
6531 ;; This must use unspec, because this only works for labels that are
6532 ;; within range,
6533
6534 (define_insn "mova"
6535 [(set (reg:SI R0_REG)
6536 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6537 "TARGET_SH1"
6538 "mova %O0,r0"
6539 [(set_attr "in_delay_slot" "no")
6540 (set_attr "type" "arith")])
6541
6542 ;; machine_dependent_reorg() will make this a `mova'.
6543 (define_insn "mova_const"
6544 [(set (reg:SI R0_REG)
6545 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6546 "TARGET_SH1"
6547 "#"
6548 [(set_attr "in_delay_slot" "no")
6549 (set_attr "type" "arith")])
6550
6551 (define_expand "GOTaddr2picreg"
6552 [(set (reg:SI R0_REG)
6553 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6554 UNSPEC_MOVA))
6555 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6556 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6557 "" "
6558 {
6559 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6560 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6561
6562 if (TARGET_SH5)
6563 operands[1] = gen_datalabel_ref (operands[1]);
6564
6565 if (TARGET_SHMEDIA)
6566 {
6567 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6568 rtx dipic = operands[0];
6569 rtx lab = PATTERN (gen_call_site ());
6570 rtx insn, equiv;
6571
6572 equiv = operands[1];
6573 operands[1] = gen_rtx_MINUS (DImode,
6574 operands[1],
6575 gen_rtx_CONST
6576 (DImode,
6577 gen_rtx_MINUS (DImode,
6578 gen_rtx_CONST (DImode,
6579 lab),
6580 pc_rtx)));
6581 operands[1] = gen_sym2PIC (operands[1]);
6582 PUT_MODE (operands[1], DImode);
6583
6584 if (GET_MODE (dipic) != DImode)
6585 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6586
6587 if (TARGET_SHMEDIA64)
6588 emit_insn (gen_movdi_const (dipic, operands[1]));
6589 else
6590 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6591
6592 emit_insn (gen_ptrel (tr, dipic, lab));
6593
6594 if (GET_MODE (operands[0]) != GET_MODE (tr))
6595 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6596
6597 insn = emit_move_insn (operands[0], tr);
6598
6599 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6600 REG_NOTES (insn));
6601
6602 DONE;
6603 }
6604 }
6605 ")
6606
6607 ;; When generating PIC, we must match label_refs especially, because
6608 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6609 ;; them to do, because they can't be loaded directly into
6610 ;; non-branch-target registers.
6611 (define_insn "*pt"
6612 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6613 (match_operand:DI 1 "" "T"))]
6614 "TARGET_SHMEDIA && flag_pic
6615 && EXTRA_CONSTRAINT_T (operands[1])"
6616 "pt %1, %0"
6617 [(set_attr "type" "pt_media")
6618 (set_attr "length" "*")])
6619
6620 (define_insn "*ptb"
6621 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6622 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6623 UNSPEC_DATALABEL)))]
6624 "TARGET_SHMEDIA && flag_pic
6625 && EXTRA_CONSTRAINT_T (operands[1])"
6626 "ptb/u datalabel %1, %0"
6627 [(set_attr "type" "pt_media")
6628 (set_attr "length" "*")])
6629
6630 (define_insn "ptrel"
6631 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6632 (plus:DI (match_operand:DI 1 "register_operand" "r")
6633 (pc)))
6634 (match_operand:DI 2 "" "")]
6635 "TARGET_SHMEDIA"
6636 "%O2: ptrel/u %1, %0"
6637 [(set_attr "type" "ptabs_media")])
6638
6639 (define_expand "builtin_setjmp_receiver"
6640 [(match_operand 0 "" "")]
6641 "flag_pic"
6642 "
6643 {
6644 emit_insn (gen_GOTaddr2picreg ());
6645 DONE;
6646 }")
6647
6648 (define_expand "call_site"
6649 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6650 "TARGET_SH1"
6651 "
6652 {
6653 static HOST_WIDE_INT i = 0;
6654 operands[0] = GEN_INT (i);
6655 i++;
6656 }")
6657
6658 (define_expand "sym_label2reg"
6659 [(set (match_operand:SI 0 "" "")
6660 (const:SI (minus:SI
6661 (const:SI
6662 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6663 (const:SI
6664 (plus:SI
6665 (match_operand:SI 2 "" "")
6666 (const_int 2))))))]
6667 "TARGET_SH1" "")
6668
6669 (define_expand "symGOT_load"
6670 [(set (match_dup 2) (match_operand 1 "" ""))
6671 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6672 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6673 ""
6674 "
6675 {
6676 rtx insn;
6677
6678 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6679 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6680
6681 if (TARGET_SHMEDIA)
6682 {
6683 rtx reg = operands[2];
6684
6685 if (GET_MODE (reg) != DImode)
6686 reg = gen_rtx_SUBREG (DImode, reg, 0);
6687
6688 if (flag_pic > 1)
6689 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6690 else
6691 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6692 }
6693 else
6694 emit_move_insn (operands[2], operands[1]);
6695
6696 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6697 operands[2],
6698 gen_rtx_REG (Pmode, PIC_REG)));
6699
6700 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6701
6702 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6703 0), 0, 0),
6704 REG_NOTES (insn));
6705
6706 DONE;
6707 }")
6708
6709 (define_expand "sym2GOT"
6710 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6711 ""
6712 "")
6713
6714 (define_expand "symGOT2reg"
6715 [(match_operand 0 "" "") (match_operand 1 "" "")]
6716 ""
6717 "
6718 {
6719 rtx gotsym, insn;
6720
6721 gotsym = gen_sym2GOT (operands[1]);
6722 PUT_MODE (gotsym, Pmode);
6723 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6724
6725 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6726
6727 DONE;
6728 }")
6729
6730 (define_expand "sym2GOTPLT"
6731 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6732 ""
6733 "")
6734
6735 (define_expand "symGOTPLT2reg"
6736 [(match_operand 0 "" "") (match_operand 1 "" "")]
6737 ""
6738 "
6739 {
6740 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6741 DONE;
6742 }")
6743
6744 (define_expand "sym2GOTOFF"
6745 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6746 ""
6747 "")
6748
6749 (define_expand "symGOTOFF2reg"
6750 [(match_operand 0 "" "") (match_operand 1 "" "")]
6751 ""
6752 "
6753 {
6754 rtx gotoffsym, insn;
6755 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6756
6757 gotoffsym = gen_sym2GOTOFF (operands[1]);
6758 PUT_MODE (gotoffsym, Pmode);
6759 emit_move_insn (t, gotoffsym);
6760 insn = emit_move_insn (operands[0],
6761 gen_rtx_PLUS (Pmode, t,
6762 gen_rtx_REG (Pmode, PIC_REG)));
6763
6764 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6765 REG_NOTES (insn));
6766
6767 DONE;
6768 }")
6769
6770 (define_expand "symPLT_label2reg"
6771 [(set (match_operand:SI 0 "" "")
6772 (const:SI (minus:SI
6773 (const:SI
6774 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6775 (const:SI
6776 (minus:SI
6777 (const:SI (plus:SI
6778 (match_operand:SI 2 "" "")
6779 (const_int 2)))
6780 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6781 ;; Even though the PIC register is not really used by the call
6782 ;; sequence in which this is expanded, the PLT code assumes the PIC
6783 ;; register is set, so we must not skip its initialization. Since
6784 ;; we only use this expand as part of calling sequences, and never
6785 ;; to take the address of a function, this is the best point to
6786 ;; insert the (use). Using the PLT to take the address of a
6787 ;; function would be wrong, not only because the PLT entry could
6788 ;; then be called from a function that doesn't initialize the PIC
6789 ;; register to the proper GOT, but also because pointers to the
6790 ;; same function might not compare equal, should they be set by
6791 ;; different shared libraries.
6792 (use (reg:SI PIC_REG))]
6793 "TARGET_SH1"
6794 "")
6795
6796 (define_expand "sym2PIC"
6797 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6798 ""
6799 "")
6800
6801 ;; case instruction for switch statements.
6802
6803 ;; Operand 0 is index
6804 ;; operand 1 is the minimum bound
6805 ;; operand 2 is the maximum bound - minimum bound + 1
6806 ;; operand 3 is CODE_LABEL for the table;
6807 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6808
6809 (define_expand "casesi"
6810 [(match_operand:SI 0 "arith_reg_operand" "")
6811 (match_operand:SI 1 "arith_reg_operand" "")
6812 (match_operand:SI 2 "arith_reg_operand" "")
6813 (match_operand 3 "" "") (match_operand 4 "" "")]
6814 ""
6815 "
6816 {
6817 rtx reg = gen_reg_rtx (SImode);
6818 rtx reg2 = gen_reg_rtx (SImode);
6819 if (TARGET_SHMEDIA)
6820 {
6821 rtx reg = gen_reg_rtx (DImode);
6822 rtx reg2 = gen_reg_rtx (DImode);
6823 rtx reg3 = gen_reg_rtx (DImode);
6824 rtx reg4 = gen_reg_rtx (DImode);
6825 rtx reg5 = gen_reg_rtx (DImode);
6826
6827 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6828 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6829 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6830
6831 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6832 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6833 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6834 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6835 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6836 (DImode, operands[3])));
6837 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6838 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6839 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6840 emit_barrier ();
6841 DONE;
6842 }
6843 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6844 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6845 /* If optimizing, casesi_worker depends on the mode of the instruction
6846 before label it 'uses' - operands[3]. */
6847 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6848 reg));
6849 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6850 if (TARGET_SH2)
6851 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6852 else
6853 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6854 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6855 operands[3], but to lab. We will fix this up in
6856 machine_dependent_reorg. */
6857 emit_barrier ();
6858 DONE;
6859 }")
6860
6861 (define_expand "casesi_0"
6862 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6863 (set (match_dup 4) (minus:SI (match_dup 4)
6864 (match_operand:SI 1 "arith_operand" "")))
6865 (set (reg:SI T_REG)
6866 (gtu:SI (match_dup 4)
6867 (match_operand:SI 2 "arith_reg_operand" "")))
6868 (set (pc)
6869 (if_then_else (ne (reg:SI T_REG)
6870 (const_int 0))
6871 (label_ref (match_operand 3 "" ""))
6872 (pc)))]
6873 "TARGET_SH1"
6874 "")
6875
6876 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6877 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6878 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6879
6880 (define_insn "casesi_worker_0"
6881 [(set (match_operand:SI 0 "register_operand" "=r,r")
6882 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6883 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6884 (clobber (match_scratch:SI 3 "=X,1"))
6885 (clobber (match_scratch:SI 4 "=&z,z"))]
6886 "TARGET_SH1"
6887 "#")
6888
6889 (define_split
6890 [(set (match_operand:SI 0 "register_operand" "")
6891 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6892 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6893 (clobber (match_scratch:SI 3 ""))
6894 (clobber (match_scratch:SI 4 ""))]
6895 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6896 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6897 (parallel [(set (match_dup 0)
6898 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6899 (label_ref (match_dup 2))] UNSPEC_CASESI))
6900 (clobber (match_dup 3))])
6901 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6902 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6903
6904 (define_split
6905 [(set (match_operand:SI 0 "register_operand" "")
6906 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6907 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6908 (clobber (match_scratch:SI 3 ""))
6909 (clobber (match_scratch:SI 4 ""))]
6910 "TARGET_SH2 && reload_completed"
6911 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6912 (parallel [(set (match_dup 0)
6913 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6914 (label_ref (match_dup 2))] UNSPEC_CASESI))
6915 (clobber (match_dup 3))])]
6916 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6917
6918 (define_insn "*casesi_worker"
6919 [(set (match_operand:SI 0 "register_operand" "=r,r")
6920 (unspec:SI [(reg:SI R0_REG)
6921 (match_operand:SI 1 "register_operand" "0,r")
6922 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6923 (clobber (match_scratch:SI 3 "=X,1"))]
6924 "TARGET_SH1"
6925 "*
6926 {
6927 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6928
6929 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6930 abort ();
6931
6932 switch (GET_MODE (diff_vec))
6933 {
6934 case SImode:
6935 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6936 case HImode:
6937 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6938 case QImode:
6939 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6940 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6941 return \"mov.b @(r0,%1),%0\";
6942 default:
6943 abort ();
6944 }
6945 }"
6946 [(set_attr "length" "4")])
6947
6948 (define_insn "casesi_shift_media"
6949 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6950 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6951 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6952 UNSPEC_CASESI)))]
6953 "TARGET_SHMEDIA"
6954 "*
6955 {
6956 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6957
6958 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6959 abort ();
6960
6961 switch (GET_MODE (diff_vec))
6962 {
6963 case SImode:
6964 return \"shlli %1, 2, %0\";
6965 case HImode:
6966 return \"shlli %1, 1, %0\";
6967 case QImode:
6968 if (rtx_equal_p (operands[0], operands[1]))
6969 return \"\";
6970 return \"add %1, r63, %0\";
6971 default:
6972 abort ();
6973 }
6974 }"
6975 [(set_attr "type" "arith_media")])
6976
6977 (define_insn "casesi_load_media"
6978 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6979 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6980 (match_operand 2 "arith_reg_operand" "r")
6981 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6982 "TARGET_SHMEDIA"
6983 "*
6984 {
6985 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6986
6987 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6988 abort ();
6989
6990 switch (GET_MODE (diff_vec))
6991 {
6992 case SImode:
6993 return \"ldx.l %1, %2, %0\";
6994 case HImode:
6995 #if 0
6996 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6997 return \"ldx.uw %1, %2, %0\";
6998 #endif
6999 return \"ldx.w %1, %2, %0\";
7000 case QImode:
7001 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7002 return \"ldx.ub %1, %2, %0\";
7003 return \"ldx.b %1, %2, %0\";
7004 default:
7005 abort ();
7006 }
7007 }"
7008 [(set_attr "type" "load_media")])
7009
7010 (define_expand "return"
7011 [(return)]
7012 "reload_completed && ! sh_need_epilogue ()"
7013 "
7014 {
7015 if (TARGET_SHMEDIA)
7016 {
7017 emit_jump_insn (gen_return_media ());
7018 DONE;
7019 }
7020
7021 if (TARGET_SHCOMPACT
7022 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7023 {
7024 emit_jump_insn (gen_shcompact_return_tramp ());
7025 DONE;
7026 }
7027 }")
7028
7029 (define_insn "*return_i"
7030 [(return)]
7031 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7032 && (current_function_args_info.call_cookie
7033 & CALL_COOKIE_RET_TRAMP (1)))
7034 && reload_completed"
7035 "%@ %#"
7036 [(set_attr "type" "return")
7037 (set_attr "needs_delay_slot" "yes")])
7038
7039 (define_expand "shcompact_return_tramp"
7040 [(return)]
7041 "TARGET_SHCOMPACT
7042 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7043 "
7044 {
7045 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7046 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7047 \"__GCC_shcompact_return_trampoline\");
7048
7049 if (flag_pic)
7050 emit_insn (gen_symGOTPLT2reg (reg, sym));
7051 else
7052 emit_move_insn (reg, sym);
7053
7054 emit_jump_insn (gen_shcompact_return_tramp_i ());
7055 DONE;
7056 }")
7057
7058 (define_insn "shcompact_return_tramp_i"
7059 [(parallel [(return) (use (reg:SI R0_REG))])]
7060 "TARGET_SHCOMPACT
7061 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7062 "jmp @r0%#"
7063 [(set_attr "type" "jump_ind")
7064 (set_attr "needs_delay_slot" "yes")])
7065
7066 (define_insn "return_media_i"
7067 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7068 "TARGET_SHMEDIA && reload_completed"
7069 "blink %0, r63"
7070 [(set_attr "type" "jump_media")])
7071
7072 (define_expand "return_media"
7073 [(return)]
7074 "TARGET_SHMEDIA && reload_completed"
7075 "
7076 {
7077 int tr_regno = sh_media_register_for_return ();
7078 rtx tr;
7079
7080 if (tr_regno < 0)
7081 {
7082 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7083
7084 tr_regno = TR0_REG;
7085 tr = gen_rtx_REG (DImode, tr_regno);
7086 emit_move_insn (tr, r18);
7087 }
7088 else
7089 tr = gen_rtx_REG (DImode, tr_regno);
7090
7091 emit_jump_insn (gen_return_media_i (tr));
7092 DONE;
7093 }")
7094
7095 (define_insn "shcompact_preserve_incoming_args"
7096 [(set (match_operand:SI 0 "register_operand" "+r")
7097 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7098 "TARGET_SHCOMPACT"
7099 ""
7100 [(set_attr "length" "0")])
7101
7102 (define_insn "shcompact_incoming_args"
7103 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7104 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7105 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7106 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7107 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7108 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7109 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7110 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7111 (set (mem:BLK (reg:SI MACL_REG))
7112 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7113 (use (reg:SI R0_REG))
7114 (clobber (reg:SI R0_REG))
7115 (clobber (reg:SI MACL_REG))
7116 (clobber (reg:SI MACH_REG))
7117 (clobber (reg:SI PR_REG))]
7118 "TARGET_SHCOMPACT"
7119 "jsr @r0%#"
7120 [(set_attr "needs_delay_slot" "yes")])
7121
7122 (define_insn "shmedia_save_restore_regs_compact"
7123 [(set (reg:SI SP_REG)
7124 (plus:SI (reg:SI SP_REG)
7125 (match_operand:SI 0 "immediate_operand" "i")))
7126 (use (reg:SI R0_REG))
7127 (clobber (reg:SI PR_REG))]
7128 "TARGET_SHCOMPACT
7129 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7130 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7131 "jsr @r0%#"
7132 [(set_attr "needs_delay_slot" "yes")])
7133
7134 (define_expand "prologue"
7135 [(const_int 0)]
7136 ""
7137 "sh_expand_prologue (); DONE;")
7138
7139 (define_expand "epilogue"
7140 [(return)]
7141 ""
7142 "
7143 {
7144 sh_expand_epilogue ();
7145 emit_jump_insn (gen_return ());
7146 DONE;
7147 }")
7148
7149 (define_expand "eh_return"
7150 [(use (match_operand 0 "register_operand" ""))
7151 (use (match_operand 1 "register_operand" ""))]
7152 ""
7153 {
7154 rtx tmp, sa = operands[0], ra = operands[1];
7155
7156 if (TARGET_SHMEDIA64)
7157 emit_insn (gen_eh_set_ra_di (ra));
7158 else
7159 emit_insn (gen_eh_set_ra_si (ra));
7160
7161 emit_move_insn (EH_RETURN_STACKADJ_RTX, sa);
7162 DONE;
7163 })
7164
7165 ;; Clobber the return address on the stack. We can't expand this
7166 ;; until we know where it will be put in the stack frame.
7167
7168 (define_insn "eh_set_ra_si"
7169 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7170 (clobber (match_scratch:SI 1 "=&r"))]
7171 "! TARGET_SHMEDIA64"
7172 "#")
7173
7174 (define_insn "eh_set_ra_di"
7175 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7176 (clobber (match_scratch:DI 1 "=&r"))]
7177 "TARGET_SHMEDIA64"
7178 "#")
7179
7180 (define_split
7181 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7182 (clobber (match_scratch 1 ""))]
7183 "reload_completed"
7184 [(const_int 0)]
7185 "
7186 {
7187 sh_set_return_address (operands[0], operands[1]);
7188 DONE;
7189 }")
7190
7191 (define_insn "blockage"
7192 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7193 ""
7194 ""
7195 [(set_attr "length" "0")])
7196 \f
7197 ;; ------------------------------------------------------------------------
7198 ;; Scc instructions
7199 ;; ------------------------------------------------------------------------
7200
7201 (define_insn "movt"
7202 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7203 (eq:SI (reg:SI T_REG) (const_int 1)))]
7204 "TARGET_SH1"
7205 "movt %0"
7206 [(set_attr "type" "arith")])
7207
7208 (define_expand "seq"
7209 [(set (match_operand:SI 0 "arith_reg_operand" "")
7210 (match_dup 1))]
7211 ""
7212 "
7213 {
7214 if (TARGET_SHMEDIA)
7215 {
7216 if (GET_MODE (operands[0]) != DImode)
7217 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7218 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7219 if (sh_compare_op1 != const0_rtx)
7220 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7221 ? GET_MODE (sh_compare_op0)
7222 : GET_MODE (sh_compare_op1),
7223 sh_compare_op1);
7224
7225 switch (GET_MODE (sh_compare_op0))
7226 {
7227 case DImode:
7228 emit_insn (gen_cmpeqdi_media (operands[0],
7229 sh_compare_op0, sh_compare_op1));
7230 break;
7231
7232 case SFmode:
7233 if (! TARGET_SHMEDIA_FPU)
7234 FAIL;
7235 emit_insn (gen_cmpeqsf_media (operands[0],
7236 sh_compare_op0, sh_compare_op1));
7237 break;
7238
7239 case DFmode:
7240 if (! TARGET_SHMEDIA_FPU)
7241 FAIL;
7242 emit_insn (gen_cmpeqdf_media (operands[0],
7243 sh_compare_op0, sh_compare_op1));
7244 break;
7245
7246 default:
7247 FAIL;
7248 }
7249 DONE;
7250 }
7251 operands[1] = prepare_scc_operands (EQ);
7252 }")
7253
7254 (define_expand "slt"
7255 [(set (match_operand:SI 0 "arith_reg_operand" "")
7256 (match_dup 1))]
7257 ""
7258 "
7259 {
7260 if (TARGET_SHMEDIA)
7261 {
7262 if (GET_MODE (operands[0]) != DImode)
7263 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7264 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7265 if (sh_compare_op1 != const0_rtx)
7266 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7267 ? GET_MODE (sh_compare_op0)
7268 : GET_MODE (sh_compare_op1),
7269 sh_compare_op1);
7270
7271 switch (GET_MODE (sh_compare_op0))
7272 {
7273 case DImode:
7274 emit_insn (gen_cmpgtdi_media (operands[0],
7275 sh_compare_op1, sh_compare_op0));
7276 break;
7277
7278 case SFmode:
7279 if (! TARGET_SHMEDIA_FPU)
7280 FAIL;
7281 emit_insn (gen_cmpgtsf_media (operands[0],
7282 sh_compare_op1, sh_compare_op0));
7283 break;
7284
7285 case DFmode:
7286 if (! TARGET_SHMEDIA_FPU)
7287 FAIL;
7288 emit_insn (gen_cmpgtdf_media (operands[0],
7289 sh_compare_op1, sh_compare_op0));
7290 break;
7291
7292 default:
7293 FAIL;
7294 }
7295 DONE;
7296 }
7297 operands[1] = prepare_scc_operands (LT);
7298 }")
7299
7300 (define_expand "sle"
7301 [(match_operand:SI 0 "arith_reg_operand" "")]
7302 ""
7303 "
7304 {
7305 rtx tmp = sh_compare_op0;
7306
7307 if (TARGET_SHMEDIA)
7308 {
7309 if (GET_MODE (operands[0]) != DImode)
7310 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7311 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7312 if (sh_compare_op1 != const0_rtx)
7313 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7314 ? GET_MODE (sh_compare_op0)
7315 : GET_MODE (sh_compare_op1),
7316 sh_compare_op1);
7317
7318 switch (GET_MODE (sh_compare_op0))
7319 {
7320 case DImode:
7321 {
7322 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7323
7324 emit_insn (gen_cmpgtdi_media (tmp,
7325 sh_compare_op0, sh_compare_op1));
7326 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7327 break;
7328 }
7329
7330 case SFmode:
7331 if (! TARGET_SHMEDIA_FPU)
7332 FAIL;
7333 emit_insn (gen_cmpgesf_media (operands[0],
7334 sh_compare_op1, sh_compare_op0));
7335 break;
7336
7337 case DFmode:
7338 if (! TARGET_SHMEDIA_FPU)
7339 FAIL;
7340 emit_insn (gen_cmpgedf_media (operands[0],
7341 sh_compare_op1, sh_compare_op0));
7342 break;
7343
7344 default:
7345 FAIL;
7346 }
7347 DONE;
7348 }
7349
7350 sh_compare_op0 = sh_compare_op1;
7351 sh_compare_op1 = tmp;
7352 emit_insn (gen_sge (operands[0]));
7353 DONE;
7354 }")
7355
7356 (define_expand "sgt"
7357 [(set (match_operand:SI 0 "arith_reg_operand" "")
7358 (match_dup 1))]
7359 ""
7360 "
7361 {
7362 if (TARGET_SHMEDIA)
7363 {
7364 if (GET_MODE (operands[0]) != DImode)
7365 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7366 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7367 if (sh_compare_op1 != const0_rtx)
7368 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7369 ? GET_MODE (sh_compare_op0)
7370 : GET_MODE (sh_compare_op1),
7371 sh_compare_op1);
7372
7373 switch (GET_MODE (sh_compare_op0))
7374 {
7375 case DImode:
7376 emit_insn (gen_cmpgtdi_media (operands[0],
7377 sh_compare_op0, sh_compare_op1));
7378 break;
7379
7380 case SFmode:
7381 if (! TARGET_SHMEDIA_FPU)
7382 FAIL;
7383 emit_insn (gen_cmpgtsf_media (operands[0],
7384 sh_compare_op0, sh_compare_op1));
7385 break;
7386
7387 case DFmode:
7388 if (! TARGET_SHMEDIA_FPU)
7389 FAIL;
7390 emit_insn (gen_cmpgtdf_media (operands[0],
7391 sh_compare_op0, sh_compare_op1));
7392 break;
7393
7394 default:
7395 FAIL;
7396 }
7397 DONE;
7398 }
7399 operands[1] = prepare_scc_operands (GT);
7400 }")
7401
7402 (define_expand "sge"
7403 [(set (match_operand:SI 0 "arith_reg_operand" "")
7404 (match_dup 1))]
7405 ""
7406 "
7407 {
7408 if (TARGET_SHMEDIA)
7409 {
7410 if (GET_MODE (operands[0]) != DImode)
7411 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7412 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7413 if (sh_compare_op1 != const0_rtx)
7414 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7415 ? GET_MODE (sh_compare_op0)
7416 : GET_MODE (sh_compare_op1),
7417 sh_compare_op1);
7418
7419 switch (GET_MODE (sh_compare_op0))
7420 {
7421 case DImode:
7422 {
7423 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7424
7425 emit_insn (gen_cmpgtdi_media (tmp,
7426 sh_compare_op1, sh_compare_op0));
7427 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7428 break;
7429 }
7430
7431 case SFmode:
7432 if (! TARGET_SHMEDIA_FPU)
7433 FAIL;
7434 emit_insn (gen_cmpgesf_media (operands[0],
7435 sh_compare_op0, sh_compare_op1));
7436 break;
7437
7438 case DFmode:
7439 if (! TARGET_SHMEDIA_FPU)
7440 FAIL;
7441 emit_insn (gen_cmpgedf_media (operands[0],
7442 sh_compare_op0, sh_compare_op1));
7443 break;
7444
7445 default:
7446 FAIL;
7447 }
7448 DONE;
7449 }
7450
7451 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7452 {
7453 if (TARGET_IEEE)
7454 {
7455 rtx lab = gen_label_rtx ();
7456 prepare_scc_operands (EQ);
7457 emit_jump_insn (gen_branch_true (lab));
7458 prepare_scc_operands (GT);
7459 emit_label (lab);
7460 emit_insn (gen_movt (operands[0]));
7461 }
7462 else
7463 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7464 DONE;
7465 }
7466 operands[1] = prepare_scc_operands (GE);
7467 }")
7468
7469 (define_expand "sgtu"
7470 [(set (match_operand:SI 0 "arith_reg_operand" "")
7471 (match_dup 1))]
7472 ""
7473 "
7474 {
7475 if (TARGET_SHMEDIA)
7476 {
7477 if (GET_MODE (operands[0]) != DImode)
7478 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7479 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7480 if (sh_compare_op1 != const0_rtx)
7481 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7482 ? GET_MODE (sh_compare_op0)
7483 : GET_MODE (sh_compare_op1),
7484 sh_compare_op1);
7485
7486 emit_insn (gen_cmpgtudi_media (operands[0],
7487 sh_compare_op0, sh_compare_op1));
7488 DONE;
7489 }
7490 operands[1] = prepare_scc_operands (GTU);
7491 }")
7492
7493 (define_expand "sltu"
7494 [(set (match_operand:SI 0 "arith_reg_operand" "")
7495 (match_dup 1))]
7496 ""
7497 "
7498 {
7499 if (TARGET_SHMEDIA)
7500 {
7501 if (GET_MODE (operands[0]) != DImode)
7502 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7503 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7504 if (sh_compare_op1 != const0_rtx)
7505 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7506 ? GET_MODE (sh_compare_op0)
7507 : GET_MODE (sh_compare_op1),
7508 sh_compare_op1);
7509
7510 emit_insn (gen_cmpgtudi_media (operands[0],
7511 sh_compare_op1, sh_compare_op0));
7512 DONE;
7513 }
7514 operands[1] = prepare_scc_operands (LTU);
7515 }")
7516
7517 (define_expand "sleu"
7518 [(set (match_operand:SI 0 "arith_reg_operand" "")
7519 (match_dup 1))]
7520 ""
7521 "
7522 {
7523 if (TARGET_SHMEDIA)
7524 {
7525 rtx tmp;
7526
7527 if (GET_MODE (operands[0]) != DImode)
7528 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7529 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7530 if (sh_compare_op1 != const0_rtx)
7531 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7532 ? GET_MODE (sh_compare_op0)
7533 : GET_MODE (sh_compare_op1),
7534 sh_compare_op1);
7535
7536 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7537
7538 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7539 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7540
7541 DONE;
7542 }
7543 operands[1] = prepare_scc_operands (LEU);
7544 }")
7545
7546 (define_expand "sgeu"
7547 [(set (match_operand:SI 0 "arith_reg_operand" "")
7548 (match_dup 1))]
7549 ""
7550 "
7551 {
7552 if (TARGET_SHMEDIA)
7553 {
7554 rtx tmp;
7555
7556 if (GET_MODE (operands[0]) != DImode)
7557 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7558 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7559 if (sh_compare_op1 != const0_rtx)
7560 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7561 ? GET_MODE (sh_compare_op0)
7562 : GET_MODE (sh_compare_op1),
7563 sh_compare_op1);
7564
7565 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7566
7567 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7568 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7569
7570 DONE;
7571 }
7572
7573 operands[1] = prepare_scc_operands (GEU);
7574 }")
7575
7576 ;; sne moves the complement of the T reg to DEST like this:
7577 ;; cmp/eq ...
7578 ;; mov #-1,temp
7579 ;; negc temp,dest
7580 ;; This is better than xoring compare result with 1 because it does
7581 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7582 ;; loop.
7583
7584 (define_expand "sne"
7585 [(set (match_dup 2) (const_int -1))
7586 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7587 (neg:SI (plus:SI (match_dup 1)
7588 (match_dup 2))))
7589 (set (reg:SI T_REG)
7590 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7591 (const_int 0)))])]
7592 ""
7593 "
7594 {
7595 if (TARGET_SHMEDIA)
7596 {
7597 rtx tmp;
7598
7599 if (GET_MODE (operands[0]) != DImode)
7600 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7601
7602 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7603 FAIL;
7604
7605 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7606 if (sh_compare_op1 != const0_rtx)
7607 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7608 ? GET_MODE (sh_compare_op0)
7609 : GET_MODE (sh_compare_op1),
7610 sh_compare_op1);
7611
7612 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7613
7614 emit_insn (gen_seq (tmp));
7615 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7616
7617 DONE;
7618 }
7619
7620 operands[1] = prepare_scc_operands (EQ);
7621 operands[2] = gen_reg_rtx (SImode);
7622 }")
7623
7624 (define_expand "sunordered"
7625 [(set (match_operand:DI 0 "arith_reg_operand" "")
7626 (unordered:DI (match_dup 1) (match_dup 2)))]
7627 "TARGET_SHMEDIA_FPU"
7628 "
7629 {
7630 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7631 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7632 }")
7633
7634 ;; Use the same trick for FP sle / sge
7635 (define_expand "movnegt"
7636 [(set (match_dup 2) (const_int -1))
7637 (parallel [(set (match_operand 0 "" "")
7638 (neg:SI (plus:SI (match_dup 1)
7639 (match_dup 2))))
7640 (set (reg:SI T_REG)
7641 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7642 (const_int 0)))])]
7643 "TARGET_SH1"
7644 "operands[2] = gen_reg_rtx (SImode);")
7645
7646 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7647 ;; This prevents a regression that occurred when we switched from xor to
7648 ;; mov/neg for sne.
7649
7650 (define_split
7651 [(set (match_operand:SI 0 "arith_reg_operand" "")
7652 (plus:SI (reg:SI T_REG)
7653 (const_int -1)))]
7654 "TARGET_SH1"
7655 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7656 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7657 "")
7658
7659 ;; -------------------------------------------------------------------------
7660 ;; Instructions to cope with inline literal tables
7661 ;; -------------------------------------------------------------------------
7662
7663 ; 2 byte integer in line
7664
7665 (define_insn "consttable_2"
7666 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7667 (match_operand 1 "" "")]
7668 UNSPECV_CONST2)]
7669 ""
7670 "*
7671 {
7672 if (operands[1] != const0_rtx)
7673 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7674 return \"\";
7675 }"
7676 [(set_attr "length" "2")
7677 (set_attr "in_delay_slot" "no")])
7678
7679 ; 4 byte integer in line
7680
7681 (define_insn "consttable_4"
7682 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7683 (match_operand 1 "" "")]
7684 UNSPECV_CONST4)]
7685 ""
7686 "*
7687 {
7688 if (operands[1] != const0_rtx)
7689 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7690 return \"\";
7691 }"
7692 [(set_attr "length" "4")
7693 (set_attr "in_delay_slot" "no")])
7694
7695 ; 8 byte integer in line
7696
7697 (define_insn "consttable_8"
7698 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7699 (match_operand 1 "" "")]
7700 UNSPECV_CONST8)]
7701 ""
7702 "*
7703 {
7704 if (operands[1] != const0_rtx)
7705 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7706 return \"\";
7707 }"
7708 [(set_attr "length" "8")
7709 (set_attr "in_delay_slot" "no")])
7710
7711 ; 4 byte floating point
7712
7713 (define_insn "consttable_sf"
7714 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7715 (match_operand 1 "" "")]
7716 UNSPECV_CONST4)]
7717 ""
7718 "*
7719 {
7720 if (operands[1] != const0_rtx)
7721 {
7722 REAL_VALUE_TYPE d;
7723 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7724 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7725 }
7726 return \"\";
7727 }"
7728 [(set_attr "length" "4")
7729 (set_attr "in_delay_slot" "no")])
7730
7731 ; 8 byte floating point
7732
7733 (define_insn "consttable_df"
7734 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7735 (match_operand 1 "" "")]
7736 UNSPECV_CONST8)]
7737 ""
7738 "*
7739 {
7740 if (operands[1] != const0_rtx)
7741 {
7742 REAL_VALUE_TYPE d;
7743 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7744 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7745 }
7746 return \"\";
7747 }"
7748 [(set_attr "length" "8")
7749 (set_attr "in_delay_slot" "no")])
7750
7751 ;; Alignment is needed for some constant tables; it may also be added for
7752 ;; Instructions at the start of loops, or after unconditional branches.
7753 ;; ??? We would get more accurate lengths if we did instruction
7754 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7755 ;; here is too conservative.
7756
7757 ; align to a two byte boundary
7758
7759 (define_expand "align_2"
7760 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7761 ""
7762 "")
7763
7764 ; align to a four byte boundary
7765 ;; align_4 and align_log are instructions for the starts of loops, or
7766 ;; after unconditional branches, which may take up extra room.
7767
7768 (define_expand "align_4"
7769 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7770 ""
7771 "")
7772
7773 ; align to a cache line boundary
7774
7775 (define_insn "align_log"
7776 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7777 ""
7778 ""
7779 [(set_attr "length" "0")
7780 (set_attr "in_delay_slot" "no")])
7781
7782 ; emitted at the end of the literal table, used to emit the
7783 ; 32bit branch labels if needed.
7784
7785 (define_insn "consttable_end"
7786 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7787 ""
7788 "* return output_jump_label_table ();"
7789 [(set_attr "in_delay_slot" "no")])
7790
7791 ; emitted at the end of the window in the literal table.
7792
7793 (define_insn "consttable_window_end"
7794 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7795 ""
7796 ""
7797 [(set_attr "length" "0")
7798 (set_attr "in_delay_slot" "no")])
7799
7800 ;; -------------------------------------------------------------------------
7801 ;; Misc
7802 ;; -------------------------------------------------------------------------
7803
7804 ;; String/block move insn.
7805
7806 (define_expand "movstrsi"
7807 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7808 (mem:BLK (match_operand:BLK 1 "" "")))
7809 (use (match_operand:SI 2 "nonmemory_operand" ""))
7810 (use (match_operand:SI 3 "immediate_operand" ""))
7811 (clobber (reg:SI PR_REG))
7812 (clobber (reg:SI R4_REG))
7813 (clobber (reg:SI R5_REG))
7814 (clobber (reg:SI R0_REG))])]
7815 "TARGET_SH1 && ! TARGET_SH5"
7816 "
7817 {
7818 if(expand_block_move (operands))
7819 DONE;
7820 else FAIL;
7821 }")
7822
7823 (define_insn "block_move_real"
7824 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7825 (mem:BLK (reg:SI R5_REG)))
7826 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7827 (clobber (reg:SI PR_REG))
7828 (clobber (reg:SI R0_REG))])]
7829 "TARGET_SH1 && ! TARGET_HARD_SH4"
7830 "jsr @%0%#"
7831 [(set_attr "type" "sfunc")
7832 (set_attr "needs_delay_slot" "yes")])
7833
7834 (define_insn "block_lump_real"
7835 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7836 (mem:BLK (reg:SI R5_REG)))
7837 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7838 (use (reg:SI R6_REG))
7839 (clobber (reg:SI PR_REG))
7840 (clobber (reg:SI T_REG))
7841 (clobber (reg:SI R4_REG))
7842 (clobber (reg:SI R5_REG))
7843 (clobber (reg:SI R6_REG))
7844 (clobber (reg:SI R0_REG))])]
7845 "TARGET_SH1 && ! TARGET_HARD_SH4"
7846 "jsr @%0%#"
7847 [(set_attr "type" "sfunc")
7848 (set_attr "needs_delay_slot" "yes")])
7849
7850 (define_insn "block_move_real_i4"
7851 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7852 (mem:BLK (reg:SI R5_REG)))
7853 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7854 (clobber (reg:SI PR_REG))
7855 (clobber (reg:SI R0_REG))
7856 (clobber (reg:SI R1_REG))
7857 (clobber (reg:SI R2_REG))])]
7858 "TARGET_HARD_SH4"
7859 "jsr @%0%#"
7860 [(set_attr "type" "sfunc")
7861 (set_attr "needs_delay_slot" "yes")])
7862
7863 (define_insn "block_lump_real_i4"
7864 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7865 (mem:BLK (reg:SI R5_REG)))
7866 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7867 (use (reg:SI R6_REG))
7868 (clobber (reg:SI PR_REG))
7869 (clobber (reg:SI T_REG))
7870 (clobber (reg:SI R4_REG))
7871 (clobber (reg:SI R5_REG))
7872 (clobber (reg:SI R6_REG))
7873 (clobber (reg:SI R0_REG))
7874 (clobber (reg:SI R1_REG))
7875 (clobber (reg:SI R2_REG))
7876 (clobber (reg:SI R3_REG))])]
7877 "TARGET_HARD_SH4"
7878 "jsr @%0%#"
7879 [(set_attr "type" "sfunc")
7880 (set_attr "needs_delay_slot" "yes")])
7881 \f
7882 ;; -------------------------------------------------------------------------
7883 ;; Floating point instructions.
7884 ;; -------------------------------------------------------------------------
7885
7886 ;; ??? All patterns should have a type attribute.
7887
7888 (define_expand "fpu_switch0"
7889 [(set (match_operand:SI 0 "" "") (match_dup 2))
7890 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7891 "TARGET_SH4"
7892 "
7893 {
7894 operands[1] = get_fpscr_rtx ();
7895 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7896 if (flag_pic)
7897 operands[2] = legitimize_pic_address (operands[2], SImode,
7898 no_new_pseudos ? operands[0] : 0);
7899 }")
7900
7901 (define_expand "fpu_switch1"
7902 [(set (match_operand:SI 0 "" "") (match_dup 2))
7903 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7904 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7905 "TARGET_SH4"
7906 "
7907 {
7908 operands[1] = get_fpscr_rtx ();
7909 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7910 if (flag_pic)
7911 operands[2] = legitimize_pic_address (operands[2], SImode,
7912 no_new_pseudos ? operands[0] : 0);
7913 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7914 }")
7915
7916 (define_expand "movpsi"
7917 [(set (match_operand:PSI 0 "register_operand" "")
7918 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7919 "TARGET_SH4"
7920 "")
7921
7922 ;; The c / m alternative is a fake to guide reload to load directly into
7923 ;; fpscr, since reload doesn't know how to use post-increment.
7924 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7925 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7926 ;; predicate after reload.
7927 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7928 ;; like a mac -> gpr move.
7929 (define_insn "fpu_switch"
7930 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
7931 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
7932 "TARGET_SH3E
7933 && (! reload_completed
7934 || true_regnum (operands[0]) != FPSCR_REG
7935 || GET_CODE (operands[1]) != MEM
7936 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7937 "@
7938 ! precision stays the same
7939 lds.l %1,fpscr
7940 mov.l %1,%0
7941 #
7942 lds %1,fpscr
7943 mov %1,%0
7944 mov.l %1,%0
7945 sts fpscr,%0
7946 sts.l fpscr,%0"
7947 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
7948 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
7949
7950 (define_split
7951 [(set (reg:PSI FPSCR_REG)
7952 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7953 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7954 [(set (match_dup 0) (match_dup 0))]
7955 "
7956 {
7957 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7958 gen_rtx (MEM, PSImode,
7959 gen_rtx (POST_INC, Pmode,
7960 operands[0]))));
7961 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7962 }")
7963
7964 (define_split
7965 [(set (reg:PSI FPSCR_REG)
7966 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7967 "TARGET_SH4"
7968 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7969 "
7970 {
7971 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7972 gen_rtx (MEM, PSImode,
7973 gen_rtx (POST_INC, Pmode,
7974 operands[0]))));
7975 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7976 }")
7977
7978 ;; ??? This uses the fp unit, but has no type indicating that.
7979 ;; If we did that, this would either give a bogus latency or introduce
7980 ;; a bogus FIFO constraint.
7981 ;; Since this insn is currently only used for prologues/epilogues,
7982 ;; it is probably best to claim no function unit, which matches the
7983 ;; current setting.
7984 (define_insn "toggle_sz"
7985 [(set (reg:PSI FPSCR_REG)
7986 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7987 "TARGET_SH4"
7988 "fschg")
7989
7990 (define_expand "addsf3"
7991 [(set (match_operand:SF 0 "arith_reg_operand" "")
7992 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7993 (match_operand:SF 2 "arith_reg_operand" "")))]
7994 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7995 "
7996 {
7997 if (TARGET_SH3E)
7998 {
7999 expand_sf_binop (&gen_addsf3_i, operands);
8000 DONE;
8001 }
8002 }")
8003
8004 (define_insn "*addsf3_media"
8005 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8006 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8007 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8008 "TARGET_SHMEDIA_FPU"
8009 "fadd.s %1, %2, %0"
8010 [(set_attr "type" "fparith_media")])
8011
8012 (define_insn_and_split "unary_sf_op"
8013 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8014 (vec_select:V2SF
8015 (vec_concat:V2SF
8016 (vec_select:SF
8017 (match_dup 0)
8018 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8019 (match_operator:SF 2 "unary_float_operator"
8020 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8021 (parallel [(match_operand 4
8022 "const_int_operand" "n")]))]))
8023 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8024 "TARGET_SHMEDIA_FPU"
8025 "#"
8026 "TARGET_SHMEDIA_FPU && reload_completed"
8027 [(set (match_dup 5) (match_dup 6))]
8028 "
8029 {
8030 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8031 rtx op1 = gen_rtx_REG (SFmode,
8032 (true_regnum (operands[1])
8033 + (INTVAL (operands[4]) ^ endian)));
8034
8035 operands[7] = gen_rtx_REG (SFmode,
8036 (true_regnum (operands[0])
8037 + (INTVAL (operands[3]) ^ endian)));
8038 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8039 }"
8040 [(set_attr "type" "fparith_media")])
8041
8042 (define_insn_and_split "binary_sf_op"
8043 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8044 (vec_select:V2SF
8045 (vec_concat:V2SF
8046 (vec_select:SF
8047 (match_dup 0)
8048 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8049 (match_operator:SF 3 "binary_float_operator"
8050 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8051 (parallel [(match_operand 5
8052 "const_int_operand" "n")]))
8053 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8054 (parallel [(match_operand 6
8055 "const_int_operand" "n")]))]))
8056 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8057 "TARGET_SHMEDIA_FPU"
8058 "#"
8059 "TARGET_SHMEDIA_FPU && reload_completed"
8060 [(set (match_dup 7) (match_dup 8))]
8061 "
8062 {
8063 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8064 rtx op1 = gen_rtx_REG (SFmode,
8065 (true_regnum (operands[1])
8066 + (INTVAL (operands[5]) ^ endian)));
8067 rtx op2 = gen_rtx_REG (SFmode,
8068 (true_regnum (operands[2])
8069 + (INTVAL (operands[6]) ^ endian)));
8070
8071 operands[7] = gen_rtx_REG (SFmode,
8072 (true_regnum (operands[0])
8073 + (INTVAL (operands[4]) ^ endian)));
8074 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8075 }"
8076 [(set_attr "type" "fparith_media")])
8077
8078 (define_insn "addsf3_i"
8079 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8080 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8081 (match_operand:SF 2 "arith_reg_operand" "f")))
8082 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8083 "TARGET_SH3E"
8084 "fadd %2,%0"
8085 [(set_attr "type" "fp")
8086 (set_attr "fp_mode" "single")])
8087
8088 (define_expand "subsf3"
8089 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8090 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8091 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8092 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8093 "
8094 {
8095 if (TARGET_SH3E)
8096 {
8097 expand_sf_binop (&gen_subsf3_i, operands);
8098 DONE;
8099 }
8100 }")
8101
8102 (define_insn "*subsf3_media"
8103 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8104 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8105 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8106 "TARGET_SHMEDIA_FPU"
8107 "fsub.s %1, %2, %0"
8108 [(set_attr "type" "fparith_media")])
8109
8110 (define_insn "subsf3_i"
8111 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8112 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8113 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8114 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8115 "TARGET_SH3E"
8116 "fsub %2,%0"
8117 [(set_attr "type" "fp")
8118 (set_attr "fp_mode" "single")])
8119
8120 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8121 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8122 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8123 ;; SH3E, we use a separate insn for SH3E mulsf3.
8124
8125 (define_expand "mulsf3"
8126 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8127 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8128 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8129 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8130 "
8131 {
8132 if (TARGET_SH4)
8133 expand_sf_binop (&gen_mulsf3_i4, operands);
8134 else if (TARGET_SH3E)
8135 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8136 if (! TARGET_SHMEDIA)
8137 DONE;
8138 }")
8139
8140 (define_insn "*mulsf3_media"
8141 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8142 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8143 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8144 "TARGET_SHMEDIA_FPU"
8145 "fmul.s %1, %2, %0"
8146 [(set_attr "type" "fparith_media")])
8147
8148 (define_insn "mulsf3_i4"
8149 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8150 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8151 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8152 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8153 "TARGET_SH3E"
8154 "fmul %2,%0"
8155 [(set_attr "type" "fp")
8156 (set_attr "fp_mode" "single")])
8157
8158 (define_insn "mulsf3_ie"
8159 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8160 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8161 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8162 "TARGET_SH3E && ! TARGET_SH4"
8163 "fmul %2,%0"
8164 [(set_attr "type" "fp")])
8165
8166 (define_insn "*mac_media"
8167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8169 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8170 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8171 "TARGET_SHMEDIA_FPU"
8172 "fmac.s %1, %2, %0"
8173 [(set_attr "type" "fparith_media")])
8174
8175 (define_insn "*macsf3"
8176 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8177 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8178 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8179 (match_operand:SF 3 "arith_reg_operand" "0")))
8180 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8181 "TARGET_SH3E && ! TARGET_SH4"
8182 "fmac fr0,%2,%0"
8183 [(set_attr "type" "fp")
8184 (set_attr "fp_mode" "single")])
8185
8186 (define_expand "divsf3"
8187 [(set (match_operand:SF 0 "arith_reg_operand" "")
8188 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8189 (match_operand:SF 2 "arith_reg_operand" "")))]
8190 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8191 "
8192 {
8193 if (TARGET_SH3E)
8194 {
8195 expand_sf_binop (&gen_divsf3_i, operands);
8196 DONE;
8197 }
8198 }")
8199
8200 (define_insn "*divsf3_media"
8201 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8202 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8203 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8204 "TARGET_SHMEDIA_FPU"
8205 "fdiv.s %1, %2, %0"
8206 [(set_attr "type" "fdiv_media")])
8207
8208 (define_insn "divsf3_i"
8209 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8210 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8211 (match_operand:SF 2 "arith_reg_operand" "f")))
8212 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8213 "TARGET_SH3E"
8214 "fdiv %2,%0"
8215 [(set_attr "type" "fdiv")
8216 (set_attr "fp_mode" "single")])
8217
8218 (define_insn "floatdisf2"
8219 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8220 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8221 "TARGET_SHMEDIA_FPU"
8222 "float.qs %1, %0"
8223 [(set_attr "type" "fpconv_media")])
8224
8225 (define_expand "floatsisf2"
8226 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8227 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8228 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8229 "
8230 {
8231 if (TARGET_SH4)
8232 {
8233 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8234 DONE;
8235 }
8236 }")
8237
8238 (define_insn "*floatsisf2_media"
8239 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8240 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8241 "TARGET_SHMEDIA_FPU"
8242 "float.ls %1, %0"
8243 [(set_attr "type" "fpconv_media")])
8244
8245 (define_insn "floatsisf2_i4"
8246 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8247 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8248 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8249 "TARGET_SH4"
8250 "float %1,%0"
8251 [(set_attr "type" "fp")
8252 (set_attr "fp_mode" "single")])
8253
8254 (define_insn "*floatsisf2_ie"
8255 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8256 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8257 "TARGET_SH3E && ! TARGET_SH4"
8258 "float %1,%0"
8259 [(set_attr "type" "fp")])
8260
8261 (define_insn "fix_truncsfdi2"
8262 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8263 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8264 "TARGET_SHMEDIA_FPU"
8265 "ftrc.sq %1, %0"
8266 [(set_attr "type" "fpconv_media")])
8267
8268 (define_expand "fix_truncsfsi2"
8269 [(set (match_operand:SI 0 "fpul_operand" "=y")
8270 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8271 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8272 "
8273 {
8274 if (TARGET_SH4)
8275 {
8276 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8277 DONE;
8278 }
8279 }")
8280
8281 (define_insn "*fix_truncsfsi2_media"
8282 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8283 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8284 "TARGET_SHMEDIA_FPU"
8285 "ftrc.sl %1, %0"
8286 [(set_attr "type" "fpconv_media")])
8287
8288 (define_insn "fix_truncsfsi2_i4"
8289 [(set (match_operand:SI 0 "fpul_operand" "=y")
8290 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8291 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8292 "TARGET_SH4"
8293 "ftrc %1,%0"
8294 [(set_attr "type" "ftrc_s")
8295 (set_attr "fp_mode" "single")])
8296
8297 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8298 ;; fix_truncsfsi2_i4.
8299 ;; (define_insn "fix_truncsfsi2_i4_2"
8300 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8301 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8302 ;; (use (reg:PSI FPSCR_REG))
8303 ;; (clobber (reg:SI FPUL_REG))]
8304 ;; "TARGET_SH4"
8305 ;; "#"
8306 ;; [(set_attr "length" "4")
8307 ;; (set_attr "fp_mode" "single")])
8308
8309 ;;(define_split
8310 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8311 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8312 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8313 ;; (clobber (reg:SI FPUL_REG))]
8314 ;; "TARGET_SH4"
8315 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8316 ;; (use (match_dup 2))])
8317 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8318
8319 (define_insn "*fixsfsi"
8320 [(set (match_operand:SI 0 "fpul_operand" "=y")
8321 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8322 "TARGET_SH3E && ! TARGET_SH4"
8323 "ftrc %1,%0"
8324 [(set_attr "type" "fp")])
8325
8326 (define_insn "cmpgtsf_t"
8327 [(set (reg:SI T_REG)
8328 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8329 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8330 "TARGET_SH3E && ! TARGET_SH4"
8331 "fcmp/gt %1,%0"
8332 [(set_attr "type" "fp")
8333 (set_attr "fp_mode" "single")])
8334
8335 (define_insn "cmpeqsf_t"
8336 [(set (reg:SI T_REG)
8337 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8338 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8339 "TARGET_SH3E && ! TARGET_SH4"
8340 "fcmp/eq %1,%0"
8341 [(set_attr "type" "fp")
8342 (set_attr "fp_mode" "single")])
8343
8344 (define_insn "ieee_ccmpeqsf_t"
8345 [(set (reg:SI T_REG)
8346 (ior:SI (reg:SI T_REG)
8347 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8348 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8349 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8350 "* return output_ieee_ccmpeq (insn, operands);"
8351 [(set_attr "length" "4")])
8352
8353
8354 (define_insn "cmpgtsf_t_i4"
8355 [(set (reg:SI T_REG)
8356 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8357 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8358 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8359 "TARGET_SH4"
8360 "fcmp/gt %1,%0"
8361 [(set_attr "type" "fp")
8362 (set_attr "fp_mode" "single")])
8363
8364 (define_insn "cmpeqsf_t_i4"
8365 [(set (reg:SI T_REG)
8366 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8367 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8368 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8369 "TARGET_SH4"
8370 "fcmp/eq %1,%0"
8371 [(set_attr "type" "fp")
8372 (set_attr "fp_mode" "single")])
8373
8374 (define_insn "*ieee_ccmpeqsf_t_4"
8375 [(set (reg:SI T_REG)
8376 (ior:SI (reg:SI T_REG)
8377 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8378 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8379 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8380 "TARGET_IEEE && TARGET_SH4"
8381 "* return output_ieee_ccmpeq (insn, operands);"
8382 [(set_attr "length" "4")
8383 (set_attr "fp_mode" "single")])
8384
8385 (define_insn "cmpeqsf_media"
8386 [(set (match_operand:DI 0 "register_operand" "=r")
8387 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8388 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8389 "TARGET_SHMEDIA_FPU"
8390 "fcmpeq.s %1, %2, %0"
8391 [(set_attr "type" "fcmp_media")])
8392
8393 (define_insn "cmpgtsf_media"
8394 [(set (match_operand:DI 0 "register_operand" "=r")
8395 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8396 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8397 "TARGET_SHMEDIA_FPU"
8398 "fcmpgt.s %1, %2, %0"
8399 [(set_attr "type" "fcmp_media")])
8400
8401 (define_insn "cmpgesf_media"
8402 [(set (match_operand:DI 0 "register_operand" "=r")
8403 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8404 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
8406 "fcmpge.s %1, %2, %0"
8407 [(set_attr "type" "fcmp_media")])
8408
8409 (define_insn "cmpunsf_media"
8410 [(set (match_operand:DI 0 "register_operand" "=r")
8411 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8412 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8413 "TARGET_SHMEDIA_FPU"
8414 "fcmpun.s %1, %2, %0"
8415 [(set_attr "type" "fcmp_media")])
8416
8417 (define_expand "cmpsf"
8418 [(set (reg:SI T_REG)
8419 (compare (match_operand:SF 0 "arith_operand" "")
8420 (match_operand:SF 1 "arith_operand" "")))]
8421 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8422 "
8423 {
8424 sh_compare_op0 = operands[0];
8425 sh_compare_op1 = operands[1];
8426 DONE;
8427 }")
8428
8429 (define_expand "negsf2"
8430 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8431 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8432 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8433 "
8434 {
8435 if (TARGET_SH3E)
8436 {
8437 expand_sf_unop (&gen_negsf2_i, operands);
8438 DONE;
8439 }
8440 }")
8441
8442 (define_insn "*negsf2_media"
8443 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8444 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8445 "TARGET_SHMEDIA_FPU"
8446 "fneg.s %1, %0"
8447 [(set_attr "type" "fmove_media")])
8448
8449 (define_insn "negsf2_i"
8450 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8451 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8452 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8453 "TARGET_SH3E"
8454 "fneg %0"
8455 [(set_attr "type" "fmove")
8456 (set_attr "fp_mode" "single")])
8457
8458 (define_expand "sqrtsf2"
8459 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8460 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8461 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8462 "
8463 {
8464 if (TARGET_SH3E)
8465 {
8466 expand_sf_unop (&gen_sqrtsf2_i, operands);
8467 DONE;
8468 }
8469 }")
8470
8471 (define_insn "*sqrtsf2_media"
8472 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8473 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8474 "TARGET_SHMEDIA_FPU"
8475 "fsqrt.s %1, %0"
8476 [(set_attr "type" "fdiv_media")])
8477
8478 (define_insn "sqrtsf2_i"
8479 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8480 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8481 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8482 "TARGET_SH3E"
8483 "fsqrt %0"
8484 [(set_attr "type" "fdiv")
8485 (set_attr "fp_mode" "single")])
8486
8487 (define_expand "abssf2"
8488 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8489 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8490 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8491 "
8492 {
8493 if (TARGET_SH3E)
8494 {
8495 expand_sf_unop (&gen_abssf2_i, operands);
8496 DONE;
8497 }
8498 }")
8499
8500 (define_insn "*abssf2_media"
8501 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8502 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8503 "TARGET_SHMEDIA_FPU"
8504 "fabs.s %1, %0"
8505 [(set_attr "type" "fmove_media")])
8506
8507 (define_insn "abssf2_i"
8508 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8509 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8510 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8511 "TARGET_SH3E"
8512 "fabs %0"
8513 [(set_attr "type" "fmove")
8514 (set_attr "fp_mode" "single")])
8515
8516 (define_expand "adddf3"
8517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8518 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8519 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8520 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8521 "
8522 {
8523 if (TARGET_SH4)
8524 {
8525 expand_df_binop (&gen_adddf3_i, operands);
8526 DONE;
8527 }
8528 }")
8529
8530 (define_insn "*adddf3_media"
8531 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8532 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8533 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8534 "TARGET_SHMEDIA_FPU"
8535 "fadd.d %1, %2, %0"
8536 [(set_attr "type" "dfparith_media")])
8537
8538 (define_insn "adddf3_i"
8539 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8540 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8541 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8542 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8543 "TARGET_SH4"
8544 "fadd %2,%0"
8545 [(set_attr "type" "dfp_arith")
8546 (set_attr "fp_mode" "double")])
8547
8548 (define_expand "subdf3"
8549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8550 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8551 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8552 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8553 "
8554 {
8555 if (TARGET_SH4)
8556 {
8557 expand_df_binop (&gen_subdf3_i, operands);
8558 DONE;
8559 }
8560 }")
8561
8562 (define_insn "*subdf3_media"
8563 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8564 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8565 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8566 "TARGET_SHMEDIA_FPU"
8567 "fsub.d %1, %2, %0"
8568 [(set_attr "type" "dfparith_media")])
8569
8570 (define_insn "subdf3_i"
8571 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8572 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8573 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8574 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8575 "TARGET_SH4"
8576 "fsub %2,%0"
8577 [(set_attr "type" "dfp_arith")
8578 (set_attr "fp_mode" "double")])
8579
8580 (define_expand "muldf3"
8581 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8582 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8583 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8584 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8585 "
8586 {
8587 if (TARGET_SH4)
8588 {
8589 expand_df_binop (&gen_muldf3_i, operands);
8590 DONE;
8591 }
8592 }")
8593
8594 (define_insn "*muldf3_media"
8595 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8596 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8597 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8598 "TARGET_SHMEDIA_FPU"
8599 "fmul.d %1, %2, %0"
8600 [(set_attr "type" "dfmul_media")])
8601
8602 (define_insn "muldf3_i"
8603 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8604 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8605 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8606 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8607 "TARGET_SH4"
8608 "fmul %2,%0"
8609 [(set_attr "type" "dfp_arith")
8610 (set_attr "fp_mode" "double")])
8611
8612 (define_expand "divdf3"
8613 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8614 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8615 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8616 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8617 "
8618 {
8619 if (TARGET_SH4)
8620 {
8621 expand_df_binop (&gen_divdf3_i, operands);
8622 DONE;
8623 }
8624 }")
8625
8626 (define_insn "*divdf3_media"
8627 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8628 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8629 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8630 "TARGET_SHMEDIA_FPU"
8631 "fdiv.d %1, %2, %0"
8632 [(set_attr "type" "dfdiv_media")])
8633
8634 (define_insn "divdf3_i"
8635 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8636 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8637 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8638 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8639 "TARGET_SH4"
8640 "fdiv %2,%0"
8641 [(set_attr "type" "dfdiv")
8642 (set_attr "fp_mode" "double")])
8643
8644 (define_insn "floatdidf2"
8645 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8646 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8647 "TARGET_SHMEDIA_FPU"
8648 "float.qd %1, %0"
8649 [(set_attr "type" "dfpconv_media")])
8650
8651 (define_expand "floatsidf2"
8652 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8653 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8654 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8655 "
8656 {
8657 if (TARGET_SH4)
8658 {
8659 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8660 get_fpscr_rtx ()));
8661 DONE;
8662 }
8663 }")
8664
8665 (define_insn "*floatsidf2_media"
8666 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8667 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8668 "TARGET_SHMEDIA_FPU"
8669 "float.ld %1, %0"
8670 [(set_attr "type" "dfpconv_media")])
8671
8672 (define_insn "floatsidf2_i"
8673 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8674 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8675 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8676 "TARGET_SH4"
8677 "float %1,%0"
8678 [(set_attr "type" "dfp_conv")
8679 (set_attr "fp_mode" "double")])
8680
8681 (define_insn "fix_truncdfdi2"
8682 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8683 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8684 "TARGET_SHMEDIA_FPU"
8685 "ftrc.dq %1, %0"
8686 [(set_attr "type" "dfpconv_media")])
8687
8688 (define_expand "fix_truncdfsi2"
8689 [(set (match_operand:SI 0 "fpul_operand" "")
8690 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8691 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8692 "
8693 {
8694 if (TARGET_SH4)
8695 {
8696 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8697 get_fpscr_rtx ()));
8698 DONE;
8699 }
8700 }")
8701
8702 (define_insn "*fix_truncdfsi2_media"
8703 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8704 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8705 "TARGET_SHMEDIA_FPU"
8706 "ftrc.dl %1, %0"
8707 [(set_attr "type" "dfpconv_media")])
8708
8709 (define_insn "fix_truncdfsi2_i"
8710 [(set (match_operand:SI 0 "fpul_operand" "=y")
8711 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8713 "TARGET_SH4"
8714 "ftrc %1,%0"
8715 [(set_attr "type" "dfp_conv")
8716 (set_attr "dfp_comp" "no")
8717 (set_attr "fp_mode" "double")])
8718
8719 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8720 ;; fix_truncdfsi2_i.
8721 ;; (define_insn "fix_truncdfsi2_i4"
8722 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8723 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8724 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8725 ;; (clobber (reg:SI FPUL_REG))]
8726 ;; "TARGET_SH4"
8727 ;; "#"
8728 ;; [(set_attr "length" "4")
8729 ;; (set_attr "fp_mode" "double")])
8730 ;;
8731 ;; (define_split
8732 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8733 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8734 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8735 ;; (clobber (reg:SI FPUL_REG))]
8736 ;; "TARGET_SH4"
8737 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8738 ;; (use (match_dup 2))])
8739 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8740
8741 (define_insn "cmpgtdf_t"
8742 [(set (reg:SI T_REG)
8743 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8744 (match_operand:DF 1 "arith_reg_operand" "f")))
8745 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8746 "TARGET_SH4"
8747 "fcmp/gt %1,%0"
8748 [(set_attr "type" "dfp_cmp")
8749 (set_attr "fp_mode" "double")])
8750
8751 (define_insn "cmpeqdf_t"
8752 [(set (reg:SI T_REG)
8753 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8754 (match_operand:DF 1 "arith_reg_operand" "f")))
8755 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8756 "TARGET_SH4"
8757 "fcmp/eq %1,%0"
8758 [(set_attr "type" "dfp_cmp")
8759 (set_attr "fp_mode" "double")])
8760
8761 (define_insn "*ieee_ccmpeqdf_t"
8762 [(set (reg:SI T_REG)
8763 (ior:SI (reg:SI T_REG)
8764 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8765 (match_operand:DF 1 "arith_reg_operand" "f"))))
8766 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8767 "TARGET_IEEE && TARGET_SH4"
8768 "* return output_ieee_ccmpeq (insn, operands);"
8769 [(set_attr "length" "4")
8770 (set_attr "fp_mode" "double")])
8771
8772 (define_insn "cmpeqdf_media"
8773 [(set (match_operand:DI 0 "register_operand" "=r")
8774 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8775 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8776 "TARGET_SHMEDIA_FPU"
8777 "fcmpeq.d %1,%2,%0"
8778 [(set_attr "type" "fcmp_media")])
8779
8780 (define_insn "cmpgtdf_media"
8781 [(set (match_operand:DI 0 "register_operand" "=r")
8782 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8783 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8784 "TARGET_SHMEDIA_FPU"
8785 "fcmpgt.d %1,%2,%0"
8786 [(set_attr "type" "fcmp_media")])
8787
8788 (define_insn "cmpgedf_media"
8789 [(set (match_operand:DI 0 "register_operand" "=r")
8790 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8791 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8792 "TARGET_SHMEDIA_FPU"
8793 "fcmpge.d %1,%2,%0"
8794 [(set_attr "type" "fcmp_media")])
8795
8796 (define_insn "cmpundf_media"
8797 [(set (match_operand:DI 0 "register_operand" "=r")
8798 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8799 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8800 "TARGET_SHMEDIA_FPU"
8801 "fcmpun.d %1,%2,%0"
8802 [(set_attr "type" "fcmp_media")])
8803
8804 (define_expand "cmpdf"
8805 [(set (reg:SI T_REG)
8806 (compare (match_operand:DF 0 "arith_operand" "")
8807 (match_operand:DF 1 "arith_operand" "")))]
8808 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8809 "
8810 {
8811 sh_compare_op0 = operands[0];
8812 sh_compare_op1 = operands[1];
8813 DONE;
8814 }")
8815
8816 (define_expand "negdf2"
8817 [(set (match_operand:DF 0 "arith_reg_operand" "")
8818 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8819 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8820 "
8821 {
8822 if (TARGET_SH4)
8823 {
8824 expand_df_unop (&gen_negdf2_i, operands);
8825 DONE;
8826 }
8827 }")
8828
8829 (define_insn "*negdf2_media"
8830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8831 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8832 "TARGET_SHMEDIA_FPU"
8833 "fneg.d %1, %0"
8834 [(set_attr "type" "fmove_media")])
8835
8836 (define_insn "negdf2_i"
8837 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8838 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8839 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8840 "TARGET_SH4"
8841 "fneg %0"
8842 [(set_attr "type" "fmove")
8843 (set_attr "fp_mode" "double")])
8844
8845 (define_expand "sqrtdf2"
8846 [(set (match_operand:DF 0 "arith_reg_operand" "")
8847 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8848 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8849 "
8850 {
8851 if (TARGET_SH4)
8852 {
8853 expand_df_unop (&gen_sqrtdf2_i, operands);
8854 DONE;
8855 }
8856 }")
8857
8858 (define_insn "*sqrtdf2_media"
8859 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8860 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8861 "TARGET_SHMEDIA_FPU"
8862 "fsqrt.d %1, %0"
8863 [(set_attr "type" "dfdiv_media")])
8864
8865 (define_insn "sqrtdf2_i"
8866 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8867 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8868 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8869 "TARGET_SH4"
8870 "fsqrt %0"
8871 [(set_attr "type" "dfdiv")
8872 (set_attr "fp_mode" "double")])
8873
8874 (define_expand "absdf2"
8875 [(set (match_operand:DF 0 "arith_reg_operand" "")
8876 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8877 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8878 "
8879 {
8880 if (TARGET_SH4)
8881 {
8882 expand_df_unop (&gen_absdf2_i, operands);
8883 DONE;
8884 }
8885 }")
8886
8887 (define_insn "*absdf2_media"
8888 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8889 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8890 "TARGET_SHMEDIA_FPU"
8891 "fabs.d %1, %0"
8892 [(set_attr "type" "fmove_media")])
8893
8894 (define_insn "absdf2_i"
8895 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8896 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8897 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8898 "TARGET_SH4"
8899 "fabs %0"
8900 [(set_attr "type" "fmove")
8901 (set_attr "fp_mode" "double")])
8902
8903 (define_expand "extendsfdf2"
8904 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8905 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8906 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8907 "
8908 {
8909 if (TARGET_SH4)
8910 {
8911 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8912 get_fpscr_rtx ()));
8913 DONE;
8914 }
8915 }")
8916
8917 (define_insn "*extendsfdf2_media"
8918 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8919 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8920 "TARGET_SHMEDIA_FPU"
8921 "fcnv.sd %1, %0"
8922 [(set_attr "type" "dfpconv_media")])
8923
8924 (define_insn "extendsfdf2_i4"
8925 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8926 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8927 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8928 "TARGET_SH4"
8929 "fcnvsd %1,%0"
8930 [(set_attr "type" "fp")
8931 (set_attr "fp_mode" "double")])
8932
8933 (define_expand "truncdfsf2"
8934 [(set (match_operand:SF 0 "fpul_operand" "")
8935 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8936 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8937 "
8938 {
8939 if (TARGET_SH4)
8940 {
8941 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8942 get_fpscr_rtx ()));
8943 DONE;
8944 }
8945 }")
8946
8947 (define_insn "*truncdfsf2_media"
8948 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8949 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8950 "TARGET_SHMEDIA_FPU"
8951 "fcnv.ds %1, %0"
8952 [(set_attr "type" "dfpconv_media")])
8953
8954 (define_insn "truncdfsf2_i4"
8955 [(set (match_operand:SF 0 "fpul_operand" "=y")
8956 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8957 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8958 "TARGET_SH4"
8959 "fcnvds %1,%0"
8960 [(set_attr "type" "fp")
8961 (set_attr "fp_mode" "double")])
8962 \f
8963 ;; Bit field extract patterns. These give better code for packed bitfields,
8964 ;; because they allow auto-increment addresses to be generated.
8965
8966 (define_expand "insv"
8967 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8968 (match_operand:SI 1 "immediate_operand" "")
8969 (match_operand:SI 2 "immediate_operand" ""))
8970 (match_operand:SI 3 "general_operand" ""))]
8971 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8972 "
8973 {
8974 rtx addr_target, orig_address, shift_reg, qi_val;
8975 HOST_WIDE_INT bitsize, size, v;
8976 rtx x = operands[3];
8977
8978 /* ??? expmed doesn't care for non-register predicates. */
8979 if (! memory_operand (operands[0], VOIDmode)
8980 || ! immediate_operand (operands[1], VOIDmode)
8981 || ! immediate_operand (operands[2], VOIDmode)
8982 || ! general_operand (x, VOIDmode))
8983 FAIL;
8984 /* If this isn't a 16 / 24 / 32 bit field, or if
8985 it doesn't start on a byte boundary, then fail. */
8986 bitsize = INTVAL (operands[1]);
8987 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8988 || (INTVAL (operands[2]) % 8) != 0)
8989 FAIL;
8990
8991 size = bitsize / 8;
8992 orig_address = XEXP (operands[0], 0);
8993 shift_reg = gen_reg_rtx (SImode);
8994 if (GET_CODE (x) == CONST_INT)
8995 {
8996 v = INTVAL (x);
8997 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8998 }
8999 else
9000 {
9001 emit_insn (gen_movsi (shift_reg, operands[3]));
9002 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9003 }
9004 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9005
9006 operands[0] = replace_equiv_address (operands[0], addr_target);
9007 emit_insn (gen_movqi (operands[0], qi_val));
9008
9009 while (size -= 1)
9010 {
9011 if (GET_CODE (x) == CONST_INT)
9012 qi_val
9013 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9014 else
9015 {
9016 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9017 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9018 }
9019 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9020 emit_insn (gen_movqi (operands[0], qi_val));
9021 }
9022
9023 DONE;
9024 }")
9025 \f
9026 ;; -------------------------------------------------------------------------
9027 ;; Peepholes
9028 ;; -------------------------------------------------------------------------
9029
9030 ;; This matches cases where a stack pointer increment at the start of the
9031 ;; epilogue combines with a stack slot read loading the return value.
9032
9033 (define_peephole
9034 [(set (match_operand:SI 0 "arith_reg_operand" "")
9035 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9036 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9037 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9038 "mov.l @%1+,%0")
9039
9040 ;; See the comment on the dt combiner pattern above.
9041
9042 (define_peephole
9043 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9044 (plus:SI (match_dup 0)
9045 (const_int -1)))
9046 (set (reg:SI T_REG)
9047 (eq:SI (match_dup 0)
9048 (const_int 0)))]
9049 "TARGET_SH2"
9050 "dt %0")
9051
9052 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9053 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9054 ;; reload when the constant is too large for a reg+offset address.
9055
9056 ;; ??? We would get much better code if this was done in reload. This would
9057 ;; require modifying find_reloads_address to recognize that if the constant
9058 ;; is out-of-range for an immediate add, then we get better code by reloading
9059 ;; the constant into a register than by reloading the sum into a register,
9060 ;; since the former is one instruction shorter if the address does not need
9061 ;; to be offsettable. Unfortunately this does not work, because there is
9062 ;; only one register, r0, that can be used as an index register. This register
9063 ;; is also the function return value register. So, if we try to force reload
9064 ;; to use double-reg addresses, then we end up with some instructions that
9065 ;; need to use r0 twice. The only way to fix this is to change the calling
9066 ;; convention so that r0 is not used to return values.
9067
9068 (define_peephole
9069 [(set (match_operand:SI 0 "register_operand" "=r")
9070 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9071 (set (mem:SI (match_dup 0))
9072 (match_operand:SI 2 "general_movsrc_operand" ""))]
9073 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9074 "mov.l %2,@(%0,%1)")
9075
9076 (define_peephole
9077 [(set (match_operand:SI 0 "register_operand" "=r")
9078 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9079 (set (match_operand:SI 2 "general_movdst_operand" "")
9080 (mem:SI (match_dup 0)))]
9081 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9082 "mov.l @(%0,%1),%2")
9083
9084 (define_peephole
9085 [(set (match_operand:SI 0 "register_operand" "=r")
9086 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9087 (set (mem:HI (match_dup 0))
9088 (match_operand:HI 2 "general_movsrc_operand" ""))]
9089 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9090 "mov.w %2,@(%0,%1)")
9091
9092 (define_peephole
9093 [(set (match_operand:SI 0 "register_operand" "=r")
9094 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9095 (set (match_operand:HI 2 "general_movdst_operand" "")
9096 (mem:HI (match_dup 0)))]
9097 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9098 "mov.w @(%0,%1),%2")
9099
9100 (define_peephole
9101 [(set (match_operand:SI 0 "register_operand" "=r")
9102 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9103 (set (mem:QI (match_dup 0))
9104 (match_operand:QI 2 "general_movsrc_operand" ""))]
9105 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9106 "mov.b %2,@(%0,%1)")
9107
9108 (define_peephole
9109 [(set (match_operand:SI 0 "register_operand" "=r")
9110 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9111 (set (match_operand:QI 2 "general_movdst_operand" "")
9112 (mem:QI (match_dup 0)))]
9113 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9114 "mov.b @(%0,%1),%2")
9115
9116 (define_peephole
9117 [(set (match_operand:SI 0 "register_operand" "=r")
9118 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9119 (set (mem:SF (match_dup 0))
9120 (match_operand:SF 2 "general_movsrc_operand" ""))]
9121 "TARGET_SH1 && REGNO (operands[0]) == 0
9122 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9123 || (GET_CODE (operands[2]) == SUBREG
9124 && REGNO (SUBREG_REG (operands[2])) < 16))
9125 && reg_unused_after (operands[0], insn)"
9126 "mov.l %2,@(%0,%1)")
9127
9128 (define_peephole
9129 [(set (match_operand:SI 0 "register_operand" "=r")
9130 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9131 (set (match_operand:SF 2 "general_movdst_operand" "")
9132
9133 (mem:SF (match_dup 0)))]
9134 "TARGET_SH1 && REGNO (operands[0]) == 0
9135 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9136 || (GET_CODE (operands[2]) == SUBREG
9137 && REGNO (SUBREG_REG (operands[2])) < 16))
9138 && reg_unused_after (operands[0], insn)"
9139 "mov.l @(%0,%1),%2")
9140
9141 (define_peephole
9142 [(set (match_operand:SI 0 "register_operand" "=r")
9143 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9144 (set (mem:SF (match_dup 0))
9145 (match_operand:SF 2 "general_movsrc_operand" ""))]
9146 "TARGET_SH3E && REGNO (operands[0]) == 0
9147 && ((GET_CODE (operands[2]) == REG
9148 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9149 || (GET_CODE (operands[2]) == SUBREG
9150 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9151 && reg_unused_after (operands[0], insn)"
9152 "fmov{.s|} %2,@(%0,%1)")
9153
9154 (define_peephole
9155 [(set (match_operand:SI 0 "register_operand" "=r")
9156 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9157 (set (match_operand:SF 2 "general_movdst_operand" "")
9158
9159 (mem:SF (match_dup 0)))]
9160 "TARGET_SH3E && REGNO (operands[0]) == 0
9161 && ((GET_CODE (operands[2]) == REG
9162 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9163 || (GET_CODE (operands[2]) == SUBREG
9164 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9165 && reg_unused_after (operands[0], insn)"
9166 "fmov{.s|} @(%0,%1),%2")
9167
9168 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9169 (define_insn "sp_switch_1"
9170 [(const_int 1)]
9171 "TARGET_SH1"
9172 "*
9173 {
9174 rtx xoperands[1];
9175
9176 xoperands[0] = sp_switch;
9177 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9178 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9179 return \"mov r0,r15\";
9180 }"
9181 [(set_attr "length" "10")])
9182
9183 ;; Switch back to the original stack for interrupt functions with the
9184 ;; sp_switch attribute. */
9185 (define_insn "sp_switch_2"
9186 [(const_int 2)]
9187 "TARGET_SH1"
9188 "mov.l @r15+,r15\;mov.l @r15+,r0"
9189 [(set_attr "length" "4")])
9190
9191 ;; Integer vector moves
9192
9193 (define_expand "movv8qi"
9194 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9195 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9196 "TARGET_SHMEDIA"
9197 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9198
9199 (define_insn "movv8qi_i"
9200 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9201 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9202 "TARGET_SHMEDIA
9203 && (register_operand (operands[0], V8QImode)
9204 || sh_register_operand (operands[1], V8QImode))"
9205 "@
9206 add %1, r63, %0
9207 movi %1, %0
9208 #
9209 ld%M1.q %m1, %0
9210 st%M0.q %m0, %N1"
9211 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9212 (set_attr "length" "4,4,16,4,4")])
9213
9214 (define_split
9215 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9216 (subreg:V8QI (const_int 0) 0))]
9217 "TARGET_SHMEDIA"
9218 [(set (match_dup 0)
9219 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9220 (const_int 0) (const_int 0) (const_int 0)
9221 (const_int 0) (const_int 0)]))])
9222
9223 (define_split
9224 [(set (match_operand 0 "arith_reg_dest" "")
9225 (match_operand 1 "sh_rep_vec" ""))]
9226 "TARGET_SHMEDIA && reload_completed
9227 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9228 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9229 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9230 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9231 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9232 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9233 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9234 [(set (match_dup 0) (match_dup 1))
9235 (match_dup 2)]
9236 "
9237 {
9238 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9239 rtx elt1 = XVECEXP (operands[1], 0, 1);
9240
9241 if (unit_size > 2)
9242 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9243 else
9244 {
9245 if (unit_size < 2)
9246 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9247 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9248 }
9249 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9250 operands[1] = XVECEXP (operands[1], 0, 0);
9251 if (unit_size < 2)
9252 {
9253 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9254 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9255 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9256 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9257 else
9258 {
9259 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9260 operands[1]
9261 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9262 }
9263 }
9264 }")
9265
9266 (define_split
9267 [(set (match_operand 0 "arith_reg_dest" "")
9268 (match_operand 1 "sh_const_vec" ""))]
9269 "TARGET_SHMEDIA && reload_completed
9270 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9271 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9272 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9273 [(set (match_dup 0) (match_dup 1))]
9274 "
9275 {
9276 rtx v = operands[1];
9277 enum machine_mode new_mode
9278 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9279
9280 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9281 operands[1]
9282 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9283 }")
9284
9285 (define_expand "movv2hi"
9286 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9287 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9288 "TARGET_SHMEDIA"
9289 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9290
9291 (define_insn "movv2hi_i"
9292 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9293 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9294 "TARGET_SHMEDIA
9295 && (register_operand (operands[0], V2HImode)
9296 || sh_register_operand (operands[1], V2HImode))"
9297 "@
9298 addz.l %1, r63, %0
9299 movi %1, %0
9300 #
9301 ld%M1.l %m1, %0
9302 st%M0.l %m0, %N1"
9303 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9304 (set_attr "length" "4,4,16,4,4")])
9305
9306 (define_expand "movv4hi"
9307 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9308 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9309 "TARGET_SHMEDIA"
9310 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9311
9312 (define_insn "movv4hi_i"
9313 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9314 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9315 "TARGET_SHMEDIA
9316 && (register_operand (operands[0], V4HImode)
9317 || sh_register_operand (operands[1], V4HImode))"
9318 "@
9319 add %1, r63, %0
9320 movi %1, %0
9321 #
9322 ld%M1.q %m1, %0
9323 st%M0.q %m0, %N1"
9324 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9325 (set_attr "length" "4,4,16,4,4")])
9326
9327 (define_expand "movv2si"
9328 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9329 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9330 "TARGET_SHMEDIA"
9331 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9332
9333 (define_insn "movv2si_i"
9334 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9335 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9336 "TARGET_SHMEDIA
9337 && (register_operand (operands[0], V2SImode)
9338 || sh_register_operand (operands[1], V2SImode))"
9339 "@
9340 add %1, r63, %0
9341 #
9342 #
9343 ld%M1.q %m1, %0
9344 st%M0.q %m0, %N1"
9345 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9346 (set_attr "length" "4,4,16,4,4")])
9347
9348 ;; Multimedia Intrinsics
9349
9350 (define_insn "absv2si2"
9351 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9352 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9353 "TARGET_SHMEDIA"
9354 "mabs.l %1, %0"
9355 [(set_attr "type" "mcmp_media")])
9356
9357 (define_insn "absv4hi2"
9358 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9359 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9360 "TARGET_SHMEDIA"
9361 "mabs.w %1, %0"
9362 [(set_attr "type" "mcmp_media")])
9363
9364 (define_insn "addv2si3"
9365 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9366 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9367 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9368 "TARGET_SHMEDIA"
9369 "madd.l %1, %2, %0"
9370 [(set_attr "type" "arith_media")])
9371
9372 (define_insn "addv4hi3"
9373 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9374 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9375 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9376 "TARGET_SHMEDIA"
9377 "madd.w %1, %2, %0"
9378 [(set_attr "type" "arith_media")])
9379
9380 (define_insn "ssaddv2si3"
9381 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9382 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9383 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9384 "TARGET_SHMEDIA"
9385 "madds.l %1, %2, %0"
9386 [(set_attr "type" "mcmp_media")])
9387
9388 (define_insn "usaddv8qi3"
9389 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9390 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9391 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9392 "TARGET_SHMEDIA"
9393 "madds.ub %1, %2, %0"
9394 [(set_attr "type" "mcmp_media")])
9395
9396 (define_insn "ssaddv4hi3"
9397 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9398 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9399 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9400 "TARGET_SHMEDIA"
9401 "madds.w %1, %2, %0"
9402 [(set_attr "type" "mcmp_media")])
9403
9404 (define_insn "negcmpeqv8qi"
9405 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9406 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9407 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9408 "TARGET_SHMEDIA"
9409 "mcmpeq.b %N1, %N2, %0"
9410 [(set_attr "type" "mcmp_media")])
9411
9412 (define_insn "negcmpeqv2si"
9413 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9414 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9415 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9416 "TARGET_SHMEDIA"
9417 "mcmpeq.l %N1, %N2, %0"
9418 [(set_attr "type" "mcmp_media")])
9419
9420 (define_insn "negcmpeqv4hi"
9421 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9422 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9423 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9424 "TARGET_SHMEDIA"
9425 "mcmpeq.w %N1, %N2, %0"
9426 [(set_attr "type" "mcmp_media")])
9427
9428 (define_insn "negcmpgtuv8qi"
9429 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9430 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9431 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9432 "TARGET_SHMEDIA"
9433 "mcmpgt.ub %N1, %N2, %0"
9434 [(set_attr "type" "mcmp_media")])
9435
9436 (define_insn "negcmpgtv2si"
9437 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9438 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9439 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9440 "TARGET_SHMEDIA"
9441 "mcmpgt.l %N1, %N2, %0"
9442 [(set_attr "type" "mcmp_media")])
9443
9444 (define_insn "negcmpgtv4hi"
9445 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9446 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9447 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9448 "TARGET_SHMEDIA"
9449 "mcmpgt.w %N1, %N2, %0"
9450 [(set_attr "type" "mcmp_media")])
9451
9452 (define_insn "mcmv"
9453 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9454 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9455 (match_operand:DI 2 "arith_reg_operand" "r"))
9456 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9457 (not:DI (match_dup 2)))))]
9458 "TARGET_SHMEDIA"
9459 "mcmv %N1, %2, %0"
9460 [(set_attr "type" "arith_media")])
9461
9462 (define_insn "mcnvs_lw"
9463 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9464 (vec_concat:V4HI
9465 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9466 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9467 "TARGET_SHMEDIA"
9468 "mcnvs.lw %N1, %N2, %0"
9469 [(set_attr "type" "mcmp_media")])
9470
9471 (define_insn "mcnvs_wb"
9472 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9473 (vec_concat:V8QI
9474 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9475 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9476 "TARGET_SHMEDIA"
9477 "mcnvs.wb %N1, %N2, %0"
9478 [(set_attr "type" "mcmp_media")])
9479
9480 (define_insn "mcnvs_wub"
9481 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9482 (vec_concat:V8QI
9483 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9484 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9485 "TARGET_SHMEDIA"
9486 "mcnvs.wub %N1, %N2, %0"
9487 [(set_attr "type" "mcmp_media")])
9488
9489 (define_insn "mextr_rl"
9490 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9491 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9492 (match_operand:HI 3 "mextr_bit_offset" "i"))
9493 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9494 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9495 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9496 "*
9497 {
9498 static char templ[16];
9499
9500 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9501 (int) INTVAL (operands[3]) >> 3);
9502 return templ;
9503 }"
9504 [(set_attr "type" "arith_media")])
9505
9506 (define_insn "*mextr_lr"
9507 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9508 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9509 (match_operand:HI 3 "mextr_bit_offset" "i"))
9510 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9511 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9512 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9513 "*
9514 {
9515 static char templ[16];
9516
9517 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9518 (int) INTVAL (operands[4]) >> 3);
9519 return templ;
9520 }"
9521 [(set_attr "type" "arith_media")])
9522
9523 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9524 ; vector then varies depending on endianness.
9525 (define_expand "mextr1"
9526 [(match_operand:DI 0 "arith_reg_dest" "")
9527 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9528 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9529 "TARGET_SHMEDIA"
9530 "
9531 {
9532 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9533 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9534 DONE;
9535 }")
9536
9537 (define_expand "mextr2"
9538 [(match_operand:DI 0 "arith_reg_dest" "")
9539 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9540 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9541 "TARGET_SHMEDIA"
9542 "
9543 {
9544 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9545 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9546 DONE;
9547 }")
9548
9549 (define_expand "mextr3"
9550 [(match_operand:DI 0 "arith_reg_dest" "")
9551 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9552 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9553 "TARGET_SHMEDIA"
9554 "
9555 {
9556 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9557 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9558 DONE;
9559 }")
9560
9561 (define_expand "mextr4"
9562 [(match_operand:DI 0 "arith_reg_dest" "")
9563 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9564 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9565 "TARGET_SHMEDIA"
9566 "
9567 {
9568 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9569 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9570 DONE;
9571 }")
9572
9573 (define_expand "mextr5"
9574 [(match_operand:DI 0 "arith_reg_dest" "")
9575 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9576 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9577 "TARGET_SHMEDIA"
9578 "
9579 {
9580 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9581 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9582 DONE;
9583 }")
9584
9585 (define_expand "mextr6"
9586 [(match_operand:DI 0 "arith_reg_dest" "")
9587 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9588 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9589 "TARGET_SHMEDIA"
9590 "
9591 {
9592 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9593 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9594 DONE;
9595 }")
9596
9597 (define_expand "mextr7"
9598 [(match_operand:DI 0 "arith_reg_dest" "")
9599 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9600 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9601 "TARGET_SHMEDIA"
9602 "
9603 {
9604 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9605 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9606 DONE;
9607 }")
9608
9609 (define_expand "mmacfx_wl"
9610 [(match_operand:V2SI 0 "arith_reg_dest" "")
9611 (match_operand:V2HI 1 "extend_reg_operand" "")
9612 (match_operand:V2HI 2 "extend_reg_operand" "")
9613 (match_operand:V2SI 3 "arith_reg_operand" "")]
9614 "TARGET_SHMEDIA"
9615 "
9616 {
9617 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9618 operands[1], operands[2]));
9619 DONE;
9620 }")
9621
9622 (define_insn "mmacfx_wl_i"
9623 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9624 (ss_plus:V2SI
9625 (match_operand:V2SI 1 "arith_reg_operand" "0")
9626 (ss_truncate:V2SI
9627 (ashift:V2DI
9628 (sign_extend:V2DI
9629 (mult:V2SI
9630 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9631 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9632 (const_int 1)))))]
9633 "TARGET_SHMEDIA"
9634 "mmacfx.wl %2, %3, %0"
9635 [(set_attr "type" "mac_media")])
9636
9637 (define_expand "mmacnfx_wl"
9638 [(match_operand:V2SI 0 "arith_reg_dest" "")
9639 (match_operand:V2HI 1 "extend_reg_operand" "")
9640 (match_operand:V2HI 2 "extend_reg_operand" "")
9641 (match_operand:V2SI 3 "arith_reg_operand" "")]
9642 "TARGET_SHMEDIA"
9643 "
9644 {
9645 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9646 operands[1], operands[2]));
9647 DONE;
9648 }")
9649
9650 (define_insn "mmacnfx_wl_i"
9651 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9652 (ss_minus:V2SI
9653 (match_operand:V2SI 1 "arith_reg_operand" "0")
9654 (ss_truncate:V2SI
9655 (ashift:V2DI
9656 (sign_extend:V2DI
9657 (mult:V2SI
9658 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9659 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9660 (const_int 1)))))]
9661 "TARGET_SHMEDIA"
9662 "mmacnfx.wl %2, %3, %0"
9663 [(set_attr "type" "mac_media")])
9664
9665 (define_insn "mulv2si3"
9666 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9667 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9668 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9669 "TARGET_SHMEDIA"
9670 "mmul.l %1, %2, %0"
9671 [(set_attr "type" "d2mpy_media")])
9672
9673 (define_insn "mulv4hi3"
9674 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9675 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9676 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9677 "TARGET_SHMEDIA"
9678 "mmul.w %1, %2, %0"
9679 [(set_attr "type" "dmpy_media")])
9680
9681 (define_insn "mmulfx_l"
9682 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9683 (ss_truncate:V2SI
9684 (ashiftrt:V2DI
9685 (mult:V2DI
9686 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9687 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9688 (const_int 31))))]
9689 "TARGET_SHMEDIA"
9690 "mmulfx.l %1, %2, %0"
9691 [(set_attr "type" "d2mpy_media")])
9692
9693 (define_insn "mmulfx_w"
9694 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9695 (ss_truncate:V4HI
9696 (ashiftrt:V4SI
9697 (mult:V4SI
9698 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9699 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9700 (const_int 15))))]
9701 "TARGET_SHMEDIA"
9702 "mmulfx.w %1, %2, %0"
9703 [(set_attr "type" "dmpy_media")])
9704
9705 (define_insn "mmulfxrp_w"
9706 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9707 (ss_truncate:V4HI
9708 (ashiftrt:V4SI
9709 (plus:V4SI
9710 (mult:V4SI
9711 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9712 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9713 (const_int 16384))
9714 (const_int 15))))]
9715 "TARGET_SHMEDIA"
9716 "mmulfxrp.w %1, %2, %0"
9717 [(set_attr "type" "dmpy_media")])
9718
9719 (define_expand "mmulhi_wl"
9720 [(match_operand:V2SI 0 "arith_reg_dest" "")
9721 (match_operand:V4HI 1 "arith_reg_operand" "")
9722 (match_operand:V4HI 2 "arith_reg_operand" "")]
9723 "TARGET_SHMEDIA"
9724 "
9725 {
9726 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9727 (operands[0], operands[1], operands[2]));
9728 DONE;
9729 }")
9730
9731 (define_expand "mmullo_wl"
9732 [(match_operand:V2SI 0 "arith_reg_dest" "")
9733 (match_operand:V4HI 1 "arith_reg_operand" "")
9734 (match_operand:V4HI 2 "arith_reg_operand" "")]
9735 "TARGET_SHMEDIA"
9736 "
9737 {
9738 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9739 (operands[0], operands[1], operands[2]));
9740 DONE;
9741 }")
9742
9743 (define_insn "mmul23_wl"
9744 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9745 (vec_select:V2SI
9746 (mult:V4SI
9747 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9748 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9749 (parallel [(const_int 2) (const_int 3)])))]
9750 "TARGET_SHMEDIA"
9751 "* return (TARGET_LITTLE_ENDIAN
9752 ? \"mmulhi.wl %1, %2, %0\"
9753 : \"mmullo.wl %1, %2, %0\");"
9754 [(set_attr "type" "dmpy_media")])
9755
9756 (define_insn "mmul01_wl"
9757 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9758 (vec_select:V2SI
9759 (mult:V4SI
9760 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9761 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9762 (parallel [(const_int 0) (const_int 1)])))]
9763 "TARGET_SHMEDIA"
9764 "* return (TARGET_LITTLE_ENDIAN
9765 ? \"mmullo.wl %1, %2, %0\"
9766 : \"mmulhi.wl %1, %2, %0\");"
9767 [(set_attr "type" "dmpy_media")])
9768
9769 (define_expand "mmulsum_wq"
9770 [(match_operand:DI 0 "arith_reg_dest" "")
9771 (match_operand:V4HI 1 "arith_reg_operand" "")
9772 (match_operand:V4HI 2 "arith_reg_operand" "")
9773 (match_operand:DI 3 "arith_reg_operand" "")]
9774 "TARGET_SHMEDIA"
9775 "
9776 {
9777 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9778 operands[1], operands[2]));
9779 DONE;
9780 }")
9781
9782 (define_insn "mmulsum_wq_i"
9783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9784 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9785 (plus:DI
9786 (plus:DI
9787 (vec_select:DI
9788 (mult:V4DI
9789 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9790 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9791 (parallel [(const_int 0)]))
9792 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9793 (sign_extend:V4DI (match_dup 3)))
9794 (parallel [(const_int 1)])))
9795 (plus:DI
9796 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9797 (sign_extend:V4DI (match_dup 3)))
9798 (parallel [(const_int 2)]))
9799 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9800 (sign_extend:V4DI (match_dup 3)))
9801 (parallel [(const_int 3)]))))))]
9802 "TARGET_SHMEDIA"
9803 "mmulsum.wq %2, %3, %0"
9804 [(set_attr "type" "mac_media")])
9805
9806 (define_expand "mperm_w"
9807 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9808 (match_operand:V4HI 1 "arith_reg_operand" "r")
9809 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9810 "TARGET_SHMEDIA"
9811 "
9812 {
9813 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9814 (operands[0], operands[1], operands[2]));
9815 DONE;
9816 }")
9817
9818 ; This use of vec_select isn't exactly correct according to rtl.texi
9819 ; (because not constant), but it seems a straightforward extension.
9820 (define_insn "mperm_w_little"
9821 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9822 (vec_select:V4HI
9823 (match_operand:V4HI 1 "arith_reg_operand" "r")
9824 (parallel
9825 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9826 (const_int 2) (const_int 0))
9827 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9828 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9829 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9830 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9831 "mperm.w %1, %N2, %0"
9832 [(set_attr "type" "arith_media")])
9833
9834 (define_insn "mperm_w_big"
9835 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9836 (vec_select:V4HI
9837 (match_operand:V4HI 1 "arith_reg_operand" "r")
9838 (parallel
9839 [(zero_extract:QI (not:QI (match_operand:QI 2
9840 "extend_reg_or_0_operand" "rU"))
9841 (const_int 2) (const_int 0))
9842 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9843 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9844 (zero_extract:QI (not:QI (match_dup 2))
9845 (const_int 2) (const_int 6))])))]
9846 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9847 "mperm.w %1, %N2, %0"
9848 [(set_attr "type" "arith_media")])
9849
9850 (define_insn "mperm_w0"
9851 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9852 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9853 "trunc_hi_operand" "r"))))]
9854 "TARGET_SHMEDIA"
9855 "mperm.w %1, r63, %0"
9856 [(set_attr "type" "arith_media")])
9857
9858 (define_expand "msad_ubq"
9859 [(match_operand:DI 0 "arith_reg_dest" "")
9860 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9861 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9862 (match_operand:DI 3 "arith_reg_operand" "")]
9863 "TARGET_SHMEDIA"
9864 "
9865 {
9866 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9867 operands[1], operands[2]));
9868 DONE;
9869 }")
9870
9871 (define_insn "msad_ubq_i"
9872 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9873 (plus:DI
9874 (plus:DI
9875 (plus:DI
9876 (plus:DI
9877 (match_operand:DI 1 "arith_reg_operand" "0")
9878 (abs:DI (vec_select:DI
9879 (minus:V8DI
9880 (zero_extend:V8DI
9881 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9882 (zero_extend:V8DI
9883 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9884 (parallel [(const_int 0)]))))
9885 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9886 (zero_extend:V8DI (match_dup 3)))
9887 (parallel [(const_int 1)]))))
9888 (plus:DI
9889 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9890 (zero_extend:V8DI (match_dup 3)))
9891 (parallel [(const_int 2)])))
9892 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9893 (zero_extend:V8DI (match_dup 3)))
9894 (parallel [(const_int 3)])))))
9895 (plus:DI
9896 (plus:DI
9897 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9898 (zero_extend:V8DI (match_dup 3)))
9899 (parallel [(const_int 4)])))
9900 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9901 (zero_extend:V8DI (match_dup 3)))
9902 (parallel [(const_int 5)]))))
9903 (plus:DI
9904 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9905 (zero_extend:V8DI (match_dup 3)))
9906 (parallel [(const_int 6)])))
9907 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9908 (zero_extend:V8DI (match_dup 3)))
9909 (parallel [(const_int 7)])))))))]
9910 "TARGET_SHMEDIA"
9911 "msad.ubq %N2, %N3, %0"
9912 [(set_attr "type" "mac_media")])
9913
9914 (define_insn "mshalds_l"
9915 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9916 (ss_truncate:V2SI
9917 (ashift:V2DI
9918 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9919 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9920 (const_int 31)))))]
9921 "TARGET_SHMEDIA"
9922 "mshalds.l %1, %2, %0"
9923 [(set_attr "type" "mcmp_media")])
9924
9925 (define_insn "mshalds_w"
9926 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9927 (ss_truncate:V4HI
9928 (ashift:V4SI
9929 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9930 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9931 (const_int 15)))))]
9932 "TARGET_SHMEDIA"
9933 "mshalds.w %1, %2, %0"
9934 [(set_attr "type" "mcmp_media")])
9935
9936 (define_insn "ashrv2si3"
9937 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9938 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9939 (match_operand:DI 2 "arith_reg_operand" "r")))]
9940 "TARGET_SHMEDIA"
9941 "mshard.l %1, %2, %0"
9942 [(set_attr "type" "arith_media")])
9943
9944 (define_insn "ashrv4hi3"
9945 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9946 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9947 (match_operand:DI 2 "arith_reg_operand" "r")))]
9948 "TARGET_SHMEDIA"
9949 "mshard.w %1, %2, %0"
9950 [(set_attr "type" "arith_media")])
9951
9952 (define_insn "mshards_q"
9953 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9954 (ss_truncate:HI
9955 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9956 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9957 "TARGET_SHMEDIA"
9958 "mshards.q %1, %N2, %0"
9959 [(set_attr "type" "mcmp_media")])
9960
9961 (define_expand "mshfhi_b"
9962 [(match_operand:V8QI 0 "arith_reg_dest" "")
9963 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9964 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9965 "TARGET_SHMEDIA"
9966 "
9967 {
9968 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9969 (operands[0], operands[1], operands[2]));
9970 DONE;
9971 }")
9972
9973 (define_expand "mshflo_b"
9974 [(match_operand:V8QI 0 "arith_reg_dest" "")
9975 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9976 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9977 "TARGET_SHMEDIA"
9978 "
9979 {
9980 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9981 (operands[0], operands[1], operands[2]));
9982 DONE;
9983 }")
9984
9985 (define_insn "mshf4_b"
9986 [(set
9987 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9988 (vec_select:V8QI
9989 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9990 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9991 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9992 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9993 "TARGET_SHMEDIA"
9994 "* return (TARGET_LITTLE_ENDIAN
9995 ? \"mshfhi.b %N1, %N2, %0\"
9996 : \"mshflo.b %N1, %N2, %0\");"
9997 [(set_attr "type" "arith_media")])
9998
9999 (define_insn "mshf0_b"
10000 [(set
10001 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10002 (vec_select:V8QI
10003 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10004 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
10005 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10006 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10007 "TARGET_SHMEDIA"
10008 "* return (TARGET_LITTLE_ENDIAN
10009 ? \"mshflo.b %N1, %N2, %0\"
10010 : \"mshfhi.b %N1, %N2, %0\");"
10011 [(set_attr "type" "arith_media")])
10012
10013 (define_expand "mshfhi_l"
10014 [(match_operand:V2SI 0 "arith_reg_dest" "")
10015 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10016 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10017 "TARGET_SHMEDIA"
10018 "
10019 {
10020 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10021 (operands[0], operands[1], operands[2]));
10022 DONE;
10023 }")
10024
10025 (define_expand "mshflo_l"
10026 [(match_operand:V2SI 0 "arith_reg_dest" "")
10027 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10028 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10029 "TARGET_SHMEDIA"
10030 "
10031 {
10032 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10033 (operands[0], operands[1], operands[2]));
10034 DONE;
10035 }")
10036
10037 (define_insn "mshf4_l"
10038 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10039 (vec_select:V2SI
10040 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10041 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10042 (parallel [(const_int 1) (const_int 3)])))]
10043 "TARGET_SHMEDIA"
10044 "* return (TARGET_LITTLE_ENDIAN
10045 ? \"mshfhi.l %N1, %N2, %0\"
10046 : \"mshflo.l %N1, %N2, %0\");"
10047 [(set_attr "type" "arith_media")])
10048
10049 (define_insn "mshf0_l"
10050 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10051 (vec_select:V2SI
10052 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10053 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10054 (parallel [(const_int 0) (const_int 2)])))]
10055 "TARGET_SHMEDIA"
10056 "* return (TARGET_LITTLE_ENDIAN
10057 ? \"mshflo.l %N1, %N2, %0\"
10058 : \"mshfhi.l %N1, %N2, %0\");"
10059 [(set_attr "type" "arith_media")])
10060
10061 (define_expand "mshfhi_w"
10062 [(match_operand:V4HI 0 "arith_reg_dest" "")
10063 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10064 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10065 "TARGET_SHMEDIA"
10066 "
10067 {
10068 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10069 (operands[0], operands[1], operands[2]));
10070 DONE;
10071 }")
10072
10073 (define_expand "mshflo_w"
10074 [(match_operand:V4HI 0 "arith_reg_dest" "")
10075 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10076 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10077 "TARGET_SHMEDIA"
10078 "
10079 {
10080 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10081 (operands[0], operands[1], operands[2]));
10082 DONE;
10083 }")
10084
10085 (define_insn "mshf4_w"
10086 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10087 (vec_select:V4HI
10088 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10089 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10090 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10091 "TARGET_SHMEDIA"
10092 "* return (TARGET_LITTLE_ENDIAN
10093 ? \"mshfhi.w %N1, %N2, %0\"
10094 : \"mshflo.w %N1, %N2, %0\");"
10095 [(set_attr "type" "arith_media")])
10096
10097 (define_insn "mshf0_w"
10098 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10099 (vec_select:V4HI
10100 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10101 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10102 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10103 "TARGET_SHMEDIA"
10104 "* return (TARGET_LITTLE_ENDIAN
10105 ? \"mshflo.w %N1, %N2, %0\"
10106 : \"mshfhi.w %N1, %N2, %0\");"
10107 [(set_attr "type" "arith_media")])
10108
10109 (define_insn "mshflo_w_x"
10110 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10111 (vec_select:V4HI
10112 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10113 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10114 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10115 "TARGET_SHMEDIA"
10116 "mshflo.w %N1, %N2, %0"
10117 [(set_attr "type" "arith_media")])
10118
10119 /* These are useful to expand ANDs and as combiner patterns. */
10120 (define_insn_and_split "mshfhi_l_di"
10121 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10122 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10123 (const_int 32))
10124 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10125 (const_int -4294967296))))]
10126 "TARGET_SHMEDIA"
10127 "@
10128 mshfhi.l %N1, %N2, %0
10129 #"
10130 "TARGET_SHMEDIA && reload_completed
10131 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10132 [(set (match_dup 3) (match_dup 4))
10133 (set (match_dup 5) (match_dup 6))]
10134 "
10135 {
10136 operands[3] = gen_lowpart (SImode, operands[0]);
10137 operands[4] = gen_highpart (SImode, operands[1]);
10138 operands[5] = gen_highpart (SImode, operands[0]);
10139 operands[6] = gen_highpart (SImode, operands[2]);
10140 }"
10141 [(set_attr "type" "arith_media")])
10142
10143 (define_insn "*mshfhi_l_di_rev"
10144 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10145 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10146 (const_int -4294967296))
10147 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10148 (const_int 32))))]
10149 "TARGET_SHMEDIA"
10150 "mshfhi.l %N2, %N1, %0"
10151 [(set_attr "type" "arith_media")])
10152
10153 (define_split
10154 [(set (match_operand:DI 0 "arith_reg_dest" "")
10155 (ior:DI (zero_extend:DI (match_operand:SI 1
10156 "extend_reg_or_0_operand" ""))
10157 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10158 (const_int -4294967296))))
10159 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10160 "TARGET_SHMEDIA"
10161 [(const_int 0)]
10162 "
10163 {
10164 emit_insn (gen_ashldi3_media (operands[3],
10165 simplify_gen_subreg (DImode, operands[1],
10166 SImode, 0),
10167 GEN_INT (32)));
10168 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10169 DONE;
10170 }")
10171
10172 (define_insn "mshflo_l_di"
10173 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10174 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10175 (const_int 4294967295))
10176 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10177 (const_int 32))))]
10178
10179 "TARGET_SHMEDIA"
10180 "mshflo.l %N1, %N2, %0"
10181 [(set_attr "type" "arith_media")])
10182
10183 (define_insn "*mshflo_l_di_rev"
10184 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10185 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10186 (const_int 32))
10187 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10188 (const_int 4294967295))))]
10189
10190 "TARGET_SHMEDIA"
10191 "mshflo.l %N2, %N1, %0"
10192 [(set_attr "type" "arith_media")])
10193
10194 ;; Combiner pattern for trampoline initialization.
10195 (define_insn_and_split "*double_shori"
10196 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10197 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10198 (const_int 32))
10199 (match_operand:DI 2 "const_int_operand" "n")))]
10200 "TARGET_SHMEDIA
10201 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10202 "#"
10203 "rtx_equal_p (operands[0], operands[1])"
10204 [(const_int 0)]
10205 "
10206 {
10207 HOST_WIDE_INT v = INTVAL (operands[2]);
10208
10209 emit_insn (gen_shori_media (operands[0], operands[0],
10210 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10211 emit_insn (gen_shori_media (operands[0], operands[0],
10212 gen_int_mode (v, HImode)));
10213 DONE;
10214 }")
10215
10216
10217 (define_insn "*mshflo_l_di_x"
10218 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10219 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10220 "rU"))
10221 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10222 (const_int 32))))]
10223
10224 "TARGET_SHMEDIA"
10225 "mshflo.l %N1, %N2, %0"
10226 [(set_attr "type" "arith_media")])
10227
10228 (define_insn_and_split "concat_v2sf"
10229 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10230 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10231 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10232 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10233
10234 "TARGET_SHMEDIA"
10235 "@
10236 mshflo.l %N1, %N2, %0
10237 #
10238 #"
10239 "TARGET_SHMEDIA && reload_completed
10240 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10241 [(set (match_dup 3) (match_dup 1))
10242 (set (match_dup 4) (match_dup 2))]
10243 "
10244 {
10245 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10246 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10247 }"
10248 [(set_attr "type" "arith_media")])
10249
10250 (define_insn "*mshflo_l_di_x_rev"
10251 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10252 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10253 (const_int 32))
10254 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10255
10256 "TARGET_SHMEDIA"
10257 "mshflo.l %N2, %N1, %0"
10258 [(set_attr "type" "arith_media")])
10259
10260 (define_insn "ashlv2si3"
10261 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10262 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10263 (match_operand:DI 2 "arith_reg_operand" "r")))]
10264 "TARGET_SHMEDIA"
10265 "mshlld.l %1, %2, %0"
10266 [(set_attr "type" "arith_media")])
10267
10268 (define_insn "ashlv4hi3"
10269 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10270 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10271 (match_operand:DI 2 "arith_reg_operand" "r")))]
10272 "TARGET_SHMEDIA"
10273 "mshlld.w %1, %2, %0"
10274 [(set_attr "type" "arith_media")])
10275
10276 (define_insn "lshrv2si3"
10277 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10278 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10279 (match_operand:DI 2 "arith_reg_operand" "r")))]
10280 "TARGET_SHMEDIA"
10281 "mshlrd.l %1, %2, %0"
10282 [(set_attr "type" "arith_media")])
10283
10284 (define_insn "lshrv4hi3"
10285 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10286 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10287 (match_operand:DI 2 "arith_reg_operand" "r")))]
10288 "TARGET_SHMEDIA"
10289 "mshlrd.w %1, %2, %0"
10290 [(set_attr "type" "arith_media")])
10291
10292 (define_insn "subv2si3"
10293 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10294 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10295 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10296 "TARGET_SHMEDIA"
10297 "msub.l %N1, %2, %0"
10298 [(set_attr "type" "arith_media")])
10299
10300 (define_insn "subv4hi3"
10301 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10302 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10303 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10304 "TARGET_SHMEDIA"
10305 "msub.w %N1, %2, %0"
10306 [(set_attr "type" "arith_media")])
10307
10308 (define_insn "sssubv2si3"
10309 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10310 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10311 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10312 "TARGET_SHMEDIA"
10313 "msubs.l %N1, %2, %0"
10314 [(set_attr "type" "mcmp_media")])
10315
10316 (define_insn "ussubv8qi3"
10317 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10318 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10319 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10320 "TARGET_SHMEDIA"
10321 "msubs.ub %1, %2, %0"
10322 [(set_attr "type" "mcmp_media")])
10323
10324 (define_insn "sssubv4hi3"
10325 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10326 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10327 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10328 "TARGET_SHMEDIA"
10329 "msubs.w %N1, %2, %0"
10330 [(set_attr "type" "mcmp_media")])
10331
10332 ;; Floating Point Intrinsics
10333
10334 (define_insn "fcosa_s"
10335 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10336 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10337 UNSPEC_FCOSA))]
10338 "TARGET_SHMEDIA"
10339 "fcosa.s %1, %0"
10340 [(set_attr "type" "atrans_media")])
10341
10342 (define_insn "fsina_s"
10343 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10344 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10345 UNSPEC_FSINA))]
10346 "TARGET_SHMEDIA"
10347 "fsina.s %1, %0"
10348 [(set_attr "type" "atrans_media")])
10349
10350 (define_insn "fipr"
10351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10352 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10353 "fp_arith_reg_operand" "f")
10354 (match_operand:V4SF 2
10355 "fp_arith_reg_operand" "f"))
10356 (parallel [(const_int 0)]))
10357 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10358 (parallel [(const_int 1)])))
10359 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10360 (parallel [(const_int 2)]))
10361 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10362 (parallel [(const_int 3)])))))]
10363 "TARGET_SHMEDIA"
10364 "fipr %1, %2, %0"
10365 [(set_attr "type" "fparith_media")])
10366
10367 (define_insn "fsrra_s"
10368 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10369 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10370 UNSPEC_FSRRA))]
10371 "TARGET_SHMEDIA"
10372 "fsrra.s %1, %0"
10373 [(set_attr "type" "atrans_media")])
10374
10375 (define_insn "ftrv"
10376 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10377 (plus:V4SF
10378 (plus:V4SF
10379 (mult:V4SF
10380 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10381 (parallel [(const_int 0) (const_int 5)
10382 (const_int 10) (const_int 15)]))
10383 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10384 (mult:V4SF
10385 (vec_select:V4SF (match_dup 1)
10386 (parallel [(const_int 4) (const_int 9)
10387 (const_int 14) (const_int 3)]))
10388 (vec_select:V4SF (match_dup 2)
10389 (parallel [(const_int 1) (const_int 2)
10390 (const_int 3) (const_int 0)]))))
10391 (plus:V4SF
10392 (mult:V4SF
10393 (vec_select:V4SF (match_dup 1)
10394 (parallel [(const_int 8) (const_int 13)
10395 (const_int 2) (const_int 7)]))
10396 (vec_select:V4SF (match_dup 2)
10397 (parallel [(const_int 2) (const_int 3)
10398 (const_int 0) (const_int 1)])))
10399 (mult:V4SF
10400 (vec_select:V4SF (match_dup 1)
10401 (parallel [(const_int 12) (const_int 1)
10402 (const_int 6) (const_int 11)]))
10403 (vec_select:V4SF (match_dup 2)
10404 (parallel [(const_int 3) (const_int 0)
10405 (const_int 1) (const_int 2)]))))))]
10406 "TARGET_SHMEDIA"
10407 "ftrv %1, %2, %0"
10408 [(set_attr "type" "fparith_media")])
10409
10410 (define_insn "nsb"
10411 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10412 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10413 UNSPEC_NSB))]
10414 "TARGET_SHMEDIA"
10415 "nsb %1, %0"
10416 [(set_attr "type" "arith_media")])
10417
10418 (define_insn "nsbsi"
10419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10420 (zero_extend:SI
10421 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10422 UNSPEC_NSB)))]
10423 "TARGET_SHMEDIA"
10424 "nsb %1, %0"
10425 [(set_attr "type" "arith_media")])
10426
10427 (define_insn "nsbdi"
10428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10429 (zero_extend:DI
10430 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10431 UNSPEC_NSB)))]
10432 "TARGET_SHMEDIA"
10433 "nsb %1, %0"
10434 [(set_attr "type" "arith_media")])
10435
10436 (define_expand "ffsdi2"
10437 [(set (match_operand:DI 0 "arith_reg_dest" "")
10438 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10439 "TARGET_SHMEDIA"
10440 "
10441 {
10442 rtx scratch = gen_reg_rtx (DImode);
10443 rtx last;
10444
10445 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10446 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10447 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10448 emit_insn (gen_nsbdi (scratch, scratch));
10449 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10450 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10451 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10452 REG_NOTES (last)
10453 = gen_rtx_EXPR_LIST (REG_EQUAL,
10454 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10455 DONE;
10456 }")
10457
10458 (define_expand "ffssi2"
10459 [(set (match_operand:SI 0 "arith_reg_dest" "")
10460 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10461 "TARGET_SHMEDIA"
10462 "
10463 {
10464 rtx scratch = gen_reg_rtx (SImode);
10465 rtx discratch = gen_reg_rtx (DImode);
10466 rtx last;
10467
10468 emit_insn (gen_adddi3 (discratch,
10469 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10470 GEN_INT (-1)));
10471 emit_insn (gen_andcdi3 (discratch,
10472 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10473 discratch));
10474 emit_insn (gen_nsbsi (scratch, discratch));
10475 last = emit_insn (gen_subsi3 (operands[0],
10476 force_reg (SImode, GEN_INT (63)), scratch));
10477 REG_NOTES (last)
10478 = gen_rtx_EXPR_LIST (REG_EQUAL,
10479 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10480 DONE;
10481 }")
10482
10483 (define_insn "byterev"
10484 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10485 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10486 (parallel [(const_int 7) (const_int 6) (const_int 5)
10487 (const_int 4) (const_int 3) (const_int 2)
10488 (const_int 1) (const_int 0)])))]
10489 "TARGET_SHMEDIA"
10490 "byterev %1, %0"
10491 [(set_attr "type" "arith_media")])
10492
10493 ;; The following description models the
10494 ;; SH4 pipeline using the DFA based scheduler.
10495 ;; The DFA based description is better way to model
10496 ;; a superscalar pipeline as compared to function unit
10497 ;; reservation model.
10498 ;; 1. The function unit based model is oriented to describe at most one
10499 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10500 ;; pipeline units by same insn. This can be done using DFA based description.
10501 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10502 ;; 3. Writing all unit reservations for an instruction class is more natural description
10503 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10504 ;; old function unit based model.
10505 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10506
10507
10508 ;; Two automata are defined to reduce number of states
10509 ;; which a single large automaton will have.(Factoring)
10510
10511 (define_automaton "inst_pipeline,fpu_pipe")
10512
10513 ;; This unit is basically the decode unit of the processor.
10514 ;; Since SH4 is a dual issue machine,it is as if there are two
10515 ;; units so that any insn can be processed by either one
10516 ;; of the decoding unit.
10517
10518 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10519
10520
10521 ;; The fixed point arithmetic calculator(?? EX Unit).
10522
10523 (define_cpu_unit "int" "inst_pipeline")
10524
10525 ;; f1_1 and f1_2 are floating point units.Actually there is
10526 ;; a f1 unit which can overlap with other f1 unit but
10527 ;; not another F1 unit.It is as though there were two
10528 ;; f1 units.
10529
10530 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10531
10532 ;; The floating point units (except FS - F2 always precedes it.)
10533
10534 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10535
10536 ;; This is basically the MA unit of SH4
10537 ;; used in LOAD/STORE pipeline.
10538
10539 (define_cpu_unit "memory" "inst_pipeline")
10540
10541 ;; However, there are LS group insns that don't use it, even ones that
10542 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10543 (define_cpu_unit "load_store" "inst_pipeline")
10544
10545 ;; The address calculator used for branch instructions.
10546 ;; This will be reserved after "issue" of branch instructions
10547 ;; and this is to make sure that no two branch instructions
10548 ;; can be issued in parallel.
10549
10550 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10551
10552 ;; ----------------------------------------------------
10553 ;; This reservation is to simplify the dual issue description.
10554
10555 (define_reservation "issue" "pipe_01|pipe_02")
10556
10557 ;; This is to express the locking of D stage.
10558 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10559
10560 (define_reservation "d_lock" "pipe_01+pipe_02")
10561
10562 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10563 (define_reservation "F01" "F0+F1")
10564
10565 ;; This is to simplify description where F1,F2,FS
10566 ;; are used simultaneously.
10567
10568 (define_reservation "fpu" "F1+F2")
10569
10570 ;; This is to highlight the fact that f1
10571 ;; cannot overlap with F1.
10572
10573 (exclusion_set "f1_1,f1_2" "F1")
10574
10575 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10576
10577 ;; Although reg moves have a latency of zero
10578 ;; we need to highlight that they use D stage
10579 ;; for one cycle.
10580
10581 ;; Group: MT
10582
10583 (define_insn_reservation "reg_mov" 0
10584 (and (eq_attr "pipe_model" "sh4")
10585 (eq_attr "type" "move"))
10586 "issue")
10587
10588 ;; Group: LS
10589
10590 (define_insn_reservation "freg_mov" 0
10591 (and (eq_attr "pipe_model" "sh4")
10592 (eq_attr "type" "fmove"))
10593 "issue+load_store")
10594
10595 ;; We don't model all pipeline stages; we model the issue ('D') stage
10596 ;; inasmuch as we allow only two instructions to issue simultanously,
10597 ;; and CO instructions prevent any simultanous issue of another instruction.
10598 ;; (This uses pipe_01 and pipe_02).
10599 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10600 ;; Double issue of EX / BR insns is prevented by using the int unit /
10601 ;; pcr_addrcalc unit in the EX stage.
10602 ;; Double issue of BR / LS instructions is prevented by using the
10603 ;; pcr_addrcalc / load_store unit in the issue cycle.
10604 ;; Double issue of FE instructions is prevented by using F0 in the first
10605 ;; pipeline stage after the first D stage.
10606 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10607 ;; (except in the cases outlined above), nor to describe the FS stage after
10608 ;; the F2 stage.
10609
10610 ;; Other MT group intructions(1 step operations)
10611 ;; Group: MT
10612 ;; Latency: 1
10613 ;; Issue Rate: 1
10614
10615 (define_insn_reservation "mt" 1
10616 (and (eq_attr "pipe_model" "sh4")
10617 (eq_attr "type" "mt_group"))
10618 "issue")
10619
10620 ;; Fixed Point Arithmetic Instructions(1 step operations)
10621 ;; Group: EX
10622 ;; Latency: 1
10623 ;; Issue Rate: 1
10624
10625 (define_insn_reservation "sh4_simple_arith" 1
10626 (and (eq_attr "pipe_model" "sh4")
10627 (eq_attr "insn_class" "ex_group"))
10628 "issue,int")
10629
10630 ;; Load and store instructions have no alignment peculiarities for the SH4,
10631 ;; but they use the load-store unit, which they share with the fmove type
10632 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10633 ;; Loads have a latency of two.
10634 ;; However, call insns can only paired with a preceding insn, and have
10635 ;; a delay slot, so that we want two more insns to be scheduled between the
10636 ;; load of the function address and the call. This is equivalent to a
10637 ;; latency of three.
10638 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10639 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10640 ;; We only do this for SImode loads of general registers, to make the work
10641 ;; for ADJUST_COST easier.
10642
10643 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10644 ;; Group: LS
10645 ;; Latency: 2
10646 ;; Issue Rate: 1
10647
10648 (define_insn_reservation "sh4_load" 2
10649 (and (eq_attr "pipe_model" "sh4")
10650 (eq_attr "type" "load,pcload"))
10651 "issue+load_store,nothing,memory")
10652
10653 ;; calls / sfuncs need an extra instruction for their delay slot.
10654 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10655 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10656 ;; count of a dynamic shift.
10657 (define_insn_reservation "sh4_load_si" 3
10658 (and (eq_attr "pipe_model" "sh4")
10659 (eq_attr "type" "load_si,pcload_si"))
10660 "issue+load_store,nothing,memory")
10661
10662 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10663
10664 ;; The load latency is upped to three higher if the dependent insn does
10665 ;; double precision computation. We want the 'default' latency to reflect
10666 ;; that increased latency because otherwise the insn priorities won't
10667 ;; allow proper scheduling.
10668 (define_insn_reservation "sh4_fload" 3
10669 (and (eq_attr "pipe_model" "sh4")
10670 (eq_attr "type" "fload,pcfload"))
10671 "issue+load_store,nothing,memory")
10672
10673 ;; (define_bypass 2 "sh4_fload" "!")
10674
10675 (define_insn_reservation "sh4_store" 1
10676 (and (eq_attr "pipe_model" "sh4")
10677 (eq_attr "type" "store"))
10678 "issue+load_store,nothing,memory")
10679
10680 ;; Load Store instructions.
10681 ;; Group: LS
10682 ;; Latency: 1
10683 ;; Issue Rate: 1
10684
10685 (define_insn_reservation "sh4_gp_fpul" 1
10686 (and (eq_attr "pipe_model" "sh4")
10687 (eq_attr "type" "gp_fpul"))
10688 "issue+load_store")
10689
10690 ;; Load Store instructions.
10691 ;; Group: LS
10692 ;; Latency: 3
10693 ;; Issue Rate: 1
10694
10695 (define_insn_reservation "sh4_fpul_gp" 3
10696 (and (eq_attr "pipe_model" "sh4")
10697 (eq_attr "type" "fpul_gp"))
10698 "issue+load_store")
10699
10700 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10701 ;; Group: BR
10702 ;; Latency when taken: 2 (or 1)
10703 ;; Issue Rate: 1
10704 ;; The latency is 1 when displacement is 0.
10705 ;; We can't really do much with the latency, even if we could express it,
10706 ;; but the pairing restrictions are useful to take into account.
10707 ;; ??? If the branch is likely, we might want to fill the delay slot;
10708 ;; if the branch is likely, but not very likely, should we pretend to use
10709 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10710
10711 (define_insn_reservation "sh4_branch" 1
10712 (and (eq_attr "pipe_model" "sh4")
10713 (eq_attr "type" "cbranch,jump"))
10714 "issue+pcr_addrcalc")
10715
10716 ;; Branch Far (JMP,RTS,BRAF)
10717 ;; Group: CO
10718 ;; Latency: 3
10719 ;; Issue Rate: 2
10720 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10721 ;; can't be distinguished from bra for the "jump" pattern.
10722
10723 (define_insn_reservation "sh4_return" 3
10724 (and (eq_attr "pipe_model" "sh4")
10725 (eq_attr "type" "return,jump_ind"))
10726 "d_lock*2")
10727
10728 ;; RTE
10729 ;; Group: CO
10730 ;; Latency: 5
10731 ;; Issue Rate: 5
10732 ;; this instruction can be executed in any of the pipelines
10733 ;; and blocks the pipeline for next 4 stages.
10734
10735 (define_insn_reservation "sh4_return_from_exp" 5
10736 (and (eq_attr "pipe_model" "sh4")
10737 (eq_attr "type" "rte"))
10738 "d_lock*5")
10739
10740 ;; OCBP, OCBWB
10741 ;; Group: CO
10742 ;; Latency: 1-5
10743 ;; Issue Rate: 1
10744
10745 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10746 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10747 (define_insn_reservation "ocbwb" 6
10748 (and (eq_attr "pipe_model" "sh4")
10749 (eq_attr "type" "cwb"))
10750 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10751
10752 ;; LDS to PR,JSR
10753 ;; Group: CO
10754 ;; Latency: 3
10755 ;; Issue Rate: 2
10756 ;; The SX stage is blocked for last 2 cycles.
10757 ;; OTOH, the only time that has an effect for insns generated by the compiler
10758 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10759 ;; or when we are doing a function call - and we don't do inter-function
10760 ;; scheduling. For the function call case, it's really best that we end with
10761 ;; something that models an rts.
10762
10763 (define_insn_reservation "sh4_lds_to_pr" 3
10764 (and (eq_attr "pipe_model" "sh4")
10765 (eq_attr "type" "prset") )
10766 "d_lock*2")
10767
10768 ;; calls introduce a longisch delay that is likely to flush the pipelines
10769 ;; of the caller's instructions. Ordinary functions tend to end with a
10770 ;; load to restore a register (in the delay slot of rts), while sfuncs
10771 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10772 ;; since there are no instructions that contend for memory access early.
10773 ;; We could, of course, provide exact scheduling information for specific
10774 ;; sfuncs, if that should prove useful.
10775
10776 (define_insn_reservation "sh4_call" 16
10777 (and (eq_attr "pipe_model" "sh4")
10778 (eq_attr "type" "call,sfunc"))
10779 "d_lock*16")
10780
10781 ;; LDS.L to PR
10782 ;; Group: CO
10783 ;; Latency: 3
10784 ;; Issue Rate: 2
10785 ;; The SX unit is blocked for last 2 cycles.
10786
10787 (define_insn_reservation "ldsmem_to_pr" 3
10788 (and (eq_attr "pipe_model" "sh4")
10789 (eq_attr "type" "pload"))
10790 "d_lock*2")
10791
10792 ;; STS from PR
10793 ;; Group: CO
10794 ;; Latency: 2
10795 ;; Issue Rate: 2
10796 ;; The SX unit in second and third cycles.
10797
10798 (define_insn_reservation "sts_from_pr" 2
10799 (and (eq_attr "pipe_model" "sh4")
10800 (eq_attr "type" "prget"))
10801 "d_lock*2")
10802
10803 ;; STS.L from PR
10804 ;; Group: CO
10805 ;; Latency: 2
10806 ;; Issue Rate: 2
10807
10808 (define_insn_reservation "sh4_prstore_mem" 2
10809 (and (eq_attr "pipe_model" "sh4")
10810 (eq_attr "type" "pstore"))
10811 "d_lock*2,nothing,memory")
10812
10813 ;; LDS to FPSCR
10814 ;; Group: CO
10815 ;; Latency: 4
10816 ;; Issue Rate: 1
10817 ;; F1 is blocked for last three cycles.
10818
10819 (define_insn_reservation "fpscr_load" 4
10820 (and (eq_attr "pipe_model" "sh4")
10821 (eq_attr "type" "gp_fpscr"))
10822 "d_lock,nothing,F1*3")
10823
10824 ;; LDS.L to FPSCR
10825 ;; Group: CO
10826 ;; Latency: 1 / 4
10827 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10828 ;; Issue Rate: 1
10829 ;; F1 is blocked for last three cycles.
10830
10831 (define_insn_reservation "fpscr_load_mem" 4
10832 (and (eq_attr "pipe_model" "sh4")
10833 (eq_attr "type" "mem_fpscr"))
10834 "d_lock,nothing,(F1+memory),F1*2")
10835
10836 \f
10837 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10838 ;; Group: CO
10839 ;; Latency: 4 / 4
10840 ;; Issue Rate: 1
10841
10842 (define_insn_reservation "multi" 4
10843 (and (eq_attr "pipe_model" "sh4")
10844 (eq_attr "type" "smpy,dmpy"))
10845 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10846
10847 ;; Fixed STS from MACL / MACH
10848 ;; Group: CO
10849 ;; Latency: 3
10850 ;; Issue Rate: 1
10851
10852 (define_insn_reservation "sh4_mac_gp" 3
10853 (and (eq_attr "pipe_model" "sh4")
10854 (eq_attr "type" "mac_gp"))
10855 "d_lock")
10856
10857
10858 ;; Single precision floating point computation FCMP/EQ,
10859 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10860 ;; Group: FE
10861 ;; Latency: 3/4
10862 ;; Issue Rate: 1
10863
10864 (define_insn_reservation "fp_arith" 3
10865 (and (eq_attr "pipe_model" "sh4")
10866 (eq_attr "type" "fp"))
10867 "issue,F01,F2")
10868
10869 (define_insn_reservation "fp_arith_ftrc" 3
10870 (and (eq_attr "pipe_model" "sh4")
10871 (eq_attr "type" "ftrc_s"))
10872 "issue,F01,F2")
10873
10874 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10875
10876 ;; Single Precision FDIV/SQRT
10877 ;; Group: FE
10878 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
10879 ;; Issue Rate: 1
10880 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10881
10882 (define_insn_reservation "fp_div" 12
10883 (and (eq_attr "pipe_model" "sh4")
10884 (eq_attr "type" "fdiv"))
10885 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10886
10887 ;; Double Precision floating point computation
10888 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10889 ;; Group: FE
10890 ;; Latency: (3,4)/5
10891 ;; Issue Rate: 1
10892
10893 (define_insn_reservation "dp_float" 4
10894 (and (eq_attr "pipe_model" "sh4")
10895 (eq_attr "type" "dfp_conv"))
10896 "issue,F01,F1+F2,F2")
10897
10898 ;; Double-precision floating-point (FADD,FMUL,FSUB)
10899 ;; Group: FE
10900 ;; Latency: (7,8)/9
10901 ;; Issue Rate: 1
10902
10903 (define_insn_reservation "fp_double_arith" 8
10904 (and (eq_attr "pipe_model" "sh4")
10905 (eq_attr "type" "dfp_arith"))
10906 "issue,F01,F1+F2,fpu*4,F2")
10907
10908 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10909 ;; Group: CO
10910 ;; Latency: 3/5
10911 ;; Issue Rate: 2
10912
10913 (define_insn_reservation "fp_double_cmp" 3
10914 (and (eq_attr "pipe_model" "sh4")
10915 (eq_attr "type" "dfp_cmp"))
10916 "d_lock,(d_lock+F01),F1+F2,F2")
10917
10918 ;; Double precision FDIV/SQRT
10919 ;; Group: FE
10920 ;; Latency: (24,25)/26
10921 ;; Issue Rate: 1
10922
10923 (define_insn_reservation "dp_div" 25
10924 (and (eq_attr "pipe_model" "sh4")
10925 (eq_attr "type" "dfdiv"))
10926 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10927
10928
10929 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10930 ;; case, we'd get a d_lock instead of issue at the end.
10931 (define_insn_reservation "arith3" 3
10932 (and (eq_attr "pipe_model" "sh4")
10933 (eq_attr "type" "arith3"))
10934 "issue,d_lock+pcr_addrcalc,issue")
10935
10936 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10937 (define_insn_reservation "arith3b" 2
10938 (and (eq_attr "pipe_model" "sh4")
10939 (eq_attr "type" "arith3"))
10940 "issue,d_lock+pcr_addrcalc")