Introduce sh2a support.
[gcc.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
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 (UNSPEC_TLSGD 20)
140 (UNSPEC_TLSLDM 21)
141 (UNSPEC_TLSIE 22)
142 (UNSPEC_DTPOFF 23)
143 (UNSPEC_GOTTPOFF 24)
144 (UNSPEC_TPOFF 25)
145 (UNSPEC_RA 26)
146
147 ;; These are used with unspec_volatile.
148 (UNSPECV_BLOCKAGE 0)
149 (UNSPECV_ALIGN 1)
150 (UNSPECV_CONST2 2)
151 (UNSPECV_CONST4 4)
152 (UNSPECV_CONST8 6)
153 (UNSPECV_WINDOW_END 10)
154 (UNSPECV_CONST_END 11)
155 ])
156
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
160
161 ;; Target CPU.
162
163 (define_attr "cpu"
164 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165 (const (symbol_ref "sh_cpu_attr")))
166
167 (define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
170
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
175
176 (define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181 (const
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
185
186 ;; cbranch conditional branch instructions
187 ;; jump unconditional jumps
188 ;; arith ordinary arithmetic
189 ;; arith3 a compound insn that behaves similarly to a sequence of
190 ;; three insns of type arith
191 ;; arith3b like above, but might end with a redirected branch
192 ;; load from memory
193 ;; load_si Likewise, SImode variant for general register.
194 ;; fload Likewise, but load to fp register.
195 ;; store to memory
196 ;; move general purpose register to register
197 ;; mt_group other sh4 mt instructions
198 ;; fmove register to register, floating point
199 ;; smpy word precision integer multiply
200 ;; dmpy longword or doublelongword precision integer multiply
201 ;; return rts
202 ;; pload load of pr reg, which can't be put into delay slot of rts
203 ;; prset copy register to pr reg, ditto
204 ;; pstore store of pr reg, which can't be put into delay slot of jsr
205 ;; prget copy pr to register, ditto
206 ;; pcload pc relative load of constant value
207 ;; pcfload Likewise, but load to fp register.
208 ;; pcload_si Likewise, SImode variant for general register.
209 ;; rte return from exception
210 ;; sfunc special function call with known used registers
211 ;; call function call
212 ;; fp floating point
213 ;; fdiv floating point divide (or square root)
214 ;; gp_fpul move from general purpose register to fpul
215 ;; fpul_gp move from fpul to general purpose register
216 ;; mac_gp move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s fix_truncsfsi2_i4
219 ;; dfdiv double precision floating point divide (or square root)
220 ;; cwb ic_invalidate_line_i
221 ;; movua SH4a unaligned load
222 ;; fsrra square root reciprocal approximate
223 ;; fsca sine and cosine approximate
224 ;; tls_load load TLS related address
225 ;; arith_media SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media SHmedia compare instructions
228 ;; dfdiv_media SHmedia double precision divide and square root
229 ;; dfmul_media SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media SHmedia longword multiply
233 ;; fcmp_media SHmedia floating point compare instructions
234 ;; fdiv_media SHmedia single precision divide and square root
235 ;; fload_media SHmedia floating point register load instructions
236 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media SHmedia unconditional branch instructions
243 ;; load_media SHmedia general register load instructions
244 ;; pt_media SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media SHmedia ptabs instruction
246 ;; store_media SHmedia general register store instructions
247 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media SHmedia mac-style fixed point operations
249 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
250 ;; atrans SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil no-op move, will be deleted.
253
254 (define_attr "type"
255 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
256 (const_string "other"))
257
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
260 ;;
261 ;; mt_group SH4 "mt" group instructions.
262 ;;
263 ;; ex_group SH4 "ex" group instructions.
264 ;;
265 ;; ls_group SH4 "ls" group instructions.
266 ;;
267
268 (define_attr "insn_class"
269 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273 (eq_attr "type" "cbranch,jump") (const_string "br_group")
274 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275 (const_string "fe_group")
276 (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")]
277 (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
281
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
283
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
285
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
293
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long. Something in the
296 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
300
301 ;; The maximum range used for SImode constant pool entries is 1018. A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table. That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
313 ;;
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
316
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321 (const_string "no")
322 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323 (const_string "yes")
324 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325 (const_string "no")
326 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327 (const_string "yes")
328 ] (const_string "no")))
329
330 (define_attr "med_branch_p" "no,yes"
331 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332 (const_int 1988))
333 (const_string "yes")
334 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335 (const_string "no")
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337 (const_int 8186))
338 (const_string "yes")
339 ] (const_string "no")))
340
341 (define_attr "med_cbranch_p" "no,yes"
342 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343 (const_int 1986))
344 (const_string "yes")
345 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346 (const_string "no")
347 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348 (const_int 8184))
349 (const_string "yes")
350 ] (const_string "no")))
351
352 (define_attr "braf_branch_p" "no,yes"
353 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354 (const_string "no")
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356 (const_int 20660))
357 (const_string "yes")
358 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359 (const_string "no")
360 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361 (const_int 65530))
362 (const_string "yes")
363 ] (const_string "no")))
364
365 (define_attr "braf_cbranch_p" "no,yes"
366 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367 (const_string "no")
368 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369 (const_int 20658))
370 (const_string "yes")
371 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372 (const_string "no")
373 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374 (const_int 65528))
375 (const_string "yes")
376 ] (const_string "no")))
377
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
384
385 ; All other instructions are two bytes long by default.
386
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390 (cond [(eq_attr "type" "cbranch")
391 (cond [(eq_attr "short_cbranch_p" "yes")
392 (const_int 2)
393 (eq_attr "med_cbranch_p" "yes")
394 (const_int 6)
395 (eq_attr "braf_cbranch_p" "yes")
396 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398 (ne (match_dup 0) (match_dup 0))
399 (const_int 14)
400 (ne (symbol_ref ("flag_pic")) (const_int 0))
401 (const_int 24)
402 ] (const_int 16))
403 (eq_attr "type" "jump")
404 (cond [(eq_attr "med_branch_p" "yes")
405 (const_int 2)
406 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407 (symbol_ref "INSN"))
408 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409 (symbol_ref "code_for_indirect_jump_scratch")))
410 (if_then_else (eq_attr "braf_branch_p" "yes")
411 (const_int 6)
412 (const_int 10))
413 (eq_attr "braf_branch_p" "yes")
414 (const_int 10)
415 ;; ??? using pc is not computed transitively.
416 (ne (match_dup 0) (match_dup 0))
417 (const_int 12)
418 (ne (symbol_ref ("flag_pic")) (const_int 0))
419 (const_int 22)
420 ] (const_int 14))
421 (eq_attr "type" "pt_media")
422 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
423 (const_int 20) (const_int 12))
424 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
425 (const_int 4)
426 (const_int 2))))
427
428 ;; DFA descriptions for the pipelines
429
430 (include "sh1.md")
431 (include "shmedia.md")
432 (include "sh4.md")
433
434 ;; Definitions for filling delay slots
435
436 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
437
438 ;; ??? This should be (nil) instead of (const_int 0)
439 (define_attr "hit_stack" "yes,no"
440 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
441 (const_int 0))
442 (const_string "no")]
443 (const_string "yes")))
444
445 (define_attr "interrupt_function" "no,yes"
446 (const (symbol_ref "current_function_interrupt")))
447
448 (define_attr "in_delay_slot" "yes,no"
449 (cond [(eq_attr "type" "cbranch") (const_string "no")
450 (eq_attr "type" "pcload,pcload_si") (const_string "no")
451 (eq_attr "needs_delay_slot" "yes") (const_string "no")
452 (eq_attr "length" "2") (const_string "yes")
453 ] (const_string "no")))
454
455 (define_attr "cond_delay_slot" "yes,no"
456 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
457 ] (const_string "no")))
458
459 (define_attr "is_sfunc" ""
460 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
461
462 (define_attr "is_mac_media" ""
463 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
464
465 (define_attr "branch_zero" "yes,no"
466 (cond [(eq_attr "type" "!cbranch") (const_string "no")
467 (ne (symbol_ref "(next_active_insn (insn)\
468 == (prev_active_insn\
469 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
470 && get_attr_length (next_active_insn (insn)) == 2")
471 (const_int 0))
472 (const_string "yes")]
473 (const_string "no")))
474
475 ;; SH4 Double-precision computation with double-precision result -
476 ;; the two halves are ready at different times.
477 (define_attr "dfp_comp" "yes,no"
478 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
479 (const_string "no")))
480
481 ;; Insns for which the latency of a preceding fp insn is decreased by one.
482 (define_attr "late_fp_use" "yes,no" (const_string "no"))
483 ;; And feeding insns for which this relevant.
484 (define_attr "any_fp_comp" "yes,no"
485 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
486 (const_string "yes")]
487 (const_string "no")))
488
489 (define_attr "any_int_load" "yes,no"
490 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
491 (const_string "yes")]
492 (const_string "no")))
493
494 (define_delay
495 (eq_attr "needs_delay_slot" "yes")
496 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
497
498 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
499 ;; and thus we can't put a pop instruction in its delay slot.
500 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
501 ;; instruction can go in the delay slot.
502
503 ;; Since a normal return (rts) implicitly uses the PR register,
504 ;; we can't allow PR register loads in an rts delay slot.
505
506 (define_delay
507 (eq_attr "type" "return")
508 [(and (eq_attr "in_delay_slot" "yes")
509 (ior (and (eq_attr "interrupt_function" "no")
510 (eq_attr "type" "!pload,prset"))
511 (and (eq_attr "interrupt_function" "yes")
512 (ior
513 (ne (symbol_ref "TARGET_SH3") (const_int 0))
514 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
515
516 ;; Since a call implicitly uses the PR register, we can't allow
517 ;; a PR register store in a jsr delay slot.
518
519 (define_delay
520 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
521 [(and (eq_attr "in_delay_slot" "yes")
522 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
523
524 ;; Say that we have annulled true branches, since this gives smaller and
525 ;; faster code when branches are predicted as not taken.
526
527 (define_delay
528 (and (eq_attr "type" "cbranch")
529 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
530 ;; SH2e has a hardware bug that pretty much prohibits the use of
531 ;; annuled delay slots.
532 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
533 (not (eq_attr "cpu" "sh2e"))) (nil)])
534 \f
535 ;; -------------------------------------------------------------------------
536 ;; SImode signed integer comparisons
537 ;; -------------------------------------------------------------------------
538
539 (define_insn ""
540 [(set (reg:SI T_REG)
541 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
542 (match_operand:SI 1 "arith_operand" "K08,r"))
543 (const_int 0)))]
544 "TARGET_SH1"
545 "tst %1,%0"
546 [(set_attr "type" "mt_group")])
547
548 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
549 ;; That would still allow reload to create cmpi instructions, but would
550 ;; perhaps allow forcing the constant into a register when that is better.
551 ;; Probably should use r0 for mem/imm compares, but force constant into a
552 ;; register for pseudo/imm compares.
553
554 (define_insn "cmpeqsi_t"
555 [(set (reg:SI T_REG)
556 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
557 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
558 "TARGET_SH1"
559 "@
560 tst %0,%0
561 cmp/eq %1,%0
562 cmp/eq %1,%0"
563 [(set_attr "type" "mt_group")])
564
565 (define_insn "cmpgtsi_t"
566 [(set (reg:SI T_REG)
567 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
568 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
569 "TARGET_SH1"
570 "@
571 cmp/gt %1,%0
572 cmp/pl %0"
573 [(set_attr "type" "mt_group")])
574
575 (define_insn "cmpgesi_t"
576 [(set (reg:SI T_REG)
577 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
578 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
579 "TARGET_SH1"
580 "@
581 cmp/ge %1,%0
582 cmp/pz %0"
583 [(set_attr "type" "mt_group")])
584
585 ;; -------------------------------------------------------------------------
586 ;; SImode unsigned integer comparisons
587 ;; -------------------------------------------------------------------------
588
589 (define_insn "cmpgeusi_t"
590 [(set (reg:SI T_REG)
591 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
592 (match_operand:SI 1 "arith_reg_operand" "r")))]
593 "TARGET_SH1"
594 "cmp/hs %1,%0"
595 [(set_attr "type" "mt_group")])
596
597 (define_insn "cmpgtusi_t"
598 [(set (reg:SI T_REG)
599 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
600 (match_operand:SI 1 "arith_reg_operand" "r")))]
601 "TARGET_SH1"
602 "cmp/hi %1,%0"
603 [(set_attr "type" "mt_group")])
604
605 ;; We save the compare operands in the cmpxx patterns and use them when
606 ;; we generate the branch.
607
608 (define_expand "cmpsi"
609 [(set (reg:SI T_REG)
610 (compare (match_operand:SI 0 "cmpsi_operand" "")
611 (match_operand:SI 1 "arith_operand" "")))]
612 "TARGET_SH1"
613 "
614 {
615 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
616 && GET_CODE (operands[1]) != CONST_INT)
617 operands[0] = copy_to_mode_reg (SImode, operands[0]);
618 sh_compare_op0 = operands[0];
619 sh_compare_op1 = operands[1];
620 DONE;
621 }")
622 \f
623 ;; -------------------------------------------------------------------------
624 ;; DImode signed integer comparisons
625 ;; -------------------------------------------------------------------------
626
627 ;; ??? Could get better scheduling by splitting the initial test from the
628 ;; rest of the insn after reload. However, the gain would hardly justify
629 ;; the sh.md size increase necessary to do that.
630
631 (define_insn ""
632 [(set (reg:SI T_REG)
633 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
634 (match_operand:DI 1 "arith_operand" "r"))
635 (const_int 0)))]
636 "TARGET_SH1"
637 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
638 insn, operands);"
639 [(set_attr "length" "6")
640 (set_attr "type" "arith3b")])
641
642 (define_insn "cmpeqdi_t"
643 [(set (reg:SI T_REG)
644 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
645 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
646 "TARGET_SH1"
647 "@
648 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
649 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
650 [(set_attr "length" "6")
651 (set_attr "type" "arith3b")])
652
653 (define_split
654 [(set (reg:SI T_REG)
655 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
656 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
657 ;; If we applied this split when not optimizing, it would only be
658 ;; applied during the machine-dependent reorg, when no new basic blocks
659 ;; may be created.
660 "TARGET_SH1 && reload_completed && optimize"
661 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
662 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
663 (label_ref (match_dup 6))
664 (pc)))
665 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
666 (match_dup 6)]
667 "
668 {
669 operands[2]
670 = gen_rtx_REG (SImode,
671 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
672 operands[3]
673 = (operands[1] == const0_rtx
674 ? const0_rtx
675 : gen_rtx_REG (SImode,
676 true_regnum (operands[1])
677 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
678 operands[4] = gen_lowpart (SImode, operands[0]);
679 operands[5] = gen_lowpart (SImode, operands[1]);
680 operands[6] = gen_label_rtx ();
681 }")
682
683 (define_insn "cmpgtdi_t"
684 [(set (reg:SI T_REG)
685 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
686 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
687 "TARGET_SH2"
688 "@
689 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
690 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
691 [(set_attr "length" "8")
692 (set_attr "type" "arith3")])
693
694 (define_insn "cmpgedi_t"
695 [(set (reg:SI T_REG)
696 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
697 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
698 "TARGET_SH2"
699 "@
700 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
701 cmp/pz\\t%S0"
702 [(set_attr "length" "8,2")
703 (set_attr "type" "arith3,mt_group")])
704 \f
705 ;; -------------------------------------------------------------------------
706 ;; DImode unsigned integer comparisons
707 ;; -------------------------------------------------------------------------
708
709 (define_insn "cmpgeudi_t"
710 [(set (reg:SI T_REG)
711 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
712 (match_operand:DI 1 "arith_reg_operand" "r")))]
713 "TARGET_SH2"
714 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
715 [(set_attr "length" "8")
716 (set_attr "type" "arith3")])
717
718 (define_insn "cmpgtudi_t"
719 [(set (reg:SI T_REG)
720 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
721 (match_operand:DI 1 "arith_reg_operand" "r")))]
722 "TARGET_SH2"
723 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
724 [(set_attr "length" "8")
725 (set_attr "type" "arith3")])
726
727 (define_insn "cmpeqdi_media"
728 [(set (match_operand:DI 0 "register_operand" "=r")
729 (eq:DI (match_operand:DI 1 "register_operand" "%r")
730 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
731 "TARGET_SHMEDIA"
732 "cmpeq %1, %N2, %0"
733 [(set_attr "type" "cmp_media")])
734
735 (define_insn "cmpgtdi_media"
736 [(set (match_operand:DI 0 "register_operand" "=r")
737 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
738 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
739 "TARGET_SHMEDIA"
740 "cmpgt %N1, %N2, %0"
741 [(set_attr "type" "cmp_media")])
742
743 (define_insn "cmpgtudi_media"
744 [(set (match_operand:DI 0 "register_operand" "=r")
745 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
746 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
747 "TARGET_SHMEDIA"
748 "cmpgtu %N1, %N2, %0"
749 [(set_attr "type" "cmp_media")])
750
751 ;; We save the compare operands in the cmpxx patterns and use them when
752 ;; we generate the branch.
753
754 (define_expand "cmpdi"
755 [(set (reg:SI T_REG)
756 (compare (match_operand:DI 0 "arith_operand" "")
757 (match_operand:DI 1 "arith_operand" "")))]
758 "TARGET_SH2 || TARGET_SHMEDIA"
759 "
760 {
761 sh_compare_op0 = operands[0];
762 sh_compare_op1 = operands[1];
763 DONE;
764 }")
765 ;; -------------------------------------------------------------------------
766 ;; Conditional move instructions
767 ;; -------------------------------------------------------------------------
768
769 ;; The insn names may seem reversed, but note that cmveq performs the move
770 ;; if op1 == 0, and cmvne does it if op1 != 0.
771
772 (define_insn "movdicc_false"
773 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
774 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
775 (const_int 0))
776 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
777 (match_operand:DI 3 "arith_reg_operand" "0")))]
778 "TARGET_SHMEDIA"
779 "cmveq %1, %N2, %0"
780 [(set_attr "type" "arith_media")])
781
782 (define_insn "movdicc_true"
783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
784 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
785 (const_int 0))
786 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
787 (match_operand:DI 3 "arith_reg_operand" "0")))]
788 "TARGET_SHMEDIA"
789 "cmvne %1, %N2, %0"
790 [(set_attr "type" "arith_media")])
791
792 (define_expand "movdicc"
793 [(set (match_operand:DI 0 "register_operand" "")
794 (if_then_else:DI (match_operand 1 "comparison_operator" "")
795 (match_operand:DI 2 "register_operand" "")
796 (match_operand:DI 3 "register_operand" "")))]
797 "TARGET_SHMEDIA"
798 "
799 {
800 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
801 && GET_MODE (sh_compare_op0) == DImode
802 && sh_compare_op1 == const0_rtx)
803 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
804 sh_compare_op0, sh_compare_op1);
805 else
806 {
807 rtx tmp;
808
809 if (no_new_pseudos)
810 FAIL;
811
812 tmp = gen_reg_rtx (DImode);
813
814 switch (GET_CODE (operands[1]))
815 {
816 case EQ:
817 emit_insn (gen_seq (tmp));
818 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
819 break;
820
821 case NE:
822 emit_insn (gen_seq (tmp));
823 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
824 break;
825
826 case GT:
827 emit_insn (gen_sgt (tmp));
828 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
829 break;
830
831 case LT:
832 emit_insn (gen_slt (tmp));
833 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
834 break;
835
836 case GE:
837 emit_insn (gen_slt (tmp));
838 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
839 break;
840
841 case LE:
842 emit_insn (gen_sgt (tmp));
843 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
844 break;
845
846 case GTU:
847 emit_insn (gen_sgtu (tmp));
848 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
849 break;
850
851 case LTU:
852 emit_insn (gen_sltu (tmp));
853 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
854 break;
855
856 case GEU:
857 emit_insn (gen_sltu (tmp));
858 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
859 break;
860
861 case LEU:
862 emit_insn (gen_sgtu (tmp));
863 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
864 break;
865
866 case UNORDERED:
867 emit_insn (gen_sunordered (tmp));
868 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
869 break;
870
871 case ORDERED:
872 emit_insn (gen_sunordered (tmp));
873 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
874 break;
875
876 case UNEQ:
877 case UNGE:
878 case UNGT:
879 case UNLE:
880 case UNLT:
881 case LTGT:
882 FAIL;
883
884 default:
885 abort ();
886 }
887 }
888 }")
889 \f
890 ;; -------------------------------------------------------------------------
891 ;; Addition instructions
892 ;; -------------------------------------------------------------------------
893
894 (define_expand "adddi3"
895 [(set (match_operand:DI 0 "arith_reg_operand" "")
896 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
897 (match_operand:DI 2 "arith_operand" "")))]
898 ""
899 "
900 {
901 if (TARGET_SH1)
902 {
903 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
904 FAIL;
905 operands[2] = force_reg (DImode, operands[2]);
906 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
907 DONE;
908 }
909 }")
910
911 (define_insn "*adddi3_media"
912 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
913 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
914 (match_operand:DI 2 "arith_operand" "r,I10")))]
915 "TARGET_SHMEDIA"
916 "@
917 add %1, %2, %0
918 addi %1, %2, %0"
919 [(set_attr "type" "arith_media")])
920
921 (define_insn "adddi3z_media"
922 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
923 (zero_extend:DI
924 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
925 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
926 "TARGET_SHMEDIA"
927 "addz.l %1, %N2, %0"
928 [(set_attr "type" "arith_media")])
929
930 (define_insn "adddi3_compact"
931 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
932 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
933 (match_operand:DI 2 "arith_reg_operand" "r")))
934 (clobber (reg:SI T_REG))]
935 "TARGET_SH1"
936 "#"
937 [(set_attr "length" "6")])
938
939 (define_split
940 [(set (match_operand:DI 0 "arith_reg_operand" "")
941 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
942 (match_operand:DI 2 "arith_reg_operand" "")))
943 (clobber (reg:SI T_REG))]
944 "TARGET_SH1 && reload_completed"
945 [(const_int 0)]
946 "
947 {
948 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
949 high0 = gen_rtx_REG (SImode,
950 true_regnum (operands[0])
951 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
952 high2 = gen_rtx_REG (SImode,
953 true_regnum (operands[2])
954 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
955 emit_insn (gen_clrt ());
956 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
957 emit_insn (gen_addc1 (high0, high0, high2));
958 DONE;
959 }")
960
961 (define_insn "addc"
962 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
963 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
964 (match_operand:SI 2 "arith_reg_operand" "r"))
965 (reg:SI T_REG)))
966 (set (reg:SI T_REG)
967 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
968 "TARGET_SH1"
969 "addc %2,%0"
970 [(set_attr "type" "arith")])
971
972 (define_insn "addc1"
973 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
974 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
975 (match_operand:SI 2 "arith_reg_operand" "r"))
976 (reg:SI T_REG)))
977 (clobber (reg:SI T_REG))]
978 "TARGET_SH1"
979 "addc %2,%0"
980 [(set_attr "type" "arith")])
981
982 (define_expand "addsi3"
983 [(set (match_operand:SI 0 "arith_reg_operand" "")
984 (plus:SI (match_operand:SI 1 "arith_operand" "")
985 (match_operand:SI 2 "arith_operand" "")))]
986 ""
987 "
988 {
989 if (TARGET_SHMEDIA)
990 operands[1] = force_reg (SImode, operands[1]);
991 }")
992
993 (define_insn "addsi3_media"
994 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
995 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
996 (match_operand:SI 2 "arith_operand" "r,I10")))]
997 "TARGET_SHMEDIA"
998 "@
999 add.l %1, %2, %0
1000 addi.l %1, %2, %0"
1001 [(set_attr "type" "arith_media")])
1002
1003 (define_insn "*addsi3_compact"
1004 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1005 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1006 (match_operand:SI 2 "arith_operand" "rI08")))]
1007 "TARGET_SH1"
1008 "add %2,%0"
1009 [(set_attr "type" "arith")])
1010
1011 ;; -------------------------------------------------------------------------
1012 ;; Subtraction instructions
1013 ;; -------------------------------------------------------------------------
1014
1015 (define_expand "subdi3"
1016 [(set (match_operand:DI 0 "arith_reg_operand" "")
1017 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1018 (match_operand:DI 2 "arith_reg_operand" "")))]
1019 ""
1020 "
1021 {
1022 if (TARGET_SH1)
1023 {
1024 operands[1] = force_reg (DImode, operands[1]);
1025 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1026 DONE;
1027 }
1028 }")
1029
1030 (define_insn "*subdi3_media"
1031 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1032 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1033 (match_operand:DI 2 "arith_reg_operand" "r")))]
1034 "TARGET_SHMEDIA"
1035 "sub %N1, %2, %0"
1036 [(set_attr "type" "arith_media")])
1037
1038 (define_insn "subdi3_compact"
1039 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1040 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1041 (match_operand:DI 2 "arith_reg_operand" "r")))
1042 (clobber (reg:SI T_REG))]
1043 "TARGET_SH1"
1044 "#"
1045 [(set_attr "length" "6")])
1046
1047 (define_split
1048 [(set (match_operand:DI 0 "arith_reg_operand" "")
1049 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1050 (match_operand:DI 2 "arith_reg_operand" "")))
1051 (clobber (reg:SI T_REG))]
1052 "TARGET_SH1 && reload_completed"
1053 [(const_int 0)]
1054 "
1055 {
1056 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1057 high0 = gen_rtx_REG (SImode,
1058 true_regnum (operands[0])
1059 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1060 high2 = gen_rtx_REG (SImode,
1061 true_regnum (operands[2])
1062 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1063 emit_insn (gen_clrt ());
1064 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1065 emit_insn (gen_subc1 (high0, high0, high2));
1066 DONE;
1067 }")
1068
1069 (define_insn "subc"
1070 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1071 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1072 (match_operand:SI 2 "arith_reg_operand" "r"))
1073 (reg:SI T_REG)))
1074 (set (reg:SI T_REG)
1075 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1076 (reg:SI T_REG))
1077 (match_dup 1)))]
1078 "TARGET_SH1"
1079 "subc %2,%0"
1080 [(set_attr "type" "arith")])
1081
1082 (define_insn "subc1"
1083 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1084 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1085 (match_operand:SI 2 "arith_reg_operand" "r"))
1086 (reg:SI T_REG)))
1087 (clobber (reg:SI T_REG))]
1088 "TARGET_SH1"
1089 "subc %2,%0"
1090 [(set_attr "type" "arith")])
1091
1092 (define_insn "*subsi3_internal"
1093 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1094 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1095 (match_operand:SI 2 "arith_reg_operand" "r")))]
1096 "TARGET_SH1"
1097 "sub %2,%0"
1098 [(set_attr "type" "arith")])
1099
1100 (define_insn "*subsi3_media"
1101 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1102 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1103 (match_operand:SI 2 "extend_reg_operand" "r")))]
1104 "TARGET_SHMEDIA"
1105 "sub.l %N1, %2, %0"
1106 [(set_attr "type" "arith_media")])
1107
1108 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1109 ;; will sometimes save one instruction. Otherwise we might get
1110 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1111 ;; are the same.
1112
1113 (define_expand "subsi3"
1114 [(set (match_operand:SI 0 "arith_reg_operand" "")
1115 (minus:SI (match_operand:SI 1 "arith_operand" "")
1116 (match_operand:SI 2 "arith_reg_operand" "")))]
1117 ""
1118 "
1119 {
1120 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1121 {
1122 emit_insn (gen_negsi2 (operands[0], operands[2]));
1123 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1124 DONE;
1125 }
1126 if (TARGET_SHMEDIA)
1127 {
1128 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1129 FAIL;
1130 if (operands[1] != const0_rtx)
1131 operands[1] = force_reg (SImode, operands[1]);
1132 }
1133 }")
1134 \f
1135 ;; -------------------------------------------------------------------------
1136 ;; Division instructions
1137 ;; -------------------------------------------------------------------------
1138
1139 ;; We take advantage of the library routines which don't clobber as many
1140 ;; registers as a normal function call would.
1141
1142 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1143 ;; also has an effect on the register that holds the address of the sfunc.
1144 ;; To make this work, we have an extra dummy insn that shows the use
1145 ;; of this register for reorg.
1146
1147 (define_insn "use_sfunc_addr"
1148 [(set (reg:SI PR_REG)
1149 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1150 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1151 ""
1152 [(set_attr "length" "0")])
1153
1154 (define_insn "udivsi3_sh2a"
1155 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1156 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1157 (match_operand:SI 2 "arith_reg_operand" "z")))]
1158 "TARGET_SH2A"
1159 "divu %2,%1"
1160 [(set_attr "type" "arith")])
1161
1162 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1163 ;; hard register 0. If we used hard register 0, then the next instruction
1164 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1165 ;; gets allocated to a stack slot that needs its address reloaded, then
1166 ;; there is nothing to prevent reload from using r0 to reload the address.
1167 ;; This reload would clobber the value in r0 we are trying to store.
1168 ;; If we let reload allocate r0, then this problem can never happen.
1169
1170 (define_insn "udivsi3_i1"
1171 [(set (match_operand:SI 0 "register_operand" "=z")
1172 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1173 (clobber (reg:SI T_REG))
1174 (clobber (reg:SI PR_REG))
1175 (clobber (reg:SI R4_REG))
1176 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1177 "TARGET_SH1 && ! TARGET_SH4"
1178 "jsr @%1%#"
1179 [(set_attr "type" "sfunc")
1180 (set_attr "needs_delay_slot" "yes")])
1181
1182 ; Since shmedia-nofpu code could be linked against shcompact code, and
1183 ; the udivsi3 libcall has the same name, we must consider all registers
1184 ; clobbered that are in the union of the registers clobbered by the
1185 ; shmedia and the shcompact implementation. Note, if the shcompact
1186 ; implementation actually used shcompact code, we'd need to clobber
1187 ; also r23 and fr23.
1188 (define_insn "udivsi3_i1_media"
1189 [(set (match_operand:SI 0 "register_operand" "=z")
1190 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1191 (clobber (reg:SI T_MEDIA_REG))
1192 (clobber (reg:SI PR_MEDIA_REG))
1193 (clobber (reg:SI R20_REG))
1194 (clobber (reg:SI R21_REG))
1195 (clobber (reg:SI R22_REG))
1196 (clobber (reg:DI TR0_REG))
1197 (clobber (reg:DI TR1_REG))
1198 (clobber (reg:DI TR2_REG))
1199 (use (match_operand:DI 1 "target_operand" "b"))]
1200 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1201 "blink %1, r18"
1202 [(set_attr "type" "sfunc")
1203 (set_attr "needs_delay_slot" "yes")])
1204
1205 (define_expand "udivsi3_i4_media"
1206 [(set (match_dup 3)
1207 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1208 (set (match_dup 4)
1209 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1210 (set (match_dup 5) (float:DF (match_dup 3)))
1211 (set (match_dup 6) (float:DF (match_dup 4)))
1212 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1213 (set (match_dup 8) (fix:DI (match_dup 7)))
1214 (set (match_operand:SI 0 "register_operand" "")
1215 (truncate:SI (match_dup 8)))]
1216 "TARGET_SHMEDIA_FPU"
1217 "
1218 {
1219 operands[3] = gen_reg_rtx (DImode);
1220 operands[4] = gen_reg_rtx (DImode);
1221 operands[5] = gen_reg_rtx (DFmode);
1222 operands[6] = gen_reg_rtx (DFmode);
1223 operands[7] = gen_reg_rtx (DFmode);
1224 operands[8] = gen_reg_rtx (DImode);
1225 }")
1226
1227 (define_insn "udivsi3_i4"
1228 [(set (match_operand:SI 0 "register_operand" "=y")
1229 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1230 (clobber (reg:SI T_REG))
1231 (clobber (reg:SI PR_REG))
1232 (clobber (reg:DF DR0_REG))
1233 (clobber (reg:DF DR2_REG))
1234 (clobber (reg:DF DR4_REG))
1235 (clobber (reg:SI R0_REG))
1236 (clobber (reg:SI R1_REG))
1237 (clobber (reg:SI R4_REG))
1238 (clobber (reg:SI R5_REG))
1239 (use (reg:PSI FPSCR_REG))
1240 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1241 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1242 "jsr @%1%#"
1243 [(set_attr "type" "sfunc")
1244 (set_attr "fp_mode" "double")
1245 (set_attr "needs_delay_slot" "yes")])
1246
1247 (define_insn "udivsi3_i4_single"
1248 [(set (match_operand:SI 0 "register_operand" "=y")
1249 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1250 (clobber (reg:SI T_REG))
1251 (clobber (reg:SI PR_REG))
1252 (clobber (reg:DF DR0_REG))
1253 (clobber (reg:DF DR2_REG))
1254 (clobber (reg:DF DR4_REG))
1255 (clobber (reg:SI R0_REG))
1256 (clobber (reg:SI R1_REG))
1257 (clobber (reg:SI R4_REG))
1258 (clobber (reg:SI R5_REG))
1259 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1260 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1261 "jsr @%1%#"
1262 [(set_attr "type" "sfunc")
1263 (set_attr "needs_delay_slot" "yes")])
1264
1265 (define_expand "udivsi3"
1266 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1267 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1268 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1269 (parallel [(set (match_operand:SI 0 "register_operand" "")
1270 (udiv:SI (reg:SI R4_REG)
1271 (reg:SI R5_REG)))
1272 (clobber (reg:SI T_REG))
1273 (clobber (reg:SI PR_REG))
1274 (clobber (reg:SI R4_REG))
1275 (use (match_dup 3))])]
1276 ""
1277 "
1278 {
1279 rtx first, last;
1280
1281 operands[3] = gen_reg_rtx (Pmode);
1282 /* Emit the move of the address to a pseudo outside of the libcall. */
1283 if (TARGET_HARD_SH4 && TARGET_SH2E)
1284 {
1285 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1286 if (TARGET_FPU_SINGLE)
1287 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1288 else
1289 last = gen_udivsi3_i4 (operands[0], operands[3]);
1290 }
1291 else if (TARGET_SHMEDIA_FPU)
1292 {
1293 operands[1] = force_reg (SImode, operands[1]);
1294 operands[2] = force_reg (SImode, operands[2]);
1295 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1296 DONE;
1297 }
1298 else if (TARGET_SH2A)
1299 {
1300 operands[1] = force_reg (SImode, operands[1]);
1301 operands[2] = force_reg (SImode, operands[2]);
1302 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1303 DONE;
1304 }
1305 else if (TARGET_SH5)
1306 {
1307 emit_move_insn (operands[3],
1308 function_symbol (TARGET_FPU_ANY
1309 ? \"__udivsi3_i4\"
1310 : \"__udivsi3\"));
1311
1312 if (TARGET_SHMEDIA)
1313 last = gen_udivsi3_i1_media (operands[0],
1314 Pmode == DImode
1315 ? operands[3]
1316 : gen_rtx_SUBREG (DImode, operands[3],
1317 0));
1318 else if (TARGET_FPU_ANY)
1319 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1320 else
1321 last = gen_udivsi3_i1 (operands[0], operands[3]);
1322 }
1323 else
1324 {
1325 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1326 last = gen_udivsi3_i1 (operands[0], operands[3]);
1327 }
1328 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1329 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1330 last = emit_insn (last);
1331 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1332 invariant code motion can move it. */
1333 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1334 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1335 DONE;
1336 }")
1337
1338 (define_insn "divsi3_sh2a"
1339 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1340 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1341 (match_operand:SI 2 "arith_reg_operand" "z")))]
1342 "TARGET_SH2A"
1343 "divs %2,%1"
1344 [(set_attr "type" "arith")])
1345
1346 (define_insn "divsi3_i1"
1347 [(set (match_operand:SI 0 "register_operand" "=z")
1348 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1349 (clobber (reg:SI T_REG))
1350 (clobber (reg:SI PR_REG))
1351 (clobber (reg:SI R1_REG))
1352 (clobber (reg:SI R2_REG))
1353 (clobber (reg:SI R3_REG))
1354 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1355 "TARGET_SH1 && ! TARGET_SH4"
1356 "jsr @%1%#"
1357 [(set_attr "type" "sfunc")
1358 (set_attr "needs_delay_slot" "yes")])
1359
1360 ; Since shmedia-nofpu code could be linked against shcompact code, and
1361 ; the sdivsi3 libcall has the same name, we must consider all registers
1362 ; clobbered that are in the union of the registers clobbered by the
1363 ; shmedia and the shcompact implementation. Note, if the shcompact
1364 ; implementation actually used shcompact code, we'd need to clobber
1365 ; also r22, r23 and fr23.
1366 (define_insn "divsi3_i1_media"
1367 [(set (match_operand:SI 0 "register_operand" "=z")
1368 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1369 (clobber (reg:SI T_MEDIA_REG))
1370 (clobber (reg:SI PR_MEDIA_REG))
1371 (clobber (reg:SI R1_REG))
1372 (clobber (reg:SI R2_REG))
1373 (clobber (reg:SI R3_REG))
1374 (clobber (reg:SI R20_REG))
1375 (clobber (reg:SI R21_REG))
1376 (clobber (reg:DI TR0_REG))
1377 (clobber (reg:DI TR1_REG))
1378 (clobber (reg:DI TR2_REG))
1379 (use (match_operand:DI 1 "target_operand" "b"))]
1380 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1381 "blink %1, r18"
1382 [(set_attr "type" "sfunc")])
1383
1384 (define_expand "divsi3_i4_media"
1385 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1386 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1387 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1388 (set (match_operand:SI 0 "register_operand" "=r")
1389 (fix:SI (match_dup 5)))]
1390 "TARGET_SHMEDIA_FPU"
1391 "
1392 {
1393 operands[3] = gen_reg_rtx (DFmode);
1394 operands[4] = gen_reg_rtx (DFmode);
1395 operands[5] = gen_reg_rtx (DFmode);
1396 }")
1397
1398 (define_insn "divsi3_i4"
1399 [(set (match_operand:SI 0 "register_operand" "=y")
1400 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1401 (clobber (reg:SI PR_REG))
1402 (clobber (reg:DF DR0_REG))
1403 (clobber (reg:DF DR2_REG))
1404 (use (reg:PSI FPSCR_REG))
1405 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1406 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1407 "jsr @%1%#"
1408 [(set_attr "type" "sfunc")
1409 (set_attr "fp_mode" "double")
1410 (set_attr "needs_delay_slot" "yes")])
1411
1412 (define_insn "divsi3_i4_single"
1413 [(set (match_operand:SI 0 "register_operand" "=y")
1414 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1415 (clobber (reg:SI PR_REG))
1416 (clobber (reg:DF DR0_REG))
1417 (clobber (reg:DF DR2_REG))
1418 (clobber (reg:SI R2_REG))
1419 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1420 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1421 "jsr @%1%#"
1422 [(set_attr "type" "sfunc")
1423 (set_attr "needs_delay_slot" "yes")])
1424
1425 (define_expand "divsi3"
1426 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1427 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1428 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1429 (parallel [(set (match_operand:SI 0 "register_operand" "")
1430 (div:SI (reg:SI R4_REG)
1431 (reg:SI R5_REG)))
1432 (clobber (reg:SI T_REG))
1433 (clobber (reg:SI PR_REG))
1434 (clobber (reg:SI R1_REG))
1435 (clobber (reg:SI R2_REG))
1436 (clobber (reg:SI R3_REG))
1437 (use (match_dup 3))])]
1438 ""
1439 "
1440 {
1441 rtx first, last;
1442
1443 operands[3] = gen_reg_rtx (Pmode);
1444 /* Emit the move of the address to a pseudo outside of the libcall. */
1445 if (TARGET_HARD_SH4 && TARGET_SH2E)
1446 {
1447 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1448 if (TARGET_FPU_SINGLE)
1449 last = gen_divsi3_i4_single (operands[0], operands[3]);
1450 else
1451 last = gen_divsi3_i4 (operands[0], operands[3]);
1452 }
1453 else if (TARGET_SH2A)
1454 {
1455 operands[1] = force_reg (SImode, operands[1]);
1456 operands[2] = force_reg (SImode, operands[2]);
1457 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1458 DONE;
1459 }
1460 else if (TARGET_SHMEDIA_FPU)
1461 {
1462 operands[1] = force_reg (SImode, operands[1]);
1463 operands[2] = force_reg (SImode, operands[2]);
1464 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1465 DONE;
1466 }
1467 else if (TARGET_SH5)
1468 {
1469 emit_move_insn (operands[3],
1470 function_symbol (TARGET_FPU_ANY
1471 ? \"__sdivsi3_i4\"
1472 : \"__sdivsi3\"));
1473
1474 if (TARGET_SHMEDIA)
1475 last = gen_divsi3_i1_media (operands[0],
1476 Pmode == DImode
1477 ? operands[3]
1478 : gen_rtx_SUBREG (DImode, operands[3],
1479 0));
1480 else if (TARGET_FPU_ANY)
1481 last = gen_divsi3_i4_single (operands[0], operands[3]);
1482 else
1483 last = gen_divsi3_i1 (operands[0], operands[3]);
1484 }
1485 else
1486 {
1487 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1488 last = gen_divsi3_i1 (operands[0], operands[3]);
1489 }
1490 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1491 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1492 last = emit_insn (last);
1493 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1494 invariant code motion can move it. */
1495 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1496 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1497 DONE;
1498 }")
1499 \f
1500 ;; -------------------------------------------------------------------------
1501 ;; Multiplication instructions
1502 ;; -------------------------------------------------------------------------
1503
1504 (define_insn "umulhisi3_i"
1505 [(set (reg:SI MACL_REG)
1506 (mult:SI (zero_extend:SI
1507 (match_operand:HI 0 "arith_reg_operand" "r"))
1508 (zero_extend:SI
1509 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1510 "TARGET_SH1"
1511 "mulu.w %1,%0"
1512 [(set_attr "type" "smpy")])
1513
1514 (define_insn "mulhisi3_i"
1515 [(set (reg:SI MACL_REG)
1516 (mult:SI (sign_extend:SI
1517 (match_operand:HI 0 "arith_reg_operand" "r"))
1518 (sign_extend:SI
1519 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1520 "TARGET_SH1"
1521 "muls.w %1,%0"
1522 [(set_attr "type" "smpy")])
1523
1524 (define_expand "mulhisi3"
1525 [(set (reg:SI MACL_REG)
1526 (mult:SI (sign_extend:SI
1527 (match_operand:HI 1 "arith_reg_operand" ""))
1528 (sign_extend:SI
1529 (match_operand:HI 2 "arith_reg_operand" ""))))
1530 (set (match_operand:SI 0 "arith_reg_operand" "")
1531 (reg:SI MACL_REG))]
1532 "TARGET_SH1"
1533 "
1534 {
1535 rtx first, last;
1536
1537 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1538 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1539 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1540 invariant code motion can move it. */
1541 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1542 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1543 /* expand_binop can't find a suitable code in umul_widen_optab to
1544 make a REG_EQUAL note from, so make one here.
1545 See also smulsi3_highpart.
1546 ??? Alternatively, we could put this at the calling site of expand_binop,
1547 i.e. expand_expr. */
1548 REG_NOTES (last)
1549 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1550 REG_NOTES (last));
1551 DONE;
1552 }")
1553
1554 (define_expand "umulhisi3"
1555 [(set (reg:SI MACL_REG)
1556 (mult:SI (zero_extend:SI
1557 (match_operand:HI 1 "arith_reg_operand" ""))
1558 (zero_extend:SI
1559 (match_operand:HI 2 "arith_reg_operand" ""))))
1560 (set (match_operand:SI 0 "arith_reg_operand" "")
1561 (reg:SI MACL_REG))]
1562 "TARGET_SH1"
1563 "
1564 {
1565 rtx first, last;
1566
1567 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1568 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1569 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1570 invariant code motion can move it. */
1571 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1572 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1573 /* expand_binop can't find a suitable code in umul_widen_optab to
1574 make a REG_EQUAL note from, so make one here.
1575 See also smulsi3_highpart.
1576 ??? Alternatively, we could put this at the calling site of expand_binop,
1577 i.e. expand_expr. */
1578 REG_NOTES (last)
1579 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1580 REG_NOTES (last));
1581 DONE;
1582 }")
1583
1584 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1585 ;; a call to a routine which clobbers known registers.
1586
1587 (define_insn ""
1588 [(set (match_operand:SI 1 "register_operand" "=z")
1589 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1590 (clobber (reg:SI MACL_REG))
1591 (clobber (reg:SI T_REG))
1592 (clobber (reg:SI PR_REG))
1593 (clobber (reg:SI R3_REG))
1594 (clobber (reg:SI R2_REG))
1595 (clobber (reg:SI R1_REG))
1596 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1597 "TARGET_SH1"
1598 "jsr @%0%#"
1599 [(set_attr "type" "sfunc")
1600 (set_attr "needs_delay_slot" "yes")])
1601
1602 (define_expand "mulsi3_call"
1603 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1604 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1605 (parallel[(set (match_operand:SI 0 "register_operand" "")
1606 (mult:SI (reg:SI R4_REG)
1607 (reg:SI R5_REG)))
1608 (clobber (reg:SI MACL_REG))
1609 (clobber (reg:SI T_REG))
1610 (clobber (reg:SI PR_REG))
1611 (clobber (reg:SI R3_REG))
1612 (clobber (reg:SI R2_REG))
1613 (clobber (reg:SI R1_REG))
1614 (use (match_operand:SI 3 "register_operand" ""))])]
1615 "TARGET_SH1"
1616 "")
1617
1618 (define_insn "mul_r"
1619 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1620 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1621 (match_operand:SI 2 "arith_reg_operand" "z")))]
1622 "TARGET_SH2A"
1623 "mulr %2,%0"
1624 [(set_attr "type" "dmpy")])
1625
1626 (define_insn "mul_l"
1627 [(set (reg:SI MACL_REG)
1628 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1629 (match_operand:SI 1 "arith_reg_operand" "r")))]
1630 "TARGET_SH2"
1631 "mul.l %1,%0"
1632 [(set_attr "type" "dmpy")])
1633
1634 (define_expand "mulsi3"
1635 [(set (reg:SI MACL_REG)
1636 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1637 (match_operand:SI 2 "arith_reg_operand" "")))
1638 (set (match_operand:SI 0 "arith_reg_operand" "")
1639 (reg:SI MACL_REG))]
1640 "TARGET_SH1"
1641 "
1642 {
1643 rtx first, last;
1644
1645 if (!TARGET_SH2)
1646 {
1647 /* The address must be set outside the libcall,
1648 since it goes into a pseudo. */
1649 rtx sym = function_symbol (\"__mulsi3\");
1650 rtx addr = force_reg (SImode, sym);
1651 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1652 operands[2], addr);
1653 first = insns;
1654 last = emit_insn (insns);
1655 }
1656 else
1657 {
1658 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1659
1660 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1661 /* consec_sets_giv can only recognize the first insn that sets a
1662 giv as the giv insn. So we must tag this also with a REG_EQUAL
1663 note. */
1664 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1665 }
1666 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1667 invariant code motion can move it. */
1668 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1669 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1670 DONE;
1671 }")
1672
1673 (define_insn "mulsidi3_i"
1674 [(set (reg:SI MACH_REG)
1675 (truncate:SI
1676 (lshiftrt:DI
1677 (mult:DI
1678 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1679 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1680 (const_int 32))))
1681 (set (reg:SI MACL_REG)
1682 (mult:SI (match_dup 0)
1683 (match_dup 1)))]
1684 "TARGET_SH2"
1685 "dmuls.l %1,%0"
1686 [(set_attr "type" "dmpy")])
1687
1688 (define_expand "mulsidi3"
1689 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1690 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1691 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1692 "TARGET_SH2 || TARGET_SHMEDIA"
1693 "
1694 {
1695 if (TARGET_SH2)
1696 {
1697 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1698 operands[2]));
1699 DONE;
1700 }
1701 }")
1702
1703 (define_insn "mulsidi3_media"
1704 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1705 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1706 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1707 "TARGET_SHMEDIA"
1708 "muls.l %1, %2, %0"
1709 [(set_attr "type" "dmpy_media")])
1710
1711 (define_insn "mulsidi3_compact"
1712 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1713 (mult:DI
1714 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1715 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1716 (clobber (reg:SI MACH_REG))
1717 (clobber (reg:SI MACL_REG))]
1718 "TARGET_SH2"
1719 "#")
1720
1721 (define_split
1722 [(set (match_operand:DI 0 "arith_reg_operand" "")
1723 (mult:DI
1724 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1725 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1726 (clobber (reg:SI MACH_REG))
1727 (clobber (reg:SI MACL_REG))]
1728 "TARGET_SH2"
1729 [(const_int 0)]
1730 "
1731 {
1732 rtx low_dst = gen_lowpart (SImode, operands[0]);
1733 rtx high_dst = gen_highpart (SImode, operands[0]);
1734
1735 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1736
1737 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1738 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1739 /* We need something to tag the possible REG_EQUAL notes on to. */
1740 emit_move_insn (operands[0], operands[0]);
1741 DONE;
1742 }")
1743
1744 (define_insn "umulsidi3_i"
1745 [(set (reg:SI MACH_REG)
1746 (truncate:SI
1747 (lshiftrt:DI
1748 (mult:DI
1749 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1750 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1751 (const_int 32))))
1752 (set (reg:SI MACL_REG)
1753 (mult:SI (match_dup 0)
1754 (match_dup 1)))]
1755 "TARGET_SH2"
1756 "dmulu.l %1,%0"
1757 [(set_attr "type" "dmpy")])
1758
1759 (define_expand "umulsidi3"
1760 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1761 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1762 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1763 "TARGET_SH2 || TARGET_SHMEDIA"
1764 "
1765 {
1766 if (TARGET_SH2)
1767 {
1768 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1769 operands[2]));
1770 DONE;
1771 }
1772 }")
1773
1774 (define_insn "umulsidi3_media"
1775 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1776 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1777 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1778 "TARGET_SHMEDIA"
1779 "mulu.l %1, %2, %0"
1780 [(set_attr "type" "dmpy_media")])
1781
1782 (define_insn "umulsidi3_compact"
1783 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1784 (mult:DI
1785 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1786 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1787 (clobber (reg:SI MACH_REG))
1788 (clobber (reg:SI MACL_REG))]
1789 "TARGET_SH2"
1790 "#")
1791
1792 (define_split
1793 [(set (match_operand:DI 0 "arith_reg_operand" "")
1794 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1795 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1796 (clobber (reg:SI MACH_REG))
1797 (clobber (reg:SI MACL_REG))]
1798 "TARGET_SH2"
1799 [(const_int 0)]
1800 "
1801 {
1802 rtx low_dst = gen_lowpart (SImode, operands[0]);
1803 rtx high_dst = gen_highpart (SImode, operands[0]);
1804
1805 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1806
1807 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1808 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1809 /* We need something to tag the possible REG_EQUAL notes on to. */
1810 emit_move_insn (operands[0], operands[0]);
1811 DONE;
1812 }")
1813
1814 (define_insn "smulsi3_highpart_i"
1815 [(set (reg:SI MACH_REG)
1816 (truncate:SI
1817 (lshiftrt:DI
1818 (mult:DI
1819 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1820 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1821 (const_int 32))))
1822 (clobber (reg:SI MACL_REG))]
1823 "TARGET_SH2"
1824 "dmuls.l %1,%0"
1825 [(set_attr "type" "dmpy")])
1826
1827 (define_expand "smulsi3_highpart"
1828 [(parallel
1829 [(set (reg:SI MACH_REG)
1830 (truncate:SI
1831 (lshiftrt:DI
1832 (mult:DI
1833 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1834 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1835 (const_int 32))))
1836 (clobber (reg:SI MACL_REG))])
1837 (set (match_operand:SI 0 "arith_reg_operand" "")
1838 (reg:SI MACH_REG))]
1839 "TARGET_SH2"
1840 "
1841 {
1842 rtx first, last;
1843
1844 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1845 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1846 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1847 invariant code motion can move it. */
1848 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1849 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1850 /* expand_binop can't find a suitable code in mul_highpart_optab to
1851 make a REG_EQUAL note from, so make one here.
1852 See also {,u}mulhisi.
1853 ??? Alternatively, we could put this at the calling site of expand_binop,
1854 i.e. expand_mult_highpart. */
1855 REG_NOTES (last)
1856 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1857 REG_NOTES (last));
1858 DONE;
1859 }")
1860
1861 (define_insn "umulsi3_highpart_i"
1862 [(set (reg:SI MACH_REG)
1863 (truncate:SI
1864 (lshiftrt:DI
1865 (mult:DI
1866 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1867 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1868 (const_int 32))))
1869 (clobber (reg:SI MACL_REG))]
1870 "TARGET_SH2"
1871 "dmulu.l %1,%0"
1872 [(set_attr "type" "dmpy")])
1873
1874 (define_expand "umulsi3_highpart"
1875 [(parallel
1876 [(set (reg:SI MACH_REG)
1877 (truncate:SI
1878 (lshiftrt:DI
1879 (mult:DI
1880 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1881 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1882 (const_int 32))))
1883 (clobber (reg:SI MACL_REG))])
1884 (set (match_operand:SI 0 "arith_reg_operand" "")
1885 (reg:SI MACH_REG))]
1886 "TARGET_SH2"
1887 "
1888 {
1889 rtx first, last;
1890
1891 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1892 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1893 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1894 invariant code motion can move it. */
1895 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1896 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1897 DONE;
1898 }")
1899 \f
1900 ;; -------------------------------------------------------------------------
1901 ;; Logical operations
1902 ;; -------------------------------------------------------------------------
1903
1904 (define_insn "*andsi3_compact"
1905 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1906 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1907 (match_operand:SI 2 "logical_operand" "r,K08")))]
1908 "TARGET_SH1"
1909 "and %2,%0"
1910 [(set_attr "type" "arith")])
1911
1912 ;; If the constant is 255, then emit an extu.b instruction instead of an
1913 ;; and, since that will give better code.
1914
1915 (define_expand "andsi3"
1916 [(set (match_operand:SI 0 "arith_reg_operand" "")
1917 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1918 (match_operand:SI 2 "logical_operand" "")))]
1919 "TARGET_SH1"
1920 "
1921 {
1922 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1923 {
1924 emit_insn (gen_zero_extendqisi2 (operands[0],
1925 gen_lowpart (QImode, operands[1])));
1926 DONE;
1927 }
1928 }")
1929
1930 (define_insn_and_split "anddi3"
1931 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1932 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1933 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1934 "TARGET_SHMEDIA"
1935 "@
1936 and %1, %2, %0
1937 andi %1, %2, %0
1938 #"
1939 "reload_completed
1940 && ! logical_operand (operands[2], DImode)"
1941 [(const_int 0)]
1942 "
1943 {
1944 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1945 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1946 else
1947 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1948 DONE;
1949 }"
1950 [(set_attr "type" "arith_media")])
1951
1952 (define_insn "andcdi3"
1953 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1954 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1955 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1956 "TARGET_SHMEDIA"
1957 "andc %1,%2,%0"
1958 [(set_attr "type" "arith_media")])
1959
1960 (define_insn "iorsi3"
1961 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1962 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1963 (match_operand:SI 2 "logical_operand" "r,K08")))]
1964 "TARGET_SH1"
1965 "or %2,%0"
1966 [(set_attr "type" "arith")])
1967
1968 (define_insn "iordi3"
1969 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1970 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1971 (match_operand:DI 2 "logical_operand" "r,I10")))]
1972 "TARGET_SHMEDIA"
1973 "@
1974 or %1, %2, %0
1975 ori %1, %2, %0"
1976 [(set_attr "type" "arith_media")])
1977
1978 (define_insn "xorsi3"
1979 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1980 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1981 (match_operand:SI 2 "logical_operand" "K08,r")))]
1982 "TARGET_SH1"
1983 "xor %2,%0"
1984 [(set_attr "type" "arith")])
1985
1986 (define_insn "xordi3"
1987 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1988 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1989 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1990 "TARGET_SHMEDIA"
1991 "@
1992 xor %1, %2, %0
1993 xori %1, %2, %0"
1994 [(set_attr "type" "arith_media")])
1995
1996 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
1997 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
1998 (define_split
1999 [(set (match_operand:DI 0 "arith_reg_operand" "")
2000 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2001 [(match_operand 1 "any_register_operand" "")
2002 (match_operand 2 "any_register_operand" "")])))]
2003 "TARGET_SHMEDIA"
2004 [(set (match_dup 5) (match_dup 4))
2005 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2006 "
2007 {
2008 enum machine_mode inmode = GET_MODE (operands[1]);
2009 int offset = 0;
2010
2011 if (GET_CODE (operands[0]) == SUBREG)
2012 {
2013 offset = SUBREG_BYTE (operands[0]);
2014 operands[0] = SUBREG_REG (operands[0]);
2015 }
2016 if (GET_CODE (operands[0]) != REG)
2017 abort ();
2018 if (! TARGET_LITTLE_ENDIAN)
2019 offset += 8 - GET_MODE_SIZE (inmode);
2020 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2021 }")
2022 \f
2023 ;; -------------------------------------------------------------------------
2024 ;; Shifts and rotates
2025 ;; -------------------------------------------------------------------------
2026
2027 (define_expand "rotldi3"
2028 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2029 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2030 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2031 "TARGET_SHMEDIA"
2032 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2033
2034 (define_insn "rotldi3_mextr"
2035 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2036 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2037 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2038 "TARGET_SHMEDIA"
2039 "*
2040 {
2041 static char templ[16];
2042
2043 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2044 8 - (int) (INTVAL (operands[2]) >> 3));
2045 return templ;
2046 }"
2047 [(set_attr "type" "arith_media")])
2048
2049 (define_expand "rotrdi3"
2050 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2051 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2052 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2053 "TARGET_SHMEDIA"
2054 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2055
2056 (define_insn "rotrdi3_mextr"
2057 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2058 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2059 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2060 "TARGET_SHMEDIA"
2061 "*
2062 {
2063 static char templ[16];
2064
2065 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2066 return templ;
2067 }"
2068 [(set_attr "type" "arith_media")])
2069
2070 (define_insn "rotlsi3_1"
2071 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2072 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2073 (const_int 1)))
2074 (set (reg:SI T_REG)
2075 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2076 "TARGET_SH1"
2077 "rotl %0"
2078 [(set_attr "type" "arith")])
2079
2080 (define_insn "rotlsi3_31"
2081 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2082 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2083 (const_int 31)))
2084 (clobber (reg:SI T_REG))]
2085 "TARGET_SH1"
2086 "rotr %0"
2087 [(set_attr "type" "arith")])
2088
2089 (define_insn "rotlsi3_16"
2090 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2091 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2092 (const_int 16)))]
2093 "TARGET_SH1"
2094 "swap.w %1,%0"
2095 [(set_attr "type" "arith")])
2096
2097 (define_expand "rotlsi3"
2098 [(set (match_operand:SI 0 "arith_reg_operand" "")
2099 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2100 (match_operand:SI 2 "immediate_operand" "")))]
2101 "TARGET_SH1"
2102 "
2103 {
2104 static const char rot_tab[] = {
2105 000, 000, 000, 000, 000, 000, 010, 001,
2106 001, 001, 011, 013, 003, 003, 003, 003,
2107 003, 003, 003, 003, 003, 013, 012, 002,
2108 002, 002, 010, 000, 000, 000, 000, 000,
2109 };
2110
2111 int count, choice;
2112
2113 if (GET_CODE (operands[2]) != CONST_INT)
2114 FAIL;
2115 count = INTVAL (operands[2]);
2116 choice = rot_tab[count];
2117 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2118 FAIL;
2119 choice &= 7;
2120 switch (choice)
2121 {
2122 case 0:
2123 emit_move_insn (operands[0], operands[1]);
2124 count -= (count & 16) * 2;
2125 break;
2126 case 3:
2127 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2128 count -= 16;
2129 break;
2130 case 1:
2131 case 2:
2132 {
2133 rtx parts[2];
2134 parts[0] = gen_reg_rtx (SImode);
2135 parts[1] = gen_reg_rtx (SImode);
2136 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2137 emit_move_insn (parts[choice-1], operands[1]);
2138 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2139 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2140 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2141 count = (count & ~16) - 8;
2142 }
2143 }
2144
2145 for (; count > 0; count--)
2146 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2147 for (; count < 0; count++)
2148 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2149
2150 DONE;
2151 }")
2152
2153 (define_insn "*rotlhi3_8"
2154 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2155 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2156 (const_int 8)))]
2157 "TARGET_SH1"
2158 "swap.b %1,%0"
2159 [(set_attr "type" "arith")])
2160
2161 (define_expand "rotlhi3"
2162 [(set (match_operand:HI 0 "arith_reg_operand" "")
2163 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2164 (match_operand:HI 2 "immediate_operand" "")))]
2165 "TARGET_SH1"
2166 "
2167 {
2168 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2169 FAIL;
2170 }")
2171
2172 ;;
2173 ;; shift left
2174
2175 (define_insn "ashlsi3_sh2a"
2176 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2177 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2178 (match_operand:SI 2 "arith_reg_operand" "r")))]
2179 "TARGET_SH2A"
2180 "shad %2,%0"
2181 [(set_attr "type" "arith")
2182 (set_attr "length" "4")])
2183
2184 ;; This pattern is used by init_expmed for computing the costs of shift
2185 ;; insns.
2186
2187 (define_insn_and_split "ashlsi3_std"
2188 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2189 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2190 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2191 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2192 "TARGET_SH3
2193 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2194 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2195 "@
2196 shld %2,%0
2197 add %0,%0
2198 shll%O2 %0
2199 #"
2200 "TARGET_SH3
2201 && reload_completed
2202 && GET_CODE (operands[2]) == CONST_INT
2203 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2204 [(set (match_dup 3) (match_dup 2))
2205 (parallel
2206 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2207 (clobber (match_dup 4))])]
2208 "operands[4] = gen_rtx_SCRATCH (SImode);"
2209 [(set_attr "length" "*,*,*,4")
2210 (set_attr "type" "dyn_shift,arith,arith,arith")])
2211
2212 (define_insn "ashlhi3_k"
2213 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2214 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2215 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2216 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2217 "@
2218 add %0,%0
2219 shll%O2 %0"
2220 [(set_attr "type" "arith")])
2221
2222 (define_insn "ashlsi3_n"
2223 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2224 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2225 (match_operand:SI 2 "const_int_operand" "n")))
2226 (clobber (reg:SI T_REG))]
2227 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2228 "#"
2229 [(set (attr "length")
2230 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2231 (const_string "2")
2232 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2233 (const_string "4")
2234 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2235 (const_string "6")]
2236 (const_string "8")))
2237 (set_attr "type" "arith")])
2238
2239 (define_split
2240 [(set (match_operand:SI 0 "arith_reg_operand" "")
2241 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2242 (match_operand:SI 2 "const_int_operand" "")))
2243 (clobber (reg:SI T_REG))]
2244 "TARGET_SH1 && reload_completed"
2245 [(use (reg:SI R0_REG))]
2246 "
2247 {
2248 gen_shifty_op (ASHIFT, operands);
2249 DONE;
2250 }")
2251
2252 (define_insn "ashlsi3_media"
2253 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2254 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2255 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2256 "TARGET_SHMEDIA"
2257 "@
2258 shlld.l %1, %2, %0
2259 shlli.l %1, %2, %0"
2260 [(set_attr "type" "arith_media")])
2261
2262 (define_expand "ashlsi3"
2263 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2264 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2265 (match_operand:SI 2 "nonmemory_operand" "")))
2266 (clobber (reg:SI T_REG))])]
2267 ""
2268 "
2269 {
2270 if (TARGET_SHMEDIA)
2271 {
2272 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2273 DONE;
2274 }
2275 if (GET_CODE (operands[2]) == CONST_INT
2276 && sh_dynamicalize_shift_p (operands[2]))
2277 operands[2] = force_reg (SImode, operands[2]);
2278 if (TARGET_SH3)
2279 {
2280 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2281 DONE;
2282 }
2283 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2284 FAIL;
2285 }")
2286
2287 (define_insn "ashlhi3"
2288 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2289 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2290 (match_operand:HI 2 "const_int_operand" "n")))
2291 (clobber (reg:SI T_REG))]
2292 "TARGET_SH1"
2293 "#"
2294 [(set (attr "length")
2295 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2296 (const_string "2")
2297 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2298 (const_string "4")]
2299 (const_string "6")))
2300 (set_attr "type" "arith")])
2301
2302 (define_split
2303 [(set (match_operand:HI 0 "arith_reg_operand" "")
2304 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2305 (match_operand:HI 2 "const_int_operand" "")))
2306 (clobber (reg:SI T_REG))]
2307 "TARGET_SH1 && reload_completed"
2308 [(use (reg:SI R0_REG))]
2309 "
2310 {
2311 gen_shifty_hi_op (ASHIFT, operands);
2312 DONE;
2313 }")
2314
2315 ;
2316 ; arithmetic shift right
2317 ;
2318
2319 (define_insn "ashrsi3_sh2a"
2320 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2321 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2322 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2323 "TARGET_SH2A"
2324 "shad %2,%0"
2325 [(set_attr "type" "dyn_shift")
2326 (set_attr "length" "4")])
2327
2328 (define_insn "ashrsi3_k"
2329 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2330 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2331 (match_operand:SI 2 "const_int_operand" "M")))
2332 (clobber (reg:SI T_REG))]
2333 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2334 "shar %0"
2335 [(set_attr "type" "arith")])
2336
2337 ;; We can't do HImode right shifts correctly unless we start out with an
2338 ;; explicit zero / sign extension; doing that would result in worse overall
2339 ;; code, so just let the machine independent code widen the mode.
2340 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2341
2342
2343 ;; ??? This should be a define expand.
2344
2345 (define_insn "ashrsi2_16"
2346 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2347 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2348 (const_int 16)))]
2349 "TARGET_SH1"
2350 "#"
2351 [(set_attr "length" "4")])
2352
2353 (define_split
2354 [(set (match_operand:SI 0 "arith_reg_operand" "")
2355 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2356 (const_int 16)))]
2357 "TARGET_SH1"
2358 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2359 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2360 "operands[2] = gen_lowpart (HImode, operands[0]);")
2361
2362 ;; ??? This should be a define expand.
2363
2364 (define_insn "ashrsi2_31"
2365 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2366 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2367 (const_int 31)))
2368 (clobber (reg:SI T_REG))]
2369 "TARGET_SH1"
2370 "#"
2371 [(set_attr "length" "4")])
2372
2373 (define_split
2374 [(set (match_operand:SI 0 "arith_reg_operand" "")
2375 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2376 (const_int 31)))
2377 (clobber (reg:SI T_REG))]
2378 "TARGET_SH1"
2379 [(const_int 0)]
2380 "
2381 {
2382 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2383 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2384 DONE;
2385 }")
2386
2387 (define_insn "ashlsi_c"
2388 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2390 (set (reg:SI T_REG)
2391 (lt:SI (match_dup 1) (const_int 0)))]
2392 "TARGET_SH1"
2393 "shll %0"
2394 [(set_attr "type" "arith")])
2395
2396 (define_insn "ashrsi3_d"
2397 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2398 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2399 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2400 "TARGET_SH3"
2401 "shad %2,%0"
2402 [(set_attr "type" "dyn_shift")])
2403
2404 (define_insn "ashrsi3_n"
2405 [(set (reg:SI R4_REG)
2406 (ashiftrt:SI (reg:SI R4_REG)
2407 (match_operand:SI 0 "const_int_operand" "i")))
2408 (clobber (reg:SI T_REG))
2409 (clobber (reg:SI PR_REG))
2410 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2411 "TARGET_SH1"
2412 "jsr @%1%#"
2413 [(set_attr "type" "sfunc")
2414 (set_attr "needs_delay_slot" "yes")])
2415
2416 (define_insn "ashrsi3_media"
2417 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2418 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2419 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2420 "TARGET_SHMEDIA"
2421 "@
2422 shard.l %1, %2, %0
2423 shari.l %1, %2, %0"
2424 [(set_attr "type" "arith_media")])
2425
2426 (define_expand "ashrsi3"
2427 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2428 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2429 (match_operand:SI 2 "nonmemory_operand" "")))
2430 (clobber (reg:SI T_REG))])]
2431 ""
2432 "
2433 {
2434 if (TARGET_SHMEDIA)
2435 {
2436 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2437 DONE;
2438 }
2439 if (expand_ashiftrt (operands))
2440 DONE;
2441 else
2442 FAIL;
2443 }")
2444
2445 ;; logical shift right
2446
2447 (define_insn "lshrsi3_sh2a"
2448 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2449 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2450 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2451 "TARGET_SH2A"
2452 "shld %2,%0"
2453 [(set_attr "type" "dyn_shift")
2454 (set_attr "length" "4")])
2455
2456 (define_insn "lshrsi3_d"
2457 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2458 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2459 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2460 "TARGET_SH3"
2461 "shld %2,%0"
2462 [(set_attr "type" "dyn_shift")])
2463
2464 ;; Only the single bit shift clobbers the T bit.
2465
2466 (define_insn "lshrsi3_m"
2467 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2468 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2469 (match_operand:SI 2 "const_int_operand" "M")))
2470 (clobber (reg:SI T_REG))]
2471 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2472 "shlr %0"
2473 [(set_attr "type" "arith")])
2474
2475 (define_insn "lshrsi3_k"
2476 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478 (match_operand:SI 2 "const_int_operand" "P27")))]
2479 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2480 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2481 "shlr%O2 %0"
2482 [(set_attr "type" "arith")])
2483
2484 (define_insn "lshrsi3_n"
2485 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487 (match_operand:SI 2 "const_int_operand" "n")))
2488 (clobber (reg:SI T_REG))]
2489 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2490 "#"
2491 [(set (attr "length")
2492 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2493 (const_string "2")
2494 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2495 (const_string "4")
2496 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2497 (const_string "6")]
2498 (const_string "8")))
2499 (set_attr "type" "arith")])
2500
2501 (define_split
2502 [(set (match_operand:SI 0 "arith_reg_operand" "")
2503 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2504 (match_operand:SI 2 "const_int_operand" "")))
2505 (clobber (reg:SI T_REG))]
2506 "TARGET_SH1 && reload_completed"
2507 [(use (reg:SI R0_REG))]
2508 "
2509 {
2510 gen_shifty_op (LSHIFTRT, operands);
2511 DONE;
2512 }")
2513
2514 (define_insn "lshrsi3_media"
2515 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2516 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2517 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2518 "TARGET_SHMEDIA"
2519 "@
2520 shlrd.l %1, %2, %0
2521 shlri.l %1, %2, %0"
2522 [(set_attr "type" "arith_media")])
2523
2524 (define_expand "lshrsi3"
2525 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2526 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2527 (match_operand:SI 2 "nonmemory_operand" "")))
2528 (clobber (reg:SI T_REG))])]
2529 ""
2530 "
2531 {
2532 if (TARGET_SHMEDIA)
2533 {
2534 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2535 DONE;
2536 }
2537 if (GET_CODE (operands[2]) == CONST_INT
2538 && sh_dynamicalize_shift_p (operands[2]))
2539 operands[2] = force_reg (SImode, operands[2]);
2540 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2541 {
2542 rtx count = copy_to_mode_reg (SImode, operands[2]);
2543 emit_insn (gen_negsi2 (count, count));
2544 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2545 DONE;
2546 }
2547 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2548 FAIL;
2549 }")
2550
2551 ;; ??? This should be a define expand.
2552
2553 (define_insn "ashldi3_k"
2554 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2555 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2556 (const_int 1)))
2557 (clobber (reg:SI T_REG))]
2558 "TARGET_SH1"
2559 "shll %R0\;rotcl %S0"
2560 [(set_attr "length" "4")
2561 (set_attr "type" "arith")])
2562
2563 (define_insn "ashldi3_media"
2564 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2565 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2566 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2567 "TARGET_SHMEDIA"
2568 "@
2569 shlld %1, %2, %0
2570 shlli %1, %2, %0"
2571 [(set_attr "type" "arith_media")])
2572
2573 (define_expand "ashldi3"
2574 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2575 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2576 (match_operand:DI 2 "immediate_operand" "")))
2577 (clobber (reg:SI T_REG))])]
2578 ""
2579 "
2580 {
2581 if (TARGET_SHMEDIA)
2582 {
2583 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2584 DONE;
2585 }
2586 if (GET_CODE (operands[2]) != CONST_INT
2587 || INTVAL (operands[2]) != 1)
2588 FAIL;
2589 }")
2590
2591 ;; ??? This should be a define expand.
2592
2593 (define_insn "lshrdi3_k"
2594 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2595 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2596 (const_int 1)))
2597 (clobber (reg:SI T_REG))]
2598 "TARGET_SH1"
2599 "shlr %S0\;rotcr %R0"
2600 [(set_attr "length" "4")
2601 (set_attr "type" "arith")])
2602
2603 (define_insn "lshrdi3_media"
2604 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2605 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2606 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2607 "TARGET_SHMEDIA"
2608 "@
2609 shlrd %1, %2, %0
2610 shlri %1, %2, %0"
2611 [(set_attr "type" "arith_media")])
2612
2613 (define_expand "lshrdi3"
2614 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2615 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2616 (match_operand:DI 2 "immediate_operand" "")))
2617 (clobber (reg:SI T_REG))])]
2618 ""
2619 "
2620 {
2621 if (TARGET_SHMEDIA)
2622 {
2623 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2624 DONE;
2625 }
2626 if (GET_CODE (operands[2]) != CONST_INT
2627 || INTVAL (operands[2]) != 1)
2628 FAIL;
2629 }")
2630
2631 ;; ??? This should be a define expand.
2632
2633 (define_insn "ashrdi3_k"
2634 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2635 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2636 (const_int 1)))
2637 (clobber (reg:SI T_REG))]
2638 "TARGET_SH1"
2639 "shar %S0\;rotcr %R0"
2640 [(set_attr "length" "4")
2641 (set_attr "type" "arith")])
2642
2643 (define_insn "ashrdi3_media"
2644 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2645 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2646 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2647 "TARGET_SHMEDIA"
2648 "@
2649 shard %1, %2, %0
2650 shari %1, %2, %0"
2651 [(set_attr "type" "arith_media")])
2652
2653 (define_expand "ashrdi3"
2654 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2655 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2656 (match_operand:DI 2 "immediate_operand" "")))
2657 (clobber (reg:SI T_REG))])]
2658 ""
2659 "
2660 {
2661 if (TARGET_SHMEDIA)
2662 {
2663 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2664 DONE;
2665 }
2666 if (GET_CODE (operands[2]) != CONST_INT
2667 || INTVAL (operands[2]) != 1)
2668 FAIL;
2669 }")
2670
2671 ;; combined left/right shift
2672
2673 (define_split
2674 [(set (match_operand:SI 0 "register_operand" "")
2675 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2676 (match_operand:SI 2 "const_int_operand" ""))
2677 (match_operand:SI 3 "const_int_operand" "")))]
2678 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2679 [(use (reg:SI R0_REG))]
2680 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2681 DONE;")
2682
2683 (define_split
2684 [(set (match_operand:SI 0 "register_operand" "")
2685 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2686 (match_operand:SI 2 "const_int_operand" ""))
2687 (match_operand:SI 3 "const_int_operand" "")))
2688 (clobber (reg:SI T_REG))]
2689 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2690 [(use (reg:SI R0_REG))]
2691 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2692 DONE;")
2693
2694 (define_insn ""
2695 [(set (match_operand:SI 0 "register_operand" "=r")
2696 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2697 (match_operand:SI 2 "const_int_operand" "n"))
2698 (match_operand:SI 3 "const_int_operand" "n")))
2699 (clobber (reg:SI T_REG))]
2700 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2701 "#"
2702 [(set (attr "length")
2703 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2704 (const_string "4")
2705 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2706 (const_string "6")
2707 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2708 (const_string "8")
2709 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2710 (const_string "10")
2711 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2712 (const_string "12")
2713 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2714 (const_string "14")
2715 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2716 (const_string "16")]
2717 (const_string "18")))
2718 (set_attr "type" "arith")])
2719
2720 (define_insn ""
2721 [(set (match_operand:SI 0 "register_operand" "=z")
2722 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2723 (match_operand:SI 2 "const_int_operand" "n"))
2724 (match_operand:SI 3 "const_int_operand" "n")))
2725 (clobber (reg:SI T_REG))]
2726 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2727 "#"
2728 [(set (attr "length")
2729 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2730 (const_string "4")
2731 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2732 (const_string "6")
2733 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2734 (const_string "8")]
2735 (const_string "10")))
2736 (set_attr "type" "arith")])
2737
2738 ;; shift left / and combination with a scratch register: The combine pass
2739 ;; does not accept the individual instructions, even though they are
2740 ;; cheap. But it needs a precise description so that it is usable after
2741 ;; reload.
2742 (define_insn "and_shl_scratch"
2743 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2744 (lshiftrt:SI
2745 (ashift:SI
2746 (and:SI
2747 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2748 (match_operand:SI 2 "const_int_operand" "N,n"))
2749 (match_operand:SI 3 "" "0,r"))
2750 (match_operand:SI 4 "const_int_operand" "n,n"))
2751 (match_operand:SI 5 "const_int_operand" "n,n")))
2752 (clobber (reg:SI T_REG))]
2753 "TARGET_SH1"
2754 "#"
2755 [(set (attr "length")
2756 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2757 (const_string "4")
2758 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2759 (const_string "6")
2760 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2761 (const_string "8")
2762 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2763 (const_string "10")]
2764 (const_string "12")))
2765 (set_attr "type" "arith")])
2766
2767 (define_split
2768 [(set (match_operand:SI 0 "register_operand" "")
2769 (lshiftrt:SI
2770 (ashift:SI
2771 (and:SI
2772 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2773 (match_operand:SI 2 "const_int_operand" ""))
2774 (match_operand:SI 3 "register_operand" ""))
2775 (match_operand:SI 4 "const_int_operand" ""))
2776 (match_operand:SI 5 "const_int_operand" "")))
2777 (clobber (reg:SI T_REG))]
2778 "TARGET_SH1"
2779 [(use (reg:SI R0_REG))]
2780 "
2781 {
2782 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2783
2784 if (INTVAL (operands[2]))
2785 {
2786 gen_shifty_op (LSHIFTRT, operands);
2787 }
2788 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2789 operands[2] = operands[4];
2790 gen_shifty_op (ASHIFT, operands);
2791 if (INTVAL (operands[5]))
2792 {
2793 operands[2] = operands[5];
2794 gen_shifty_op (LSHIFTRT, operands);
2795 }
2796 DONE;
2797 }")
2798
2799 ;; signed left/right shift combination.
2800 (define_split
2801 [(set (match_operand:SI 0 "register_operand" "")
2802 (sign_extract:SI
2803 (ashift:SI (match_operand:SI 1 "register_operand" "")
2804 (match_operand:SI 2 "const_int_operand" ""))
2805 (match_operand:SI 3 "const_int_operand" "")
2806 (const_int 0)))
2807 (clobber (reg:SI T_REG))]
2808 "TARGET_SH1"
2809 [(use (reg:SI R0_REG))]
2810 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2811 DONE;")
2812
2813 (define_insn "shl_sext_ext"
2814 [(set (match_operand:SI 0 "register_operand" "=r")
2815 (sign_extract:SI
2816 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2817 (match_operand:SI 2 "const_int_operand" "n"))
2818 (match_operand:SI 3 "const_int_operand" "n")
2819 (const_int 0)))
2820 (clobber (reg:SI T_REG))]
2821 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2822 "#"
2823 [(set (attr "length")
2824 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2825 (const_string "2")
2826 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2827 (const_string "4")
2828 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2829 (const_string "6")
2830 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2831 (const_string "8")
2832 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2833 (const_string "10")
2834 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2835 (const_string "12")
2836 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2837 (const_string "14")
2838 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2839 (const_string "16")]
2840 (const_string "18")))
2841 (set_attr "type" "arith")])
2842
2843 (define_insn "shl_sext_sub"
2844 [(set (match_operand:SI 0 "register_operand" "=z")
2845 (sign_extract:SI
2846 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2847 (match_operand:SI 2 "const_int_operand" "n"))
2848 (match_operand:SI 3 "const_int_operand" "n")
2849 (const_int 0)))
2850 (clobber (reg:SI T_REG))]
2851 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2852 "#"
2853 [(set (attr "length")
2854 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2855 (const_string "6")
2856 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2857 (const_string "8")
2858 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2859 (const_string "10")
2860 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2861 (const_string "12")]
2862 (const_string "14")))
2863 (set_attr "type" "arith")])
2864
2865 ;; These patterns are found in expansions of DImode shifts by 16, and
2866 ;; allow the xtrct instruction to be generated from C source.
2867
2868 (define_insn "xtrct_left"
2869 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2870 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2871 (const_int 16))
2872 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2873 (const_int 16))))]
2874 "TARGET_SH1"
2875 "xtrct %1,%0"
2876 [(set_attr "type" "arith")])
2877
2878 (define_insn "xtrct_right"
2879 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2880 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2881 (const_int 16))
2882 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2883 (const_int 16))))]
2884 "TARGET_SH1"
2885 "xtrct %2,%0"
2886 [(set_attr "type" "arith")])
2887
2888 ;; -------------------------------------------------------------------------
2889 ;; Unary arithmetic
2890 ;; -------------------------------------------------------------------------
2891
2892 (define_insn "negc"
2893 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2894 (neg:SI (plus:SI (reg:SI T_REG)
2895 (match_operand:SI 1 "arith_reg_operand" "r"))))
2896 (set (reg:SI T_REG)
2897 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2898 (const_int 0)))]
2899 "TARGET_SH1"
2900 "negc %1,%0"
2901 [(set_attr "type" "arith")])
2902
2903 (define_insn "*negdi_media"
2904 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2905 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2906 "TARGET_SHMEDIA"
2907 "sub r63, %1, %0"
2908 [(set_attr "type" "arith_media")])
2909
2910 (define_expand "negdi2"
2911 [(set (match_operand:DI 0 "arith_reg_operand" "")
2912 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2913 ""
2914 "
2915 {
2916 if (TARGET_SH1)
2917 {
2918 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2919 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2920
2921 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2922 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2923
2924 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2925 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2926
2927 emit_insn (gen_clrt ());
2928 emit_insn (gen_negc (low_dst, low_src));
2929 emit_insn (gen_negc (high_dst, high_src));
2930 DONE;
2931 }
2932 }")
2933
2934 (define_insn "negsi2"
2935 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2936 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2937 "TARGET_SH1"
2938 "neg %1,%0"
2939 [(set_attr "type" "arith")])
2940
2941 (define_insn "one_cmplsi2"
2942 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2943 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2944 "TARGET_SH1"
2945 "not %1,%0"
2946 [(set_attr "type" "arith")])
2947
2948 (define_expand "one_cmpldi2"
2949 [(set (match_operand:DI 0 "arith_reg_operand" "")
2950 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2951 (const_int -1)))]
2952 "TARGET_SHMEDIA" "")
2953 \f
2954 ;; -------------------------------------------------------------------------
2955 ;; Zero extension instructions
2956 ;; -------------------------------------------------------------------------
2957
2958 (define_insn "zero_extendsidi2"
2959 [(set (match_operand:DI 0 "register_operand" "=r")
2960 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2961 "TARGET_SHMEDIA"
2962 "addz.l %1, r63, %0"
2963 [(set_attr "type" "arith_media")])
2964
2965 (define_insn "zero_extendhidi2"
2966 [(set (match_operand:DI 0 "register_operand" "=r,r")
2967 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2968 "TARGET_SHMEDIA"
2969 "@
2970 #
2971 ld%M1.uw %m1, %0"
2972 [(set_attr "type" "*,load_media")])
2973
2974 (define_split
2975 [(set (match_operand:DI 0 "register_operand" "")
2976 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2977 "TARGET_SHMEDIA && reload_completed"
2978 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2979 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2980 "
2981 {
2982 if (GET_CODE (operands[1]) == TRUNCATE)
2983 operands[1] = XEXP (operands[1], 0);
2984 }")
2985
2986 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2987 ;; reload the entire truncate expression.
2988 (define_insn_and_split "*loaddi_trunc"
2989 [(set (match_operand 0 "int_gpr_dest" "=r")
2990 (truncate (match_operand:DI 1 "memory_operand" "m")))]
2991 "TARGET_SHMEDIA && reload_completed"
2992 "#"
2993 "TARGET_SHMEDIA && reload_completed"
2994 [(set (match_dup 0) (match_dup 1))]
2995 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
2996
2997 (define_insn "zero_extendqidi2"
2998 [(set (match_operand:DI 0 "register_operand" "=r,r")
2999 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3000 "TARGET_SHMEDIA"
3001 "@
3002 andi %1, 255, %0
3003 ld%M1.ub %m1, %0"
3004 [(set_attr "type" "arith_media,load_media")])
3005
3006 (define_expand "zero_extendhisi2"
3007 [(set (match_operand:SI 0 "arith_reg_operand" "")
3008 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3009 ""
3010 "
3011 {
3012 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3013 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3014 }")
3015
3016 (define_insn "*zero_extendhisi2_compact"
3017 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3018 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3019 "TARGET_SH1"
3020 "extu.w %1,%0"
3021 [(set_attr "type" "arith")])
3022
3023 (define_insn "*zero_extendhisi2_media"
3024 [(set (match_operand:SI 0 "register_operand" "=r,r")
3025 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3026 "TARGET_SHMEDIA"
3027 "@
3028 #
3029 ld%M1.uw %m1, %0"
3030 [(set_attr "type" "arith_media,load_media")])
3031
3032 (define_split
3033 [(set (match_operand:SI 0 "register_operand" "")
3034 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3035 "TARGET_SHMEDIA && reload_completed"
3036 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3037 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3038 "
3039 {
3040 if (GET_CODE (operands[1]) == TRUNCATE)
3041 operands[1] = XEXP (operands[1], 0);
3042 }")
3043
3044 (define_expand "zero_extendqisi2"
3045 [(set (match_operand:SI 0 "arith_reg_operand" "")
3046 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3047 ""
3048 "
3049 {
3050 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3051 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3052 }")
3053
3054 (define_insn "*zero_extendqisi2_compact"
3055 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3056 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3057 "TARGET_SH1"
3058 "extu.b %1,%0"
3059 [(set_attr "type" "arith")])
3060
3061 (define_insn "*zero_extendqisi2_media"
3062 [(set (match_operand:SI 0 "register_operand" "=r,r")
3063 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3064 "TARGET_SHMEDIA"
3065 "@
3066 andi %1, 255, %0
3067 ld%M1.ub %m1, %0"
3068 [(set_attr "type" "arith_media,load_media")])
3069
3070 (define_insn "zero_extendqihi2"
3071 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3072 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3073 "TARGET_SH1"
3074 "extu.b %1,%0"
3075 [(set_attr "type" "arith")])
3076
3077 ;; -------------------------------------------------------------------------
3078 ;; Sign extension instructions
3079 ;; -------------------------------------------------------------------------
3080
3081 ;; ??? This should be a define expand.
3082 ;; ??? Or perhaps it should be dropped?
3083
3084 ;; convert_move generates good code for SH[1-4].
3085 (define_insn "extendsidi2"
3086 [(set (match_operand:DI 0 "register_operand" "=r,r")
3087 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3088 "TARGET_SHMEDIA"
3089 "@
3090 add.l %1, r63, %0
3091 ld%M1.l %m1, %0"
3092 [(set_attr "type" "arith_media,load_media")])
3093
3094 (define_insn "extendhidi2"
3095 [(set (match_operand:DI 0 "register_operand" "=r,r")
3096 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3097 "TARGET_SHMEDIA"
3098 "@
3099 #
3100 ld%M1.w %m1, %0"
3101 [(set_attr "type" "*,load_media")])
3102
3103 (define_split
3104 [(set (match_operand:DI 0 "register_operand" "")
3105 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3106 "TARGET_SHMEDIA && reload_completed"
3107 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3108 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3109 "
3110 {
3111 if (GET_CODE (operands[1]) == TRUNCATE)
3112 operands[1] = XEXP (operands[1], 0);
3113 }")
3114
3115 (define_insn "extendqidi2"
3116 [(set (match_operand:DI 0 "register_operand" "=r,r")
3117 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3118 "TARGET_SHMEDIA"
3119 "@
3120 #
3121 ld%M1.b %m1, %0"
3122 [(set_attr "type" "*,load_media")])
3123
3124 (define_split
3125 [(set (match_operand:DI 0 "register_operand" "")
3126 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3127 "TARGET_SHMEDIA && reload_completed"
3128 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3129 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3130 "
3131 {
3132 if (GET_CODE (operands[1]) == TRUNCATE)
3133 operands[1] = XEXP (operands[1], 0);
3134 }")
3135
3136 (define_expand "extendhisi2"
3137 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3138 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3139 ""
3140 "")
3141
3142 (define_insn "*extendhisi2_compact"
3143 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3144 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3145 "TARGET_SH1"
3146 "@
3147 exts.w %1,%0
3148 mov.w %1,%0"
3149 [(set_attr "type" "arith,load")])
3150
3151 (define_insn "*extendhisi2_media"
3152 [(set (match_operand:SI 0 "register_operand" "=r,r")
3153 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3154 "TARGET_SHMEDIA"
3155 "@
3156 #
3157 ld%M1.w %m1, %0"
3158 [(set_attr "type" "arith_media,load_media")])
3159
3160 (define_split
3161 [(set (match_operand:SI 0 "register_operand" "")
3162 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3163 "TARGET_SHMEDIA && reload_completed"
3164 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3165 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3166 "
3167 {
3168 if (GET_CODE (operands[1]) == TRUNCATE)
3169 operands[1] = XEXP (operands[1], 0);
3170 }")
3171
3172 (define_expand "extendqisi2"
3173 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3174 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3175 ""
3176 "")
3177
3178 (define_insn "*extendqisi2_compact"
3179 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3180 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3181 "TARGET_SH1"
3182 "@
3183 exts.b %1,%0
3184 mov.b %1,%0"
3185 [(set_attr "type" "arith,load")])
3186
3187 (define_insn "*extendqisi2_media"
3188 [(set (match_operand:SI 0 "register_operand" "=r,r")
3189 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3190 "TARGET_SHMEDIA"
3191 "@
3192 #
3193 ld%M1.b %m1, %0"
3194 [(set_attr "type" "arith_media,load_media")])
3195
3196 (define_split
3197 [(set (match_operand:SI 0 "register_operand" "")
3198 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3199 "TARGET_SHMEDIA && reload_completed"
3200 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3201 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3202 "
3203 {
3204 if (GET_CODE (operands[1]) == TRUNCATE)
3205 operands[1] = XEXP (operands[1], 0);
3206 }")
3207
3208 (define_insn "extendqihi2"
3209 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3210 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3211 "TARGET_SH1"
3212 "@
3213 exts.b %1,%0
3214 mov.b %1,%0"
3215 [(set_attr "type" "arith,load")])
3216
3217 /* It would seem useful to combine the truncXi patterns into the movXi
3218 patterns, but unary operators are ignored when matching constraints,
3219 so we need separate patterns. */
3220 (define_insn "truncdisi2"
3221 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3222 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3223 "TARGET_SHMEDIA"
3224 "@
3225 add.l %1, r63, %0
3226 st%M0.l %m0, %1
3227 fst%M0.s %m0, %T1
3228 fmov.ls %1, %0
3229 fmov.sl %T1, %0
3230 fmov.s %T1, %0"
3231 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3232
3233
3234 (define_insn "truncdihi2"
3235 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3236 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3237 "TARGET_SHMEDIA"
3238 "@
3239 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3240 st%M0.w %m0, %1"
3241 [(set_attr "type" "arith_media,store_media")
3242 (set_attr "length" "8,4")])
3243
3244 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3245 ; Because we use zero extension, we can't provide signed QImode compares
3246 ; using a simple compare or conditional banch insn.
3247 (define_insn "truncdiqi2"
3248 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3249 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3250 "TARGET_SHMEDIA"
3251 "@
3252 andi %1, 255, %0
3253 st%M0.b %m0, %1"
3254 [(set_attr "type" "arith_media,store")])
3255
3256 ;; -------------------------------------------------------------------------
3257 ;; Move instructions
3258 ;; -------------------------------------------------------------------------
3259
3260 ;; define push and pop so it is easy for sh.c
3261 ;; We can't use push and pop on SHcompact because the stack must always
3262 ;; be 8-byte aligned.
3263
3264 (define_expand "push"
3265 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3266 (match_operand:SI 0 "register_operand" "r,l,x"))]
3267 "TARGET_SH1 && ! TARGET_SH5"
3268 "")
3269
3270 (define_expand "pop"
3271 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3272 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3273 "TARGET_SH1 && ! TARGET_SH5"
3274 "")
3275
3276 (define_expand "push_e"
3277 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3278 (match_operand:SF 0 "" ""))
3279 (use (reg:PSI FPSCR_REG))
3280 (clobber (scratch:SI))])]
3281 "TARGET_SH1 && ! TARGET_SH5"
3282 "")
3283
3284 (define_insn "push_fpul"
3285 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3286 "TARGET_SH2E && ! TARGET_SH5"
3287 "sts.l fpul,@-r15"
3288 [(set_attr "type" "store")
3289 (set_attr "late_fp_use" "yes")
3290 (set_attr "hit_stack" "yes")])
3291
3292 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3293 ;; so use that.
3294 (define_expand "push_4"
3295 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3296 (match_operand:DF 0 "" ""))
3297 (use (reg:PSI FPSCR_REG))
3298 (clobber (scratch:SI))])]
3299 "TARGET_SH1 && ! TARGET_SH5"
3300 "")
3301
3302 (define_expand "pop_e"
3303 [(parallel [(set (match_operand:SF 0 "" "")
3304 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3305 (use (reg:PSI FPSCR_REG))
3306 (clobber (scratch:SI))])]
3307 "TARGET_SH1 && ! TARGET_SH5"
3308 "")
3309
3310 (define_insn "pop_fpul"
3311 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3312 "TARGET_SH2E && ! TARGET_SH5"
3313 "lds.l @r15+,fpul"
3314 [(set_attr "type" "load")
3315 (set_attr "hit_stack" "yes")])
3316
3317 (define_expand "pop_4"
3318 [(parallel [(set (match_operand:DF 0 "" "")
3319 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3320 (use (reg:PSI FPSCR_REG))
3321 (clobber (scratch:SI))])]
3322 "TARGET_SH1 && ! TARGET_SH5"
3323 "")
3324
3325 (define_expand "push_fpscr"
3326 [(const_int 0)]
3327 "TARGET_SH2E"
3328 "
3329 {
3330 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3331 gen_rtx_PRE_DEC (Pmode,
3332 stack_pointer_rtx)),
3333 get_fpscr_rtx ()));
3334 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3335 DONE;
3336 }")
3337
3338 (define_expand "pop_fpscr"
3339 [(const_int 0)]
3340 "TARGET_SH2E"
3341 "
3342 {
3343 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3344 gen_rtx_MEM (PSImode,
3345 gen_rtx_POST_INC (Pmode,
3346 stack_pointer_rtx))));
3347 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3348 DONE;
3349 }")
3350
3351 ;; These two patterns can happen as the result of optimization, when
3352 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3353 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3354
3355 (define_insn "clrt"
3356 [(set (reg:SI T_REG) (const_int 0))]
3357 "TARGET_SH1"
3358 "clrt")
3359
3360 (define_insn "sett"
3361 [(set (reg:SI T_REG) (const_int 1))]
3362 "TARGET_SH1"
3363 "sett")
3364
3365 ;; t/r must come after r/r, lest reload will try to reload stuff like
3366 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3367 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3368 (define_insn "movsi_i"
3369 [(set (match_operand:SI 0 "general_movdst_operand"
3370 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3371 (match_operand:SI 1 "general_movsrc_operand"
3372 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3373 "TARGET_SH1
3374 && ! TARGET_SH2E
3375 && ! TARGET_SH2A
3376 && (register_operand (operands[0], SImode)
3377 || register_operand (operands[1], SImode))"
3378 "@
3379 mov.l %1,%0
3380 mov %1,%0
3381 cmp/pl %1
3382 mov.l %1,%0
3383 sts %1,%0
3384 sts %1,%0
3385 movt %0
3386 mov.l %1,%0
3387 sts.l %1,%0
3388 sts.l %1,%0
3389 lds %1,%0
3390 lds %1,%0
3391 lds.l %1,%0
3392 lds.l %1,%0
3393 fake %1,%0"
3394 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3395 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3396
3397 ;; t/r must come after r/r, lest reload will try to reload stuff like
3398 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3399 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3400 ;; will require a reload.
3401 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3402 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3403 (define_insn "movsi_ie"
3404 [(set (match_operand:SI 0 "general_movdst_operand"
3405 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3406 (match_operand:SI 1 "general_movsrc_operand"
3407 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3408 "(TARGET_SH2E || TARGET_SH2A)
3409 && (register_operand (operands[0], SImode)
3410 || register_operand (operands[1], SImode))"
3411 "@
3412 mov.l %1,%0
3413 mov %1,%0
3414 movi20 %1,%0
3415 cmp/pl %1
3416 mov.l %1,%0
3417 sts %1,%0
3418 sts %1,%0
3419 movt %0
3420 mov.l %1,%0
3421 sts.l %1,%0
3422 sts.l %1,%0
3423 lds %1,%0
3424 lds %1,%0
3425 lds.l %1,%0
3426 lds.l %1,%0
3427 lds.l %1,%0
3428 sts.l %1,%0
3429 fake %1,%0
3430 lds %1,%0
3431 sts %1,%0
3432 fsts fpul,%0
3433 flds %1,fpul
3434 fmov %1,%0
3435 ! move optimized away"
3436 [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3437 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3438 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3439
3440 (define_insn "movsi_i_lowpart"
3441 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3442 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3443 "TARGET_SH1
3444 && (register_operand (operands[0], SImode)
3445 || register_operand (operands[1], SImode))"
3446 "@
3447 mov.l %1,%0
3448 mov %1,%0
3449 mov.l %1,%0
3450 sts %1,%0
3451 sts %1,%0
3452 movt %0
3453 mov.l %1,%0
3454 fake %1,%0"
3455 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3456
3457 (define_insn_and_split "load_ra"
3458 [(set (match_operand:SI 0 "general_movdst_operand" "")
3459 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3460 "TARGET_SH1"
3461 "#"
3462 "&& ! rtx_equal_function_value_matters"
3463 [(set (match_dup 0) (match_dup 1))]
3464 "
3465 {
3466 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3467 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3468 }")
3469
3470 (define_insn "*movsi_media"
3471 [(set (match_operand:SI 0 "general_movdst_operand"
3472 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3473 (match_operand:SI 1 "general_movsrc_operand"
3474 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3475 "TARGET_SHMEDIA_FPU
3476 && (register_operand (operands[0], SImode)
3477 || sh_register_operand (operands[1], SImode))"
3478 "@
3479 add.l %1, r63, %0
3480 movi %1, %0
3481 #
3482 ld%M1.l %m1, %0
3483 st%M0.l %m0, %N1
3484 fld%M1.s %m1, %0
3485 fst%M0.s %m0, %1
3486 fmov.ls %N1, %0
3487 fmov.sl %1, %0
3488 fmov.s %1, %0
3489 ptabs %1, %0
3490 gettr %1, %0
3491 pt %1, %0"
3492 [(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")
3493 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3494
3495 (define_insn "*movsi_media_nofpu"
3496 [(set (match_operand:SI 0 "general_movdst_operand"
3497 "=r,r,r,r,m,*b,r,b")
3498 (match_operand:SI 1 "general_movsrc_operand"
3499 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3500 "TARGET_SHMEDIA
3501 && (register_operand (operands[0], SImode)
3502 || sh_register_operand (operands[1], SImode))"
3503 "@
3504 add.l %1, r63, %0
3505 movi %1, %0
3506 #
3507 ld%M1.l %m1, %0
3508 st%M0.l %m0, %N1
3509 ptabs %1, %0
3510 gettr %1, %0
3511 pt %1, %0"
3512 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3513 (set_attr "length" "4,4,8,4,4,4,4,12")])
3514
3515 (define_split
3516 [(set (match_operand:SI 0 "arith_reg_operand" "")
3517 (match_operand:SI 1 "immediate_operand" ""))]
3518 "TARGET_SHMEDIA && reload_completed
3519 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3520 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3521 "
3522 {
3523 operands[2] = shallow_copy_rtx (operands[1]);
3524 PUT_MODE (operands[2], DImode);
3525 }")
3526
3527 (define_split
3528 [(set (match_operand:SI 0 "register_operand" "")
3529 (match_operand:SI 1 "immediate_operand" ""))]
3530 "TARGET_SHMEDIA && reload_completed
3531 && ((GET_CODE (operands[1]) == CONST_INT
3532 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3533 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3534 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3535
3536 (define_expand "movsi"
3537 [(set (match_operand:SI 0 "general_movdst_operand" "")
3538 (match_operand:SI 1 "general_movsrc_operand" ""))]
3539 ""
3540 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3541
3542 (define_expand "ic_invalidate_line"
3543 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3544 (match_dup 1)] UNSPEC_ICACHE)
3545 (clobber (scratch:SI))])]
3546 "TARGET_HARD_SH4 || TARGET_SH5"
3547 "
3548 {
3549 if (TARGET_SHMEDIA)
3550 {
3551 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3552 DONE;
3553 }
3554 else if (TARGET_SHCOMPACT)
3555 {
3556 operands[1] = function_symbol (\"__ic_invalidate\");
3557 operands[1] = force_reg (Pmode, operands[1]);
3558 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3559 DONE;
3560 }
3561 else if (TARGET_SH4A_ARCH)
3562 {
3563 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3564 DONE;
3565 }
3566 operands[0] = force_reg (Pmode, operands[0]);
3567 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3568 Pmode)));
3569 }")
3570
3571 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3572 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3573 ;; the requirement *1*00 for associative address writes. The alignment of
3574 ;; %0 implies that its least significant bit is cleared,
3575 ;; thus we clear the V bit of a matching entry if there is one.
3576 (define_insn "ic_invalidate_line_i"
3577 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3578 (match_operand:SI 1 "register_operand" "r")]
3579 UNSPEC_ICACHE)
3580 (clobber (match_scratch:SI 2 "=&r"))]
3581 "TARGET_HARD_SH4"
3582 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3583 [(set_attr "length" "8")
3584 (set_attr "type" "cwb")])
3585
3586 (define_insn "ic_invalidate_line_sh4a"
3587 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3588 UNSPEC_ICACHE)]
3589 "TARGET_SH4A_ARCH"
3590 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3591 [(set_attr "length" "16")
3592 (set_attr "type" "cwb")])
3593
3594 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3595 ;; an add in the code that calculates the address.
3596 (define_insn "ic_invalidate_line_media"
3597 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3598 UNSPEC_ICACHE)]
3599 "TARGET_SHMEDIA"
3600 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3601 [(set_attr "length" "16")
3602 (set_attr "type" "invalidate_line_media")])
3603
3604 (define_insn "ic_invalidate_line_compact"
3605 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3606 (match_operand:SI 1 "register_operand" "r")]
3607 UNSPEC_ICACHE)
3608 (clobber (reg:SI PR_REG))]
3609 "TARGET_SHCOMPACT"
3610 "jsr @%1%#"
3611 [(set_attr "type" "sfunc")
3612 (set_attr "needs_delay_slot" "yes")])
3613
3614 (define_expand "initialize_trampoline"
3615 [(match_operand:SI 0 "" "")
3616 (match_operand:SI 1 "" "")
3617 (match_operand:SI 2 "" "")]
3618 "TARGET_SHCOMPACT"
3619 "
3620 {
3621 rtx sfun, tramp;
3622
3623 tramp = force_reg (Pmode, operands[0]);
3624 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3625 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3626 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3627
3628 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3629 DONE;
3630 }")
3631
3632 (define_insn "initialize_trampoline_compact"
3633 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3634 (match_operand:SI 1 "register_operand" "r")
3635 (reg:SI R2_REG) (reg:SI R3_REG)]
3636 UNSPEC_INIT_TRAMP)
3637
3638 (clobber (reg:SI PR_REG))]
3639 "TARGET_SHCOMPACT"
3640 "jsr @%1%#"
3641 [(set_attr "type" "sfunc")
3642 (set_attr "needs_delay_slot" "yes")])
3643
3644 (define_insn "movqi_i"
3645 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3646 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3647 "TARGET_SH1
3648 && (arith_reg_operand (operands[0], QImode)
3649 || arith_reg_operand (operands[1], QImode))"
3650 "@
3651 mov %1,%0
3652 mov.b %1,%0
3653 mov.b %1,%0
3654 movt %0
3655 sts %1,%0
3656 lds %1,%0"
3657 [(set_attr "type" "move,load,store,move,move,move")])
3658
3659 (define_insn "*movqi_media"
3660 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3661 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3662 "TARGET_SHMEDIA
3663 && (arith_reg_operand (operands[0], QImode)
3664 || arith_reg_or_0_operand (operands[1], QImode))"
3665 "@
3666 add.l %1, r63, %0
3667 movi %1, %0
3668 ld%M1.ub %m1, %0
3669 st%M0.b %m0, %N1"
3670 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3671
3672 (define_expand "movqi"
3673 [(set (match_operand:QI 0 "general_operand" "")
3674 (match_operand:QI 1 "general_operand" ""))]
3675 ""
3676 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3677
3678 (define_expand "reload_inqi"
3679 [(set (match_operand:SI 2 "" "=&r")
3680 (match_operand:QI 1 "inqhi_operand" ""))
3681 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3682 (truncate:QI (match_dup 3)))]
3683 "TARGET_SHMEDIA"
3684 "
3685 {
3686 rtx inner = XEXP (operands[1], 0);
3687 int regno = REGNO (inner);
3688
3689 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3690 operands[1] = gen_rtx_REG (SImode, regno);
3691 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3692 }")
3693
3694 /* When storing r0, we have to avoid reg+reg addressing. */
3695 (define_insn "movhi_i"
3696 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3697 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3698 "TARGET_SH1
3699 && (arith_reg_operand (operands[0], HImode)
3700 || arith_reg_operand (operands[1], HImode))
3701 && (GET_CODE (operands[0]) != MEM
3702 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3703 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3704 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3705 "@
3706 mov.w %1,%0
3707 mov %1,%0
3708 mov.w %1,%0
3709 movt %0
3710 mov.w %1,%0
3711 sts %1,%0
3712 lds %1,%0
3713 fake %1,%0"
3714 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3715
3716 (define_insn "*movhi_media"
3717 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3718 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3719 "TARGET_SHMEDIA
3720 && (arith_reg_operand (operands[0], HImode)
3721 || arith_reg_or_0_operand (operands[1], HImode))"
3722 "@
3723 add.l %1, r63, %0
3724 movi %1, %0
3725 #
3726 ld%M1.w %m1, %0
3727 st%M0.w %m0, %N1"
3728 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3729
3730 (define_split
3731 [(set (match_operand:HI 0 "register_operand" "")
3732 (match_operand:HI 1 "immediate_operand" ""))]
3733 "TARGET_SHMEDIA && reload_completed
3734 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3735 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3736
3737 (define_expand "movhi"
3738 [(set (match_operand:HI 0 "general_movdst_operand" "")
3739 (match_operand:HI 1 "general_movsrc_operand" ""))]
3740 ""
3741 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3742
3743 (define_expand "reload_inhi"
3744 [(set (match_operand:SI 2 "" "=&r")
3745 (match_operand:HI 1 "inqhi_operand" ""))
3746 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3747 (truncate:HI (match_dup 3)))]
3748 "TARGET_SHMEDIA"
3749 "
3750 {
3751 rtx inner = XEXP (operands[1], 0);
3752 int regno = REGNO (inner);
3753
3754 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3755 operands[1] = gen_rtx_REG (SImode, regno);
3756 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3757 }")
3758
3759 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3760 ;; compiled with -m2 -ml -O3 -funroll-loops
3761 (define_insn "*movdi_i"
3762 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3763 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3764 "TARGET_SH1
3765 && (arith_reg_operand (operands[0], DImode)
3766 || arith_reg_operand (operands[1], DImode))"
3767 "* return output_movedouble (insn, operands, DImode);"
3768 [(set_attr "length" "4")
3769 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3770
3771 ;; If the output is a register and the input is memory or a register, we have
3772 ;; to be careful and see which word needs to be loaded first.
3773
3774 (define_split
3775 [(set (match_operand:DI 0 "general_movdst_operand" "")
3776 (match_operand:DI 1 "general_movsrc_operand" ""))]
3777 "TARGET_SH1 && reload_completed"
3778 [(set (match_dup 2) (match_dup 3))
3779 (set (match_dup 4) (match_dup 5))]
3780 "
3781 {
3782 int regno;
3783
3784 if ((GET_CODE (operands[0]) == MEM
3785 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3786 || (GET_CODE (operands[1]) == MEM
3787 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3788 FAIL;
3789
3790 if (GET_CODE (operands[0]) == REG)
3791 regno = REGNO (operands[0]);
3792 else if (GET_CODE (operands[0]) == SUBREG)
3793 regno = subreg_regno (operands[0]);
3794 else if (GET_CODE (operands[0]) == MEM)
3795 regno = -1;
3796 else
3797 abort ();
3798
3799 if (regno == -1
3800 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3801 {
3802 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3803 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3804 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3805 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3806 }
3807 else
3808 {
3809 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3810 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3811 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3812 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3813 }
3814
3815 if (operands[2] == 0 || operands[3] == 0
3816 || operands[4] == 0 || operands[5] == 0)
3817 FAIL;
3818 }")
3819
3820 (define_insn "*movdi_media"
3821 [(set (match_operand:DI 0 "general_movdst_operand"
3822 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3823 (match_operand:DI 1 "general_movsrc_operand"
3824 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3825 "TARGET_SHMEDIA_FPU
3826 && (register_operand (operands[0], DImode)
3827 || sh_register_operand (operands[1], DImode))"
3828 "@
3829 add %1, r63, %0
3830 movi %1, %0
3831 #
3832 ld%M1.q %m1, %0
3833 st%M0.q %m0, %N1
3834 fld%M1.d %m1, %0
3835 fst%M0.d %m0, %1
3836 fmov.qd %N1, %0
3837 fmov.dq %1, %0
3838 fmov.d %1, %0
3839 ptabs %1, %0
3840 gettr %1, %0
3841 pt %1, %0"
3842 [(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")
3843 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3844
3845 (define_insn "*movdi_media_nofpu"
3846 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3847 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3848 "TARGET_SHMEDIA
3849 && (register_operand (operands[0], DImode)
3850 || sh_register_operand (operands[1], DImode))"
3851 "@
3852 add %1, r63, %0
3853 movi %1, %0
3854 #
3855 ld%M1.q %m1, %0
3856 st%M0.q %m0, %N1
3857 ptabs %1, %0
3858 gettr %1, %0
3859 pt %1, %0"
3860 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3861 (set_attr "length" "4,4,16,4,4,4,4,*")])
3862
3863 (define_split
3864 [(set (match_operand:DI 0 "arith_reg_operand" "")
3865 (match_operand:DI 1 "immediate_operand" ""))]
3866 "TARGET_SHMEDIA && reload_completed
3867 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3868 [(set (match_dup 0) (match_dup 1))]
3869 "
3870 {
3871 rtx insn;
3872
3873 if (TARGET_SHMEDIA64)
3874 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3875 else
3876 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3877
3878 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3879 REG_NOTES (insn));
3880
3881 DONE;
3882 }")
3883
3884 (define_expand "movdi_const"
3885 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3886 (const:DI (sign_extend:DI
3887 (truncate:HI
3888 (ashiftrt:DI
3889 (match_operand:DI 1 "immediate_operand" "s")
3890 (const_int 48))))))
3891 (set (match_dup 0)
3892 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3893 (zero_extend:DI
3894 (truncate:HI
3895 (const:DI
3896 (sign_extend:DI
3897 (truncate:HI
3898 (ashiftrt:SI
3899 (match_dup 1)
3900 (const_int 32)))))))))
3901 (set (match_dup 0)
3902 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3903 (zero_extend:DI
3904 (truncate:HI
3905 (const:DI
3906 (sign_extend:DI
3907 (truncate:HI
3908 (ashiftrt:SI
3909 (match_dup 1)
3910 (const_int 16)))))))))
3911 (set (match_dup 0)
3912 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3913 (zero_extend:DI
3914 (truncate:HI
3915 (const:DI
3916 (sign_extend:DI
3917 (truncate:HI
3918 (match_dup 1))))))))]
3919 "TARGET_SHMEDIA64 && reload_completed
3920 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3921 "
3922 {
3923 sh_mark_label (operands[1], 4);
3924 }")
3925
3926 (define_expand "movdi_const_32bit"
3927 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3928 (const:DI (sign_extend:DI
3929 (truncate:HI
3930 (ashiftrt:DI
3931 (match_operand:DI 1 "immediate_operand" "s")
3932 (const_int 16))))))
3933 (set (match_dup 0)
3934 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3935 (zero_extend:DI
3936 (truncate:HI
3937 (const:DI
3938 (sign_extend:DI
3939 (truncate:HI
3940 (match_dup 1))))))))]
3941 "TARGET_SHMEDIA32 && reload_completed
3942 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3943 "
3944 {
3945 sh_mark_label (operands[1], 2);
3946 }")
3947
3948 (define_expand "movdi_const_16bit"
3949 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3950 (const:DI (sign_extend:DI
3951 (truncate:HI
3952 (match_operand:DI 1 "immediate_operand" "s")))))]
3953 "TARGET_SHMEDIA && flag_pic && reload_completed
3954 && GET_CODE (operands[1]) == SYMBOL_REF"
3955 "")
3956
3957 (define_split
3958 [(set (match_operand:DI 0 "arith_reg_operand" "")
3959 (match_operand:DI 1 "immediate_operand" ""))]
3960 "TARGET_SHMEDIA && reload_completed
3961 && GET_CODE (operands[1]) == CONST_INT
3962 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3963 [(set (match_dup 0) (match_dup 2))
3964 (match_dup 1)]
3965 "
3966 {
3967 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3968 unsigned HOST_WIDE_INT low = val;
3969 unsigned HOST_WIDE_INT high = val;
3970 unsigned HOST_WIDE_INT sign;
3971 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3972
3973 /* Sign-extend the 16 least-significant bits. */
3974 low &= 0xffff;
3975 low ^= 0x8000;
3976 low -= 0x8000;
3977
3978 /* Arithmetic shift right the word by 16 bits. */
3979 high >>= 16;
3980 sign = 1;
3981 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3982 high ^= sign;
3983 high -= sign;
3984 do
3985 {
3986 /* If we can't generate the constant with a two-insn movi / shori
3987 sequence, try some other strategies. */
3988 if (! CONST_OK_FOR_I16 (high))
3989 {
3990 /* Try constant load / left shift. We know VAL != 0. */
3991 val2 = val ^ (val-1);
3992 if (val2 > 0x1ffff)
3993 {
3994 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3995
3996 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
3997 || (! CONST_OK_FOR_I16 (high >> 16)
3998 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
3999 {
4000 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4001 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4002 GEN_INT (trailing_zeroes));
4003 break;
4004 }
4005 }
4006 /* Try constant load / right shift. */
4007 val2 = (val >> 15) + 1;
4008 if (val2 == (val2 & -val2))
4009 {
4010 int shift = 49 - exact_log2 (val2);
4011
4012 val2 = trunc_int_for_mode (val << shift, DImode);
4013 if (CONST_OK_FOR_I16 (val2))
4014 {
4015 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4016 GEN_INT (shift));
4017 break;
4018 }
4019 }
4020 /* Try mperm.w . */
4021 val2 = val & 0xffff;
4022 if ((val >> 16 & 0xffff) == val2
4023 && (val >> 32 & 0xffff) == val2
4024 && (val >> 48 & 0xffff) == val2)
4025 {
4026 val2 = (HOST_WIDE_INT) val >> 48;
4027 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4028 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4029 break;
4030 }
4031 /* Try movi / mshflo.l */
4032 val2 = (HOST_WIDE_INT) val >> 32;
4033 if (val2 == ((unsigned HOST_WIDE_INT)
4034 trunc_int_for_mode (val, SImode)))
4035 {
4036 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4037 operands[0]);
4038 break;
4039 }
4040 /* Try movi / mshflo.l w/ r63. */
4041 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4042 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4043 {
4044 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4045 const0_rtx);
4046 break;
4047 }
4048 }
4049 val2 = high;
4050 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4051 }
4052 while (0);
4053 operands[2] = GEN_INT (val2);
4054 }")
4055
4056 (define_split
4057 [(set (match_operand:DI 0 "arith_reg_operand" "")
4058 (match_operand:DI 1 "immediate_operand" ""))]
4059 "TARGET_SHMEDIA && reload_completed
4060 && GET_CODE (operands[1]) == CONST_DOUBLE"
4061 [(set (match_dup 0) (match_dup 2))
4062 (set (match_dup 0)
4063 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4064 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4065 "
4066 {
4067 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4068 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4069 unsigned HOST_WIDE_INT val = low;
4070 unsigned HOST_WIDE_INT sign;
4071
4072 /* Sign-extend the 16 least-significant bits. */
4073 val &= 0xffff;
4074 val ^= 0x8000;
4075 val -= 0x8000;
4076 operands[1] = GEN_INT (val);
4077
4078 /* Arithmetic shift right the double-word by 16 bits. */
4079 low >>= 16;
4080 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4081 high >>= 16;
4082 sign = 1;
4083 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4084 high ^= sign;
4085 high -= sign;
4086
4087 /* This will only be true if high is a sign-extension of low, i.e.,
4088 it must be either 0 or (unsigned)-1, and be zero iff the
4089 most-significant bit of low is set. */
4090 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4091 operands[2] = GEN_INT (low);
4092 else
4093 operands[2] = immed_double_const (low, high, DImode);
4094 }")
4095
4096 (define_insn "shori_media"
4097 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4098 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4099 (const_int 16))
4100 (zero_extend:DI
4101 (truncate:HI
4102 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4103 "TARGET_SHMEDIA"
4104 "@
4105 shori %u2, %0
4106 #"
4107 [(set_attr "type" "arith_media,*")])
4108
4109 (define_expand "movdi"
4110 [(set (match_operand:DI 0 "general_movdst_operand" "")
4111 (match_operand:DI 1 "general_movsrc_operand" ""))]
4112 ""
4113 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4114
4115 (define_insn "movdf_media"
4116 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4117 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4118 "TARGET_SHMEDIA_FPU
4119 && (register_operand (operands[0], DFmode)
4120 || sh_register_operand (operands[1], DFmode))"
4121 "@
4122 fmov.d %1, %0
4123 fmov.qd %N1, %0
4124 fmov.dq %1, %0
4125 add %1, r63, %0
4126 #
4127 fld%M1.d %m1, %0
4128 fst%M0.d %m0, %1
4129 ld%M1.q %m1, %0
4130 st%M0.q %m0, %N1"
4131 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4132
4133 (define_insn "movdf_media_nofpu"
4134 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4135 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4136 "TARGET_SHMEDIA
4137 && (register_operand (operands[0], DFmode)
4138 || sh_register_operand (operands[1], DFmode))"
4139 "@
4140 add %1, r63, %0
4141 #
4142 ld%M1.q %m1, %0
4143 st%M0.q %m0, %N1"
4144 [(set_attr "type" "arith_media,*,load_media,store_media")])
4145
4146 (define_split
4147 [(set (match_operand:DF 0 "arith_reg_operand" "")
4148 (match_operand:DF 1 "immediate_operand" ""))]
4149 "TARGET_SHMEDIA && reload_completed"
4150 [(set (match_dup 3) (match_dup 2))]
4151 "
4152 {
4153 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4154 long values[2];
4155 REAL_VALUE_TYPE value;
4156
4157 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4158 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4159
4160 if (HOST_BITS_PER_WIDE_INT >= 64)
4161 operands[2] = immed_double_const ((unsigned long) values[endian]
4162 | ((HOST_WIDE_INT) values[1 - endian]
4163 << 32), 0, DImode);
4164 else if (HOST_BITS_PER_WIDE_INT == 32)
4165 operands[2] = immed_double_const (values[endian], values[1 - endian],
4166 DImode);
4167 else
4168 abort ();
4169
4170 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4171 }")
4172
4173 ;; ??? This should be a define expand.
4174
4175 (define_insn "movdf_k"
4176 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4177 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4178 "TARGET_SH1
4179 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4180 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4181 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4182 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4183 && (arith_reg_operand (operands[0], DFmode)
4184 || arith_reg_operand (operands[1], DFmode))"
4185 "* return output_movedouble (insn, operands, DFmode);"
4186 [(set_attr "length" "4")
4187 (set_attr "type" "move,pcload,load,store")])
4188
4189 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4190 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4191 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4192 ;; the d/m/c/X alternative, which is split later into single-precision
4193 ;; instructions. And when not optimizing, no splits are done before fixing
4194 ;; up pcloads, so we need usable length information for that.
4195 (define_insn "movdf_i4"
4196 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4197 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4198 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4199 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4200 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4201 && (arith_reg_operand (operands[0], DFmode)
4202 || arith_reg_operand (operands[1], DFmode))"
4203 "@
4204 fmov %1,%0
4205 #
4206 #
4207 fmov.d %1,%0
4208 fmov.d %1,%0
4209 #
4210 #
4211 #
4212 #
4213 #"
4214 [(set_attr_alternative "length"
4215 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4216 (const_int 4)
4217 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4218 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4219 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4220 (const_int 4)
4221 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4222 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4223 ;; increment or decrement r15 explicitly.
4224 (if_then_else
4225 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4226 (const_int 10) (const_int 8))
4227 (if_then_else
4228 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4229 (const_int 10) (const_int 8))])
4230 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4231 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4232 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4233 (const_string "double")
4234 (const_string "none")))])
4235
4236 ;; Moving DFmode between fp/general registers through memory
4237 ;; (the top of the stack) is faster than moving through fpul even for
4238 ;; little endian. Because the type of an instruction is important for its
4239 ;; scheduling, it is beneficial to split these operations, rather than
4240 ;; emitting them in one single chunk, even if this will expose a stack
4241 ;; use that will prevent scheduling of other stack accesses beyond this
4242 ;; instruction.
4243 (define_split
4244 [(set (match_operand:DF 0 "register_operand" "")
4245 (match_operand:DF 1 "register_operand" ""))
4246 (use (match_operand:PSI 2 "fpscr_operand" ""))
4247 (clobber (match_scratch:SI 3 "=X"))]
4248 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4249 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4250 [(const_int 0)]
4251 "
4252 {
4253 rtx insn, tos;
4254
4255 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4256 {
4257 emit_move_insn (stack_pointer_rtx,
4258 plus_constant (stack_pointer_rtx, -8));
4259 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4260 }
4261 else
4262 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4263 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4264 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4265 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4266 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4267 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4268 else
4269 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4270 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4271 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4272 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4273 else
4274 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4275 DONE;
4276 }")
4277
4278 ;; local-alloc sometimes allocates scratch registers even when not required,
4279 ;; so we must be prepared to handle these.
4280
4281 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4282 (define_split
4283 [(set (match_operand:DF 0 "general_movdst_operand" "")
4284 (match_operand:DF 1 "general_movsrc_operand" ""))
4285 (use (match_operand:PSI 2 "fpscr_operand" ""))
4286 (clobber (match_scratch:SI 3 ""))]
4287 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4288 && reload_completed
4289 && true_regnum (operands[0]) < 16
4290 && true_regnum (operands[1]) < 16"
4291 [(set (match_dup 0) (match_dup 1))]
4292 "
4293 {
4294 /* If this was a reg <-> mem operation with base + index reg addressing,
4295 we have to handle this in a special way. */
4296 rtx mem = operands[0];
4297 int store_p = 1;
4298 if (! memory_operand (mem, DFmode))
4299 {
4300 mem = operands[1];
4301 store_p = 0;
4302 }
4303 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4304 mem = SUBREG_REG (mem);
4305 if (GET_CODE (mem) == MEM)
4306 {
4307 rtx addr = XEXP (mem, 0);
4308 if (GET_CODE (addr) == PLUS
4309 && GET_CODE (XEXP (addr, 0)) == REG
4310 && GET_CODE (XEXP (addr, 1)) == REG)
4311 {
4312 int offset;
4313 rtx reg0 = gen_rtx_REG (Pmode, 0);
4314 rtx regop = operands[store_p], word0 ,word1;
4315
4316 if (GET_CODE (regop) == SUBREG)
4317 alter_subreg (&regop);
4318 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4319 offset = 2;
4320 else
4321 offset = 4;
4322 mem = copy_rtx (mem);
4323 PUT_MODE (mem, SImode);
4324 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4325 alter_subreg (&word0);
4326 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4327 alter_subreg (&word1);
4328 if (store_p || ! refers_to_regno_p (REGNO (word0),
4329 REGNO (word0) + 1, addr, 0))
4330 {
4331 emit_insn (store_p
4332 ? gen_movsi_ie (mem, word0)
4333 : gen_movsi_ie (word0, mem));
4334 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4335 mem = copy_rtx (mem);
4336 emit_insn (store_p
4337 ? gen_movsi_ie (mem, word1)
4338 : gen_movsi_ie (word1, mem));
4339 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4340 }
4341 else
4342 {
4343 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4344 emit_insn (gen_movsi_ie (word1, mem));
4345 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4346 mem = copy_rtx (mem);
4347 emit_insn (gen_movsi_ie (word0, mem));
4348 }
4349 DONE;
4350 }
4351 }
4352 }")
4353
4354 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4355 (define_split
4356 [(set (match_operand:DF 0 "register_operand" "")
4357 (match_operand:DF 1 "memory_operand" ""))
4358 (use (match_operand:PSI 2 "fpscr_operand" ""))
4359 (clobber (reg:SI R0_REG))]
4360 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4361 [(parallel [(set (match_dup 0) (match_dup 1))
4362 (use (match_dup 2))
4363 (clobber (scratch:SI))])]
4364 "")
4365
4366 (define_expand "reload_indf"
4367 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4368 (match_operand:DF 1 "immediate_operand" "FQ"))
4369 (use (reg:PSI FPSCR_REG))
4370 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4371 "TARGET_SH1"
4372 "")
4373
4374 (define_expand "reload_outdf"
4375 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4376 (match_operand:DF 1 "register_operand" "af,r"))
4377 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4378 "TARGET_SH1"
4379 "")
4380
4381 ;; Simplify no-op moves.
4382 (define_split
4383 [(set (match_operand:SF 0 "register_operand" "")
4384 (match_operand:SF 1 "register_operand" ""))
4385 (use (match_operand:PSI 2 "fpscr_operand" ""))
4386 (clobber (match_scratch:SI 3 ""))]
4387 "TARGET_SH2E && reload_completed
4388 && true_regnum (operands[0]) == true_regnum (operands[1])"
4389 [(set (match_dup 0) (match_dup 0))]
4390 "")
4391
4392 ;; fmovd substitute post-reload splits
4393 (define_split
4394 [(set (match_operand:DF 0 "register_operand" "")
4395 (match_operand:DF 1 "register_operand" ""))
4396 (use (match_operand:PSI 2 "fpscr_operand" ""))
4397 (clobber (match_scratch:SI 3 ""))]
4398 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4399 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4400 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4401 [(const_int 0)]
4402 "
4403 {
4404 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4405 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4406 gen_rtx_REG (SFmode, src), operands[2]));
4407 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4408 gen_rtx_REG (SFmode, src + 1), operands[2]));
4409 DONE;
4410 }")
4411
4412 (define_split
4413 [(set (match_operand:DF 0 "register_operand" "")
4414 (mem:DF (match_operand:SI 1 "register_operand" "")))
4415 (use (match_operand:PSI 2 "fpscr_operand" ""))
4416 (clobber (match_scratch:SI 3 ""))]
4417 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4418 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4419 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4420 [(const_int 0)]
4421 "
4422 {
4423 int regno = true_regnum (operands[0]);
4424 rtx insn;
4425 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4426
4427 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4428 regno + !! TARGET_LITTLE_ENDIAN),
4429 mem2, operands[2]));
4430 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4431 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4432 regno + ! TARGET_LITTLE_ENDIAN),
4433 gen_rtx_MEM (SFmode, operands[1]),
4434 operands[2]));
4435 DONE;
4436 }")
4437
4438 (define_split
4439 [(set (match_operand:DF 0 "register_operand" "")
4440 (match_operand:DF 1 "memory_operand" ""))
4441 (use (match_operand:PSI 2 "fpscr_operand" ""))
4442 (clobber (match_scratch:SI 3 ""))]
4443 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4444 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4445 [(const_int 0)]
4446 "
4447 {
4448 int regno = true_regnum (operands[0]);
4449 rtx addr, insn, adjust = NULL_RTX;
4450 rtx mem2 = copy_rtx (operands[1]);
4451 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4452 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4453
4454 PUT_MODE (mem2, SFmode);
4455 operands[1] = copy_rtx (mem2);
4456 addr = XEXP (mem2, 0);
4457 if (GET_CODE (addr) != POST_INC)
4458 {
4459 /* If we have to modify the stack pointer, the value that we have
4460 read with post-increment might be modified by an interrupt,
4461 so write it back. */
4462 if (REGNO (addr) == STACK_POINTER_REGNUM)
4463 adjust = gen_push_e (reg0);
4464 else
4465 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4466 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4467 }
4468 addr = XEXP (addr, 0);
4469 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4470 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4471 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4472 if (adjust)
4473 emit_insn (adjust);
4474 else
4475 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4476 DONE;
4477 }")
4478
4479 (define_split
4480 [(set (match_operand:DF 0 "memory_operand" "")
4481 (match_operand:DF 1 "register_operand" ""))
4482 (use (match_operand:PSI 2 "fpscr_operand" ""))
4483 (clobber (match_scratch:SI 3 ""))]
4484 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4485 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4486 [(const_int 0)]
4487 "
4488 {
4489 int regno = true_regnum (operands[1]);
4490 rtx insn, addr, adjust = NULL_RTX;
4491
4492 operands[0] = copy_rtx (operands[0]);
4493 PUT_MODE (operands[0], SFmode);
4494 insn = emit_insn (gen_movsf_ie (operands[0],
4495 gen_rtx_REG (SFmode,
4496 regno + ! TARGET_LITTLE_ENDIAN),
4497 operands[2]));
4498 operands[0] = copy_rtx (operands[0]);
4499 addr = XEXP (operands[0], 0);
4500 if (GET_CODE (addr) != PRE_DEC)
4501 {
4502 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4503 emit_insn_before (adjust, insn);
4504 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4505 }
4506 addr = XEXP (addr, 0);
4507 if (! adjust)
4508 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4509 insn = emit_insn (gen_movsf_ie (operands[0],
4510 gen_rtx_REG (SFmode,
4511 regno + !! TARGET_LITTLE_ENDIAN),
4512 operands[2]));
4513 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4514 DONE;
4515 }")
4516
4517 ;; If the output is a register and the input is memory or a register, we have
4518 ;; to be careful and see which word needs to be loaded first.
4519
4520 (define_split
4521 [(set (match_operand:DF 0 "general_movdst_operand" "")
4522 (match_operand:DF 1 "general_movsrc_operand" ""))]
4523 "TARGET_SH1 && reload_completed"
4524 [(set (match_dup 2) (match_dup 3))
4525 (set (match_dup 4) (match_dup 5))]
4526 "
4527 {
4528 int regno;
4529
4530 if ((GET_CODE (operands[0]) == MEM
4531 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4532 || (GET_CODE (operands[1]) == MEM
4533 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4534 FAIL;
4535
4536 if (GET_CODE (operands[0]) == REG)
4537 regno = REGNO (operands[0]);
4538 else if (GET_CODE (operands[0]) == SUBREG)
4539 regno = subreg_regno (operands[0]);
4540 else if (GET_CODE (operands[0]) == MEM)
4541 regno = -1;
4542 else
4543 abort ();
4544
4545 if (regno == -1
4546 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4547 {
4548 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4549 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4550 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4551 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4552 }
4553 else
4554 {
4555 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4556 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4557 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4558 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4559 }
4560
4561 if (operands[2] == 0 || operands[3] == 0
4562 || operands[4] == 0 || operands[5] == 0)
4563 FAIL;
4564 }")
4565
4566 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4567 ;; used only once, let combine add in the index again.
4568
4569 (define_split
4570 [(set (match_operand:SI 0 "register_operand" "")
4571 (match_operand:SI 1 "" ""))
4572 (clobber (match_operand 2 "register_operand" ""))]
4573 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4574 [(use (reg:SI R0_REG))]
4575 "
4576 {
4577 rtx addr, reg, const_int;
4578
4579 if (GET_CODE (operands[1]) != MEM)
4580 FAIL;
4581 addr = XEXP (operands[1], 0);
4582 if (GET_CODE (addr) != PLUS)
4583 FAIL;
4584 reg = XEXP (addr, 0);
4585 const_int = XEXP (addr, 1);
4586 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4587 && GET_CODE (const_int) == CONST_INT))
4588 FAIL;
4589 emit_move_insn (operands[2], const_int);
4590 emit_move_insn (operands[0],
4591 change_address (operands[1], VOIDmode,
4592 gen_rtx_PLUS (SImode, reg, operands[2])));
4593 DONE;
4594 }")
4595
4596 (define_split
4597 [(set (match_operand:SI 1 "" "")
4598 (match_operand:SI 0 "register_operand" ""))
4599 (clobber (match_operand 2 "register_operand" ""))]
4600 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4601 [(use (reg:SI R0_REG))]
4602 "
4603 {
4604 rtx addr, reg, const_int;
4605
4606 if (GET_CODE (operands[1]) != MEM)
4607 FAIL;
4608 addr = XEXP (operands[1], 0);
4609 if (GET_CODE (addr) != PLUS)
4610 FAIL;
4611 reg = XEXP (addr, 0);
4612 const_int = XEXP (addr, 1);
4613 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4614 && GET_CODE (const_int) == CONST_INT))
4615 FAIL;
4616 emit_move_insn (operands[2], const_int);
4617 emit_move_insn (change_address (operands[1], VOIDmode,
4618 gen_rtx_PLUS (SImode, reg, operands[2])),
4619 operands[0]);
4620 DONE;
4621 }")
4622
4623 (define_expand "movdf"
4624 [(set (match_operand:DF 0 "general_movdst_operand" "")
4625 (match_operand:DF 1 "general_movsrc_operand" ""))]
4626 ""
4627 "
4628 {
4629 if (prepare_move_operands (operands, DFmode)) DONE;
4630 if (TARGET_SHMEDIA)
4631 {
4632 if (TARGET_SHMEDIA_FPU)
4633 emit_insn (gen_movdf_media (operands[0], operands[1]));
4634 else
4635 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4636 DONE;
4637 }
4638 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4639 {
4640 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4641 DONE;
4642 }
4643 }")
4644
4645 ;;This is incompatible with the way gcc uses subregs.
4646 ;;(define_insn "movv2sf_i"
4647 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4648 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4649 ;; "TARGET_SHMEDIA_FPU
4650 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4651 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4652 ;; "@
4653 ;; #
4654 ;; fld%M1.p %m1, %0
4655 ;; fst%M0.p %m0, %1"
4656 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4657
4658 (define_insn_and_split "movv2sf_i"
4659 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4660 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4661 "TARGET_SHMEDIA_FPU"
4662 "#"
4663 "TARGET_SHMEDIA_FPU && reload_completed"
4664 [(set (match_dup 0) (match_dup 1))]
4665 "
4666 {
4667 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4668 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4669 }")
4670
4671 (define_expand "movv2sf"
4672 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4673 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4674 "TARGET_SHMEDIA_FPU"
4675 "
4676 {
4677 if (prepare_move_operands (operands, V2SFmode))
4678 DONE;
4679 }")
4680
4681 (define_expand "addv2sf3"
4682 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4683 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4684 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4685 "TARGET_SHMEDIA_FPU"
4686 "
4687 {
4688 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4689 DONE;
4690 }")
4691
4692 (define_expand "subv2sf3"
4693 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4694 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4695 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4696 "TARGET_SHMEDIA_FPU"
4697 "
4698 {
4699 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4700 DONE;
4701 }")
4702
4703 (define_expand "mulv2sf3"
4704 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4705 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4706 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4707 "TARGET_SHMEDIA_FPU"
4708 "
4709 {
4710 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4711 DONE;
4712 }")
4713
4714 (define_expand "divv2sf3"
4715 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4716 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4717 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4718 "TARGET_SHMEDIA_FPU"
4719 "
4720 {
4721 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4722 DONE;
4723 }")
4724
4725 (define_insn_and_split "*movv4sf_i"
4726 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4727 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4728 "TARGET_SHMEDIA_FPU"
4729 "#"
4730 "&& reload_completed"
4731 [(const_int 0)]
4732 "
4733 {
4734 int i;
4735
4736 for (i = 0; i < 4/2; i++)
4737 {
4738 rtx x, y;
4739
4740 if (GET_CODE (operands[0]) == MEM)
4741 x = gen_rtx_MEM (V2SFmode,
4742 plus_constant (XEXP (operands[0], 0),
4743 i * GET_MODE_SIZE (V2SFmode)));
4744 else
4745 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4746
4747 if (GET_CODE (operands[1]) == MEM)
4748 y = gen_rtx_MEM (V2SFmode,
4749 plus_constant (XEXP (operands[1], 0),
4750 i * GET_MODE_SIZE (V2SFmode)));
4751 else
4752 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4753
4754 emit_insn (gen_movv2sf_i (x, y));
4755 }
4756
4757 DONE;
4758 }"
4759 [(set_attr "length" "8")])
4760
4761 (define_expand "movv4sf"
4762 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4763 (match_operand:V4SF 1 "general_operand" ""))]
4764 "TARGET_SHMEDIA_FPU"
4765 "
4766 {
4767 if (prepare_move_operands (operands, V4SFmode))
4768 DONE;
4769 }")
4770
4771 (define_insn_and_split "*movv16sf_i"
4772 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4773 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4774 "TARGET_SHMEDIA_FPU"
4775 "#"
4776 "&& reload_completed"
4777 [(const_int 0)]
4778 "
4779 {
4780 int i;
4781
4782 for (i = 0; i < 16/2; i++)
4783 {
4784 rtx x,y;
4785
4786 if (GET_CODE (operands[0]) == MEM)
4787 x = gen_rtx_MEM (V2SFmode,
4788 plus_constant (XEXP (operands[0], 0),
4789 i * GET_MODE_SIZE (V2SFmode)));
4790 else
4791 {
4792 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4793 alter_subreg (&x);
4794 }
4795
4796 if (GET_CODE (operands[1]) == MEM)
4797 y = gen_rtx_MEM (V2SFmode,
4798 plus_constant (XEXP (operands[1], 0),
4799 i * GET_MODE_SIZE (V2SFmode)));
4800 else
4801 {
4802 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4803 alter_subreg (&y);
4804 }
4805
4806 emit_insn (gen_movv2sf_i (x, y));
4807 }
4808
4809 DONE;
4810 }"
4811 [(set_attr "length" "32")])
4812
4813 (define_expand "movv16sf"
4814 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4815 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4816 "TARGET_SHMEDIA_FPU"
4817 "
4818 {
4819 if (prepare_move_operands (operands, V16SFmode))
4820 DONE;
4821 }")
4822
4823 (define_insn "movsf_media"
4824 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4825 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4826 "TARGET_SHMEDIA_FPU
4827 && (register_operand (operands[0], SFmode)
4828 || sh_register_operand (operands[1], SFmode))"
4829 "@
4830 fmov.s %1, %0
4831 fmov.ls %N1, %0
4832 fmov.sl %1, %0
4833 add.l %1, r63, %0
4834 #
4835 fld%M1.s %m1, %0
4836 fst%M0.s %m0, %1
4837 ld%M1.l %m1, %0
4838 st%M0.l %m0, %N1"
4839 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4840
4841 (define_insn "movsf_media_nofpu"
4842 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4843 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4844 "TARGET_SHMEDIA
4845 && (register_operand (operands[0], SFmode)
4846 || sh_register_operand (operands[1], SFmode))"
4847 "@
4848 add.l %1, r63, %0
4849 #
4850 ld%M1.l %m1, %0
4851 st%M0.l %m0, %N1"
4852 [(set_attr "type" "arith_media,*,load_media,store_media")])
4853
4854 (define_split
4855 [(set (match_operand:SF 0 "arith_reg_operand" "")
4856 (match_operand:SF 1 "immediate_operand" ""))]
4857 "TARGET_SHMEDIA && reload_completed
4858 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4859 [(set (match_dup 3) (match_dup 2))]
4860 "
4861 {
4862 long values;
4863 REAL_VALUE_TYPE value;
4864
4865 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4866 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4867 operands[2] = GEN_INT (values);
4868
4869 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4870 }")
4871
4872 (define_insn "movsf_i"
4873 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4874 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4875 "TARGET_SH1
4876 && (! TARGET_SH2E
4877 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4878 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4879 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4880 && (arith_reg_operand (operands[0], SFmode)
4881 || arith_reg_operand (operands[1], SFmode))"
4882 "@
4883 mov %1,%0
4884 mov #0,%0
4885 mov.l %1,%0
4886 mov.l %1,%0
4887 mov.l %1,%0
4888 lds %1,%0
4889 sts %1,%0"
4890 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4891
4892 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4893 ;; update_flow_info would not know where to put REG_EQUAL notes
4894 ;; when the destination changes mode.
4895 (define_insn "movsf_ie"
4896 [(set (match_operand:SF 0 "general_movdst_operand"
4897 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4898 (match_operand:SF 1 "general_movsrc_operand"
4899 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4900 (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"))
4901 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4902
4903 "TARGET_SH2E
4904 && (arith_reg_operand (operands[0], SFmode)
4905 || arith_reg_operand (operands[1], SFmode)
4906 || arith_reg_operand (operands[3], SImode)
4907 || (fpul_operand (operands[0], SFmode)
4908 && memory_operand (operands[1], SFmode)
4909 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4910 || (fpul_operand (operands[1], SFmode)
4911 && memory_operand (operands[0], SFmode)
4912 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4913 "@
4914 fmov %1,%0
4915 mov %1,%0
4916 fldi0 %0
4917 fldi1 %0
4918 #
4919 fmov.s %1,%0
4920 fmov.s %1,%0
4921 mov.l %1,%0
4922 mov.l %1,%0
4923 mov.l %1,%0
4924 fsts fpul,%0
4925 flds %1,fpul
4926 lds.l %1,%0
4927 #
4928 sts %1,%0
4929 lds %1,%0
4930 sts.l %1,%0
4931 lds.l %1,%0
4932 ! move optimized away"
4933 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4934 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4935 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4936 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4937 (const_string "single")
4938 (const_string "none")))])
4939
4940 (define_split
4941 [(set (match_operand:SF 0 "register_operand" "")
4942 (match_operand:SF 1 "register_operand" ""))
4943 (use (match_operand:PSI 2 "fpscr_operand" ""))
4944 (clobber (reg:SI FPUL_REG))]
4945 "TARGET_SH1"
4946 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4947 (use (match_dup 2))
4948 (clobber (scratch:SI))])
4949 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4950 (use (match_dup 2))
4951 (clobber (scratch:SI))])]
4952 "")
4953
4954 (define_expand "movsf"
4955 [(set (match_operand:SF 0 "general_movdst_operand" "")
4956 (match_operand:SF 1 "general_movsrc_operand" ""))]
4957 ""
4958 "
4959 {
4960 if (prepare_move_operands (operands, SFmode))
4961 DONE;
4962 if (TARGET_SHMEDIA)
4963 {
4964 if (TARGET_SHMEDIA_FPU)
4965 emit_insn (gen_movsf_media (operands[0], operands[1]));
4966 else
4967 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4968 DONE;
4969 }
4970 if (TARGET_SH2E)
4971 {
4972 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4973 DONE;
4974 }
4975 }")
4976
4977 (define_insn "mov_nop"
4978 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4979 "TARGET_SH2E"
4980 ""
4981 [(set_attr "length" "0")
4982 (set_attr "type" "nil")])
4983
4984 (define_expand "reload_insf"
4985 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4986 (match_operand:SF 1 "immediate_operand" "FQ"))
4987 (use (reg:PSI FPSCR_REG))
4988 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4989 "TARGET_SH1"
4990 "")
4991
4992 (define_expand "reload_insi"
4993 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4994 (match_operand:SF 1 "immediate_operand" "FQ"))
4995 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4996 "TARGET_SH1"
4997 "")
4998
4999 (define_insn "*movsi_y"
5000 [(set (match_operand:SI 0 "register_operand" "=y,y")
5001 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5002 (clobber (match_scratch:SI 2 "=&z,r"))]
5003 "TARGET_SH2E
5004 && (reload_in_progress || reload_completed)"
5005 "#"
5006 [(set_attr "length" "4")
5007 (set_attr "type" "pcload,move")])
5008
5009 (define_split
5010 [(set (match_operand:SI 0 "register_operand" "")
5011 (match_operand:SI 1 "immediate_operand" ""))
5012 (clobber (match_operand:SI 2 "register_operand" ""))]
5013 "TARGET_SH1"
5014 [(set (match_dup 2) (match_dup 1))
5015 (set (match_dup 0) (match_dup 2))]
5016 "")
5017
5018 (define_split
5019 [(set (match_operand:SI 0 "register_operand" "")
5020 (match_operand:SI 1 "memory_operand" ""))
5021 (clobber (reg:SI R0_REG))]
5022 "TARGET_SH1"
5023 [(set (match_dup 0) (match_dup 1))]
5024 "")
5025 \f
5026 ;; ------------------------------------------------------------------------
5027 ;; Define the real conditional branch instructions.
5028 ;; ------------------------------------------------------------------------
5029
5030 (define_insn "branch_true"
5031 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5032 (label_ref (match_operand 0 "" ""))
5033 (pc)))]
5034 "TARGET_SH1"
5035 "* return output_branch (1, insn, operands);"
5036 [(set_attr "type" "cbranch")])
5037
5038 (define_insn "branch_false"
5039 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5040 (label_ref (match_operand 0 "" ""))
5041 (pc)))]
5042 "TARGET_SH1"
5043 "* return output_branch (0, insn, operands);"
5044 [(set_attr "type" "cbranch")])
5045
5046 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5047 ;; which destination is too far away.
5048 ;; The const_int_operand is distinct for each branch target; it avoids
5049 ;; unwanted matches with redundant_insn.
5050 (define_insn "block_branch_redirect"
5051 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5052 "TARGET_SH1"
5053 ""
5054 [(set_attr "length" "0")])
5055
5056 ;; This one has the additional purpose to record a possible scratch register
5057 ;; for the following branch.
5058 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5059 ;; because the insn then might be deemed dead and deleted. And we can't
5060 ;; make the use in the jump insn explicit because that would disable
5061 ;; delay slot scheduling from the target.
5062 (define_insn "indirect_jump_scratch"
5063 [(set (match_operand:SI 0 "register_operand" "=r")
5064 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5065 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5066 "TARGET_SH1"
5067 ""
5068 [(set_attr "length" "0")])
5069
5070 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5071 ;; being pulled into the delay slot of a condbranch that has been made to
5072 ;; jump around the unconditional jump because it was out of range.
5073 (define_insn "stuff_delay_slot"
5074 [(set (pc)
5075 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5076 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5077 "TARGET_SH1"
5078 ""
5079 [(set_attr "length" "0")
5080 (set_attr "cond_delay_slot" "yes")])
5081 \f
5082 ;; Conditional branch insns
5083
5084 (define_expand "beq_media"
5085 [(set (pc)
5086 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5087 (match_operand:DI 2 "arith_operand" "r,I06"))
5088 (label_ref:DI (match_operand 0 "" ""))
5089 (pc)))]
5090 "TARGET_SHMEDIA"
5091 "")
5092
5093 (define_insn "*beq_media_i"
5094 [(set (pc)
5095 (if_then_else (match_operator 3 "equality_comparison_operator"
5096 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5097 (match_operand:DI 2 "arith_operand" "r,I06")])
5098 (match_operand:DI 0 "target_operand" "b,b")
5099 (pc)))]
5100 "TARGET_SHMEDIA"
5101 "@
5102 b%o3%' %1, %2, %0
5103 b%o3i%' %1, %2, %0"
5104 [(set_attr "type" "cbranch_media")])
5105
5106 (define_expand "bne_media"
5107 [(set (pc)
5108 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5109 (match_operand:DI 2 "arith_operand" "r,I06"))
5110 (label_ref:DI (match_operand 0 "" ""))
5111 (pc)))]
5112 "TARGET_SHMEDIA"
5113 "")
5114
5115 (define_expand "bgt_media"
5116 [(set (pc)
5117 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5118 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5119 (label_ref:DI (match_operand 0 "" ""))
5120 (pc)))]
5121 "TARGET_SHMEDIA"
5122 "")
5123
5124 (define_expand "bge_media"
5125 [(set (pc)
5126 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5127 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5128 (label_ref:DI (match_operand 0 "" ""))
5129 (pc)))]
5130 "TARGET_SHMEDIA"
5131 "")
5132
5133 (define_expand "bgtu_media"
5134 [(set (pc)
5135 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5136 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5137 (label_ref:DI (match_operand 0 "" ""))
5138 (pc)))]
5139 "TARGET_SHMEDIA"
5140 "")
5141
5142 (define_expand "bgeu_media"
5143 [(set (pc)
5144 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5145 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5146 (label_ref:DI (match_operand 0 "" ""))
5147 (pc)))]
5148 "TARGET_SHMEDIA"
5149 "")
5150
5151 (define_insn "*bgt_media_i"
5152 [(set (pc)
5153 (if_then_else (match_operator 3 "greater_comparison_operator"
5154 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5155 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5156 (match_operand:DI 0 "target_operand" "b")
5157 (pc)))]
5158 "TARGET_SHMEDIA"
5159 "b%o3%' %N1, %N2, %0"
5160 [(set_attr "type" "cbranch_media")])
5161
5162 ;; These are only needed to make invert_jump() happy.
5163 (define_insn "*blt_media_i"
5164 [(set (pc)
5165 (if_then_else (match_operator 3 "less_comparison_operator"
5166 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5167 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5168 (match_operand:DI 0 "target_operand" "b")
5169 (pc)))]
5170 "TARGET_SHMEDIA"
5171 "b%o3%' %N2, %N1, %0"
5172 [(set_attr "type" "cbranch_media")])
5173
5174 (define_expand "beq"
5175 [(set (pc)
5176 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5177 (label_ref (match_operand 0 "" ""))
5178 (pc)))]
5179 ""
5180 "
5181 {
5182 if (TARGET_SHMEDIA)
5183 {
5184 if (GET_MODE (sh_compare_op0) != DImode)
5185 {
5186 rtx tmp = gen_reg_rtx (DImode);
5187
5188 emit_insn (gen_seq (tmp));
5189 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5190 DONE;
5191 }
5192
5193 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5194 emit_jump_insn (gen_beq_media (operands[0],
5195 sh_compare_op0, sh_compare_op1));
5196 DONE;
5197 }
5198
5199 from_compare (operands, EQ);
5200 }")
5201
5202 (define_expand "bne"
5203 [(set (pc)
5204 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5205 (label_ref (match_operand 0 "" ""))
5206 (pc)))]
5207 ""
5208 "
5209 {
5210 if (TARGET_SHMEDIA)
5211 {
5212 if (GET_MODE (sh_compare_op0) != DImode)
5213 {
5214 rtx tmp = gen_reg_rtx (DImode);
5215
5216 emit_insn (gen_seq (tmp));
5217 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5218 DONE;
5219 }
5220
5221 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5222 emit_jump_insn (gen_bne_media (operands[0],
5223 sh_compare_op0, sh_compare_op1));
5224 DONE;
5225 }
5226
5227 from_compare (operands, EQ);
5228 }")
5229
5230 (define_expand "bgt"
5231 [(set (pc)
5232 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5233 (label_ref (match_operand 0 "" ""))
5234 (pc)))]
5235 ""
5236 "
5237 {
5238 if (TARGET_SHMEDIA)
5239 {
5240 if (GET_MODE (sh_compare_op0) != DImode)
5241 {
5242 rtx tmp = gen_reg_rtx (DImode);
5243
5244 emit_insn (gen_sgt (tmp));
5245 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5246 DONE;
5247 }
5248
5249 if (sh_compare_op0 != const0_rtx)
5250 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5251 if (sh_compare_op1 != const0_rtx)
5252 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5253 emit_jump_insn (gen_bgt_media (operands[0],
5254 sh_compare_op0, sh_compare_op1));
5255 DONE;
5256 }
5257
5258 from_compare (operands, GT);
5259 }")
5260
5261 (define_expand "blt"
5262 [(set (pc)
5263 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5264 (label_ref (match_operand 0 "" ""))
5265 (pc)))]
5266 ""
5267 "
5268 {
5269 if (TARGET_SHMEDIA)
5270 {
5271 if (GET_MODE (sh_compare_op0) != DImode)
5272 {
5273 rtx tmp = gen_reg_rtx (DImode);
5274
5275 emit_insn (gen_slt (tmp));
5276 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5277 DONE;
5278 }
5279
5280 if (sh_compare_op0 != const0_rtx)
5281 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5282 if (sh_compare_op1 != const0_rtx)
5283 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5284 emit_jump_insn (gen_bgt_media (operands[0],
5285 sh_compare_op1, sh_compare_op0));
5286 DONE;
5287 }
5288
5289 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5290 {
5291 rtx tmp = sh_compare_op0;
5292 sh_compare_op0 = sh_compare_op1;
5293 sh_compare_op1 = tmp;
5294 emit_insn (gen_bgt (operands[0]));
5295 DONE;
5296 }
5297 from_compare (operands, GE);
5298 }")
5299
5300 (define_expand "ble"
5301 [(set (pc)
5302 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5303 (label_ref (match_operand 0 "" ""))
5304 (pc)))]
5305 ""
5306 "
5307 {
5308 if (TARGET_SHMEDIA)
5309 {
5310 if (GET_MODE (sh_compare_op0) != DImode)
5311 {
5312 rtx tmp = gen_reg_rtx (DImode);
5313
5314 emit_insn (gen_sle (tmp));
5315 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5316 DONE;
5317 }
5318
5319 if (sh_compare_op0 != const0_rtx)
5320 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5321 if (sh_compare_op1 != const0_rtx)
5322 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5323 emit_jump_insn (gen_bge_media (operands[0],
5324 sh_compare_op1, sh_compare_op0));
5325 DONE;
5326 }
5327
5328 if (TARGET_SH2E
5329 && TARGET_IEEE
5330 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5331 {
5332 rtx tmp = sh_compare_op0;
5333 sh_compare_op0 = sh_compare_op1;
5334 sh_compare_op1 = tmp;
5335 emit_insn (gen_bge (operands[0]));
5336 DONE;
5337 }
5338 from_compare (operands, GT);
5339 }")
5340
5341 (define_expand "bge"
5342 [(set (pc)
5343 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5344 (label_ref (match_operand 0 "" ""))
5345 (pc)))]
5346 ""
5347 "
5348 {
5349 if (TARGET_SHMEDIA)
5350 {
5351 if (GET_MODE (sh_compare_op0) != DImode)
5352 {
5353 rtx tmp = gen_reg_rtx (DImode);
5354
5355 emit_insn (gen_sge (tmp));
5356 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5357 DONE;
5358 }
5359
5360 if (sh_compare_op0 != const0_rtx)
5361 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5362 if (sh_compare_op1 != const0_rtx)
5363 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5364 emit_jump_insn (gen_bge_media (operands[0],
5365 sh_compare_op0, sh_compare_op1));
5366 DONE;
5367 }
5368
5369 if (TARGET_SH2E
5370 && ! TARGET_IEEE
5371 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5372 {
5373 rtx tmp = sh_compare_op0;
5374 sh_compare_op0 = sh_compare_op1;
5375 sh_compare_op1 = tmp;
5376 emit_insn (gen_ble (operands[0]));
5377 DONE;
5378 }
5379 from_compare (operands, GE);
5380 }")
5381
5382 (define_expand "bgtu"
5383 [(set (pc)
5384 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5385 (label_ref (match_operand 0 "" ""))
5386 (pc)))]
5387 ""
5388 "
5389 {
5390 if (TARGET_SHMEDIA)
5391 {
5392 if (sh_compare_op0 != const0_rtx)
5393 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5394 if (sh_compare_op1 != const0_rtx)
5395 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5396 emit_jump_insn (gen_bgtu_media (operands[0],
5397 sh_compare_op0, sh_compare_op1));
5398 DONE;
5399 }
5400
5401 from_compare (operands, GTU);
5402 }")
5403
5404 (define_expand "bltu"
5405 [(set (pc)
5406 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5407 (label_ref (match_operand 0 "" ""))
5408 (pc)))]
5409 ""
5410 "
5411 {
5412 if (TARGET_SHMEDIA)
5413 {
5414 if (sh_compare_op0 != const0_rtx)
5415 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5416 if (sh_compare_op1 != const0_rtx)
5417 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5418 emit_jump_insn (gen_bgtu_media (operands[0],
5419 sh_compare_op1, sh_compare_op0));
5420 DONE;
5421 }
5422
5423 from_compare (operands, GEU);
5424 }")
5425
5426 (define_expand "bgeu"
5427 [(set (pc)
5428 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5429 (label_ref (match_operand 0 "" ""))
5430 (pc)))]
5431 ""
5432 "
5433 {
5434 if (TARGET_SHMEDIA)
5435 {
5436 if (sh_compare_op0 != const0_rtx)
5437 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5438 if (sh_compare_op1 != const0_rtx)
5439 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5440 emit_jump_insn (gen_bgeu_media (operands[0],
5441 sh_compare_op0, sh_compare_op1));
5442 DONE;
5443 }
5444
5445 from_compare (operands, GEU);
5446 }")
5447
5448 (define_expand "bleu"
5449 [(set (pc)
5450 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5451 (label_ref (match_operand 0 "" ""))
5452 (pc)))]
5453 ""
5454 "
5455 {
5456 if (TARGET_SHMEDIA)
5457 {
5458 if (sh_compare_op0 != const0_rtx)
5459 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5460 if (sh_compare_op1 != const0_rtx)
5461 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5462 emit_jump_insn (gen_bgeu_media (operands[0],
5463 sh_compare_op1, sh_compare_op0));
5464 DONE;
5465 }
5466
5467 from_compare (operands, GTU);
5468 }")
5469
5470 (define_expand "bunordered"
5471 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5472 (set (pc)
5473 (if_then_else (ne (match_dup 1) (const_int 0))
5474 (label_ref:DI (match_operand 0 "" ""))
5475 (pc)))]
5476 "TARGET_SHMEDIA"
5477 "
5478 {
5479 operands[1] = gen_reg_rtx (DImode);
5480 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5481 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5482 }")
5483 \f
5484 ;; ------------------------------------------------------------------------
5485 ;; Jump and linkage insns
5486 ;; ------------------------------------------------------------------------
5487
5488 (define_insn "jump_compact"
5489 [(set (pc)
5490 (label_ref (match_operand 0 "" "")))]
5491 "TARGET_SH1"
5492 "*
5493 {
5494 /* The length is 16 if the delay slot is unfilled. */
5495 if (get_attr_length(insn) > 4)
5496 return output_far_jump(insn, operands[0]);
5497 else
5498 return \"bra %l0%#\";
5499 }"
5500 [(set_attr "type" "jump")
5501 (set_attr "needs_delay_slot" "yes")])
5502
5503 ;; ??? It would be much saner to explicitly use the scratch register
5504 ;; in the jump insn, and have indirect_jump_scratch only set it,
5505 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5506 ;; from the target then, as it uses simplejump_p.
5507 ;;(define_insn "jump_compact_far"
5508 ;; [(set (pc)
5509 ;; (label_ref (match_operand 0 "" "")))
5510 ;; (use (match_operand 1 "register_operand" "r")]
5511 ;; "TARGET_SH1"
5512 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5513 ;; [(set_attr "type" "jump")
5514 ;; (set_attr "needs_delay_slot" "yes")])
5515
5516 (define_insn "jump_media"
5517 [(set (pc)
5518 (match_operand:DI 0 "target_operand" "b"))]
5519 "TARGET_SHMEDIA"
5520 "blink %0, r63"
5521 [(set_attr "type" "jump_media")])
5522
5523 (define_expand "jump"
5524 [(set (pc)
5525 (label_ref (match_operand 0 "" "")))]
5526 ""
5527 "
5528 {
5529 if (TARGET_SH1)
5530 emit_jump_insn (gen_jump_compact (operands[0]));
5531 else if (TARGET_SHMEDIA)
5532 {
5533 if (reload_in_progress || reload_completed)
5534 FAIL;
5535 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5536 operands[0])));
5537 }
5538 DONE;
5539 }")
5540
5541 (define_insn "force_mode_for_call"
5542 [(use (reg:PSI FPSCR_REG))]
5543 "TARGET_SHCOMPACT"
5544 ""
5545 [(set_attr "length" "0")
5546 (set (attr "fp_mode")
5547 (if_then_else (eq_attr "fpu_single" "yes")
5548 (const_string "single") (const_string "double")))])
5549
5550 (define_insn "calli"
5551 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5552 (match_operand 1 "" ""))
5553 (use (reg:PSI FPSCR_REG))
5554 (clobber (reg:SI PR_REG))]
5555 "TARGET_SH1"
5556 "jsr @%0%#"
5557 [(set_attr "type" "call")
5558 (set (attr "fp_mode")
5559 (if_then_else (eq_attr "fpu_single" "yes")
5560 (const_string "single") (const_string "double")))
5561 (set_attr "needs_delay_slot" "yes")
5562 (set_attr "fp_set" "unknown")])
5563
5564 ;; This is a pc-rel call, using bsrf, for use with PIC.
5565
5566 (define_insn "calli_pcrel"
5567 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5568 (match_operand 1 "" ""))
5569 (use (reg:PSI FPSCR_REG))
5570 (use (reg:SI PIC_REG))
5571 (use (match_operand 2 "" ""))
5572 (clobber (reg:SI PR_REG))]
5573 "TARGET_SH2"
5574 "bsrf %0\\n%O2:%#"
5575 [(set_attr "type" "call")
5576 (set (attr "fp_mode")
5577 (if_then_else (eq_attr "fpu_single" "yes")
5578 (const_string "single") (const_string "double")))
5579 (set_attr "needs_delay_slot" "yes")
5580 (set_attr "fp_set" "unknown")])
5581
5582 (define_insn_and_split "call_pcrel"
5583 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5584 (match_operand 1 "" ""))
5585 (use (reg:PSI FPSCR_REG))
5586 (use (reg:SI PIC_REG))
5587 (clobber (reg:SI PR_REG))
5588 (clobber (match_scratch:SI 2 "=r"))]
5589 "TARGET_SH2"
5590 "#"
5591 "reload_completed"
5592 [(const_int 0)]
5593 "
5594 {
5595 rtx lab = PATTERN (gen_call_site ());
5596
5597 if (SYMBOL_REF_LOCAL_P (operands[0]))
5598 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5599 else
5600 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5601 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5602 DONE;
5603 }"
5604 [(set_attr "type" "call")
5605 (set (attr "fp_mode")
5606 (if_then_else (eq_attr "fpu_single" "yes")
5607 (const_string "single") (const_string "double")))
5608 (set_attr "needs_delay_slot" "yes")
5609 (set_attr "fp_set" "unknown")])
5610
5611 (define_insn "call_compact"
5612 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5613 (match_operand 1 "" ""))
5614 (match_operand 2 "immediate_operand" "n")
5615 (use (reg:SI R0_REG))
5616 (use (reg:SI R1_REG))
5617 (use (reg:PSI FPSCR_REG))
5618 (clobber (reg:SI PR_REG))]
5619 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5620 "jsr @%0%#"
5621 [(set_attr "type" "call")
5622 (set (attr "fp_mode")
5623 (if_then_else (eq_attr "fpu_single" "yes")
5624 (const_string "single") (const_string "double")))
5625 (set_attr "needs_delay_slot" "yes")])
5626
5627 (define_insn "call_compact_rettramp"
5628 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5629 (match_operand 1 "" ""))
5630 (match_operand 2 "immediate_operand" "n")
5631 (use (reg:SI R0_REG))
5632 (use (reg:SI R1_REG))
5633 (use (reg:PSI FPSCR_REG))
5634 (clobber (reg:SI R10_REG))
5635 (clobber (reg:SI PR_REG))]
5636 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5637 "jsr @%0%#"
5638 [(set_attr "type" "call")
5639 (set (attr "fp_mode")
5640 (if_then_else (eq_attr "fpu_single" "yes")
5641 (const_string "single") (const_string "double")))
5642 (set_attr "needs_delay_slot" "yes")])
5643
5644 (define_insn "call_media"
5645 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5646 (match_operand 1 "" ""))
5647 (clobber (reg:DI PR_MEDIA_REG))]
5648 "TARGET_SHMEDIA"
5649 "blink %0, r18"
5650 [(set_attr "type" "jump_media")])
5651
5652 (define_insn "call_valuei"
5653 [(set (match_operand 0 "" "=rf")
5654 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5655 (match_operand 2 "" "")))
5656 (use (reg:PSI FPSCR_REG))
5657 (clobber (reg:SI PR_REG))]
5658 "TARGET_SH1"
5659 "jsr @%1%#"
5660 [(set_attr "type" "call")
5661 (set (attr "fp_mode")
5662 (if_then_else (eq_attr "fpu_single" "yes")
5663 (const_string "single") (const_string "double")))
5664 (set_attr "needs_delay_slot" "yes")
5665 (set_attr "fp_set" "unknown")])
5666
5667 (define_insn "call_valuei_pcrel"
5668 [(set (match_operand 0 "" "=rf")
5669 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5670 (match_operand 2 "" "")))
5671 (use (reg:PSI FPSCR_REG))
5672 (use (reg:SI PIC_REG))
5673 (use (match_operand 3 "" ""))
5674 (clobber (reg:SI PR_REG))]
5675 "TARGET_SH2"
5676 "bsrf %1\\n%O3:%#"
5677 [(set_attr "type" "call")
5678 (set (attr "fp_mode")
5679 (if_then_else (eq_attr "fpu_single" "yes")
5680 (const_string "single") (const_string "double")))
5681 (set_attr "needs_delay_slot" "yes")
5682 (set_attr "fp_set" "unknown")])
5683
5684 (define_insn_and_split "call_value_pcrel"
5685 [(set (match_operand 0 "" "=rf")
5686 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5687 (match_operand 2 "" "")))
5688 (use (reg:PSI FPSCR_REG))
5689 (use (reg:SI PIC_REG))
5690 (clobber (reg:SI PR_REG))
5691 (clobber (match_scratch:SI 3 "=r"))]
5692 "TARGET_SH2"
5693 "#"
5694 "reload_completed"
5695 [(const_int 0)]
5696 "
5697 {
5698 rtx lab = PATTERN (gen_call_site ());
5699
5700 if (SYMBOL_REF_LOCAL_P (operands[1]))
5701 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5702 else
5703 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5704 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5705 operands[2], lab));
5706 DONE;
5707 }"
5708 [(set_attr "type" "call")
5709 (set (attr "fp_mode")
5710 (if_then_else (eq_attr "fpu_single" "yes")
5711 (const_string "single") (const_string "double")))
5712 (set_attr "needs_delay_slot" "yes")
5713 (set_attr "fp_set" "unknown")])
5714
5715 (define_insn "call_value_compact"
5716 [(set (match_operand 0 "" "=rf")
5717 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5718 (match_operand 2 "" "")))
5719 (match_operand 3 "immediate_operand" "n")
5720 (use (reg:SI R0_REG))
5721 (use (reg:SI R1_REG))
5722 (use (reg:PSI FPSCR_REG))
5723 (clobber (reg:SI PR_REG))]
5724 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5725 "jsr @%1%#"
5726 [(set_attr "type" "call")
5727 (set (attr "fp_mode")
5728 (if_then_else (eq_attr "fpu_single" "yes")
5729 (const_string "single") (const_string "double")))
5730 (set_attr "needs_delay_slot" "yes")])
5731
5732 (define_insn "call_value_compact_rettramp"
5733 [(set (match_operand 0 "" "=rf")
5734 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5735 (match_operand 2 "" "")))
5736 (match_operand 3 "immediate_operand" "n")
5737 (use (reg:SI R0_REG))
5738 (use (reg:SI R1_REG))
5739 (use (reg:PSI FPSCR_REG))
5740 (clobber (reg:SI R10_REG))
5741 (clobber (reg:SI PR_REG))]
5742 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5743 "jsr @%1%#"
5744 [(set_attr "type" "call")
5745 (set (attr "fp_mode")
5746 (if_then_else (eq_attr "fpu_single" "yes")
5747 (const_string "single") (const_string "double")))
5748 (set_attr "needs_delay_slot" "yes")])
5749
5750 (define_insn "call_value_media"
5751 [(set (match_operand 0 "" "=rf")
5752 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5753 (match_operand 2 "" "")))
5754 (clobber (reg:DI PR_MEDIA_REG))]
5755 "TARGET_SHMEDIA"
5756 "blink %1, r18"
5757 [(set_attr "type" "jump_media")])
5758
5759 (define_expand "call"
5760 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5761 (match_operand 1 "" ""))
5762 (match_operand 2 "" "")
5763 (use (reg:PSI FPSCR_REG))
5764 (clobber (reg:SI PR_REG))])]
5765 ""
5766 "
5767 {
5768 if (TARGET_SHMEDIA)
5769 {
5770 operands[0] = XEXP (operands[0], 0);
5771 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5772 {
5773 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5774 {
5775 rtx reg = gen_reg_rtx (Pmode);
5776
5777 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5778 operands[0] = reg;
5779 }
5780 else
5781 {
5782 operands[0] = gen_sym2PIC (operands[0]);
5783 PUT_MODE (operands[0], Pmode);
5784 }
5785 }
5786 if (GET_MODE (operands[0]) == SImode)
5787 {
5788 if (GET_CODE (operands[0]) == REG)
5789 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5790 else if (GET_CODE (operands[0]) == SUBREG)
5791 {
5792 operands[0] = SUBREG_REG (operands[0]);
5793 if (GET_MODE (operands[0]) != DImode)
5794 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5795 }
5796 else
5797 {
5798 operands[0] = shallow_copy_rtx (operands[0]);
5799 PUT_MODE (operands[0], DImode);
5800 }
5801 }
5802 if (! target_reg_operand (operands[0], DImode))
5803 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5804 emit_call_insn (gen_call_media (operands[0], operands[1]));
5805 DONE;
5806 }
5807 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5808 {
5809 rtx cookie_rtx = operands[2];
5810 long cookie = INTVAL (cookie_rtx);
5811 rtx func = XEXP (operands[0], 0);
5812 rtx r0, r1;
5813
5814 if (flag_pic)
5815 {
5816 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5817 {
5818 rtx reg = gen_reg_rtx (Pmode);
5819
5820 emit_insn (gen_symGOTPLT2reg (reg, func));
5821 func = reg;
5822 }
5823 else
5824 func = legitimize_pic_address (func, Pmode, 0);
5825 }
5826
5827 r0 = gen_rtx_REG (SImode, R0_REG);
5828 r1 = gen_rtx_REG (SImode, R1_REG);
5829
5830 /* Since such a call function may use all call-clobbered
5831 registers, we force a mode switch earlier, so that we don't
5832 run out of registers when adjusting fpscr for the call. */
5833 emit_insn (gen_force_mode_for_call ());
5834
5835 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5836 if (flag_pic)
5837 {
5838 rtx reg = gen_reg_rtx (Pmode);
5839
5840 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5841 operands[0] = reg;
5842 }
5843 operands[0] = force_reg (SImode, operands[0]);
5844
5845 emit_move_insn (r0, func);
5846 emit_move_insn (r1, cookie_rtx);
5847
5848 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5849 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5850 operands[2]));
5851 else
5852 emit_call_insn (gen_call_compact (operands[0], operands[1],
5853 operands[2]));
5854
5855 DONE;
5856 }
5857 else if (TARGET_SHCOMPACT && flag_pic
5858 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5859 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5860 {
5861 rtx reg = gen_reg_rtx (Pmode);
5862
5863 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5864 XEXP (operands[0], 0) = reg;
5865 }
5866 if (flag_pic && TARGET_SH2
5867 && GET_CODE (operands[0]) == MEM
5868 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5869 {
5870 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5871 DONE;
5872 }
5873 else
5874 {
5875 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5876 operands[1] = operands[2];
5877 }
5878
5879 emit_call_insn (gen_calli (operands[0], operands[1]));
5880 DONE;
5881 }")
5882
5883 (define_insn "call_pop_compact"
5884 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5885 (match_operand 1 "" ""))
5886 (match_operand 2 "immediate_operand" "n")
5887 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5888 (match_operand 3 "immediate_operand" "n")))
5889 (use (reg:SI R0_REG))
5890 (use (reg:SI R1_REG))
5891 (use (reg:PSI FPSCR_REG))
5892 (clobber (reg:SI PR_REG))]
5893 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5894 "jsr @%0%#"
5895 [(set_attr "type" "call")
5896 (set (attr "fp_mode")
5897 (if_then_else (eq_attr "fpu_single" "yes")
5898 (const_string "single") (const_string "double")))
5899 (set_attr "needs_delay_slot" "yes")])
5900
5901 (define_insn "call_pop_compact_rettramp"
5902 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5903 (match_operand 1 "" ""))
5904 (match_operand 2 "immediate_operand" "n")
5905 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5906 (match_operand 3 "immediate_operand" "n")))
5907 (use (reg:SI R0_REG))
5908 (use (reg:SI R1_REG))
5909 (use (reg:PSI FPSCR_REG))
5910 (clobber (reg:SI R10_REG))
5911 (clobber (reg:SI PR_REG))]
5912 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5913 "jsr @%0%#"
5914 [(set_attr "type" "call")
5915 (set (attr "fp_mode")
5916 (if_then_else (eq_attr "fpu_single" "yes")
5917 (const_string "single") (const_string "double")))
5918 (set_attr "needs_delay_slot" "yes")])
5919
5920 (define_expand "call_pop"
5921 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5922 (match_operand 1 "" ""))
5923 (match_operand 2 "" "")
5924 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5925 (match_operand 3 "" "")))])]
5926 "TARGET_SHCOMPACT"
5927 "
5928 {
5929 if (operands[2] && INTVAL (operands[2]))
5930 {
5931 rtx cookie_rtx = operands[2];
5932 long cookie = INTVAL (cookie_rtx);
5933 rtx func = XEXP (operands[0], 0);
5934 rtx r0, r1;
5935
5936 if (flag_pic)
5937 {
5938 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5939 {
5940 rtx reg = gen_reg_rtx (Pmode);
5941
5942 emit_insn (gen_symGOTPLT2reg (reg, func));
5943 func = reg;
5944 }
5945 else
5946 func = legitimize_pic_address (func, Pmode, 0);
5947 }
5948
5949 r0 = gen_rtx_REG (SImode, R0_REG);
5950 r1 = gen_rtx_REG (SImode, R1_REG);
5951
5952 /* Since such a call function may use all call-clobbered
5953 registers, we force a mode switch earlier, so that we don't
5954 run out of registers when adjusting fpscr for the call. */
5955 emit_insn (gen_force_mode_for_call ());
5956
5957 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5958 if (flag_pic)
5959 {
5960 rtx reg = gen_reg_rtx (Pmode);
5961
5962 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5963 operands[0] = reg;
5964 }
5965 operands[0] = force_reg (SImode, operands[0]);
5966
5967 emit_move_insn (r0, func);
5968 emit_move_insn (r1, cookie_rtx);
5969
5970 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5971 emit_call_insn (gen_call_pop_compact_rettramp
5972 (operands[0], operands[1], operands[2], operands[3]));
5973 else
5974 emit_call_insn (gen_call_pop_compact
5975 (operands[0], operands[1], operands[2], operands[3]));
5976
5977 DONE;
5978 }
5979
5980 abort ();
5981 }")
5982
5983 (define_expand "call_value"
5984 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5985 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5986 (match_operand 2 "" "")))
5987 (match_operand 3 "" "")
5988 (use (reg:PSI FPSCR_REG))
5989 (clobber (reg:SI PR_REG))])]
5990 ""
5991 "
5992 {
5993 if (TARGET_SHMEDIA)
5994 {
5995 operands[1] = XEXP (operands[1], 0);
5996 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5997 {
5998 if (! SYMBOL_REF_LOCAL_P (operands[1]))
5999 {
6000 rtx reg = gen_reg_rtx (Pmode);
6001
6002 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6003 operands[1] = reg;
6004 }
6005 else
6006 {
6007 operands[1] = gen_sym2PIC (operands[1]);
6008 PUT_MODE (operands[1], Pmode);
6009 }
6010 }
6011 if (GET_MODE (operands[1]) == SImode)
6012 {
6013 if (GET_CODE (operands[1]) == REG)
6014 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6015 else if (GET_CODE (operands[1]) == SUBREG)
6016 {
6017 operands[1] = SUBREG_REG (operands[1]);
6018 if (GET_MODE (operands[1]) != DImode)
6019 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6020 }
6021 else
6022 {
6023 operands[1] = shallow_copy_rtx (operands[1]);
6024 PUT_MODE (operands[1], DImode);
6025 }
6026 }
6027 if (! target_reg_operand (operands[1], DImode))
6028 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6029 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6030 operands[2]));
6031 DONE;
6032 }
6033 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6034 {
6035 rtx cookie_rtx = operands[3];
6036 long cookie = INTVAL (cookie_rtx);
6037 rtx func = XEXP (operands[1], 0);
6038 rtx r0, r1;
6039
6040 if (flag_pic)
6041 {
6042 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6043 {
6044 rtx reg = gen_reg_rtx (Pmode);
6045
6046 emit_insn (gen_symGOTPLT2reg (reg, func));
6047 func = reg;
6048 }
6049 else
6050 func = legitimize_pic_address (func, Pmode, 0);
6051 }
6052
6053 r0 = gen_rtx_REG (SImode, R0_REG);
6054 r1 = gen_rtx_REG (SImode, R1_REG);
6055
6056 /* Since such a call function may use all call-clobbered
6057 registers, we force a mode switch earlier, so that we don't
6058 run out of registers when adjusting fpscr for the call. */
6059 emit_insn (gen_force_mode_for_call ());
6060
6061 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6062 if (flag_pic)
6063 {
6064 rtx reg = gen_reg_rtx (Pmode);
6065
6066 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6067 operands[1] = reg;
6068 }
6069 operands[1] = force_reg (SImode, operands[1]);
6070
6071 emit_move_insn (r0, func);
6072 emit_move_insn (r1, cookie_rtx);
6073
6074 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6075 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6076 operands[1],
6077 operands[2],
6078 operands[3]));
6079 else
6080 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6081 operands[2], operands[3]));
6082
6083 DONE;
6084 }
6085 else if (TARGET_SHCOMPACT && flag_pic
6086 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6087 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6088 {
6089 rtx reg = gen_reg_rtx (Pmode);
6090
6091 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6092 XEXP (operands[1], 0) = reg;
6093 }
6094 if (flag_pic && TARGET_SH2
6095 && GET_CODE (operands[1]) == MEM
6096 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6097 {
6098 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6099 operands[2]));
6100 DONE;
6101 }
6102 else
6103 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6104
6105 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6106 DONE;
6107 }")
6108
6109 (define_insn "sibcalli"
6110 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6111 (match_operand 1 "" ""))
6112 (use (reg:PSI FPSCR_REG))
6113 (return)]
6114 "TARGET_SH1"
6115 "jmp @%0%#"
6116 [(set_attr "needs_delay_slot" "yes")
6117 (set (attr "fp_mode")
6118 (if_then_else (eq_attr "fpu_single" "yes")
6119 (const_string "single") (const_string "double")))
6120 (set_attr "type" "jump_ind")])
6121
6122 (define_insn "sibcalli_pcrel"
6123 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6124 (match_operand 1 "" ""))
6125 (use (match_operand 2 "" ""))
6126 (use (reg:PSI FPSCR_REG))
6127 (return)]
6128 "TARGET_SH2"
6129 "braf %0\\n%O2:%#"
6130 [(set_attr "needs_delay_slot" "yes")
6131 (set (attr "fp_mode")
6132 (if_then_else (eq_attr "fpu_single" "yes")
6133 (const_string "single") (const_string "double")))
6134 (set_attr "type" "jump_ind")])
6135
6136 (define_insn_and_split "sibcall_pcrel"
6137 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6138 (match_operand 1 "" ""))
6139 (use (reg:PSI FPSCR_REG))
6140 (clobber (match_scratch:SI 2 "=k"))
6141 (return)]
6142 "TARGET_SH2"
6143 "#"
6144 "reload_completed"
6145 [(const_int 0)]
6146 "
6147 {
6148 rtx lab = PATTERN (gen_call_site ());
6149 rtx call_insn;
6150
6151 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6152 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6153 lab));
6154 SIBLING_CALL_P (call_insn) = 1;
6155 DONE;
6156 }"
6157 [(set_attr "needs_delay_slot" "yes")
6158 (set (attr "fp_mode")
6159 (if_then_else (eq_attr "fpu_single" "yes")
6160 (const_string "single") (const_string "double")))
6161 (set_attr "type" "jump_ind")])
6162
6163 (define_insn "sibcall_compact"
6164 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6165 (match_operand 1 "" ""))
6166 (return)
6167 (use (match_operand:SI 2 "register_operand" "z,x"))
6168 (use (reg:SI R1_REG))
6169 (use (reg:PSI FPSCR_REG))
6170 ;; We want to make sure the `x' above will only match MACH_REG
6171 ;; because sibcall_epilogue may clobber MACL_REG.
6172 (clobber (reg:SI MACL_REG))]
6173 "TARGET_SHCOMPACT"
6174 "@
6175 jmp @%0%#
6176 jmp @%0\\n sts %2, r0"
6177 [(set_attr "needs_delay_slot" "yes,no")
6178 (set_attr "length" "2,4")
6179 (set (attr "fp_mode") (const_string "single"))
6180 (set_attr "type" "jump_ind")])
6181
6182 (define_insn "sibcall_media"
6183 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6184 (match_operand 1 "" ""))
6185 (use (reg:SI PR_MEDIA_REG))
6186 (return)]
6187 "TARGET_SHMEDIA"
6188 "blink %0, r63"
6189 [(set_attr "type" "jump_media")])
6190
6191 (define_expand "sibcall"
6192 [(parallel
6193 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6194 (match_operand 1 "" ""))
6195 (match_operand 2 "" "")
6196 (use (reg:PSI FPSCR_REG))
6197 (return)])]
6198 ""
6199 "
6200 {
6201 if (TARGET_SHMEDIA)
6202 {
6203 operands[0] = XEXP (operands[0], 0);
6204 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6205 {
6206 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6207 {
6208 rtx reg = gen_reg_rtx (Pmode);
6209
6210 /* We must not use GOTPLT for sibcalls, because PIC_REG
6211 must be restored before the PLT code gets to run. */
6212 emit_insn (gen_symGOT2reg (reg, operands[0]));
6213 operands[0] = reg;
6214 }
6215 else
6216 {
6217 operands[0] = gen_sym2PIC (operands[0]);
6218 PUT_MODE (operands[0], Pmode);
6219 }
6220 }
6221 if (GET_MODE (operands[0]) == SImode)
6222 {
6223 if (GET_CODE (operands[0]) == REG)
6224 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6225 else if (GET_CODE (operands[0]) == SUBREG)
6226 {
6227 operands[0] = SUBREG_REG (operands[0]);
6228 if (GET_MODE (operands[0]) != DImode)
6229 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6230 }
6231 else
6232 {
6233 operands[0] = shallow_copy_rtx (operands[0]);
6234 PUT_MODE (operands[0], DImode);
6235 }
6236 }
6237 if (! target_reg_operand (operands[0], DImode))
6238 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6239 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6240 DONE;
6241 }
6242 else if (TARGET_SHCOMPACT && operands[2]
6243 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6244 {
6245 rtx cookie_rtx = operands[2];
6246 long cookie = INTVAL (cookie_rtx);
6247 rtx func = XEXP (operands[0], 0);
6248 rtx mach, r1;
6249
6250 if (flag_pic)
6251 {
6252 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6253 {
6254 rtx reg = gen_reg_rtx (Pmode);
6255
6256 emit_insn (gen_symGOT2reg (reg, func));
6257 func = reg;
6258 }
6259 else
6260 func = legitimize_pic_address (func, Pmode, 0);
6261 }
6262
6263 /* FIXME: if we could tell whether all argument registers are
6264 already taken, we could decide whether to force the use of
6265 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6266 simple way to tell. We could use the CALL_COOKIE, but we
6267 can't currently tell a register used for regular argument
6268 passing from one that is unused. If we leave it up to reload
6269 to decide which register to use, it seems to always choose
6270 R0_REG, which leaves no available registers in SIBCALL_REGS
6271 to hold the address of the trampoline. */
6272 mach = gen_rtx_REG (SImode, MACH_REG);
6273 r1 = gen_rtx_REG (SImode, R1_REG);
6274
6275 /* Since such a call function may use all call-clobbered
6276 registers, we force a mode switch earlier, so that we don't
6277 run out of registers when adjusting fpscr for the call. */
6278 emit_insn (gen_force_mode_for_call ());
6279
6280 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6281 if (flag_pic)
6282 {
6283 rtx reg = gen_reg_rtx (Pmode);
6284
6285 emit_insn (gen_symGOT2reg (reg, operands[0]));
6286 operands[0] = reg;
6287 }
6288 operands[0] = force_reg (SImode, operands[0]);
6289
6290 /* We don't need a return trampoline, since the callee will
6291 return directly to the upper caller. */
6292 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6293 {
6294 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6295 cookie_rtx = GEN_INT (cookie);
6296 }
6297
6298 emit_move_insn (mach, func);
6299 emit_move_insn (r1, cookie_rtx);
6300
6301 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6302 DONE;
6303 }
6304 else if (TARGET_SHCOMPACT && flag_pic
6305 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6306 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6307 {
6308 rtx reg = gen_reg_rtx (Pmode);
6309
6310 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6311 XEXP (operands[0], 0) = reg;
6312 }
6313 if (flag_pic && TARGET_SH2
6314 && GET_CODE (operands[0]) == MEM
6315 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6316 /* The PLT needs the PIC register, but the epilogue would have
6317 to restore it, so we can only use PC-relative PIC calls for
6318 static functions. */
6319 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6320 {
6321 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6322 DONE;
6323 }
6324 else
6325 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6326
6327 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6328 DONE;
6329 }")
6330
6331 (define_expand "sibcall_value"
6332 [(set (match_operand 0 "" "")
6333 (call (match_operand 1 "" "")
6334 (match_operand 2 "" "")))
6335 (match_operand 3 "" "")]
6336 ""
6337 "
6338 {
6339 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6340 DONE;
6341 }")
6342
6343 (define_insn "call_value_pop_compact"
6344 [(set (match_operand 0 "" "=rf")
6345 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6346 (match_operand 2 "" "")))
6347 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6348 (match_operand 4 "immediate_operand" "n")))
6349 (match_operand 3 "immediate_operand" "n")
6350 (use (reg:SI R0_REG))
6351 (use (reg:SI R1_REG))
6352 (use (reg:PSI FPSCR_REG))
6353 (clobber (reg:SI PR_REG))]
6354 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6355 "jsr @%1%#"
6356 [(set_attr "type" "call")
6357 (set (attr "fp_mode")
6358 (if_then_else (eq_attr "fpu_single" "yes")
6359 (const_string "single") (const_string "double")))
6360 (set_attr "needs_delay_slot" "yes")])
6361
6362 (define_insn "call_value_pop_compact_rettramp"
6363 [(set (match_operand 0 "" "=rf")
6364 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6365 (match_operand 2 "" "")))
6366 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6367 (match_operand 4 "immediate_operand" "n")))
6368 (match_operand 3 "immediate_operand" "n")
6369 (use (reg:SI R0_REG))
6370 (use (reg:SI R1_REG))
6371 (use (reg:PSI FPSCR_REG))
6372 (clobber (reg:SI R10_REG))
6373 (clobber (reg:SI PR_REG))]
6374 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6375 "jsr @%1%#"
6376 [(set_attr "type" "call")
6377 (set (attr "fp_mode")
6378 (if_then_else (eq_attr "fpu_single" "yes")
6379 (const_string "single") (const_string "double")))
6380 (set_attr "needs_delay_slot" "yes")])
6381
6382 (define_expand "call_value_pop"
6383 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6384 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6385 (match_operand 2 "" "")))
6386 (match_operand 3 "" "")
6387 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6388 (match_operand 4 "" "")))])]
6389 "TARGET_SHCOMPACT"
6390 "
6391 {
6392 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6393 {
6394 rtx cookie_rtx = operands[3];
6395 long cookie = INTVAL (cookie_rtx);
6396 rtx func = XEXP (operands[1], 0);
6397 rtx r0, r1;
6398
6399 if (flag_pic)
6400 {
6401 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6402 {
6403 rtx reg = gen_reg_rtx (Pmode);
6404
6405 emit_insn (gen_symGOTPLT2reg (reg, func));
6406 func = reg;
6407 }
6408 else
6409 func = legitimize_pic_address (func, Pmode, 0);
6410 }
6411
6412 r0 = gen_rtx_REG (SImode, R0_REG);
6413 r1 = gen_rtx_REG (SImode, R1_REG);
6414
6415 /* Since such a call function may use all call-clobbered
6416 registers, we force a mode switch earlier, so that we don't
6417 run out of registers when adjusting fpscr for the call. */
6418 emit_insn (gen_force_mode_for_call ());
6419
6420 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6421 if (flag_pic)
6422 {
6423 rtx reg = gen_reg_rtx (Pmode);
6424
6425 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6426 operands[1] = reg;
6427 }
6428 operands[1] = force_reg (SImode, operands[1]);
6429
6430 emit_move_insn (r0, func);
6431 emit_move_insn (r1, cookie_rtx);
6432
6433 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6434 emit_call_insn (gen_call_value_pop_compact_rettramp
6435 (operands[0], operands[1], operands[2],
6436 operands[3], operands[4]));
6437 else
6438 emit_call_insn (gen_call_value_pop_compact
6439 (operands[0], operands[1], operands[2],
6440 operands[3], operands[4]));
6441
6442 DONE;
6443 }
6444
6445 abort ();
6446 }")
6447
6448 (define_expand "sibcall_epilogue"
6449 [(return)]
6450 ""
6451 "
6452 {
6453 sh_expand_epilogue (1);
6454 if (TARGET_SHCOMPACT)
6455 {
6456 rtx insn, set;
6457
6458 /* If epilogue clobbers r0, preserve it in macl. */
6459 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6460 if ((set = single_set (insn))
6461 && GET_CODE (SET_DEST (set)) == REG
6462 && REGNO (SET_DEST (set)) == R0_REG)
6463 {
6464 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6465 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6466 rtx i;
6467
6468 /* We can't tell at this point whether the sibcall is a
6469 sibcall_compact and, if it is, whether it uses r0 or
6470 mach as operand 2, so let the instructions that
6471 preserve r0 be optimized away if r0 turns out to be
6472 dead. */
6473 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6474 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6475 REG_NOTES (i));
6476 i = emit_move_insn (r0, tmp);
6477 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6478 REG_NOTES (i));
6479 break;
6480 }
6481 }
6482 DONE;
6483 }")
6484
6485 (define_insn "indirect_jump_compact"
6486 [(set (pc)
6487 (match_operand:SI 0 "arith_reg_operand" "r"))]
6488 "TARGET_SH1"
6489 "jmp @%0%#"
6490 [(set_attr "needs_delay_slot" "yes")
6491 (set_attr "type" "jump_ind")])
6492
6493 (define_expand "indirect_jump"
6494 [(set (pc)
6495 (match_operand 0 "register_operand" ""))]
6496 ""
6497 "
6498 {
6499 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6500 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6501 }")
6502
6503 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6504 ;; which can be present in structured code from indirect jumps which can not
6505 ;; be present in structured code. This allows -fprofile-arcs to work.
6506
6507 ;; For SH1 processors.
6508 (define_insn "casesi_jump_1"
6509 [(set (pc)
6510 (match_operand:SI 0 "register_operand" "r"))
6511 (use (label_ref (match_operand 1 "" "")))]
6512 "TARGET_SH1"
6513 "jmp @%0%#"
6514 [(set_attr "needs_delay_slot" "yes")
6515 (set_attr "type" "jump_ind")])
6516
6517 ;; For all later processors.
6518 (define_insn "casesi_jump_2"
6519 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6520 (label_ref (match_operand 1 "" ""))))
6521 (use (label_ref (match_operand 2 "" "")))]
6522 "TARGET_SH2
6523 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6524 "braf %0%#"
6525 [(set_attr "needs_delay_slot" "yes")
6526 (set_attr "type" "jump_ind")])
6527
6528 (define_insn "casesi_jump_media"
6529 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6530 (use (label_ref (match_operand 1 "" "")))]
6531 "TARGET_SHMEDIA"
6532 "blink %0, r63"
6533 [(set_attr "type" "jump_media")])
6534
6535 ;; Call subroutine returning any type.
6536 ;; ??? This probably doesn't work.
6537
6538 (define_expand "untyped_call"
6539 [(parallel [(call (match_operand 0 "" "")
6540 (const_int 0))
6541 (match_operand 1 "" "")
6542 (match_operand 2 "" "")])]
6543 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6544 "
6545 {
6546 int i;
6547
6548 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6549
6550 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6551 {
6552 rtx set = XVECEXP (operands[2], 0, i);
6553 emit_move_insn (SET_DEST (set), SET_SRC (set));
6554 }
6555
6556 /* The optimizer does not know that the call sets the function value
6557 registers we stored in the result block. We avoid problems by
6558 claiming that all hard registers are used and clobbered at this
6559 point. */
6560 emit_insn (gen_blockage ());
6561
6562 DONE;
6563 }")
6564 \f
6565 ;; ------------------------------------------------------------------------
6566 ;; Misc insns
6567 ;; ------------------------------------------------------------------------
6568
6569 (define_insn "dect"
6570 [(set (reg:SI T_REG)
6571 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6572 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6573 "TARGET_SH2"
6574 "dt %0"
6575 [(set_attr "type" "arith")])
6576
6577 (define_insn "nop"
6578 [(const_int 0)]
6579 ""
6580 "nop")
6581
6582 ;; Load address of a label. This is only generated by the casesi expand,
6583 ;; and by machine_dependent_reorg (fixing up fp moves).
6584 ;; This must use unspec, because this only works for labels that are
6585 ;; within range,
6586
6587 (define_insn "mova"
6588 [(set (reg:SI R0_REG)
6589 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6590 "TARGET_SH1"
6591 "mova %O0,r0"
6592 [(set_attr "in_delay_slot" "no")
6593 (set_attr "type" "arith")])
6594
6595 ;; machine_dependent_reorg will make this a `mova'.
6596 (define_insn "mova_const"
6597 [(set (reg:SI R0_REG)
6598 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6599 "TARGET_SH1"
6600 "#"
6601 [(set_attr "in_delay_slot" "no")
6602 (set_attr "type" "arith")])
6603
6604 (define_expand "GOTaddr2picreg"
6605 [(set (reg:SI R0_REG)
6606 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6607 UNSPEC_MOVA))
6608 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6609 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6610 "" "
6611 {
6612 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6613 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6614
6615 if (TARGET_SH5)
6616 operands[1] = gen_datalabel_ref (operands[1]);
6617
6618 if (TARGET_SHMEDIA)
6619 {
6620 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6621 rtx dipic = operands[0];
6622 rtx lab = PATTERN (gen_call_site ());
6623 rtx insn, equiv;
6624
6625 equiv = operands[1];
6626 operands[1] = gen_rtx_MINUS (DImode,
6627 operands[1],
6628 gen_rtx_CONST
6629 (DImode,
6630 gen_rtx_MINUS (DImode,
6631 gen_rtx_CONST (DImode,
6632 lab),
6633 pc_rtx)));
6634 operands[1] = gen_sym2PIC (operands[1]);
6635 PUT_MODE (operands[1], DImode);
6636
6637 if (GET_MODE (dipic) != DImode)
6638 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6639
6640 if (TARGET_SHMEDIA64)
6641 emit_insn (gen_movdi_const (dipic, operands[1]));
6642 else
6643 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6644
6645 emit_insn (gen_ptrel (tr, dipic, lab));
6646
6647 if (GET_MODE (operands[0]) != GET_MODE (tr))
6648 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6649
6650 insn = emit_move_insn (operands[0], tr);
6651
6652 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6653 REG_NOTES (insn));
6654
6655 DONE;
6656 }
6657 }
6658 ")
6659
6660 (define_insn "*ptb"
6661 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6662 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6663 UNSPEC_DATALABEL)))]
6664 "TARGET_SHMEDIA && flag_pic
6665 && EXTRA_CONSTRAINT_Csy (operands[1])"
6666 "ptb/u datalabel %1, %0"
6667 [(set_attr "type" "pt_media")
6668 (set_attr "length" "*")])
6669
6670 (define_insn "ptrel"
6671 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6672 (plus:DI (match_operand:DI 1 "register_operand" "r")
6673 (pc)))
6674 (match_operand:DI 2 "" "")]
6675 "TARGET_SHMEDIA"
6676 "%O2: ptrel/u %1, %0"
6677 [(set_attr "type" "ptabs_media")])
6678
6679 (define_expand "builtin_setjmp_receiver"
6680 [(match_operand 0 "" "")]
6681 "flag_pic"
6682 "
6683 {
6684 emit_insn (gen_GOTaddr2picreg ());
6685 DONE;
6686 }")
6687
6688 (define_expand "call_site"
6689 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6690 "TARGET_SH1"
6691 "
6692 {
6693 static HOST_WIDE_INT i = 0;
6694 operands[0] = GEN_INT (i);
6695 i++;
6696 }")
6697
6698 (define_expand "sym_label2reg"
6699 [(set (match_operand:SI 0 "" "")
6700 (const:SI (minus:SI
6701 (const:SI
6702 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6703 (const:SI
6704 (plus:SI
6705 (match_operand:SI 2 "" "")
6706 (const_int 2))))))]
6707 "TARGET_SH1" "")
6708
6709 (define_expand "symGOT_load"
6710 [(set (match_dup 2) (match_operand 1 "" ""))
6711 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6712 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6713 ""
6714 "
6715 {
6716 rtx insn;
6717
6718 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6719 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6720
6721 if (TARGET_SHMEDIA)
6722 {
6723 rtx reg = operands[2];
6724
6725 if (GET_MODE (reg) != DImode)
6726 reg = gen_rtx_SUBREG (DImode, reg, 0);
6727
6728 if (flag_pic > 1)
6729 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6730 else
6731 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6732 }
6733 else
6734 emit_move_insn (operands[2], operands[1]);
6735
6736 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6737 operands[2],
6738 gen_rtx_REG (Pmode, PIC_REG)));
6739
6740 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6741
6742 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6743 0), 0, 0),
6744 REG_NOTES (insn));
6745
6746 DONE;
6747 }")
6748
6749 (define_expand "sym2GOT"
6750 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6751 ""
6752 "")
6753
6754 (define_expand "symGOT2reg"
6755 [(match_operand 0 "" "") (match_operand 1 "" "")]
6756 ""
6757 "
6758 {
6759 rtx gotsym, insn;
6760
6761 gotsym = gen_sym2GOT (operands[1]);
6762 PUT_MODE (gotsym, Pmode);
6763 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6764
6765 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6766
6767 DONE;
6768 }")
6769
6770 (define_expand "sym2GOTPLT"
6771 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6772 ""
6773 "")
6774
6775 (define_expand "symGOTPLT2reg"
6776 [(match_operand 0 "" "") (match_operand 1 "" "")]
6777 ""
6778 "
6779 {
6780 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6781 DONE;
6782 }")
6783
6784 (define_expand "sym2GOTOFF"
6785 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6786 ""
6787 "")
6788
6789 (define_expand "symGOTOFF2reg"
6790 [(match_operand 0 "" "") (match_operand 1 "" "")]
6791 ""
6792 "
6793 {
6794 rtx gotoffsym, insn;
6795 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6796
6797 gotoffsym = gen_sym2GOTOFF (operands[1]);
6798 PUT_MODE (gotoffsym, Pmode);
6799 emit_move_insn (t, gotoffsym);
6800 insn = emit_move_insn (operands[0],
6801 gen_rtx_PLUS (Pmode, t,
6802 gen_rtx_REG (Pmode, PIC_REG)));
6803
6804 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6805 REG_NOTES (insn));
6806
6807 DONE;
6808 }")
6809
6810 (define_expand "symPLT_label2reg"
6811 [(set (match_operand:SI 0 "" "")
6812 (const:SI (minus:SI
6813 (const:SI
6814 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6815 (const:SI
6816 (minus:SI
6817 (const:SI (plus:SI
6818 (match_operand:SI 2 "" "")
6819 (const_int 2)))
6820 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6821 ;; Even though the PIC register is not really used by the call
6822 ;; sequence in which this is expanded, the PLT code assumes the PIC
6823 ;; register is set, so we must not skip its initialization. Since
6824 ;; we only use this expand as part of calling sequences, and never
6825 ;; to take the address of a function, this is the best point to
6826 ;; insert the (use). Using the PLT to take the address of a
6827 ;; function would be wrong, not only because the PLT entry could
6828 ;; then be called from a function that doesn't initialize the PIC
6829 ;; register to the proper GOT, but also because pointers to the
6830 ;; same function might not compare equal, should they be set by
6831 ;; different shared libraries.
6832 (use (reg:SI PIC_REG))]
6833 "TARGET_SH1"
6834 "")
6835
6836 (define_expand "sym2PIC"
6837 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6838 ""
6839 "")
6840
6841 ;; TLS code generation.
6842 ;; ??? this should be a define_insn_and_split
6843 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6844 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6845 ;; for details.
6846
6847 (define_insn "tls_global_dynamic"
6848 [(set (match_operand:SI 0 "register_operand" "=&z")
6849 (call (unspec:SI [(match_operand:SI 1 "" "")]
6850 UNSPEC_TLSGD)
6851 (const_int 0)))
6852 (use (reg:PSI FPSCR_REG))
6853 (use (reg:SI PIC_REG))
6854 (clobber (reg:SI PR_REG))
6855 (clobber (scratch:SI))]
6856 "TARGET_SH1"
6857 "*
6858 {
6859 return \"\\
6860 mov.l\\t1f,r4\\n\\
6861 \\tmova\\t2f,r0\\n\\
6862 \\tmov.l\\t2f,r1\\n\\
6863 \\tadd\\tr0,r1\\n\\
6864 \\tjsr\\t@r1\\n\\
6865 \\tadd\\tr12,r4\\n\\
6866 \\tbra\\t3f\\n\\
6867 \\tnop\\n\\
6868 \\t.align\\t2\\n\\
6869 1:\\t.long\\t%a1@TLSGD\\n\\
6870 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6871 3:\";
6872 }"
6873 [(set_attr "type" "tls_load")
6874 (set_attr "length" "26")])
6875
6876 (define_insn "tls_local_dynamic"
6877 [(set (match_operand:SI 0 "register_operand" "=&z")
6878 (call (unspec:SI [(match_operand:SI 1 "" "")]
6879 UNSPEC_TLSLDM)
6880 (const_int 0)))
6881 (use (reg:PSI FPSCR_REG))
6882 (use (reg:SI PIC_REG))
6883 (clobber (reg:SI PR_REG))
6884 (clobber (scratch:SI))]
6885 "TARGET_SH1"
6886 "*
6887 {
6888 return \"\\
6889 mov.l\\t1f,r4\\n\\
6890 \\tmova\\t2f,r0\\n\\
6891 \\tmov.l\\t2f,r1\\n\\
6892 \\tadd\\tr0,r1\\n\\
6893 \\tjsr\\t@r1\\n\\
6894 \\tadd\\tr12,r4\\n\\
6895 \\tbra\\t3f\\n\\
6896 \\tnop\\n\\
6897 \\t.align\\t2\\n\\
6898 1:\\t.long\\t%a1@TLSLDM\\n\\
6899 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6900 3:\";
6901 }"
6902 [(set_attr "type" "tls_load")
6903 (set_attr "length" "26")])
6904
6905 (define_expand "sym2DTPOFF"
6906 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6907 ""
6908 "")
6909
6910 (define_expand "symDTPOFF2reg"
6911 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6912 ""
6913 "
6914 {
6915 rtx dtpoffsym, insn;
6916 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6917
6918 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6919 PUT_MODE (dtpoffsym, Pmode);
6920 emit_move_insn (t, dtpoffsym);
6921 insn = emit_move_insn (operands[0],
6922 gen_rtx_PLUS (Pmode, t, operands[2]));
6923 DONE;
6924 }")
6925
6926 (define_expand "sym2GOTTPOFF"
6927 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6928 ""
6929 "")
6930
6931 (define_insn "tls_initial_exec"
6932 [(set (match_operand:SI 0 "register_operand" "=&r")
6933 (unspec:SI [(match_operand:SI 1 "" "")]
6934 UNSPEC_TLSIE))
6935 (use (reg:SI GBR_REG))
6936 (use (reg:SI PIC_REG))
6937 (clobber (reg:SI R0_REG))]
6938 ""
6939 "*
6940 {
6941 return \"\\
6942 mov.l\\t1f,r0\\n\\
6943 \\tstc\\tgbr,%0\\n\\
6944 \\tmov.l\\t@(r0,r12),r0\\n\\
6945 \\tbra\\t2f\\n\\
6946 \\tadd\\tr0,%0\\n\\
6947 \\t.align\\t2\\n\\
6948 1:\\t.long\\t%a1\\n\\
6949 2:\";
6950 }"
6951 [(set_attr "type" "tls_load")
6952 (set_attr "length" "16")])
6953
6954 (define_expand "sym2TPOFF"
6955 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6956 ""
6957 "")
6958
6959 (define_expand "symTPOFF2reg"
6960 [(match_operand 0 "" "") (match_operand 1 "" "")]
6961 ""
6962 "
6963 {
6964 rtx tpoffsym, insn;
6965
6966 tpoffsym = gen_sym2TPOFF (operands[1]);
6967 PUT_MODE (tpoffsym, Pmode);
6968 insn = emit_move_insn (operands[0], tpoffsym);
6969 DONE;
6970 }")
6971
6972 (define_insn "load_gbr"
6973 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6974 (use (reg:SI GBR_REG))]
6975 ""
6976 "stc gbr,%0"
6977 [(set_attr "type" "tls_load")])
6978
6979 ;; case instruction for switch statements.
6980
6981 ;; Operand 0 is index
6982 ;; operand 1 is the minimum bound
6983 ;; operand 2 is the maximum bound - minimum bound + 1
6984 ;; operand 3 is CODE_LABEL for the table;
6985 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6986
6987 (define_expand "casesi"
6988 [(match_operand:SI 0 "arith_reg_operand" "")
6989 (match_operand:SI 1 "arith_reg_operand" "")
6990 (match_operand:SI 2 "arith_reg_operand" "")
6991 (match_operand 3 "" "") (match_operand 4 "" "")]
6992 ""
6993 "
6994 {
6995 rtx reg = gen_reg_rtx (SImode);
6996 rtx reg2 = gen_reg_rtx (SImode);
6997 if (TARGET_SHMEDIA)
6998 {
6999 rtx reg = gen_reg_rtx (DImode);
7000 rtx reg2 = gen_reg_rtx (DImode);
7001 rtx reg3 = gen_reg_rtx (DImode);
7002 rtx reg4 = gen_reg_rtx (DImode);
7003 rtx reg5 = gen_reg_rtx (DImode);
7004
7005 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7006 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7007 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7008
7009 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7010 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7011 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7012 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7013 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7014 (DImode, operands[3])));
7015 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7016 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7017 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7018 emit_barrier ();
7019 DONE;
7020 }
7021 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7022 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7023 /* If optimizing, casesi_worker depends on the mode of the instruction
7024 before label it 'uses' - operands[3]. */
7025 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7026 reg));
7027 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7028 if (TARGET_SH2)
7029 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7030 else
7031 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7032 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7033 operands[3], but to lab. We will fix this up in
7034 machine_dependent_reorg. */
7035 emit_barrier ();
7036 DONE;
7037 }")
7038
7039 (define_expand "casesi_0"
7040 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7041 (set (match_dup 4) (minus:SI (match_dup 4)
7042 (match_operand:SI 1 "arith_operand" "")))
7043 (set (reg:SI T_REG)
7044 (gtu:SI (match_dup 4)
7045 (match_operand:SI 2 "arith_reg_operand" "")))
7046 (set (pc)
7047 (if_then_else (ne (reg:SI T_REG)
7048 (const_int 0))
7049 (label_ref (match_operand 3 "" ""))
7050 (pc)))]
7051 "TARGET_SH1"
7052 "")
7053
7054 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7055 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7056 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7057
7058 (define_insn "casesi_worker_0"
7059 [(set (match_operand:SI 0 "register_operand" "=r,r")
7060 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7061 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7062 (clobber (match_scratch:SI 3 "=X,1"))
7063 (clobber (match_scratch:SI 4 "=&z,z"))]
7064 "TARGET_SH1"
7065 "#")
7066
7067 (define_split
7068 [(set (match_operand:SI 0 "register_operand" "")
7069 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7070 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7071 (clobber (match_scratch:SI 3 ""))
7072 (clobber (match_scratch:SI 4 ""))]
7073 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7074 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7075 (parallel [(set (match_dup 0)
7076 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7077 (label_ref (match_dup 2))] UNSPEC_CASESI))
7078 (clobber (match_dup 3))])
7079 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7080 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7081
7082 (define_split
7083 [(set (match_operand:SI 0 "register_operand" "")
7084 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7085 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7086 (clobber (match_scratch:SI 3 ""))
7087 (clobber (match_scratch:SI 4 ""))]
7088 "TARGET_SH2 && reload_completed"
7089 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7090 (parallel [(set (match_dup 0)
7091 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7092 (label_ref (match_dup 2))] UNSPEC_CASESI))
7093 (clobber (match_dup 3))])]
7094 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7095
7096 (define_insn "casesi_worker_1"
7097 [(set (match_operand:SI 0 "register_operand" "=r,r")
7098 (unspec:SI [(reg:SI R0_REG)
7099 (match_operand:SI 1 "register_operand" "0,r")
7100 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7101 (clobber (match_scratch:SI 3 "=X,1"))]
7102 "TARGET_SH1"
7103 "*
7104 {
7105 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7106
7107 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7108 abort ();
7109
7110 switch (GET_MODE (diff_vec))
7111 {
7112 case SImode:
7113 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7114 case HImode:
7115 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7116 case QImode:
7117 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7118 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7119 return \"mov.b @(r0,%1),%0\";
7120 default:
7121 abort ();
7122 }
7123 }"
7124 [(set_attr "length" "4")])
7125
7126 (define_insn "casesi_worker_2"
7127 [(set (match_operand:SI 0 "register_operand" "=r,r")
7128 (unspec:SI [(reg:SI R0_REG)
7129 (match_operand:SI 1 "register_operand" "0,r")
7130 (label_ref (match_operand 2 "" ""))
7131 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7132 (clobber (match_operand:SI 4 "" "=X,1"))]
7133 "TARGET_SH2 && reload_completed && flag_pic"
7134 "*
7135 {
7136 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7137 const char *load;
7138
7139 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7140 abort ();
7141
7142 switch (GET_MODE (diff_vec))
7143 {
7144 case SImode:
7145 output_asm_insn (\"shll2 %1\", operands);
7146 load = \"mov.l @(r0,%1),%0\"; break;
7147 case HImode:
7148 output_asm_insn (\"add %1,%1\", operands);
7149 load = \"mov.w @(r0,%1),%0\"; break;
7150 case QImode:
7151 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7152 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7153 else
7154 load = \"mov.b @(r0,%1),%0\";
7155 break;
7156 default:
7157 abort ();
7158 }
7159 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7160 return load;
7161 }"
7162 [(set_attr "length" "8")])
7163
7164 (define_insn "casesi_shift_media"
7165 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7166 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7167 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7168 UNSPEC_CASESI)))]
7169 "TARGET_SHMEDIA"
7170 "*
7171 {
7172 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7173
7174 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7175 abort ();
7176
7177 switch (GET_MODE (diff_vec))
7178 {
7179 case SImode:
7180 return \"shlli %1, 2, %0\";
7181 case HImode:
7182 return \"shlli %1, 1, %0\";
7183 case QImode:
7184 if (rtx_equal_p (operands[0], operands[1]))
7185 return \"\";
7186 return \"add %1, r63, %0\";
7187 default:
7188 abort ();
7189 }
7190 }"
7191 [(set_attr "type" "arith_media")])
7192
7193 (define_insn "casesi_load_media"
7194 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7195 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7196 (match_operand 2 "arith_reg_operand" "r")
7197 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7198 "TARGET_SHMEDIA"
7199 "*
7200 {
7201 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7202
7203 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7204 abort ();
7205
7206 switch (GET_MODE (diff_vec))
7207 {
7208 case SImode:
7209 return \"ldx.l %1, %2, %0\";
7210 case HImode:
7211 #if 0
7212 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7213 return \"ldx.uw %1, %2, %0\";
7214 #endif
7215 return \"ldx.w %1, %2, %0\";
7216 case QImode:
7217 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7218 return \"ldx.ub %1, %2, %0\";
7219 return \"ldx.b %1, %2, %0\";
7220 default:
7221 abort ();
7222 }
7223 }"
7224 [(set_attr "type" "load_media")])
7225
7226 (define_expand "return"
7227 [(return)]
7228 "reload_completed && ! sh_need_epilogue ()"
7229 "
7230 {
7231 if (TARGET_SHMEDIA)
7232 {
7233 emit_jump_insn (gen_return_media ());
7234 DONE;
7235 }
7236
7237 if (TARGET_SHCOMPACT
7238 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7239 {
7240 emit_jump_insn (gen_shcompact_return_tramp ());
7241 DONE;
7242 }
7243 }")
7244
7245 (define_insn "*return_i"
7246 [(return)]
7247 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7248 && (current_function_args_info.call_cookie
7249 & CALL_COOKIE_RET_TRAMP (1)))
7250 && reload_completed"
7251 "%@ %#"
7252 [(set_attr "type" "return")
7253 (set_attr "needs_delay_slot" "yes")])
7254
7255 (define_expand "shcompact_return_tramp"
7256 [(return)]
7257 "TARGET_SHCOMPACT
7258 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7259 "
7260 {
7261 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7262 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7263
7264 if (flag_pic)
7265 emit_insn (gen_symGOTPLT2reg (reg, sym));
7266 else
7267 emit_move_insn (reg, sym);
7268
7269 emit_jump_insn (gen_shcompact_return_tramp_i ());
7270 DONE;
7271 }")
7272
7273 (define_insn "shcompact_return_tramp_i"
7274 [(parallel [(return) (use (reg:SI R0_REG))])]
7275 "TARGET_SHCOMPACT
7276 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7277 "jmp @r0%#"
7278 [(set_attr "type" "jump_ind")
7279 (set_attr "needs_delay_slot" "yes")])
7280
7281 (define_insn "return_media_i"
7282 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7283 "TARGET_SHMEDIA && reload_completed"
7284 "blink %0, r63"
7285 [(set_attr "type" "jump_media")])
7286
7287 (define_insn "return_media_rte"
7288 [(return)]
7289 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7290 "rte"
7291 [(set_attr "type" "jump_media")])
7292
7293 (define_expand "return_media"
7294 [(return)]
7295 "TARGET_SHMEDIA && reload_completed"
7296 "
7297 {
7298 int tr_regno = sh_media_register_for_return ();
7299 rtx tr;
7300
7301 if (current_function_interrupt)
7302 {
7303 emit_jump_insn (gen_return_media_rte ());
7304 DONE;
7305 }
7306 if (tr_regno < 0)
7307 {
7308 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7309
7310 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7311 abort ();
7312 tr_regno = TR0_REG;
7313 tr = gen_rtx_REG (DImode, tr_regno);
7314 emit_move_insn (tr, r18);
7315 }
7316 else
7317 tr = gen_rtx_REG (DImode, tr_regno);
7318
7319 emit_jump_insn (gen_return_media_i (tr));
7320 DONE;
7321 }")
7322
7323 (define_insn "shcompact_preserve_incoming_args"
7324 [(set (match_operand:SI 0 "register_operand" "+r")
7325 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7326 "TARGET_SHCOMPACT"
7327 ""
7328 [(set_attr "length" "0")])
7329
7330 (define_insn "shcompact_incoming_args"
7331 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7332 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7333 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7334 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7335 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7336 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7337 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7338 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7339 (set (mem:BLK (reg:SI MACL_REG))
7340 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7341 (use (reg:SI R0_REG))
7342 (clobber (reg:SI R0_REG))
7343 (clobber (reg:SI MACL_REG))
7344 (clobber (reg:SI MACH_REG))
7345 (clobber (reg:SI PR_REG))]
7346 "TARGET_SHCOMPACT"
7347 "jsr @r0%#"
7348 [(set_attr "needs_delay_slot" "yes")])
7349
7350 (define_insn "shmedia_save_restore_regs_compact"
7351 [(set (reg:SI SP_REG)
7352 (plus:SI (reg:SI SP_REG)
7353 (match_operand:SI 0 "immediate_operand" "i")))
7354 (use (reg:SI R0_REG))
7355 (clobber (reg:SI PR_REG))]
7356 "TARGET_SHCOMPACT
7357 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7358 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7359 "jsr @r0%#"
7360 [(set_attr "needs_delay_slot" "yes")])
7361
7362 (define_expand "prologue"
7363 [(const_int 0)]
7364 ""
7365 "sh_expand_prologue (); DONE;")
7366
7367 (define_expand "epilogue"
7368 [(return)]
7369 ""
7370 "
7371 {
7372 sh_expand_epilogue (0);
7373 emit_jump_insn (gen_return ());
7374 DONE;
7375 }")
7376
7377 (define_expand "eh_return"
7378 [(use (match_operand 0 "register_operand" ""))]
7379 ""
7380 {
7381 rtx ra = operands[0];
7382
7383 if (TARGET_SHMEDIA64)
7384 emit_insn (gen_eh_set_ra_di (ra));
7385 else
7386 emit_insn (gen_eh_set_ra_si (ra));
7387
7388 DONE;
7389 })
7390
7391 ;; Clobber the return address on the stack. We can't expand this
7392 ;; until we know where it will be put in the stack frame.
7393
7394 (define_insn "eh_set_ra_si"
7395 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7396 (clobber (match_scratch:SI 1 "=&r"))]
7397 "! TARGET_SHMEDIA64"
7398 "#")
7399
7400 (define_insn "eh_set_ra_di"
7401 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7402 (clobber (match_scratch:DI 1 "=&r"))]
7403 "TARGET_SHMEDIA64"
7404 "#")
7405
7406 (define_split
7407 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7408 (clobber (match_scratch 1 ""))]
7409 "reload_completed"
7410 [(const_int 0)]
7411 "
7412 {
7413 sh_set_return_address (operands[0], operands[1]);
7414 DONE;
7415 }")
7416
7417 (define_insn "blockage"
7418 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7419 ""
7420 ""
7421 [(set_attr "length" "0")])
7422 \f
7423 ;; ------------------------------------------------------------------------
7424 ;; Scc instructions
7425 ;; ------------------------------------------------------------------------
7426
7427 (define_insn "movt"
7428 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7429 (eq:SI (reg:SI T_REG) (const_int 1)))]
7430 "TARGET_SH1"
7431 "movt %0"
7432 [(set_attr "type" "arith")])
7433
7434 (define_expand "seq"
7435 [(set (match_operand:SI 0 "arith_reg_operand" "")
7436 (match_dup 1))]
7437 ""
7438 "
7439 {
7440 if (TARGET_SHMEDIA)
7441 {
7442 if (GET_MODE (operands[0]) != DImode)
7443 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7444 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7445 if (sh_compare_op1 != const0_rtx)
7446 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7447 ? GET_MODE (sh_compare_op0)
7448 : GET_MODE (sh_compare_op1),
7449 sh_compare_op1);
7450
7451 switch (GET_MODE (sh_compare_op0))
7452 {
7453 case DImode:
7454 emit_insn (gen_cmpeqdi_media (operands[0],
7455 sh_compare_op0, sh_compare_op1));
7456 break;
7457
7458 case SFmode:
7459 if (! TARGET_SHMEDIA_FPU)
7460 FAIL;
7461 emit_insn (gen_cmpeqsf_media (operands[0],
7462 sh_compare_op0, sh_compare_op1));
7463 break;
7464
7465 case DFmode:
7466 if (! TARGET_SHMEDIA_FPU)
7467 FAIL;
7468 emit_insn (gen_cmpeqdf_media (operands[0],
7469 sh_compare_op0, sh_compare_op1));
7470 break;
7471
7472 default:
7473 FAIL;
7474 }
7475 DONE;
7476 }
7477 if (sh_expand_t_scc (EQ, operands[0]))
7478 DONE;
7479 if (! rtx_equal_function_value_matters)
7480 FAIL;
7481 operands[1] = prepare_scc_operands (EQ);
7482 }")
7483
7484 (define_expand "slt"
7485 [(set (match_operand:SI 0 "arith_reg_operand" "")
7486 (match_dup 1))]
7487 ""
7488 "
7489 {
7490 if (TARGET_SHMEDIA)
7491 {
7492 if (GET_MODE (operands[0]) != DImode)
7493 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7494 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7495 if (sh_compare_op1 != const0_rtx)
7496 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7497 ? GET_MODE (sh_compare_op0)
7498 : GET_MODE (sh_compare_op1),
7499 sh_compare_op1);
7500
7501 switch (GET_MODE (sh_compare_op0))
7502 {
7503 case DImode:
7504 emit_insn (gen_cmpgtdi_media (operands[0],
7505 sh_compare_op1, sh_compare_op0));
7506 break;
7507
7508 case SFmode:
7509 if (! TARGET_SHMEDIA_FPU)
7510 FAIL;
7511 emit_insn (gen_cmpgtsf_media (operands[0],
7512 sh_compare_op1, sh_compare_op0));
7513 break;
7514
7515 case DFmode:
7516 if (! TARGET_SHMEDIA_FPU)
7517 FAIL;
7518 emit_insn (gen_cmpgtdf_media (operands[0],
7519 sh_compare_op1, sh_compare_op0));
7520 break;
7521
7522 default:
7523 FAIL;
7524 }
7525 DONE;
7526 }
7527 if (! rtx_equal_function_value_matters)
7528 FAIL;
7529 operands[1] = prepare_scc_operands (LT);
7530 }")
7531
7532 (define_expand "sle"
7533 [(match_operand:SI 0 "arith_reg_operand" "")]
7534 ""
7535 "
7536 {
7537 rtx tmp = sh_compare_op0;
7538
7539 if (TARGET_SHMEDIA)
7540 {
7541 if (GET_MODE (operands[0]) != DImode)
7542 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7543 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7544 if (sh_compare_op1 != const0_rtx)
7545 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7546 ? GET_MODE (sh_compare_op0)
7547 : GET_MODE (sh_compare_op1),
7548 sh_compare_op1);
7549
7550 switch (GET_MODE (sh_compare_op0))
7551 {
7552 case DImode:
7553 {
7554 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7555
7556 emit_insn (gen_cmpgtdi_media (tmp,
7557 sh_compare_op0, sh_compare_op1));
7558 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7559 break;
7560 }
7561
7562 case SFmode:
7563 if (! TARGET_SHMEDIA_FPU)
7564 FAIL;
7565 emit_insn (gen_cmpgesf_media (operands[0],
7566 sh_compare_op1, sh_compare_op0));
7567 break;
7568
7569 case DFmode:
7570 if (! TARGET_SHMEDIA_FPU)
7571 FAIL;
7572 emit_insn (gen_cmpgedf_media (operands[0],
7573 sh_compare_op1, sh_compare_op0));
7574 break;
7575
7576 default:
7577 FAIL;
7578 }
7579 DONE;
7580 }
7581
7582 sh_compare_op0 = sh_compare_op1;
7583 sh_compare_op1 = tmp;
7584 emit_insn (gen_sge (operands[0]));
7585 DONE;
7586 }")
7587
7588 (define_expand "sgt"
7589 [(set (match_operand:SI 0 "arith_reg_operand" "")
7590 (match_dup 1))]
7591 ""
7592 "
7593 {
7594 if (TARGET_SHMEDIA)
7595 {
7596 if (GET_MODE (operands[0]) != DImode)
7597 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7598 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7599 if (sh_compare_op1 != const0_rtx)
7600 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7601 ? GET_MODE (sh_compare_op0)
7602 : GET_MODE (sh_compare_op1),
7603 sh_compare_op1);
7604
7605 switch (GET_MODE (sh_compare_op0))
7606 {
7607 case DImode:
7608 emit_insn (gen_cmpgtdi_media (operands[0],
7609 sh_compare_op0, sh_compare_op1));
7610 break;
7611
7612 case SFmode:
7613 if (! TARGET_SHMEDIA_FPU)
7614 FAIL;
7615 emit_insn (gen_cmpgtsf_media (operands[0],
7616 sh_compare_op0, sh_compare_op1));
7617 break;
7618
7619 case DFmode:
7620 if (! TARGET_SHMEDIA_FPU)
7621 FAIL;
7622 emit_insn (gen_cmpgtdf_media (operands[0],
7623 sh_compare_op0, sh_compare_op1));
7624 break;
7625
7626 default:
7627 FAIL;
7628 }
7629 DONE;
7630 }
7631 if (! rtx_equal_function_value_matters)
7632 FAIL;
7633 operands[1] = prepare_scc_operands (GT);
7634 }")
7635
7636 (define_expand "sge"
7637 [(set (match_operand:SI 0 "arith_reg_operand" "")
7638 (match_dup 1))]
7639 ""
7640 "
7641 {
7642 if (TARGET_SHMEDIA)
7643 {
7644 if (GET_MODE (operands[0]) != DImode)
7645 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7646 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7647 if (sh_compare_op1 != const0_rtx)
7648 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7649 ? GET_MODE (sh_compare_op0)
7650 : GET_MODE (sh_compare_op1),
7651 sh_compare_op1);
7652
7653 switch (GET_MODE (sh_compare_op0))
7654 {
7655 case DImode:
7656 {
7657 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7658
7659 emit_insn (gen_cmpgtdi_media (tmp,
7660 sh_compare_op1, sh_compare_op0));
7661 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7662 break;
7663 }
7664
7665 case SFmode:
7666 if (! TARGET_SHMEDIA_FPU)
7667 FAIL;
7668 emit_insn (gen_cmpgesf_media (operands[0],
7669 sh_compare_op0, sh_compare_op1));
7670 break;
7671
7672 case DFmode:
7673 if (! TARGET_SHMEDIA_FPU)
7674 FAIL;
7675 emit_insn (gen_cmpgedf_media (operands[0],
7676 sh_compare_op0, sh_compare_op1));
7677 break;
7678
7679 default:
7680 FAIL;
7681 }
7682 DONE;
7683 }
7684
7685 if (! rtx_equal_function_value_matters)
7686 FAIL;
7687 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7688 {
7689 if (TARGET_IEEE)
7690 {
7691 rtx lab = gen_label_rtx ();
7692 prepare_scc_operands (EQ);
7693 emit_jump_insn (gen_branch_true (lab));
7694 prepare_scc_operands (GT);
7695 emit_label (lab);
7696 emit_insn (gen_movt (operands[0]));
7697 }
7698 else
7699 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7700 DONE;
7701 }
7702 operands[1] = prepare_scc_operands (GE);
7703 }")
7704
7705 (define_expand "sgtu"
7706 [(set (match_operand:SI 0 "arith_reg_operand" "")
7707 (match_dup 1))]
7708 ""
7709 "
7710 {
7711 if (TARGET_SHMEDIA)
7712 {
7713 if (GET_MODE (operands[0]) != DImode)
7714 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7715 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7716 if (sh_compare_op1 != const0_rtx)
7717 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7718 ? GET_MODE (sh_compare_op0)
7719 : GET_MODE (sh_compare_op1),
7720 sh_compare_op1);
7721
7722 emit_insn (gen_cmpgtudi_media (operands[0],
7723 sh_compare_op0, sh_compare_op1));
7724 DONE;
7725 }
7726 if (! rtx_equal_function_value_matters)
7727 FAIL;
7728 operands[1] = prepare_scc_operands (GTU);
7729 }")
7730
7731 (define_expand "sltu"
7732 [(set (match_operand:SI 0 "arith_reg_operand" "")
7733 (match_dup 1))]
7734 ""
7735 "
7736 {
7737 if (TARGET_SHMEDIA)
7738 {
7739 if (GET_MODE (operands[0]) != DImode)
7740 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7741 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7742 if (sh_compare_op1 != const0_rtx)
7743 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7744 ? GET_MODE (sh_compare_op0)
7745 : GET_MODE (sh_compare_op1),
7746 sh_compare_op1);
7747
7748 emit_insn (gen_cmpgtudi_media (operands[0],
7749 sh_compare_op1, sh_compare_op0));
7750 DONE;
7751 }
7752 if (! rtx_equal_function_value_matters)
7753 FAIL;
7754 operands[1] = prepare_scc_operands (LTU);
7755 }")
7756
7757 (define_expand "sleu"
7758 [(set (match_operand:SI 0 "arith_reg_operand" "")
7759 (match_dup 1))]
7760 ""
7761 "
7762 {
7763 if (TARGET_SHMEDIA)
7764 {
7765 rtx tmp;
7766
7767 if (GET_MODE (operands[0]) != DImode)
7768 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7769 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7770 if (sh_compare_op1 != const0_rtx)
7771 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7772 ? GET_MODE (sh_compare_op0)
7773 : GET_MODE (sh_compare_op1),
7774 sh_compare_op1);
7775
7776 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7777
7778 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7779 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7780
7781 DONE;
7782 }
7783 if (! rtx_equal_function_value_matters)
7784 FAIL;
7785 operands[1] = prepare_scc_operands (LEU);
7786 }")
7787
7788 (define_expand "sgeu"
7789 [(set (match_operand:SI 0 "arith_reg_operand" "")
7790 (match_dup 1))]
7791 ""
7792 "
7793 {
7794 if (TARGET_SHMEDIA)
7795 {
7796 rtx tmp;
7797
7798 if (GET_MODE (operands[0]) != DImode)
7799 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7800 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7801 if (sh_compare_op1 != const0_rtx)
7802 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7803 ? GET_MODE (sh_compare_op0)
7804 : GET_MODE (sh_compare_op1),
7805 sh_compare_op1);
7806
7807 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7808
7809 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7810 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7811
7812 DONE;
7813 }
7814
7815 if (! rtx_equal_function_value_matters)
7816 FAIL;
7817 operands[1] = prepare_scc_operands (GEU);
7818 }")
7819
7820 ;; sne moves the complement of the T reg to DEST like this:
7821 ;; cmp/eq ...
7822 ;; mov #-1,temp
7823 ;; negc temp,dest
7824 ;; This is better than xoring compare result with 1 because it does
7825 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7826 ;; loop.
7827
7828 (define_expand "sne"
7829 [(set (match_dup 2) (const_int -1))
7830 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7831 (neg:SI (plus:SI (match_dup 1)
7832 (match_dup 2))))
7833 (set (reg:SI T_REG)
7834 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7835 (const_int 0)))])]
7836 ""
7837 "
7838 {
7839 if (TARGET_SHMEDIA)
7840 {
7841 rtx tmp;
7842
7843 if (GET_MODE (operands[0]) != DImode)
7844 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7845
7846 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7847 FAIL;
7848
7849 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7850 if (sh_compare_op1 != const0_rtx)
7851 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7852 ? GET_MODE (sh_compare_op0)
7853 : GET_MODE (sh_compare_op1),
7854 sh_compare_op1);
7855
7856 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7857
7858 emit_insn (gen_seq (tmp));
7859 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7860
7861 DONE;
7862 }
7863
7864 if (sh_expand_t_scc (NE, operands[0]))
7865 DONE;
7866 if (! rtx_equal_function_value_matters)
7867 FAIL;
7868 operands[1] = prepare_scc_operands (EQ);
7869 operands[2] = gen_reg_rtx (SImode);
7870 }")
7871
7872 (define_expand "sunordered"
7873 [(set (match_operand:DI 0 "arith_reg_operand" "")
7874 (unordered:DI (match_dup 1) (match_dup 2)))]
7875 "TARGET_SHMEDIA_FPU"
7876 "
7877 {
7878 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7879 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7880 }")
7881
7882 ;; Use the same trick for FP sle / sge
7883 (define_expand "movnegt"
7884 [(set (match_dup 2) (const_int -1))
7885 (parallel [(set (match_operand 0 "" "")
7886 (neg:SI (plus:SI (match_dup 1)
7887 (match_dup 2))))
7888 (set (reg:SI T_REG)
7889 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7890 (const_int 0)))])]
7891 "TARGET_SH1"
7892 "operands[2] = gen_reg_rtx (SImode);")
7893
7894 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7895 ;; This prevents a regression that occurred when we switched from xor to
7896 ;; mov/neg for sne.
7897
7898 (define_split
7899 [(set (match_operand:SI 0 "arith_reg_operand" "")
7900 (plus:SI (reg:SI T_REG)
7901 (const_int -1)))]
7902 "TARGET_SH1"
7903 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7904 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7905 "")
7906
7907 ;; -------------------------------------------------------------------------
7908 ;; Instructions to cope with inline literal tables
7909 ;; -------------------------------------------------------------------------
7910
7911 ; 2 byte integer in line
7912
7913 (define_insn "consttable_2"
7914 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7915 (match_operand 1 "" "")]
7916 UNSPECV_CONST2)]
7917 ""
7918 "*
7919 {
7920 if (operands[1] != const0_rtx)
7921 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7922 return \"\";
7923 }"
7924 [(set_attr "length" "2")
7925 (set_attr "in_delay_slot" "no")])
7926
7927 ; 4 byte integer in line
7928
7929 (define_insn "consttable_4"
7930 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7931 (match_operand 1 "" "")]
7932 UNSPECV_CONST4)]
7933 ""
7934 "*
7935 {
7936 if (operands[1] != const0_rtx)
7937 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7938 return \"\";
7939 }"
7940 [(set_attr "length" "4")
7941 (set_attr "in_delay_slot" "no")])
7942
7943 ; 8 byte integer in line
7944
7945 (define_insn "consttable_8"
7946 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7947 (match_operand 1 "" "")]
7948 UNSPECV_CONST8)]
7949 ""
7950 "*
7951 {
7952 if (operands[1] != const0_rtx)
7953 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7954 return \"\";
7955 }"
7956 [(set_attr "length" "8")
7957 (set_attr "in_delay_slot" "no")])
7958
7959 ; 4 byte floating point
7960
7961 (define_insn "consttable_sf"
7962 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7963 (match_operand 1 "" "")]
7964 UNSPECV_CONST4)]
7965 ""
7966 "*
7967 {
7968 if (operands[1] != const0_rtx)
7969 {
7970 REAL_VALUE_TYPE d;
7971 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7972 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7973 }
7974 return \"\";
7975 }"
7976 [(set_attr "length" "4")
7977 (set_attr "in_delay_slot" "no")])
7978
7979 ; 8 byte floating point
7980
7981 (define_insn "consttable_df"
7982 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7983 (match_operand 1 "" "")]
7984 UNSPECV_CONST8)]
7985 ""
7986 "*
7987 {
7988 if (operands[1] != const0_rtx)
7989 {
7990 REAL_VALUE_TYPE d;
7991 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7992 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7993 }
7994 return \"\";
7995 }"
7996 [(set_attr "length" "8")
7997 (set_attr "in_delay_slot" "no")])
7998
7999 ;; Alignment is needed for some constant tables; it may also be added for
8000 ;; Instructions at the start of loops, or after unconditional branches.
8001 ;; ??? We would get more accurate lengths if we did instruction
8002 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8003 ;; here is too conservative.
8004
8005 ; align to a two byte boundary
8006
8007 (define_expand "align_2"
8008 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8009 ""
8010 "")
8011
8012 ; align to a four byte boundary
8013 ;; align_4 and align_log are instructions for the starts of loops, or
8014 ;; after unconditional branches, which may take up extra room.
8015
8016 (define_expand "align_4"
8017 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8018 ""
8019 "")
8020
8021 ; align to a cache line boundary
8022
8023 (define_insn "align_log"
8024 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8025 ""
8026 ""
8027 [(set_attr "length" "0")
8028 (set_attr "in_delay_slot" "no")])
8029
8030 ; emitted at the end of the literal table, used to emit the
8031 ; 32bit branch labels if needed.
8032
8033 (define_insn "consttable_end"
8034 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8035 ""
8036 "* return output_jump_label_table ();"
8037 [(set_attr "in_delay_slot" "no")])
8038
8039 ; emitted at the end of the window in the literal table.
8040
8041 (define_insn "consttable_window_end"
8042 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8043 ""
8044 ""
8045 [(set_attr "length" "0")
8046 (set_attr "in_delay_slot" "no")])
8047
8048 ;; -------------------------------------------------------------------------
8049 ;; Misc
8050 ;; -------------------------------------------------------------------------
8051
8052 ;; String/block move insn.
8053
8054 (define_expand "movmemsi"
8055 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8056 (mem:BLK (match_operand:BLK 1 "" "")))
8057 (use (match_operand:SI 2 "nonmemory_operand" ""))
8058 (use (match_operand:SI 3 "immediate_operand" ""))
8059 (clobber (reg:SI PR_REG))
8060 (clobber (reg:SI R4_REG))
8061 (clobber (reg:SI R5_REG))
8062 (clobber (reg:SI R0_REG))])]
8063 "TARGET_SH1 && ! TARGET_SH5"
8064 "
8065 {
8066 if(expand_block_move (operands))
8067 DONE;
8068 else FAIL;
8069 }")
8070
8071 (define_insn "block_move_real"
8072 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8073 (mem:BLK (reg:SI R5_REG)))
8074 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8075 (clobber (reg:SI PR_REG))
8076 (clobber (reg:SI R0_REG))])]
8077 "TARGET_SH1 && ! TARGET_HARD_SH4"
8078 "jsr @%0%#"
8079 [(set_attr "type" "sfunc")
8080 (set_attr "needs_delay_slot" "yes")])
8081
8082 (define_insn "block_lump_real"
8083 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8084 (mem:BLK (reg:SI R5_REG)))
8085 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8086 (use (reg:SI R6_REG))
8087 (clobber (reg:SI PR_REG))
8088 (clobber (reg:SI T_REG))
8089 (clobber (reg:SI R4_REG))
8090 (clobber (reg:SI R5_REG))
8091 (clobber (reg:SI R6_REG))
8092 (clobber (reg:SI R0_REG))])]
8093 "TARGET_SH1 && ! TARGET_HARD_SH4"
8094 "jsr @%0%#"
8095 [(set_attr "type" "sfunc")
8096 (set_attr "needs_delay_slot" "yes")])
8097
8098 (define_insn "block_move_real_i4"
8099 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8100 (mem:BLK (reg:SI R5_REG)))
8101 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8102 (clobber (reg:SI PR_REG))
8103 (clobber (reg:SI R0_REG))
8104 (clobber (reg:SI R1_REG))
8105 (clobber (reg:SI R2_REG))])]
8106 "TARGET_HARD_SH4"
8107 "jsr @%0%#"
8108 [(set_attr "type" "sfunc")
8109 (set_attr "needs_delay_slot" "yes")])
8110
8111 (define_insn "block_lump_real_i4"
8112 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8113 (mem:BLK (reg:SI R5_REG)))
8114 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8115 (use (reg:SI R6_REG))
8116 (clobber (reg:SI PR_REG))
8117 (clobber (reg:SI T_REG))
8118 (clobber (reg:SI R4_REG))
8119 (clobber (reg:SI R5_REG))
8120 (clobber (reg:SI R6_REG))
8121 (clobber (reg:SI R0_REG))
8122 (clobber (reg:SI R1_REG))
8123 (clobber (reg:SI R2_REG))
8124 (clobber (reg:SI R3_REG))])]
8125 "TARGET_HARD_SH4"
8126 "jsr @%0%#"
8127 [(set_attr "type" "sfunc")
8128 (set_attr "needs_delay_slot" "yes")])
8129 \f
8130 ;; -------------------------------------------------------------------------
8131 ;; Floating point instructions.
8132 ;; -------------------------------------------------------------------------
8133
8134 ;; ??? All patterns should have a type attribute.
8135
8136 (define_expand "fpu_switch0"
8137 [(set (match_operand:SI 0 "" "") (match_dup 2))
8138 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8139 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8140 "
8141 {
8142 operands[1] = get_fpscr_rtx ();
8143 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8144 if (flag_pic)
8145 operands[2] = legitimize_pic_address (operands[2], SImode,
8146 no_new_pseudos ? operands[0] : 0);
8147 }")
8148
8149 (define_expand "fpu_switch1"
8150 [(set (match_operand:SI 0 "" "") (match_dup 2))
8151 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8152 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8153 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8154 "
8155 {
8156 operands[1] = get_fpscr_rtx ();
8157 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8158 if (flag_pic)
8159 operands[2] = legitimize_pic_address (operands[2], SImode,
8160 no_new_pseudos ? operands[0] : 0);
8161 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8162 }")
8163
8164 (define_expand "movpsi"
8165 [(set (match_operand:PSI 0 "register_operand" "")
8166 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8167 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8168 "")
8169
8170 ;; The c / m alternative is a fake to guide reload to load directly into
8171 ;; fpscr, since reload doesn't know how to use post-increment.
8172 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8173 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8174 ;; predicate after reload.
8175 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8176 ;; like a mac -> gpr move.
8177 (define_insn "fpu_switch"
8178 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8179 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8180 "TARGET_SH2E
8181 && (! reload_completed
8182 || true_regnum (operands[0]) != FPSCR_REG
8183 || GET_CODE (operands[1]) != MEM
8184 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8185 "@
8186 ! precision stays the same
8187 lds.l %1,fpscr
8188 mov.l %1,%0
8189 #
8190 lds %1,fpscr
8191 mov %1,%0
8192 mov.l %1,%0
8193 sts fpscr,%0
8194 sts.l fpscr,%0"
8195 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8196 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8197
8198 (define_split
8199 [(set (reg:PSI FPSCR_REG)
8200 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8201 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8202 [(set (match_dup 0) (match_dup 0))]
8203 "
8204 {
8205 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8206 gen_rtx_MEM (PSImode,
8207 gen_rtx_POST_INC (Pmode,
8208 operands[0]))));
8209 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8210 }")
8211
8212 (define_split
8213 [(set (reg:PSI FPSCR_REG)
8214 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8215 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8216 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8217 "
8218 {
8219 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8220 gen_rtx_MEM (PSImode,
8221 gen_rtx_POST_INC (Pmode,
8222 operands[0]))));
8223 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8224 }")
8225
8226 ;; ??? This uses the fp unit, but has no type indicating that.
8227 ;; If we did that, this would either give a bogus latency or introduce
8228 ;; a bogus FIFO constraint.
8229 ;; Since this insn is currently only used for prologues/epilogues,
8230 ;; it is probably best to claim no function unit, which matches the
8231 ;; current setting.
8232 (define_insn "toggle_sz"
8233 [(set (reg:PSI FPSCR_REG)
8234 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8235 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8236 "fschg"
8237 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8238
8239 ;; There's no way we can use it today, since optimize mode switching
8240 ;; doesn't enable us to know from which mode we're switching to the
8241 ;; mode it requests, to tell whether we can use a relative mode switch
8242 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8243 ;; memory).
8244 (define_insn "toggle_pr"
8245 [(set (reg:PSI FPSCR_REG)
8246 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8247 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8248 "fpchg"
8249 [(set_attr "type" "fp")])
8250
8251 (define_expand "addsf3"
8252 [(set (match_operand:SF 0 "arith_reg_operand" "")
8253 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8254 (match_operand:SF 2 "arith_reg_operand" "")))]
8255 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8256 "
8257 {
8258 if (TARGET_SH2E)
8259 {
8260 expand_sf_binop (&gen_addsf3_i, operands);
8261 DONE;
8262 }
8263 }")
8264
8265 (define_insn "*addsf3_media"
8266 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8267 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8268 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8269 "TARGET_SHMEDIA_FPU"
8270 "fadd.s %1, %2, %0"
8271 [(set_attr "type" "fparith_media")])
8272
8273 (define_insn_and_split "unary_sf_op"
8274 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8275 (vec_select:V2SF
8276 (vec_concat:V2SF
8277 (vec_select:SF
8278 (match_dup 0)
8279 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8280 (match_operator:SF 2 "unary_float_operator"
8281 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8282 (parallel [(match_operand 4
8283 "const_int_operand" "n")]))]))
8284 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8285 "TARGET_SHMEDIA_FPU"
8286 "#"
8287 "TARGET_SHMEDIA_FPU && reload_completed"
8288 [(set (match_dup 5) (match_dup 6))]
8289 "
8290 {
8291 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8292 rtx op1 = gen_rtx_REG (SFmode,
8293 (true_regnum (operands[1])
8294 + (INTVAL (operands[4]) ^ endian)));
8295
8296 operands[7] = gen_rtx_REG (SFmode,
8297 (true_regnum (operands[0])
8298 + (INTVAL (operands[3]) ^ endian)));
8299 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8300 }"
8301 [(set_attr "type" "fparith_media")])
8302
8303 (define_insn_and_split "binary_sf_op"
8304 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8305 (vec_select:V2SF
8306 (vec_concat:V2SF
8307 (vec_select:SF
8308 (match_dup 0)
8309 (parallel [(match_operand 7 "const_int_operand" "n")]))
8310 (match_operator:SF 3 "binary_float_operator"
8311 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8312 (parallel [(match_operand 5
8313 "const_int_operand" "n")]))
8314 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8315 (parallel [(match_operand 6
8316 "const_int_operand" "n")]))]))
8317 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8318 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8319 "#"
8320 "&& reload_completed"
8321 [(set (match_dup 8) (match_dup 9))]
8322 "
8323 {
8324 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8325 rtx op1 = gen_rtx_REG (SFmode,
8326 (true_regnum (operands[1])
8327 + (INTVAL (operands[5]) ^ endian)));
8328 rtx op2 = gen_rtx_REG (SFmode,
8329 (true_regnum (operands[2])
8330 + (INTVAL (operands[6]) ^ endian)));
8331
8332 operands[8] = gen_rtx_REG (SFmode,
8333 (true_regnum (operands[0])
8334 + (INTVAL (operands[4]) ^ endian)));
8335 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8336 }"
8337 [(set_attr "type" "fparith_media")])
8338
8339 (define_insn "addsf3_i"
8340 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8341 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8342 (match_operand:SF 2 "arith_reg_operand" "f")))
8343 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8344 "TARGET_SH2E"
8345 "fadd %2,%0"
8346 [(set_attr "type" "fp")
8347 (set_attr "fp_mode" "single")])
8348
8349 (define_expand "subsf3"
8350 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8351 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8352 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8353 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8354 "
8355 {
8356 if (TARGET_SH2E)
8357 {
8358 expand_sf_binop (&gen_subsf3_i, operands);
8359 DONE;
8360 }
8361 }")
8362
8363 (define_insn "*subsf3_media"
8364 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8365 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8366 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8367 "TARGET_SHMEDIA_FPU"
8368 "fsub.s %1, %2, %0"
8369 [(set_attr "type" "fparith_media")])
8370
8371 (define_insn "subsf3_i"
8372 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8373 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8374 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8375 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8376 "TARGET_SH2E"
8377 "fsub %2,%0"
8378 [(set_attr "type" "fp")
8379 (set_attr "fp_mode" "single")])
8380
8381 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8382 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8383 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8384 ;; SH3E, we use a separate insn for SH3E mulsf3.
8385
8386 (define_expand "mulsf3"
8387 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8388 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8389 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8390 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8391 "
8392 {
8393 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8394 expand_sf_binop (&gen_mulsf3_i4, operands);
8395 else if (TARGET_SH2E)
8396 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8397 if (! TARGET_SHMEDIA)
8398 DONE;
8399 }")
8400
8401 (define_insn "*mulsf3_media"
8402 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8403 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8404 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
8406 "fmul.s %1, %2, %0"
8407 [(set_attr "type" "fparith_media")])
8408
8409 (define_insn "mulsf3_i4"
8410 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8411 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8412 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8413 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8414 "TARGET_SH2E"
8415 "fmul %2,%0"
8416 [(set_attr "type" "fp")
8417 (set_attr "fp_mode" "single")])
8418
8419 (define_insn "mulsf3_ie"
8420 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8421 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8422 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8423 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8424 "fmul %2,%0"
8425 [(set_attr "type" "fp")])
8426
8427 (define_insn "*mac_media"
8428 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8429 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8430 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8431 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8432 "TARGET_SHMEDIA_FPU"
8433 "fmac.s %1, %2, %0"
8434 [(set_attr "type" "fparith_media")])
8435
8436 (define_insn "*macsf3"
8437 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8438 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8439 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8440 (match_operand:SF 3 "arith_reg_operand" "0")))
8441 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8442 "TARGET_SH2E && ! TARGET_SH4"
8443 "fmac fr0,%2,%0"
8444 [(set_attr "type" "fp")
8445 (set_attr "fp_mode" "single")])
8446
8447 (define_expand "divsf3"
8448 [(set (match_operand:SF 0 "arith_reg_operand" "")
8449 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8450 (match_operand:SF 2 "arith_reg_operand" "")))]
8451 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8452 "
8453 {
8454 if (TARGET_SH2E)
8455 {
8456 expand_sf_binop (&gen_divsf3_i, operands);
8457 DONE;
8458 }
8459 }")
8460
8461 (define_insn "*divsf3_media"
8462 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8463 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8464 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8465 "TARGET_SHMEDIA_FPU"
8466 "fdiv.s %1, %2, %0"
8467 [(set_attr "type" "fdiv_media")])
8468
8469 (define_insn "divsf3_i"
8470 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8471 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8472 (match_operand:SF 2 "arith_reg_operand" "f")))
8473 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8474 "TARGET_SH2E"
8475 "fdiv %2,%0"
8476 [(set_attr "type" "fdiv")
8477 (set_attr "fp_mode" "single")])
8478
8479 (define_insn "floatdisf2"
8480 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8481 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8482 "TARGET_SHMEDIA_FPU"
8483 "float.qs %1, %0"
8484 [(set_attr "type" "fpconv_media")])
8485
8486 (define_expand "floatsisf2"
8487 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8488 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8489 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8490 "
8491 {
8492 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8493 {
8494 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8495 DONE;
8496 }
8497 }")
8498
8499 (define_insn "*floatsisf2_media"
8500 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8501 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8502 "TARGET_SHMEDIA_FPU"
8503 "float.ls %1, %0"
8504 [(set_attr "type" "fpconv_media")])
8505
8506 (define_insn "floatsisf2_i4"
8507 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8508 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8509 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8510 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8511 "float %1,%0"
8512 [(set_attr "type" "fp")
8513 (set_attr "fp_mode" "single")])
8514
8515 (define_insn "*floatsisf2_ie"
8516 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8517 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8518 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8519 "float %1,%0"
8520 [(set_attr "type" "fp")])
8521
8522 (define_insn "fix_truncsfdi2"
8523 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8524 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8525 "TARGET_SHMEDIA_FPU"
8526 "ftrc.sq %1, %0"
8527 [(set_attr "type" "fpconv_media")])
8528
8529 (define_expand "fix_truncsfsi2"
8530 [(set (match_operand:SI 0 "fpul_operand" "=y")
8531 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8532 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8533 "
8534 {
8535 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8536 {
8537 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8538 DONE;
8539 }
8540 }")
8541
8542 (define_insn "*fix_truncsfsi2_media"
8543 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8544 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8545 "TARGET_SHMEDIA_FPU"
8546 "ftrc.sl %1, %0"
8547 [(set_attr "type" "fpconv_media")])
8548
8549 (define_insn "fix_truncsfsi2_i4"
8550 [(set (match_operand:SI 0 "fpul_operand" "=y")
8551 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8552 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8553 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8554 "ftrc %1,%0"
8555 [(set_attr "type" "ftrc_s")
8556 (set_attr "fp_mode" "single")])
8557
8558 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8559 ;; fix_truncsfsi2_i4.
8560 ;; (define_insn "fix_truncsfsi2_i4_2"
8561 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8562 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8563 ;; (use (reg:PSI FPSCR_REG))
8564 ;; (clobber (reg:SI FPUL_REG))]
8565 ;; "TARGET_SH4"
8566 ;; "#"
8567 ;; [(set_attr "length" "4")
8568 ;; (set_attr "fp_mode" "single")])
8569
8570 ;;(define_split
8571 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8572 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8573 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8574 ;; (clobber (reg:SI FPUL_REG))]
8575 ;; "TARGET_SH4"
8576 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8577 ;; (use (match_dup 2))])
8578 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8579
8580 (define_insn "*fixsfsi"
8581 [(set (match_operand:SI 0 "fpul_operand" "=y")
8582 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8583 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8584 "ftrc %1,%0"
8585 [(set_attr "type" "fp")])
8586
8587 (define_insn "cmpgtsf_t"
8588 [(set (reg:SI T_REG)
8589 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8590 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8591 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8592 "fcmp/gt %1,%0"
8593 [(set_attr "type" "fp")
8594 (set_attr "fp_mode" "single")])
8595
8596 (define_insn "cmpeqsf_t"
8597 [(set (reg:SI T_REG)
8598 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8599 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8600 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8601 "fcmp/eq %1,%0"
8602 [(set_attr "type" "fp")
8603 (set_attr "fp_mode" "single")])
8604
8605 (define_insn "ieee_ccmpeqsf_t"
8606 [(set (reg:SI T_REG)
8607 (ior:SI (reg:SI T_REG)
8608 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8609 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8610 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8611 "* return output_ieee_ccmpeq (insn, operands);"
8612 [(set_attr "length" "4")])
8613
8614
8615 (define_insn "cmpgtsf_t_i4"
8616 [(set (reg:SI T_REG)
8617 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8618 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8619 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8620 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8621 "fcmp/gt %1,%0"
8622 [(set_attr "type" "fp")
8623 (set_attr "fp_mode" "single")])
8624
8625 (define_insn "cmpeqsf_t_i4"
8626 [(set (reg:SI T_REG)
8627 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8628 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8629 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8630 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8631 "fcmp/eq %1,%0"
8632 [(set_attr "type" "fp")
8633 (set_attr "fp_mode" "single")])
8634
8635 (define_insn "*ieee_ccmpeqsf_t_4"
8636 [(set (reg:SI T_REG)
8637 (ior:SI (reg:SI T_REG)
8638 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8639 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8640 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8641 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8642 "* return output_ieee_ccmpeq (insn, operands);"
8643 [(set_attr "length" "4")
8644 (set_attr "fp_mode" "single")])
8645
8646 (define_insn "cmpeqsf_media"
8647 [(set (match_operand:DI 0 "register_operand" "=r")
8648 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8649 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8650 "TARGET_SHMEDIA_FPU"
8651 "fcmpeq.s %1, %2, %0"
8652 [(set_attr "type" "fcmp_media")])
8653
8654 (define_insn "cmpgtsf_media"
8655 [(set (match_operand:DI 0 "register_operand" "=r")
8656 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8657 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8658 "TARGET_SHMEDIA_FPU"
8659 "fcmpgt.s %1, %2, %0"
8660 [(set_attr "type" "fcmp_media")])
8661
8662 (define_insn "cmpgesf_media"
8663 [(set (match_operand:DI 0 "register_operand" "=r")
8664 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8665 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8666 "TARGET_SHMEDIA_FPU"
8667 "fcmpge.s %1, %2, %0"
8668 [(set_attr "type" "fcmp_media")])
8669
8670 (define_insn "cmpunsf_media"
8671 [(set (match_operand:DI 0 "register_operand" "=r")
8672 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8673 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8674 "TARGET_SHMEDIA_FPU"
8675 "fcmpun.s %1, %2, %0"
8676 [(set_attr "type" "fcmp_media")])
8677
8678 (define_expand "cmpsf"
8679 [(set (reg:SI T_REG)
8680 (compare (match_operand:SF 0 "arith_operand" "")
8681 (match_operand:SF 1 "arith_operand" "")))]
8682 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8683 "
8684 {
8685 sh_compare_op0 = operands[0];
8686 sh_compare_op1 = operands[1];
8687 DONE;
8688 }")
8689
8690 (define_expand "negsf2"
8691 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8692 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8693 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8694 "
8695 {
8696 if (TARGET_SH2E)
8697 {
8698 expand_sf_unop (&gen_negsf2_i, operands);
8699 DONE;
8700 }
8701 }")
8702
8703 (define_insn "*negsf2_media"
8704 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8705 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8706 "TARGET_SHMEDIA_FPU"
8707 "fneg.s %1, %0"
8708 [(set_attr "type" "fmove_media")])
8709
8710 (define_insn "negsf2_i"
8711 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8712 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8713 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8714 "TARGET_SH2E"
8715 "fneg %0"
8716 [(set_attr "type" "fmove")
8717 (set_attr "fp_mode" "single")])
8718
8719 (define_expand "sqrtsf2"
8720 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8721 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8722 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8723 "
8724 {
8725 if (TARGET_SH3E)
8726 {
8727 expand_sf_unop (&gen_sqrtsf2_i, operands);
8728 DONE;
8729 }
8730 }")
8731
8732 (define_insn "*sqrtsf2_media"
8733 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8734 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8735 "TARGET_SHMEDIA_FPU"
8736 "fsqrt.s %1, %0"
8737 [(set_attr "type" "fdiv_media")])
8738
8739 (define_insn "sqrtsf2_i"
8740 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8741 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8742 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8743 "TARGET_SH3E"
8744 "fsqrt %0"
8745 [(set_attr "type" "fdiv")
8746 (set_attr "fp_mode" "single")])
8747
8748 (define_insn "rsqrtsf2"
8749 [(set (match_operand:SF 0 "register_operand" "=f")
8750 (div:SF (match_operand:SF 1 "immediate_operand" "i")
8751 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8752 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8753 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8754 && operands[1] == CONST1_RTX (SFmode)"
8755 "fsrra %0"
8756 [(set_attr "type" "fsrra")
8757 (set_attr "fp_mode" "single")])
8758
8759 (define_insn "fsca"
8760 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8761 (vec_concat:V2SF
8762 (unspec:SF [(mult:SF
8763 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8764 (match_operand:SF 2 "immediate_operand" "i"))
8765 ] UNSPEC_FSINA)
8766 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8767 ] UNSPEC_FCOSA)))
8768 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8769 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8770 && operands[2] == sh_fsca_int2sf ()"
8771 "fsca fpul,%d0"
8772 [(set_attr "type" "fsca")
8773 (set_attr "fp_mode" "single")])
8774
8775 (define_expand "sinsf2"
8776 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8777 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8778 UNSPEC_FSINA))]
8779 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8780 "
8781 {
8782 rtx scaled = gen_reg_rtx (SFmode);
8783 rtx truncated = gen_reg_rtx (SImode);
8784 rtx fsca = gen_reg_rtx (V2SFmode);
8785 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8786
8787 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8788 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8789 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8790 get_fpscr_rtx ()));
8791 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8792 DONE;
8793 }")
8794
8795 (define_expand "cossf2"
8796 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8797 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8798 UNSPEC_FCOSA))]
8799 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8800 "
8801 {
8802 rtx scaled = gen_reg_rtx (SFmode);
8803 rtx truncated = gen_reg_rtx (SImode);
8804 rtx fsca = gen_reg_rtx (V2SFmode);
8805 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8806
8807 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8808 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8809 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8810 get_fpscr_rtx ()));
8811 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8812 DONE;
8813 }")
8814
8815 (define_expand "sindf2"
8816 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8817 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8818 UNSPEC_FSINA))]
8819 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8820 "
8821 {
8822 rtx scaled = gen_reg_rtx (DFmode);
8823 rtx truncated = gen_reg_rtx (SImode);
8824 rtx fsca = gen_reg_rtx (V2SFmode);
8825 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8826 rtx sfresult = gen_reg_rtx (SFmode);
8827
8828 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8829 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8830 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8831 get_fpscr_rtx ()));
8832 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8833 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8834 DONE;
8835 }")
8836
8837 (define_expand "cosdf2"
8838 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8839 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8840 UNSPEC_FCOSA))]
8841 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8842 "
8843 {
8844 rtx scaled = gen_reg_rtx (DFmode);
8845 rtx truncated = gen_reg_rtx (SImode);
8846 rtx fsca = gen_reg_rtx (V2SFmode);
8847 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8848 rtx sfresult = gen_reg_rtx (SFmode);
8849
8850 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8851 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8852 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8853 get_fpscr_rtx ()));
8854 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8855 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8856 DONE;
8857 }")
8858
8859 (define_expand "abssf2"
8860 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8861 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8862 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8863 "
8864 {
8865 if (TARGET_SH2E)
8866 {
8867 expand_sf_unop (&gen_abssf2_i, operands);
8868 DONE;
8869 }
8870 }")
8871
8872 (define_insn "*abssf2_media"
8873 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8874 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8875 "TARGET_SHMEDIA_FPU"
8876 "fabs.s %1, %0"
8877 [(set_attr "type" "fmove_media")])
8878
8879 (define_insn "abssf2_i"
8880 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8881 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8882 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8883 "TARGET_SH2E"
8884 "fabs %0"
8885 [(set_attr "type" "fmove")
8886 (set_attr "fp_mode" "single")])
8887
8888 (define_expand "adddf3"
8889 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8890 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8891 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8892 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8893 "
8894 {
8895 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8896 {
8897 expand_df_binop (&gen_adddf3_i, operands);
8898 DONE;
8899 }
8900 }")
8901
8902 (define_insn "*adddf3_media"
8903 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8904 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8905 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8906 "TARGET_SHMEDIA_FPU"
8907 "fadd.d %1, %2, %0"
8908 [(set_attr "type" "dfparith_media")])
8909
8910 (define_insn "adddf3_i"
8911 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8912 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8913 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8914 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8916 "fadd %2,%0"
8917 [(set_attr "type" "dfp_arith")
8918 (set_attr "fp_mode" "double")])
8919
8920 (define_expand "subdf3"
8921 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8922 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8923 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8924 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8925 "
8926 {
8927 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8928 {
8929 expand_df_binop (&gen_subdf3_i, operands);
8930 DONE;
8931 }
8932 }")
8933
8934 (define_insn "*subdf3_media"
8935 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8936 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8937 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8938 "TARGET_SHMEDIA_FPU"
8939 "fsub.d %1, %2, %0"
8940 [(set_attr "type" "dfparith_media")])
8941
8942 (define_insn "subdf3_i"
8943 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8944 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8945 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8946 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8947 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8948 "fsub %2,%0"
8949 [(set_attr "type" "dfp_arith")
8950 (set_attr "fp_mode" "double")])
8951
8952 (define_expand "muldf3"
8953 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8954 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8955 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8956 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8957 "
8958 {
8959 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8960 {
8961 expand_df_binop (&gen_muldf3_i, operands);
8962 DONE;
8963 }
8964 }")
8965
8966 (define_insn "*muldf3_media"
8967 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8968 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8969 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8970 "TARGET_SHMEDIA_FPU"
8971 "fmul.d %1, %2, %0"
8972 [(set_attr "type" "dfmul_media")])
8973
8974 (define_insn "muldf3_i"
8975 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8976 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8977 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8978 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8979 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8980 "fmul %2,%0"
8981 [(set_attr "type" "dfp_arith")
8982 (set_attr "fp_mode" "double")])
8983
8984 (define_expand "divdf3"
8985 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8986 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8987 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8988 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8989 "
8990 {
8991 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8992 {
8993 expand_df_binop (&gen_divdf3_i, operands);
8994 DONE;
8995 }
8996 }")
8997
8998 (define_insn "*divdf3_media"
8999 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9000 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9001 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9002 "TARGET_SHMEDIA_FPU"
9003 "fdiv.d %1, %2, %0"
9004 [(set_attr "type" "dfdiv_media")])
9005
9006 (define_insn "divdf3_i"
9007 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9008 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9009 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9010 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9011 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9012 "fdiv %2,%0"
9013 [(set_attr "type" "dfdiv")
9014 (set_attr "fp_mode" "double")])
9015
9016 (define_insn "floatdidf2"
9017 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9018 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9019 "TARGET_SHMEDIA_FPU"
9020 "float.qd %1, %0"
9021 [(set_attr "type" "dfpconv_media")])
9022
9023 (define_expand "floatsidf2"
9024 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9025 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9026 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9027 "
9028 {
9029 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9030 {
9031 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9032 get_fpscr_rtx ()));
9033 DONE;
9034 }
9035 }")
9036
9037 (define_insn "*floatsidf2_media"
9038 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9039 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9040 "TARGET_SHMEDIA_FPU"
9041 "float.ld %1, %0"
9042 [(set_attr "type" "dfpconv_media")])
9043
9044 (define_insn "floatsidf2_i"
9045 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9046 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9047 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9048 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9049 "float %1,%0"
9050 [(set_attr "type" "dfp_conv")
9051 (set_attr "fp_mode" "double")])
9052
9053 (define_insn "fix_truncdfdi2"
9054 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9055 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9056 "TARGET_SHMEDIA_FPU"
9057 "ftrc.dq %1, %0"
9058 [(set_attr "type" "dfpconv_media")])
9059
9060 (define_expand "fix_truncdfsi2"
9061 [(set (match_operand:SI 0 "fpul_operand" "")
9062 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9063 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9064 "
9065 {
9066 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9067 {
9068 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9069 get_fpscr_rtx ()));
9070 DONE;
9071 }
9072 }")
9073
9074 (define_insn "*fix_truncdfsi2_media"
9075 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9076 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9077 "TARGET_SHMEDIA_FPU"
9078 "ftrc.dl %1, %0"
9079 [(set_attr "type" "dfpconv_media")])
9080
9081 (define_insn "fix_truncdfsi2_i"
9082 [(set (match_operand:SI 0 "fpul_operand" "=y")
9083 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9084 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9085 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9086 "ftrc %1,%0"
9087 [(set_attr "type" "dfp_conv")
9088 (set_attr "dfp_comp" "no")
9089 (set_attr "fp_mode" "double")])
9090
9091 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
9092 ;; fix_truncdfsi2_i.
9093 ;; (define_insn "fix_truncdfsi2_i4"
9094 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9095 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9096 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9097 ;; (clobber (reg:SI FPUL_REG))]
9098 ;; "TARGET_SH4"
9099 ;; "#"
9100 ;; [(set_attr "length" "4")
9101 ;; (set_attr "fp_mode" "double")])
9102 ;;
9103 ;; (define_split
9104 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9105 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9106 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9107 ;; (clobber (reg:SI FPUL_REG))]
9108 ;; "TARGET_SH4"
9109 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9110 ;; (use (match_dup 2))])
9111 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
9112
9113 (define_insn "cmpgtdf_t"
9114 [(set (reg:SI T_REG)
9115 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9116 (match_operand:DF 1 "arith_reg_operand" "f")))
9117 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9118 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9119 "fcmp/gt %1,%0"
9120 [(set_attr "type" "dfp_cmp")
9121 (set_attr "fp_mode" "double")])
9122
9123 (define_insn "cmpeqdf_t"
9124 [(set (reg:SI T_REG)
9125 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9126 (match_operand:DF 1 "arith_reg_operand" "f")))
9127 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9128 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9129 "fcmp/eq %1,%0"
9130 [(set_attr "type" "dfp_cmp")
9131 (set_attr "fp_mode" "double")])
9132
9133 (define_insn "*ieee_ccmpeqdf_t"
9134 [(set (reg:SI T_REG)
9135 (ior:SI (reg:SI T_REG)
9136 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9137 (match_operand:DF 1 "arith_reg_operand" "f"))))
9138 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9139 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9140 "* return output_ieee_ccmpeq (insn, operands);"
9141 [(set_attr "length" "4")
9142 (set_attr "fp_mode" "double")])
9143
9144 (define_insn "cmpeqdf_media"
9145 [(set (match_operand:DI 0 "register_operand" "=r")
9146 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9147 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9148 "TARGET_SHMEDIA_FPU"
9149 "fcmpeq.d %1,%2,%0"
9150 [(set_attr "type" "fcmp_media")])
9151
9152 (define_insn "cmpgtdf_media"
9153 [(set (match_operand:DI 0 "register_operand" "=r")
9154 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9155 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9156 "TARGET_SHMEDIA_FPU"
9157 "fcmpgt.d %1,%2,%0"
9158 [(set_attr "type" "fcmp_media")])
9159
9160 (define_insn "cmpgedf_media"
9161 [(set (match_operand:DI 0 "register_operand" "=r")
9162 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9163 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9164 "TARGET_SHMEDIA_FPU"
9165 "fcmpge.d %1,%2,%0"
9166 [(set_attr "type" "fcmp_media")])
9167
9168 (define_insn "cmpundf_media"
9169 [(set (match_operand:DI 0 "register_operand" "=r")
9170 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9171 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9172 "TARGET_SHMEDIA_FPU"
9173 "fcmpun.d %1,%2,%0"
9174 [(set_attr "type" "fcmp_media")])
9175
9176 (define_expand "cmpdf"
9177 [(set (reg:SI T_REG)
9178 (compare (match_operand:DF 0 "arith_operand" "")
9179 (match_operand:DF 1 "arith_operand" "")))]
9180 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9181 "
9182 {
9183 sh_compare_op0 = operands[0];
9184 sh_compare_op1 = operands[1];
9185 DONE;
9186 }")
9187
9188 (define_expand "negdf2"
9189 [(set (match_operand:DF 0 "arith_reg_operand" "")
9190 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9191 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9192 "
9193 {
9194 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9195 {
9196 expand_df_unop (&gen_negdf2_i, operands);
9197 DONE;
9198 }
9199 }")
9200
9201 (define_insn "*negdf2_media"
9202 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9203 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9204 "TARGET_SHMEDIA_FPU"
9205 "fneg.d %1, %0"
9206 [(set_attr "type" "fmove_media")])
9207
9208 (define_insn "negdf2_i"
9209 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9210 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9211 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9212 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9213 "fneg %0"
9214 [(set_attr "type" "fmove")
9215 (set_attr "fp_mode" "double")])
9216
9217 (define_expand "sqrtdf2"
9218 [(set (match_operand:DF 0 "arith_reg_operand" "")
9219 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9220 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9221 "
9222 {
9223 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9224 {
9225 expand_df_unop (&gen_sqrtdf2_i, operands);
9226 DONE;
9227 }
9228 }")
9229
9230 (define_insn "*sqrtdf2_media"
9231 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9232 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9233 "TARGET_SHMEDIA_FPU"
9234 "fsqrt.d %1, %0"
9235 [(set_attr "type" "dfdiv_media")])
9236
9237 (define_insn "sqrtdf2_i"
9238 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9239 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9240 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9241 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9242 "fsqrt %0"
9243 [(set_attr "type" "dfdiv")
9244 (set_attr "fp_mode" "double")])
9245
9246 (define_expand "absdf2"
9247 [(set (match_operand:DF 0 "arith_reg_operand" "")
9248 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9249 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9250 "
9251 {
9252 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9253 {
9254 expand_df_unop (&gen_absdf2_i, operands);
9255 DONE;
9256 }
9257 }")
9258
9259 (define_insn "*absdf2_media"
9260 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9261 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9262 "TARGET_SHMEDIA_FPU"
9263 "fabs.d %1, %0"
9264 [(set_attr "type" "fmove_media")])
9265
9266 (define_insn "absdf2_i"
9267 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9268 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9269 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9270 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9271 "fabs %0"
9272 [(set_attr "type" "fmove")
9273 (set_attr "fp_mode" "double")])
9274
9275 (define_expand "extendsfdf2"
9276 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9277 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9278 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9279 "
9280 {
9281 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9282 {
9283 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9284 get_fpscr_rtx ()));
9285 DONE;
9286 }
9287 }")
9288
9289 (define_insn "*extendsfdf2_media"
9290 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9291 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9292 "TARGET_SHMEDIA_FPU"
9293 "fcnv.sd %1, %0"
9294 [(set_attr "type" "dfpconv_media")])
9295
9296 (define_insn "extendsfdf2_i4"
9297 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9298 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9299 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9300 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9301 "fcnvsd %1,%0"
9302 [(set_attr "type" "fp")
9303 (set_attr "fp_mode" "double")])
9304
9305 (define_expand "truncdfsf2"
9306 [(set (match_operand:SF 0 "fpul_operand" "")
9307 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9308 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9309 "
9310 {
9311 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9312 {
9313 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9314 get_fpscr_rtx ()));
9315 DONE;
9316 }
9317 }")
9318
9319 (define_insn "*truncdfsf2_media"
9320 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9321 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9322 "TARGET_SHMEDIA_FPU"
9323 "fcnv.ds %1, %0"
9324 [(set_attr "type" "dfpconv_media")])
9325
9326 (define_insn "truncdfsf2_i4"
9327 [(set (match_operand:SF 0 "fpul_operand" "=y")
9328 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9329 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9330 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9331 "fcnvds %1,%0"
9332 [(set_attr "type" "fp")
9333 (set_attr "fp_mode" "double")])
9334 \f
9335 ;; Bit field extract patterns. These give better code for packed bitfields,
9336 ;; because they allow auto-increment addresses to be generated.
9337
9338 (define_expand "insv"
9339 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9340 (match_operand:SI 1 "immediate_operand" "")
9341 (match_operand:SI 2 "immediate_operand" ""))
9342 (match_operand:SI 3 "general_operand" ""))]
9343 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9344 "
9345 {
9346 rtx addr_target, orig_address, shift_reg, qi_val;
9347 HOST_WIDE_INT bitsize, size, v = 0;
9348 rtx x = operands[3];
9349
9350 /* ??? expmed doesn't care for non-register predicates. */
9351 if (! memory_operand (operands[0], VOIDmode)
9352 || ! immediate_operand (operands[1], VOIDmode)
9353 || ! immediate_operand (operands[2], VOIDmode)
9354 || ! general_operand (x, VOIDmode))
9355 FAIL;
9356 /* If this isn't a 16 / 24 / 32 bit field, or if
9357 it doesn't start on a byte boundary, then fail. */
9358 bitsize = INTVAL (operands[1]);
9359 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9360 || (INTVAL (operands[2]) % 8) != 0)
9361 FAIL;
9362
9363 size = bitsize / 8;
9364 orig_address = XEXP (operands[0], 0);
9365 shift_reg = gen_reg_rtx (SImode);
9366 if (GET_CODE (x) == CONST_INT)
9367 {
9368 v = INTVAL (x);
9369 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9370 }
9371 else
9372 {
9373 emit_insn (gen_movsi (shift_reg, operands[3]));
9374 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9375 }
9376 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9377
9378 operands[0] = replace_equiv_address (operands[0], addr_target);
9379 emit_insn (gen_movqi (operands[0], qi_val));
9380
9381 while (size -= 1)
9382 {
9383 if (GET_CODE (x) == CONST_INT)
9384 qi_val
9385 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9386 else
9387 {
9388 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9389 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9390 }
9391 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9392 emit_insn (gen_movqi (operands[0], qi_val));
9393 }
9394
9395 DONE;
9396 }")
9397
9398 (define_insn "movua"
9399 [(set (match_operand:SI 0 "register_operand" "=z")
9400 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9401 (const_int 32) (const_int 0)))]
9402 "TARGET_SH4A_ARCH"
9403 "movua.l %1,%0"
9404 [(set_attr "type" "movua")])
9405
9406 ;; We shouldn't need this, but cse replaces increments with references
9407 ;; to other regs before flow has a chance to create post_inc
9408 ;; addressing modes, and only postreload's cse_move2add brings the
9409 ;; increments back to a usable form.
9410 (define_peephole2
9411 [(set (match_operand:SI 0 "register_operand" "")
9412 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9413 (const_int 32) (const_int 0)))
9414 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9415 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9416 [(set (match_operand:SI 0 "register_operand" "")
9417 (sign_extract:SI (mem:SI (post_inc:SI
9418 (match_operand:SI 1 "register_operand" "")))
9419 (const_int 32) (const_int 0)))]
9420 "")
9421
9422 (define_expand "extv"
9423 [(set (match_operand:SI 0 "register_operand" "")
9424 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9425 (match_operand 2 "const_int_operand" "")
9426 (match_operand 3 "const_int_operand" "")))]
9427 ""
9428 {
9429 if (TARGET_SH4A_ARCH
9430 && INTVAL (operands[2]) == 32
9431 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9432 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9433 {
9434 emit_insn (gen_movua (operands[0],
9435 adjust_address (operands[1], SImode, 0)));
9436 DONE;
9437 }
9438
9439 FAIL;
9440 })
9441
9442 (define_expand "extzv"
9443 [(set (match_operand:SI 0 "register_operand" "")
9444 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9445 (match_operand 2 "const_int_operand" "")
9446 (match_operand 3 "const_int_operand" "")))]
9447 ""
9448 {
9449 if (TARGET_SH4A_ARCH
9450 && INTVAL (operands[2]) == 32
9451 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9452 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9453 {
9454 emit_insn (gen_movua (operands[0],
9455 adjust_address (operands[1], SImode, 0)));
9456 DONE;
9457 }
9458
9459 FAIL;
9460 })
9461
9462 \f
9463 ;; -------------------------------------------------------------------------
9464 ;; Peepholes
9465 ;; -------------------------------------------------------------------------
9466
9467 ;; This matches cases where a stack pointer increment at the start of the
9468 ;; epilogue combines with a stack slot read loading the return value.
9469
9470 (define_peephole
9471 [(set (match_operand:SI 0 "arith_reg_operand" "")
9472 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9473 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9474 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9475 "mov.l @%1+,%0")
9476
9477 ;; See the comment on the dt combiner pattern above.
9478
9479 (define_peephole
9480 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9481 (plus:SI (match_dup 0)
9482 (const_int -1)))
9483 (set (reg:SI T_REG)
9484 (eq:SI (match_dup 0)
9485 (const_int 0)))]
9486 "TARGET_SH2"
9487 "dt %0")
9488
9489 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9490 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9491 ;; reload when the constant is too large for a reg+offset address.
9492
9493 ;; ??? We would get much better code if this was done in reload. This would
9494 ;; require modifying find_reloads_address to recognize that if the constant
9495 ;; is out-of-range for an immediate add, then we get better code by reloading
9496 ;; the constant into a register than by reloading the sum into a register,
9497 ;; since the former is one instruction shorter if the address does not need
9498 ;; to be offsettable. Unfortunately this does not work, because there is
9499 ;; only one register, r0, that can be used as an index register. This register
9500 ;; is also the function return value register. So, if we try to force reload
9501 ;; to use double-reg addresses, then we end up with some instructions that
9502 ;; need to use r0 twice. The only way to fix this is to change the calling
9503 ;; convention so that r0 is not used to return values.
9504
9505 (define_peephole
9506 [(set (match_operand:SI 0 "register_operand" "=r")
9507 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9508 (set (mem:SI (match_dup 0))
9509 (match_operand:SI 2 "general_movsrc_operand" ""))]
9510 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9511 "mov.l %2,@(%0,%1)")
9512
9513 (define_peephole
9514 [(set (match_operand:SI 0 "register_operand" "=r")
9515 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9516 (set (match_operand:SI 2 "general_movdst_operand" "")
9517 (mem:SI (match_dup 0)))]
9518 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9519 "mov.l @(%0,%1),%2")
9520
9521 (define_peephole
9522 [(set (match_operand:SI 0 "register_operand" "=r")
9523 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9524 (set (mem:HI (match_dup 0))
9525 (match_operand:HI 2 "general_movsrc_operand" ""))]
9526 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9527 "mov.w %2,@(%0,%1)")
9528
9529 (define_peephole
9530 [(set (match_operand:SI 0 "register_operand" "=r")
9531 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9532 (set (match_operand:HI 2 "general_movdst_operand" "")
9533 (mem:HI (match_dup 0)))]
9534 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9535 "mov.w @(%0,%1),%2")
9536
9537 (define_peephole
9538 [(set (match_operand:SI 0 "register_operand" "=r")
9539 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9540 (set (mem:QI (match_dup 0))
9541 (match_operand:QI 2 "general_movsrc_operand" ""))]
9542 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9543 "mov.b %2,@(%0,%1)")
9544
9545 (define_peephole
9546 [(set (match_operand:SI 0 "register_operand" "=r")
9547 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9548 (set (match_operand:QI 2 "general_movdst_operand" "")
9549 (mem:QI (match_dup 0)))]
9550 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9551 "mov.b @(%0,%1),%2")
9552
9553 (define_peephole
9554 [(set (match_operand:SI 0 "register_operand" "=r")
9555 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9556 (set (mem:SF (match_dup 0))
9557 (match_operand:SF 2 "general_movsrc_operand" ""))]
9558 "TARGET_SH1 && REGNO (operands[0]) == 0
9559 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9560 || (GET_CODE (operands[2]) == SUBREG
9561 && REGNO (SUBREG_REG (operands[2])) < 16))
9562 && reg_unused_after (operands[0], insn)"
9563 "mov.l %2,@(%0,%1)")
9564
9565 (define_peephole
9566 [(set (match_operand:SI 0 "register_operand" "=r")
9567 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9568 (set (match_operand:SF 2 "general_movdst_operand" "")
9569
9570 (mem:SF (match_dup 0)))]
9571 "TARGET_SH1 && REGNO (operands[0]) == 0
9572 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9573 || (GET_CODE (operands[2]) == SUBREG
9574 && REGNO (SUBREG_REG (operands[2])) < 16))
9575 && reg_unused_after (operands[0], insn)"
9576 "mov.l @(%0,%1),%2")
9577
9578 (define_peephole
9579 [(set (match_operand:SI 0 "register_operand" "=r")
9580 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9581 (set (mem:SF (match_dup 0))
9582 (match_operand:SF 2 "general_movsrc_operand" ""))]
9583 "TARGET_SH2E && REGNO (operands[0]) == 0
9584 && ((GET_CODE (operands[2]) == REG
9585 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9586 || (GET_CODE (operands[2]) == SUBREG
9587 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9588 && reg_unused_after (operands[0], insn)"
9589 "fmov{.s|} %2,@(%0,%1)")
9590
9591 (define_peephole
9592 [(set (match_operand:SI 0 "register_operand" "=r")
9593 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9594 (set (match_operand:SF 2 "general_movdst_operand" "")
9595
9596 (mem:SF (match_dup 0)))]
9597 "TARGET_SH2E && REGNO (operands[0]) == 0
9598 && ((GET_CODE (operands[2]) == REG
9599 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9600 || (GET_CODE (operands[2]) == SUBREG
9601 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9602 && reg_unused_after (operands[0], insn)"
9603 "fmov{.s|} @(%0,%1),%2")
9604
9605 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9606 (define_insn "sp_switch_1"
9607 [(const_int 1)]
9608 "TARGET_SH1"
9609 "*
9610 {
9611 rtx xoperands[1];
9612
9613 xoperands[0] = sp_switch;
9614 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9615 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9616 return \"mov r0,r15\";
9617 }"
9618 [(set_attr "length" "10")])
9619
9620 ;; Switch back to the original stack for interrupt functions with the
9621 ;; sp_switch attribute. */
9622 (define_insn "sp_switch_2"
9623 [(const_int 2)]
9624 "TARGET_SH1"
9625 "mov.l @r15+,r15\;mov.l @r15+,r0"
9626 [(set_attr "length" "4")])
9627
9628 ;; Integer vector moves
9629
9630 (define_expand "movv8qi"
9631 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9632 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9633 "TARGET_SHMEDIA"
9634 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9635
9636 (define_insn "movv8qi_i"
9637 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9638 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9639 "TARGET_SHMEDIA
9640 && (register_operand (operands[0], V8QImode)
9641 || sh_register_operand (operands[1], V8QImode))"
9642 "@
9643 add %1, r63, %0
9644 movi %1, %0
9645 #
9646 ld%M1.q %m1, %0
9647 st%M0.q %m0, %N1"
9648 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9649 (set_attr "length" "4,4,16,4,4")])
9650
9651 (define_split
9652 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9653 (subreg:V8QI (const_int 0) 0))]
9654 "TARGET_SHMEDIA"
9655 [(set (match_dup 0)
9656 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9657 (const_int 0) (const_int 0) (const_int 0)
9658 (const_int 0) (const_int 0)]))])
9659
9660 (define_split
9661 [(set (match_operand 0 "arith_reg_dest" "")
9662 (match_operand 1 "sh_rep_vec" ""))]
9663 "TARGET_SHMEDIA && reload_completed
9664 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9665 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9666 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9667 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9668 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9669 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9670 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9671 [(set (match_dup 0) (match_dup 1))
9672 (match_dup 2)]
9673 "
9674 {
9675 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9676 rtx elt1 = XVECEXP (operands[1], 0, 1);
9677
9678 if (unit_size > 2)
9679 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9680 else
9681 {
9682 if (unit_size < 2)
9683 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9684 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9685 }
9686 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9687 operands[1] = XVECEXP (operands[1], 0, 0);
9688 if (unit_size < 2)
9689 {
9690 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9691 operands[1]
9692 = GEN_INT (TARGET_LITTLE_ENDIAN
9693 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9694 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9695 else
9696 {
9697 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9698 operands[1]
9699 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9700 }
9701 }
9702 }")
9703
9704 (define_split
9705 [(set (match_operand 0 "arith_reg_dest" "")
9706 (match_operand 1 "sh_const_vec" ""))]
9707 "TARGET_SHMEDIA && reload_completed
9708 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9709 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9710 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9711 [(set (match_dup 0) (match_dup 1))]
9712 "
9713 {
9714 rtx v = operands[1];
9715 enum machine_mode new_mode
9716 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9717
9718 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9719 operands[1]
9720 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9721 }")
9722
9723 (define_expand "movv2hi"
9724 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9725 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9726 "TARGET_SHMEDIA"
9727 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9728
9729 (define_insn "movv2hi_i"
9730 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9731 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9732 "TARGET_SHMEDIA
9733 && (register_operand (operands[0], V2HImode)
9734 || sh_register_operand (operands[1], V2HImode))"
9735 "@
9736 addz.l %1, r63, %0
9737 movi %1, %0
9738 #
9739 ld%M1.l %m1, %0
9740 st%M0.l %m0, %N1"
9741 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9742 (set_attr "length" "4,4,16,4,4")])
9743
9744 (define_expand "movv4hi"
9745 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9746 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9747 "TARGET_SHMEDIA"
9748 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9749
9750 (define_insn "movv4hi_i"
9751 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9752 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9753 "TARGET_SHMEDIA
9754 && (register_operand (operands[0], V4HImode)
9755 || sh_register_operand (operands[1], V4HImode))"
9756 "@
9757 add %1, r63, %0
9758 movi %1, %0
9759 #
9760 ld%M1.q %m1, %0
9761 st%M0.q %m0, %N1"
9762 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9763 (set_attr "length" "4,4,16,4,4")])
9764
9765 (define_expand "movv2si"
9766 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9767 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9768 "TARGET_SHMEDIA"
9769 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9770
9771 (define_insn "movv2si_i"
9772 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9773 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9774 "TARGET_SHMEDIA
9775 && (register_operand (operands[0], V2SImode)
9776 || sh_register_operand (operands[1], V2SImode))"
9777 "@
9778 add %1, r63, %0
9779 #
9780 #
9781 ld%M1.q %m1, %0
9782 st%M0.q %m0, %N1"
9783 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9784 (set_attr "length" "4,4,16,4,4")])
9785
9786 ;; Multimedia Intrinsics
9787
9788 (define_insn "absv2si2"
9789 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9790 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9791 "TARGET_SHMEDIA"
9792 "mabs.l %1, %0"
9793 [(set_attr "type" "mcmp_media")])
9794
9795 (define_insn "absv4hi2"
9796 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9797 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9798 "TARGET_SHMEDIA"
9799 "mabs.w %1, %0"
9800 [(set_attr "type" "mcmp_media")])
9801
9802 (define_insn "addv2si3"
9803 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9804 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9805 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9806 "TARGET_SHMEDIA"
9807 "madd.l %1, %2, %0"
9808 [(set_attr "type" "arith_media")])
9809
9810 (define_insn "addv4hi3"
9811 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9812 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9813 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9814 "TARGET_SHMEDIA"
9815 "madd.w %1, %2, %0"
9816 [(set_attr "type" "arith_media")])
9817
9818 (define_insn "ssaddv2si3"
9819 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9820 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9821 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9822 "TARGET_SHMEDIA"
9823 "madds.l %1, %2, %0"
9824 [(set_attr "type" "mcmp_media")])
9825
9826 (define_insn "usaddv8qi3"
9827 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9828 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9829 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9830 "TARGET_SHMEDIA"
9831 "madds.ub %1, %2, %0"
9832 [(set_attr "type" "mcmp_media")])
9833
9834 (define_insn "ssaddv4hi3"
9835 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9836 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9837 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9838 "TARGET_SHMEDIA"
9839 "madds.w %1, %2, %0"
9840 [(set_attr "type" "mcmp_media")])
9841
9842 (define_insn "negcmpeqv8qi"
9843 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9844 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9845 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9846 "TARGET_SHMEDIA"
9847 "mcmpeq.b %N1, %N2, %0"
9848 [(set_attr "type" "mcmp_media")])
9849
9850 (define_insn "negcmpeqv2si"
9851 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9852 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9853 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9854 "TARGET_SHMEDIA"
9855 "mcmpeq.l %N1, %N2, %0"
9856 [(set_attr "type" "mcmp_media")])
9857
9858 (define_insn "negcmpeqv4hi"
9859 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9860 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9861 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9862 "TARGET_SHMEDIA"
9863 "mcmpeq.w %N1, %N2, %0"
9864 [(set_attr "type" "mcmp_media")])
9865
9866 (define_insn "negcmpgtuv8qi"
9867 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9868 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9869 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9870 "TARGET_SHMEDIA"
9871 "mcmpgt.ub %N1, %N2, %0"
9872 [(set_attr "type" "mcmp_media")])
9873
9874 (define_insn "negcmpgtv2si"
9875 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9876 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9877 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9878 "TARGET_SHMEDIA"
9879 "mcmpgt.l %N1, %N2, %0"
9880 [(set_attr "type" "mcmp_media")])
9881
9882 (define_insn "negcmpgtv4hi"
9883 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9884 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9885 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9886 "TARGET_SHMEDIA"
9887 "mcmpgt.w %N1, %N2, %0"
9888 [(set_attr "type" "mcmp_media")])
9889
9890 (define_insn "mcmv"
9891 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9892 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9893 (match_operand:DI 2 "arith_reg_operand" "r"))
9894 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9895 (not:DI (match_dup 2)))))]
9896 "TARGET_SHMEDIA"
9897 "mcmv %N1, %2, %0"
9898 [(set_attr "type" "arith_media")])
9899
9900 (define_insn "mcnvs_lw"
9901 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9902 (vec_concat:V4HI
9903 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9904 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9905 "TARGET_SHMEDIA"
9906 "mcnvs.lw %N1, %N2, %0"
9907 [(set_attr "type" "mcmp_media")])
9908
9909 (define_insn "mcnvs_wb"
9910 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9911 (vec_concat:V8QI
9912 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9913 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9914 "TARGET_SHMEDIA"
9915 "mcnvs.wb %N1, %N2, %0"
9916 [(set_attr "type" "mcmp_media")])
9917
9918 (define_insn "mcnvs_wub"
9919 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9920 (vec_concat:V8QI
9921 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9922 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9923 "TARGET_SHMEDIA"
9924 "mcnvs.wub %N1, %N2, %0"
9925 [(set_attr "type" "mcmp_media")])
9926
9927 (define_insn "mextr_rl"
9928 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9929 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9930 (match_operand:HI 3 "mextr_bit_offset" "i"))
9931 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9932 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9933 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9934 "*
9935 {
9936 static char templ[16];
9937
9938 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9939 (int) INTVAL (operands[3]) >> 3);
9940 return templ;
9941 }"
9942 [(set_attr "type" "arith_media")])
9943
9944 (define_insn "*mextr_lr"
9945 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9946 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9947 (match_operand:HI 3 "mextr_bit_offset" "i"))
9948 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9949 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9950 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9951 "*
9952 {
9953 static char templ[16];
9954
9955 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9956 (int) INTVAL (operands[4]) >> 3);
9957 return templ;
9958 }"
9959 [(set_attr "type" "arith_media")])
9960
9961 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9962 ; vector then varies depending on endianness.
9963 (define_expand "mextr1"
9964 [(match_operand:DI 0 "arith_reg_dest" "")
9965 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9966 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9967 "TARGET_SHMEDIA"
9968 "
9969 {
9970 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9971 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9972 DONE;
9973 }")
9974
9975 (define_expand "mextr2"
9976 [(match_operand:DI 0 "arith_reg_dest" "")
9977 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9978 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9979 "TARGET_SHMEDIA"
9980 "
9981 {
9982 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9983 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9984 DONE;
9985 }")
9986
9987 (define_expand "mextr3"
9988 [(match_operand:DI 0 "arith_reg_dest" "")
9989 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9990 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9991 "TARGET_SHMEDIA"
9992 "
9993 {
9994 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9995 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9996 DONE;
9997 }")
9998
9999 (define_expand "mextr4"
10000 [(match_operand:DI 0 "arith_reg_dest" "")
10001 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10002 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10003 "TARGET_SHMEDIA"
10004 "
10005 {
10006 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10007 GEN_INT (4 * 8), GEN_INT (4 * 8)));
10008 DONE;
10009 }")
10010
10011 (define_expand "mextr5"
10012 [(match_operand:DI 0 "arith_reg_dest" "")
10013 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10014 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10015 "TARGET_SHMEDIA"
10016 "
10017 {
10018 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10019 GEN_INT (5 * 8), GEN_INT (3 * 8)));
10020 DONE;
10021 }")
10022
10023 (define_expand "mextr6"
10024 [(match_operand:DI 0 "arith_reg_dest" "")
10025 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10026 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10027 "TARGET_SHMEDIA"
10028 "
10029 {
10030 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10031 GEN_INT (6 * 8), GEN_INT (2 * 8)));
10032 DONE;
10033 }")
10034
10035 (define_expand "mextr7"
10036 [(match_operand:DI 0 "arith_reg_dest" "")
10037 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10038 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10039 "TARGET_SHMEDIA"
10040 "
10041 {
10042 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10043 GEN_INT (7 * 8), GEN_INT (1 * 8)));
10044 DONE;
10045 }")
10046
10047 (define_expand "mmacfx_wl"
10048 [(match_operand:V2SI 0 "arith_reg_dest" "")
10049 (match_operand:V2HI 1 "extend_reg_operand" "")
10050 (match_operand:V2HI 2 "extend_reg_operand" "")
10051 (match_operand:V2SI 3 "arith_reg_operand" "")]
10052 "TARGET_SHMEDIA"
10053 "
10054 {
10055 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10056 operands[1], operands[2]));
10057 DONE;
10058 }")
10059
10060 (define_insn "mmacfx_wl_i"
10061 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10062 (ss_plus:V2SI
10063 (match_operand:V2SI 1 "arith_reg_operand" "0")
10064 (ss_truncate:V2SI
10065 (ashift:V2DI
10066 (sign_extend:V2DI
10067 (mult:V2SI
10068 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10069 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10070 (const_int 1)))))]
10071 "TARGET_SHMEDIA"
10072 "mmacfx.wl %2, %3, %0"
10073 [(set_attr "type" "mac_media")])
10074
10075 (define_expand "mmacnfx_wl"
10076 [(match_operand:V2SI 0 "arith_reg_dest" "")
10077 (match_operand:V2HI 1 "extend_reg_operand" "")
10078 (match_operand:V2HI 2 "extend_reg_operand" "")
10079 (match_operand:V2SI 3 "arith_reg_operand" "")]
10080 "TARGET_SHMEDIA"
10081 "
10082 {
10083 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10084 operands[1], operands[2]));
10085 DONE;
10086 }")
10087
10088 (define_insn "mmacnfx_wl_i"
10089 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10090 (ss_minus:V2SI
10091 (match_operand:V2SI 1 "arith_reg_operand" "0")
10092 (ss_truncate:V2SI
10093 (ashift:V2DI
10094 (sign_extend:V2DI
10095 (mult:V2SI
10096 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10097 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10098 (const_int 1)))))]
10099 "TARGET_SHMEDIA"
10100 "mmacnfx.wl %2, %3, %0"
10101 [(set_attr "type" "mac_media")])
10102
10103 (define_insn "mulv2si3"
10104 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10105 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10106 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10107 "TARGET_SHMEDIA"
10108 "mmul.l %1, %2, %0"
10109 [(set_attr "type" "d2mpy_media")])
10110
10111 (define_insn "mulv4hi3"
10112 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10113 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10114 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10115 "TARGET_SHMEDIA"
10116 "mmul.w %1, %2, %0"
10117 [(set_attr "type" "dmpy_media")])
10118
10119 (define_insn "mmulfx_l"
10120 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10121 (ss_truncate:V2SI
10122 (ashiftrt:V2DI
10123 (mult:V2DI
10124 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10125 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10126 (const_int 31))))]
10127 "TARGET_SHMEDIA"
10128 "mmulfx.l %1, %2, %0"
10129 [(set_attr "type" "d2mpy_media")])
10130
10131 (define_insn "mmulfx_w"
10132 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10133 (ss_truncate:V4HI
10134 (ashiftrt:V4SI
10135 (mult:V4SI
10136 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10137 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10138 (const_int 15))))]
10139 "TARGET_SHMEDIA"
10140 "mmulfx.w %1, %2, %0"
10141 [(set_attr "type" "dmpy_media")])
10142
10143 (define_insn "mmulfxrp_w"
10144 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10145 (ss_truncate:V4HI
10146 (ashiftrt:V4SI
10147 (plus:V4SI
10148 (mult:V4SI
10149 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10150 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10151 (const_int 16384))
10152 (const_int 15))))]
10153 "TARGET_SHMEDIA"
10154 "mmulfxrp.w %1, %2, %0"
10155 [(set_attr "type" "dmpy_media")])
10156
10157 (define_expand "mmulhi_wl"
10158 [(match_operand:V2SI 0 "arith_reg_dest" "")
10159 (match_operand:V4HI 1 "arith_reg_operand" "")
10160 (match_operand:V4HI 2 "arith_reg_operand" "")]
10161 "TARGET_SHMEDIA"
10162 "
10163 {
10164 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10165 (operands[0], operands[1], operands[2]));
10166 DONE;
10167 }")
10168
10169 (define_expand "mmullo_wl"
10170 [(match_operand:V2SI 0 "arith_reg_dest" "")
10171 (match_operand:V4HI 1 "arith_reg_operand" "")
10172 (match_operand:V4HI 2 "arith_reg_operand" "")]
10173 "TARGET_SHMEDIA"
10174 "
10175 {
10176 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10177 (operands[0], operands[1], operands[2]));
10178 DONE;
10179 }")
10180
10181 (define_insn "mmul23_wl"
10182 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10183 (vec_select:V2SI
10184 (mult:V4SI
10185 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10186 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10187 (parallel [(const_int 2) (const_int 3)])))]
10188 "TARGET_SHMEDIA"
10189 "* return (TARGET_LITTLE_ENDIAN
10190 ? \"mmulhi.wl %1, %2, %0\"
10191 : \"mmullo.wl %1, %2, %0\");"
10192 [(set_attr "type" "dmpy_media")])
10193
10194 (define_insn "mmul01_wl"
10195 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10196 (vec_select:V2SI
10197 (mult:V4SI
10198 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10199 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10200 (parallel [(const_int 0) (const_int 1)])))]
10201 "TARGET_SHMEDIA"
10202 "* return (TARGET_LITTLE_ENDIAN
10203 ? \"mmullo.wl %1, %2, %0\"
10204 : \"mmulhi.wl %1, %2, %0\");"
10205 [(set_attr "type" "dmpy_media")])
10206
10207 (define_expand "mmulsum_wq"
10208 [(match_operand:DI 0 "arith_reg_dest" "")
10209 (match_operand:V4HI 1 "arith_reg_operand" "")
10210 (match_operand:V4HI 2 "arith_reg_operand" "")
10211 (match_operand:DI 3 "arith_reg_operand" "")]
10212 "TARGET_SHMEDIA"
10213 "
10214 {
10215 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10216 operands[1], operands[2]));
10217 DONE;
10218 }")
10219
10220 (define_insn "mmulsum_wq_i"
10221 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10222 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10223 (plus:DI
10224 (plus:DI
10225 (vec_select:DI
10226 (mult:V4DI
10227 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10228 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10229 (parallel [(const_int 0)]))
10230 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10231 (sign_extend:V4DI (match_dup 3)))
10232 (parallel [(const_int 1)])))
10233 (plus:DI
10234 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10235 (sign_extend:V4DI (match_dup 3)))
10236 (parallel [(const_int 2)]))
10237 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10238 (sign_extend:V4DI (match_dup 3)))
10239 (parallel [(const_int 3)]))))))]
10240 "TARGET_SHMEDIA"
10241 "mmulsum.wq %2, %3, %0"
10242 [(set_attr "type" "mac_media")])
10243
10244 (define_expand "mperm_w"
10245 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10246 (match_operand:V4HI 1 "arith_reg_operand" "r")
10247 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10248 "TARGET_SHMEDIA"
10249 "
10250 {
10251 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10252 (operands[0], operands[1], operands[2]));
10253 DONE;
10254 }")
10255
10256 ; This use of vec_select isn't exactly correct according to rtl.texi
10257 ; (because not constant), but it seems a straightforward extension.
10258 (define_insn "mperm_w_little"
10259 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10260 (vec_select:V4HI
10261 (match_operand:V4HI 1 "arith_reg_operand" "r")
10262 (parallel
10263 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10264 (const_int 2) (const_int 0))
10265 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10266 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10267 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10268 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10269 "mperm.w %1, %N2, %0"
10270 [(set_attr "type" "arith_media")])
10271
10272 (define_insn "mperm_w_big"
10273 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10274 (vec_select:V4HI
10275 (match_operand:V4HI 1 "arith_reg_operand" "r")
10276 (parallel
10277 [(zero_extract:QI (not:QI (match_operand:QI 2
10278 "extend_reg_or_0_operand" "rZ"))
10279 (const_int 2) (const_int 0))
10280 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10281 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10282 (zero_extract:QI (not:QI (match_dup 2))
10283 (const_int 2) (const_int 6))])))]
10284 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10285 "mperm.w %1, %N2, %0"
10286 [(set_attr "type" "arith_media")])
10287
10288 (define_insn "mperm_w0"
10289 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10290 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10291 "trunc_hi_operand" "r"))))]
10292 "TARGET_SHMEDIA"
10293 "mperm.w %1, r63, %0"
10294 [(set_attr "type" "arith_media")])
10295
10296 (define_expand "msad_ubq"
10297 [(match_operand:DI 0 "arith_reg_dest" "")
10298 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10299 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10300 (match_operand:DI 3 "arith_reg_operand" "")]
10301 "TARGET_SHMEDIA"
10302 "
10303 {
10304 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10305 operands[1], operands[2]));
10306 DONE;
10307 }")
10308
10309 (define_insn "msad_ubq_i"
10310 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10311 (plus:DI
10312 (plus:DI
10313 (plus:DI
10314 (plus:DI
10315 (match_operand:DI 1 "arith_reg_operand" "0")
10316 (abs:DI (vec_select:DI
10317 (minus:V8DI
10318 (zero_extend:V8DI
10319 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10320 (zero_extend:V8DI
10321 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10322 (parallel [(const_int 0)]))))
10323 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10324 (zero_extend:V8DI (match_dup 3)))
10325 (parallel [(const_int 1)]))))
10326 (plus:DI
10327 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10328 (zero_extend:V8DI (match_dup 3)))
10329 (parallel [(const_int 2)])))
10330 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10331 (zero_extend:V8DI (match_dup 3)))
10332 (parallel [(const_int 3)])))))
10333 (plus:DI
10334 (plus:DI
10335 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10336 (zero_extend:V8DI (match_dup 3)))
10337 (parallel [(const_int 4)])))
10338 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10339 (zero_extend:V8DI (match_dup 3)))
10340 (parallel [(const_int 5)]))))
10341 (plus:DI
10342 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10343 (zero_extend:V8DI (match_dup 3)))
10344 (parallel [(const_int 6)])))
10345 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10346 (zero_extend:V8DI (match_dup 3)))
10347 (parallel [(const_int 7)])))))))]
10348 "TARGET_SHMEDIA"
10349 "msad.ubq %N2, %N3, %0"
10350 [(set_attr "type" "mac_media")])
10351
10352 (define_insn "mshalds_l"
10353 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10354 (ss_truncate:V2SI
10355 (ashift:V2DI
10356 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10357 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10358 (const_int 31)))))]
10359 "TARGET_SHMEDIA"
10360 "mshalds.l %1, %2, %0"
10361 [(set_attr "type" "mcmp_media")])
10362
10363 (define_insn "mshalds_w"
10364 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10365 (ss_truncate:V4HI
10366 (ashift:V4SI
10367 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10368 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10369 (const_int 15)))))]
10370 "TARGET_SHMEDIA"
10371 "mshalds.w %1, %2, %0"
10372 [(set_attr "type" "mcmp_media")])
10373
10374 (define_insn "ashrv2si3"
10375 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10376 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10377 (match_operand:DI 2 "arith_reg_operand" "r")))]
10378 "TARGET_SHMEDIA"
10379 "mshard.l %1, %2, %0"
10380 [(set_attr "type" "arith_media")])
10381
10382 (define_insn "ashrv4hi3"
10383 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10384 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10385 (match_operand:DI 2 "arith_reg_operand" "r")))]
10386 "TARGET_SHMEDIA"
10387 "mshard.w %1, %2, %0"
10388 [(set_attr "type" "arith_media")])
10389
10390 (define_insn "mshards_q"
10391 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10392 (ss_truncate:HI
10393 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10394 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10395 "TARGET_SHMEDIA"
10396 "mshards.q %1, %N2, %0"
10397 [(set_attr "type" "mcmp_media")])
10398
10399 (define_expand "mshfhi_b"
10400 [(match_operand:V8QI 0 "arith_reg_dest" "")
10401 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10402 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10403 "TARGET_SHMEDIA"
10404 "
10405 {
10406 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10407 (operands[0], operands[1], operands[2]));
10408 DONE;
10409 }")
10410
10411 (define_expand "mshflo_b"
10412 [(match_operand:V8QI 0 "arith_reg_dest" "")
10413 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10414 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10415 "TARGET_SHMEDIA"
10416 "
10417 {
10418 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10419 (operands[0], operands[1], operands[2]));
10420 DONE;
10421 }")
10422
10423 (define_insn "mshf4_b"
10424 [(set
10425 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10426 (vec_select:V8QI
10427 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10428 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10429 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10430 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10431 "TARGET_SHMEDIA"
10432 "* return (TARGET_LITTLE_ENDIAN
10433 ? \"mshfhi.b %N1, %N2, %0\"
10434 : \"mshflo.b %N1, %N2, %0\");"
10435 [(set_attr "type" "arith_media")])
10436
10437 (define_insn "mshf0_b"
10438 [(set
10439 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10440 (vec_select:V8QI
10441 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10442 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10443 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10444 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10445 "TARGET_SHMEDIA"
10446 "* return (TARGET_LITTLE_ENDIAN
10447 ? \"mshflo.b %N1, %N2, %0\"
10448 : \"mshfhi.b %N1, %N2, %0\");"
10449 [(set_attr "type" "arith_media")])
10450
10451 (define_expand "mshfhi_l"
10452 [(match_operand:V2SI 0 "arith_reg_dest" "")
10453 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10454 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10455 "TARGET_SHMEDIA"
10456 "
10457 {
10458 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10459 (operands[0], operands[1], operands[2]));
10460 DONE;
10461 }")
10462
10463 (define_expand "mshflo_l"
10464 [(match_operand:V2SI 0 "arith_reg_dest" "")
10465 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10466 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10467 "TARGET_SHMEDIA"
10468 "
10469 {
10470 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10471 (operands[0], operands[1], operands[2]));
10472 DONE;
10473 }")
10474
10475 (define_insn "mshf4_l"
10476 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10477 (vec_select:V2SI
10478 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10479 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10480 (parallel [(const_int 1) (const_int 3)])))]
10481 "TARGET_SHMEDIA"
10482 "* return (TARGET_LITTLE_ENDIAN
10483 ? \"mshfhi.l %N1, %N2, %0\"
10484 : \"mshflo.l %N1, %N2, %0\");"
10485 [(set_attr "type" "arith_media")])
10486
10487 (define_insn "mshf0_l"
10488 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10489 (vec_select:V2SI
10490 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10491 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10492 (parallel [(const_int 0) (const_int 2)])))]
10493 "TARGET_SHMEDIA"
10494 "* return (TARGET_LITTLE_ENDIAN
10495 ? \"mshflo.l %N1, %N2, %0\"
10496 : \"mshfhi.l %N1, %N2, %0\");"
10497 [(set_attr "type" "arith_media")])
10498
10499 (define_expand "mshfhi_w"
10500 [(match_operand:V4HI 0 "arith_reg_dest" "")
10501 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10502 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10503 "TARGET_SHMEDIA"
10504 "
10505 {
10506 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10507 (operands[0], operands[1], operands[2]));
10508 DONE;
10509 }")
10510
10511 (define_expand "mshflo_w"
10512 [(match_operand:V4HI 0 "arith_reg_dest" "")
10513 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10514 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10515 "TARGET_SHMEDIA"
10516 "
10517 {
10518 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10519 (operands[0], operands[1], operands[2]));
10520 DONE;
10521 }")
10522
10523 (define_insn "mshf4_w"
10524 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10525 (vec_select:V4HI
10526 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10527 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10528 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10529 "TARGET_SHMEDIA"
10530 "* return (TARGET_LITTLE_ENDIAN
10531 ? \"mshfhi.w %N1, %N2, %0\"
10532 : \"mshflo.w %N1, %N2, %0\");"
10533 [(set_attr "type" "arith_media")])
10534
10535 (define_insn "mshf0_w"
10536 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10537 (vec_select:V4HI
10538 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10539 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10540 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10541 "TARGET_SHMEDIA"
10542 "* return (TARGET_LITTLE_ENDIAN
10543 ? \"mshflo.w %N1, %N2, %0\"
10544 : \"mshfhi.w %N1, %N2, %0\");"
10545 [(set_attr "type" "arith_media")])
10546
10547 (define_insn "mshflo_w_x"
10548 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10549 (vec_select:V4HI
10550 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10551 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10552 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10553 "TARGET_SHMEDIA"
10554 "mshflo.w %N1, %N2, %0"
10555 [(set_attr "type" "arith_media")])
10556
10557 /* These are useful to expand ANDs and as combiner patterns. */
10558 (define_insn_and_split "mshfhi_l_di"
10559 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10560 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10561 (const_int 32))
10562 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10563 (const_int -4294967296))))]
10564 "TARGET_SHMEDIA"
10565 "@
10566 mshfhi.l %N1, %N2, %0
10567 #"
10568 "TARGET_SHMEDIA && reload_completed
10569 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10570 [(set (match_dup 3) (match_dup 4))
10571 (set (match_dup 5) (match_dup 6))]
10572 "
10573 {
10574 operands[3] = gen_lowpart (SImode, operands[0]);
10575 operands[4] = gen_highpart (SImode, operands[1]);
10576 operands[5] = gen_highpart (SImode, operands[0]);
10577 operands[6] = gen_highpart (SImode, operands[2]);
10578 }"
10579 [(set_attr "type" "arith_media")])
10580
10581 (define_insn "*mshfhi_l_di_rev"
10582 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10583 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10584 (const_int -4294967296))
10585 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10586 (const_int 32))))]
10587 "TARGET_SHMEDIA"
10588 "mshfhi.l %N2, %N1, %0"
10589 [(set_attr "type" "arith_media")])
10590
10591 (define_split
10592 [(set (match_operand:DI 0 "arith_reg_dest" "")
10593 (ior:DI (zero_extend:DI (match_operand:SI 1
10594 "extend_reg_or_0_operand" ""))
10595 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10596 (const_int -4294967296))))
10597 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10598 "TARGET_SHMEDIA"
10599 [(const_int 0)]
10600 "
10601 {
10602 emit_insn (gen_ashldi3_media (operands[3],
10603 simplify_gen_subreg (DImode, operands[1],
10604 SImode, 0),
10605 GEN_INT (32)));
10606 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10607 DONE;
10608 }")
10609
10610 (define_insn "mshflo_l_di"
10611 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10612 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10613 (const_int 4294967295))
10614 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10615 (const_int 32))))]
10616
10617 "TARGET_SHMEDIA"
10618 "mshflo.l %N1, %N2, %0"
10619 [(set_attr "type" "arith_media")])
10620
10621 (define_insn "*mshflo_l_di_rev"
10622 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10623 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10624 (const_int 32))
10625 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10626 (const_int 4294967295))))]
10627
10628 "TARGET_SHMEDIA"
10629 "mshflo.l %N2, %N1, %0"
10630 [(set_attr "type" "arith_media")])
10631
10632 ;; Combiner pattern for trampoline initialization.
10633 (define_insn_and_split "*double_shori"
10634 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10635 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10636 (const_int 32))
10637 (match_operand:DI 2 "const_int_operand" "n")))]
10638 "TARGET_SHMEDIA
10639 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10640 "#"
10641 "rtx_equal_p (operands[0], operands[1])"
10642 [(const_int 0)]
10643 "
10644 {
10645 HOST_WIDE_INT v = INTVAL (operands[2]);
10646
10647 emit_insn (gen_shori_media (operands[0], operands[0],
10648 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10649 emit_insn (gen_shori_media (operands[0], operands[0],
10650 gen_int_mode (v, HImode)));
10651 DONE;
10652 }")
10653
10654
10655 (define_insn "*mshflo_l_di_x"
10656 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10657 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10658 "rZ"))
10659 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10660 (const_int 32))))]
10661
10662 "TARGET_SHMEDIA"
10663 "mshflo.l %N1, %N2, %0"
10664 [(set_attr "type" "arith_media")])
10665
10666 (define_insn_and_split "concat_v2sf"
10667 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10668 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10669 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10670 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10671
10672 "TARGET_SHMEDIA"
10673 "@
10674 mshflo.l %N1, %N2, %0
10675 #
10676 #"
10677 "TARGET_SHMEDIA && reload_completed
10678 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10679 [(set (match_dup 3) (match_dup 1))
10680 (set (match_dup 4) (match_dup 2))]
10681 "
10682 {
10683 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10684 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10685 }"
10686 [(set_attr "type" "arith_media")])
10687
10688 (define_insn "*mshflo_l_di_x_rev"
10689 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10690 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10691 (const_int 32))
10692 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10693
10694 "TARGET_SHMEDIA"
10695 "mshflo.l %N2, %N1, %0"
10696 [(set_attr "type" "arith_media")])
10697
10698 (define_insn "ashlv2si3"
10699 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10700 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10701 (match_operand:DI 2 "arith_reg_operand" "r")))]
10702 "TARGET_SHMEDIA"
10703 "mshlld.l %1, %2, %0"
10704 [(set_attr "type" "arith_media")])
10705
10706 (define_insn "ashlv4hi3"
10707 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10708 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10709 (match_operand:DI 2 "arith_reg_operand" "r")))]
10710 "TARGET_SHMEDIA"
10711 "mshlld.w %1, %2, %0"
10712 [(set_attr "type" "arith_media")])
10713
10714 (define_insn "lshrv2si3"
10715 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10716 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10717 (match_operand:DI 2 "arith_reg_operand" "r")))]
10718 "TARGET_SHMEDIA"
10719 "mshlrd.l %1, %2, %0"
10720 [(set_attr "type" "arith_media")])
10721
10722 (define_insn "lshrv4hi3"
10723 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10724 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10725 (match_operand:DI 2 "arith_reg_operand" "r")))]
10726 "TARGET_SHMEDIA"
10727 "mshlrd.w %1, %2, %0"
10728 [(set_attr "type" "arith_media")])
10729
10730 (define_insn "subv2si3"
10731 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10732 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10733 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10734 "TARGET_SHMEDIA"
10735 "msub.l %N1, %2, %0"
10736 [(set_attr "type" "arith_media")])
10737
10738 (define_insn "subv4hi3"
10739 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10740 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10741 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10742 "TARGET_SHMEDIA"
10743 "msub.w %N1, %2, %0"
10744 [(set_attr "type" "arith_media")])
10745
10746 (define_insn "sssubv2si3"
10747 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10748 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10749 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10750 "TARGET_SHMEDIA"
10751 "msubs.l %N1, %2, %0"
10752 [(set_attr "type" "mcmp_media")])
10753
10754 (define_insn "ussubv8qi3"
10755 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10756 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10757 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10758 "TARGET_SHMEDIA"
10759 "msubs.ub %1, %2, %0"
10760 [(set_attr "type" "mcmp_media")])
10761
10762 (define_insn "sssubv4hi3"
10763 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10764 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10765 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10766 "TARGET_SHMEDIA"
10767 "msubs.w %N1, %2, %0"
10768 [(set_attr "type" "mcmp_media")])
10769
10770 ;; Floating Point Intrinsics
10771
10772 (define_insn "fcosa_s"
10773 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10774 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10775 UNSPEC_FCOSA))]
10776 "TARGET_SHMEDIA"
10777 "fcosa.s %1, %0"
10778 [(set_attr "type" "atrans_media")])
10779
10780 (define_insn "fsina_s"
10781 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10782 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10783 UNSPEC_FSINA))]
10784 "TARGET_SHMEDIA"
10785 "fsina.s %1, %0"
10786 [(set_attr "type" "atrans_media")])
10787
10788 (define_insn "fipr"
10789 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10790 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10791 "fp_arith_reg_operand" "f")
10792 (match_operand:V4SF 2
10793 "fp_arith_reg_operand" "f"))
10794 (parallel [(const_int 0)]))
10795 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10796 (parallel [(const_int 1)])))
10797 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10798 (parallel [(const_int 2)]))
10799 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10800 (parallel [(const_int 3)])))))]
10801 "TARGET_SHMEDIA"
10802 "fipr.s %1, %2, %0"
10803 [(set_attr "type" "fparith_media")])
10804
10805 (define_insn "fsrra_s"
10806 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10807 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10808 UNSPEC_FSRRA))]
10809 "TARGET_SHMEDIA"
10810 "fsrra.s %1, %0"
10811 [(set_attr "type" "atrans_media")])
10812
10813 (define_insn "ftrv"
10814 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10815 (plus:V4SF
10816 (plus:V4SF
10817 (mult:V4SF
10818 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10819 (parallel [(const_int 0) (const_int 5)
10820 (const_int 10) (const_int 15)]))
10821 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10822 (mult:V4SF
10823 (vec_select:V4SF (match_dup 1)
10824 (parallel [(const_int 4) (const_int 9)
10825 (const_int 14) (const_int 3)]))
10826 (vec_select:V4SF (match_dup 2)
10827 (parallel [(const_int 1) (const_int 2)
10828 (const_int 3) (const_int 0)]))))
10829 (plus:V4SF
10830 (mult:V4SF
10831 (vec_select:V4SF (match_dup 1)
10832 (parallel [(const_int 8) (const_int 13)
10833 (const_int 2) (const_int 7)]))
10834 (vec_select:V4SF (match_dup 2)
10835 (parallel [(const_int 2) (const_int 3)
10836 (const_int 0) (const_int 1)])))
10837 (mult:V4SF
10838 (vec_select:V4SF (match_dup 1)
10839 (parallel [(const_int 12) (const_int 1)
10840 (const_int 6) (const_int 11)]))
10841 (vec_select:V4SF (match_dup 2)
10842 (parallel [(const_int 3) (const_int 0)
10843 (const_int 1) (const_int 2)]))))))]
10844 "TARGET_SHMEDIA"
10845 "ftrv.s %1, %2, %0"
10846 [(set_attr "type" "fparith_media")])
10847
10848 (define_insn "nsb"
10849 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10850 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10851 UNSPEC_NSB))]
10852 "TARGET_SHMEDIA"
10853 "nsb %1, %0"
10854 [(set_attr "type" "arith_media")])
10855
10856 (define_insn "nsbsi"
10857 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10858 (zero_extend:SI
10859 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10860 UNSPEC_NSB)))]
10861 "TARGET_SHMEDIA"
10862 "nsb %1, %0"
10863 [(set_attr "type" "arith_media")])
10864
10865 (define_insn "nsbdi"
10866 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10867 (zero_extend:DI
10868 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10869 UNSPEC_NSB)))]
10870 "TARGET_SHMEDIA"
10871 "nsb %1, %0"
10872 [(set_attr "type" "arith_media")])
10873
10874 (define_expand "ffsdi2"
10875 [(set (match_operand:DI 0 "arith_reg_dest" "")
10876 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10877 "TARGET_SHMEDIA"
10878 "
10879 {
10880 rtx scratch = gen_reg_rtx (DImode);
10881 rtx last;
10882
10883 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10884 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10885 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10886 emit_insn (gen_nsbdi (scratch, scratch));
10887 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10888 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10889 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10890 REG_NOTES (last)
10891 = gen_rtx_EXPR_LIST (REG_EQUAL,
10892 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10893 DONE;
10894 }")
10895
10896 (define_expand "ffssi2"
10897 [(set (match_operand:SI 0 "arith_reg_dest" "")
10898 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10899 "TARGET_SHMEDIA"
10900 "
10901 {
10902 rtx scratch = gen_reg_rtx (SImode);
10903 rtx discratch = gen_reg_rtx (DImode);
10904 rtx last;
10905
10906 emit_insn (gen_adddi3 (discratch,
10907 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10908 constm1_rtx));
10909 emit_insn (gen_andcdi3 (discratch,
10910 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10911 discratch));
10912 emit_insn (gen_nsbsi (scratch, discratch));
10913 last = emit_insn (gen_subsi3 (operands[0],
10914 force_reg (SImode, GEN_INT (63)), scratch));
10915 REG_NOTES (last)
10916 = gen_rtx_EXPR_LIST (REG_EQUAL,
10917 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10918 DONE;
10919 }")
10920
10921 (define_insn "byterev"
10922 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10923 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10924 (parallel [(const_int 7) (const_int 6) (const_int 5)
10925 (const_int 4) (const_int 3) (const_int 2)
10926 (const_int 1) (const_int 0)])))]
10927 "TARGET_SHMEDIA"
10928 "byterev %1, %0"
10929 [(set_attr "type" "arith_media")])
10930
10931 (define_insn "prefetch"
10932 [(prefetch (match_operand:QI 0 "address_operand" "p")
10933 (match_operand:SI 1 "const_int_operand" "n")
10934 (match_operand:SI 2 "const_int_operand" "n"))]
10935 "TARGET_SHMEDIA || TARGET_HARD_SH4"
10936 "*
10937 {
10938 if (TARGET_HARD_SH4)
10939 return \"pref @%0\";
10940 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10941 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10942 return \"\";
10943 }"
10944 [(set_attr "type" "other")])
10945