]> gcc.gnu.org Git - gcc.git/blob - gcc/config/sh/sh.md
sh.md (truncdiqi2): Use andi opcode for immediate.
[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, 2003
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of 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,sh3,sh3e,sh4,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 ;; tls_load load TLS related address
222 ;; arith_media SHmedia arithmetic, logical, and shift instructions
223 ;; cbranch_media SHmedia conditional branch instructions
224 ;; cmp_media SHmedia compare instructions
225 ;; dfdiv_media SHmedia double precision divide and square root
226 ;; dfmul_media SHmedia double precision multiply instruction
227 ;; dfparith_media SHmedia double precision floating point arithmetic
228 ;; dfpconv_media SHmedia double precision floating point conversions
229 ;; dmpy_media SHmedia longword multiply
230 ;; fcmp_media SHmedia floating point compare instructions
231 ;; fdiv_media SHmedia single precision divide and square root
232 ;; fload_media SHmedia floating point register load instructions
233 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
234 ;; fparith_media SHmedia single precision floating point arithmetic
235 ;; fpconv_media SHmedia single precision floating point conversions
236 ;; fstore_media SHmedia floating point register store instructions
237 ;; gettr_media SHmedia gettr instruction
238 ;; invalidate_line_media SHmedia invalidate_line sequence
239 ;; jump_media SHmedia unconditional branch instructions
240 ;; load_media SHmedia general register load instructions
241 ;; pt_media SHmedia pt instruction (expanded by assembler)
242 ;; ptabs_media SHmedia ptabs instruction
243 ;; store_media SHmedia general register store instructions
244 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
245 ;; mac_media SHmedia mac-style fixed point operations
246 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
247 ;; atrans SHmedia approximate transcendental functions
248 ;; ustore_media SHmedia unaligned stores
249 ;; nil no-op move, will be deleted.
250
251 (define_attr "type"
252 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
253 (const_string "other"))
254
255 ;; We define a new attribute namely "insn_class".We use
256 ;; this for the DFA based pipeline description.
257 ;;
258 ;; mt_group SH4 "mt" group instructions.
259 ;;
260 ;; ex_group SH4 "ex" group instructions.
261 ;;
262 ;; ls_group SH4 "ls" group instructions.
263 ;;
264
265 (define_attr "insn_class"
266 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270 (eq_attr "type" "cbranch,jump") (const_string "br_group")
271 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272 (const_string "fe_group")
273 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
274 (const_string "none")))
275 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276 ;; so these do not belong in an insn group, although they are modeled
277 ;; with their own define_insn_reservations.
278
279 ;; Indicate what precision must be selected in fpscr for this insn, if any.
280
281 (define_attr "fp_mode" "single,double,none" (const_string "none"))
282
283 ;; Indicate if the fpu mode is set by this instruction
284 ;; "unknown" must have the value as "none" in fp_mode, and means
285 ;; that the instruction/abi has left the processor in an unknown
286 ;; state.
287 ;; "none" means that nothing has changed and no mode is set.
288 ;; This attribute is only used for the Renesas ABI.
289 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
290
291 ; If a conditional branch destination is within -252..258 bytes away
292 ; from the instruction it can be 2 bytes long. Something in the
293 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
294 ; branches are initially assumed to be 16 bytes long.
295 ; In machine_dependent_reorg, we split all branches that are longer than
296 ; 2 bytes.
297
298 ;; The maximum range used for SImode constant pool entries is 1018. A final
299 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
301 ;; instruction around the pool table, 2 bytes of alignment before the table,
302 ;; and 30 bytes of alignment after the table. That gives a maximum total
303 ;; pool size of 1058 bytes.
304 ;; Worst case code/pool content size ratio is 1:2 (using asms).
305 ;; Thus, in the worst case, there is one instruction in front of a maximum
306 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
308 ;; If we have a forward branch, the initial table will be put after the
309 ;; unconditional branch.
310 ;;
311 ;; ??? We could do much better by keeping track of the actual pcloads within
312 ;; the branch range and in the pcload range in front of the branch range.
313
314 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
315 ;; inside an le.
316 (define_attr "short_cbranch_p" "no,yes"
317 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
318 (const_string "no")
319 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
320 (const_string "yes")
321 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
322 (const_string "no")
323 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
324 (const_string "yes")
325 ] (const_string "no")))
326
327 (define_attr "med_branch_p" "no,yes"
328 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
329 (const_int 1988))
330 (const_string "yes")
331 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
332 (const_string "no")
333 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
334 (const_int 8186))
335 (const_string "yes")
336 ] (const_string "no")))
337
338 (define_attr "med_cbranch_p" "no,yes"
339 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
340 (const_int 1986))
341 (const_string "yes")
342 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343 (const_string "no")
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
345 (const_int 8184))
346 (const_string "yes")
347 ] (const_string "no")))
348
349 (define_attr "braf_branch_p" "no,yes"
350 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
351 (const_string "no")
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
353 (const_int 20660))
354 (const_string "yes")
355 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356 (const_string "no")
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
358 (const_int 65530))
359 (const_string "yes")
360 ] (const_string "no")))
361
362 (define_attr "braf_cbranch_p" "no,yes"
363 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364 (const_string "no")
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
366 (const_int 20658))
367 (const_string "yes")
368 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369 (const_string "no")
370 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
371 (const_int 65528))
372 (const_string "yes")
373 ] (const_string "no")))
374
375 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
376 ; For wider ranges, we need a combination of a code and a data part.
377 ; If we can get a scratch register for a long range jump, the code
378 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
380 ; long; otherwise, it must be 6 bytes long.
381
382 ; All other instructions are two bytes long by default.
383
384 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385 ;; but getattrtab doesn't understand this.
386 (define_attr "length" ""
387 (cond [(eq_attr "type" "cbranch")
388 (cond [(eq_attr "short_cbranch_p" "yes")
389 (const_int 2)
390 (eq_attr "med_cbranch_p" "yes")
391 (const_int 6)
392 (eq_attr "braf_cbranch_p" "yes")
393 (const_int 12)
394 ;; ??? using pc is not computed transitively.
395 (ne (match_dup 0) (match_dup 0))
396 (const_int 14)
397 (ne (symbol_ref ("flag_pic")) (const_int 0))
398 (const_int 24)
399 ] (const_int 16))
400 (eq_attr "type" "jump")
401 (cond [(eq_attr "med_branch_p" "yes")
402 (const_int 2)
403 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
404 (symbol_ref "INSN"))
405 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
406 (symbol_ref "code_for_indirect_jump_scratch")))
407 (if_then_else (eq_attr "braf_branch_p" "yes")
408 (const_int 6)
409 (const_int 10))
410 (eq_attr "braf_branch_p" "yes")
411 (const_int 10)
412 ;; ??? using pc is not computed transitively.
413 (ne (match_dup 0) (match_dup 0))
414 (const_int 12)
415 (ne (symbol_ref ("flag_pic")) (const_int 0))
416 (const_int 22)
417 ] (const_int 14))
418 (eq_attr "type" "pt_media")
419 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420 (const_int 20) (const_int 12))
421 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
422 (const_int 4)
423 (const_int 2))))
424
425 ;; (define_function_unit {name} {num-units} {n-users} {test}
426 ;; {ready-delay} {issue-delay} [{conflict-list}])
427
428 ;; Load and store instructions save a cycle if they are aligned on a
429 ;; four byte boundary. Using a function unit for stores encourages
430 ;; gcc to separate load and store instructions by one instruction,
431 ;; which makes it more likely that the linker will be able to word
432 ;; align them when relaxing.
433
434 ;; Loads have a latency of two.
435 ;; However, call insns can have a delay slot, so that we want one more
436 ;; insn to be scheduled between the load of the function address and the call.
437 ;; This is equivalent to a latency of three.
438 ;; We cannot use a conflict list for this, because we need to distinguish
439 ;; between the actual call address and the function arguments.
440 ;; ADJUST_COST can only properly handle reductions of the cost, so we
441 ;; use a latency of three here.
442 ;; We only do this for SImode loads of general registers, to make the work
443 ;; for ADJUST_COST easier.
444 (define_function_unit "memory" 1 0
445 (and (eq_attr "pipe_model" "sh1")
446 (eq_attr "type" "load_si,pcload_si"))
447 3 2)
448 (define_function_unit "memory" 1 0
449 (and (eq_attr "pipe_model" "sh1")
450 (eq_attr "type" "load,pcload,pload,store,pstore"))
451 2 2)
452
453 (define_function_unit "int" 1 0
454 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
455
456 (define_function_unit "int" 1 0
457 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
458
459 (define_function_unit "int" 1 0
460 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
461
462 ;; ??? These are approximations.
463 (define_function_unit "mpy" 1 0
464 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
465 (define_function_unit "mpy" 1 0
466 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
467
468 (define_function_unit "fp" 1 0
469 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
470 (define_function_unit "fp" 1 0
471 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
472
473
474 ;; SH-5 SHmedia scheduling
475 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
476 ;; single-issue machine. It has four pipelines, the branch unit (br),
477 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
478 ;; the floating point unit (fpu).
479 ;; Here model the instructions with a latency greater than one cycle.
480
481 ;; Every instruction on SH-5 occupies the issue resource for at least one
482 ;; cycle.
483 (define_function_unit "sh5issue" 1 0
484 (and (eq_attr "pipe_model" "sh5media")
485 (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
486
487 ;; Specify the various types of instruction which have latency > 1
488 (define_function_unit "sh5issue" 1 0
489 (and (eq_attr "pipe_model" "sh5media")
490 (eq_attr "type" "mcmp_media")) 2 1)
491
492 (define_function_unit "sh5issue" 1 0
493 (and (eq_attr "pipe_model" "sh5media")
494 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
495 ;; but see sh_adjust_cost for mac_media exception.
496
497 (define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "fload_media,fmove_media")) 4 1)
500
501 (define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "d2mpy_media")) 4 2)
504
505 (define_function_unit "sh5issue" 1 0
506 (and (eq_attr "pipe_model" "sh5media")
507 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
508
509 (define_function_unit "sh5issue" 1 0
510 (and (eq_attr "pipe_model" "sh5media")
511 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
512
513 (define_function_unit "sh5issue" 1 0
514 (and (eq_attr "pipe_model" "sh5media")
515 (eq_attr "type" "invalidate_line_media")) 7 7)
516
517 (define_function_unit "sh5issue" 1 0
518 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
519
520 (define_function_unit "sh5issue" 1 0
521 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
522
523 ;; Floating-point divide and square-root occupy an additional resource,
524 ;; which is not internally pipelined. However, other instructions
525 ;; can continue to issue.
526 (define_function_unit "sh5fds" 1 0
527 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
528
529 (define_function_unit "sh5fds" 1 0
530 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
531
532 ; Definitions for filling branch delay slots.
533
534 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
535
536 ;; ??? This should be (nil) instead of (const_int 0)
537 (define_attr "hit_stack" "yes,no"
538 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
539 (const_int 0))
540 (const_string "no")]
541 (const_string "yes")))
542
543 (define_attr "interrupt_function" "no,yes"
544 (const (symbol_ref "current_function_interrupt")))
545
546 (define_attr "in_delay_slot" "yes,no"
547 (cond [(eq_attr "type" "cbranch") (const_string "no")
548 (eq_attr "type" "pcload,pcload_si") (const_string "no")
549 (eq_attr "needs_delay_slot" "yes") (const_string "no")
550 (eq_attr "length" "2") (const_string "yes")
551 ] (const_string "no")))
552
553 (define_attr "cond_delay_slot" "yes,no"
554 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
555 ] (const_string "no")))
556
557 (define_attr "is_sfunc" ""
558 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
559
560 (define_attr "is_mac_media" ""
561 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
562
563 (define_attr "branch_zero" "yes,no"
564 (cond [(eq_attr "type" "!cbranch") (const_string "no")
565 (ne (symbol_ref "(next_active_insn (insn)\
566 == (prev_active_insn\
567 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
568 && get_attr_length (next_active_insn (insn)) == 2")
569 (const_int 0))
570 (const_string "yes")]
571 (const_string "no")))
572
573 ;; SH4 Double-precision computation with double-precision result -
574 ;; the two halves are ready at different times.
575 (define_attr "dfp_comp" "yes,no"
576 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
577 (const_string "no")))
578
579 ;; Insns for which the latency of a preceding fp insn is decreased by one.
580 (define_attr "late_fp_use" "yes,no" (const_string "no"))
581 ;; And feeding insns for which this relevant.
582 (define_attr "any_fp_comp" "yes,no"
583 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
584 (const_string "yes")]
585 (const_string "no")))
586
587 (define_attr "any_int_load" "yes,no"
588 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
589 (const_string "yes")]
590 (const_string "no")))
591
592 (define_delay
593 (eq_attr "needs_delay_slot" "yes")
594 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
595
596 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
597 ;; and thus we can't put a pop instruction in its delay slot.
598 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
599 ;; instruction can go in the delay slot.
600
601 ;; Since a normal return (rts) implicitly uses the PR register,
602 ;; we can't allow PR register loads in an rts delay slot.
603
604 (define_delay
605 (eq_attr "type" "return")
606 [(and (eq_attr "in_delay_slot" "yes")
607 (ior (and (eq_attr "interrupt_function" "no")
608 (eq_attr "type" "!pload,prset"))
609 (and (eq_attr "interrupt_function" "yes")
610 (ior
611 (ne (symbol_ref "TARGET_SH3") (const_int 0))
612 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
613
614 ;; Since a call implicitly uses the PR register, we can't allow
615 ;; a PR register store in a jsr delay slot.
616
617 (define_delay
618 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
619 [(and (eq_attr "in_delay_slot" "yes")
620 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
621
622 ;; Say that we have annulled true branches, since this gives smaller and
623 ;; faster code when branches are predicted as not taken.
624
625 (define_delay
626 (and (eq_attr "type" "cbranch")
627 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
628 ;; SH2e has a hardware bug that pretty much prohibits the use of
629 ;; annuled delay slots.
630 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
631 (not (eq_attr "cpu" "sh2e"))) (nil)])
632 \f
633 ;; -------------------------------------------------------------------------
634 ;; SImode signed integer comparisons
635 ;; -------------------------------------------------------------------------
636
637 (define_insn ""
638 [(set (reg:SI T_REG)
639 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
640 (match_operand:SI 1 "arith_operand" "K08,r"))
641 (const_int 0)))]
642 "TARGET_SH1"
643 "tst %1,%0"
644 [(set_attr "type" "mt_group")])
645
646 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
647 ;; That would still allow reload to create cmpi instructions, but would
648 ;; perhaps allow forcing the constant into a register when that is better.
649 ;; Probably should use r0 for mem/imm compares, but force constant into a
650 ;; register for pseudo/imm compares.
651
652 (define_insn "cmpeqsi_t"
653 [(set (reg:SI T_REG)
654 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
655 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
656 "TARGET_SH1"
657 "@
658 tst %0,%0
659 cmp/eq %1,%0
660 cmp/eq %1,%0"
661 [(set_attr "type" "mt_group")])
662
663 (define_insn "cmpgtsi_t"
664 [(set (reg:SI T_REG)
665 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
666 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
667 "TARGET_SH1"
668 "@
669 cmp/gt %1,%0
670 cmp/pl %0"
671 [(set_attr "type" "mt_group")])
672
673 (define_insn "cmpgesi_t"
674 [(set (reg:SI T_REG)
675 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
676 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
677 "TARGET_SH1"
678 "@
679 cmp/ge %1,%0
680 cmp/pz %0"
681 [(set_attr "type" "mt_group")])
682
683 ;; -------------------------------------------------------------------------
684 ;; SImode unsigned integer comparisons
685 ;; -------------------------------------------------------------------------
686
687 (define_insn "cmpgeusi_t"
688 [(set (reg:SI T_REG)
689 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690 (match_operand:SI 1 "arith_reg_operand" "r")))]
691 "TARGET_SH1"
692 "cmp/hs %1,%0"
693 [(set_attr "type" "mt_group")])
694
695 (define_insn "cmpgtusi_t"
696 [(set (reg:SI T_REG)
697 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
698 (match_operand:SI 1 "arith_reg_operand" "r")))]
699 "TARGET_SH1"
700 "cmp/hi %1,%0"
701 [(set_attr "type" "mt_group")])
702
703 ;; We save the compare operands in the cmpxx patterns and use them when
704 ;; we generate the branch.
705
706 (define_expand "cmpsi"
707 [(set (reg:SI T_REG)
708 (compare (match_operand:SI 0 "arith_operand" "")
709 (match_operand:SI 1 "arith_operand" "")))]
710 "TARGET_SH1"
711 "
712 {
713 sh_compare_op0 = operands[0];
714 sh_compare_op1 = operands[1];
715 DONE;
716 }")
717 \f
718 ;; -------------------------------------------------------------------------
719 ;; DImode signed integer comparisons
720 ;; -------------------------------------------------------------------------
721
722 ;; ??? Could get better scheduling by splitting the initial test from the
723 ;; rest of the insn after reload. However, the gain would hardly justify
724 ;; the sh.md size increase necessary to do that.
725
726 (define_insn ""
727 [(set (reg:SI T_REG)
728 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
729 (match_operand:DI 1 "arith_operand" "r"))
730 (const_int 0)))]
731 "TARGET_SH1"
732 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
733 insn, operands);"
734 [(set_attr "length" "6")
735 (set_attr "type" "arith3b")])
736
737 (define_insn "cmpeqdi_t"
738 [(set (reg:SI T_REG)
739 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
740 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
741 "TARGET_SH1"
742 "@
743 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
744 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
745 [(set_attr "length" "6")
746 (set_attr "type" "arith3b")])
747
748 (define_split
749 [(set (reg:SI T_REG)
750 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
751 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
752 ;; If we applied this split when not optimizing, it would only be
753 ;; applied during the machine-dependent reorg, when no new basic blocks
754 ;; may be created.
755 "TARGET_SH1 && reload_completed && optimize"
756 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
757 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
758 (label_ref (match_dup 6))
759 (pc)))
760 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
761 (match_dup 6)]
762 "
763 {
764 operands[2]
765 = gen_rtx_REG (SImode,
766 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
767 operands[3]
768 = (operands[1] == const0_rtx
769 ? const0_rtx
770 : gen_rtx_REG (SImode,
771 true_regnum (operands[1])
772 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
773 operands[4] = gen_lowpart (SImode, operands[0]);
774 operands[5] = gen_lowpart (SImode, operands[1]);
775 operands[6] = gen_label_rtx ();
776 }")
777
778 (define_insn "cmpgtdi_t"
779 [(set (reg:SI T_REG)
780 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
781 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
782 "TARGET_SH2"
783 "@
784 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
785 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
786 [(set_attr "length" "8")
787 (set_attr "type" "arith3")])
788
789 (define_insn "cmpgedi_t"
790 [(set (reg:SI T_REG)
791 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
792 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
793 "TARGET_SH2"
794 "@
795 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
796 cmp/pz\\t%S0"
797 [(set_attr "length" "8,2")
798 (set_attr "type" "arith3,mt_group")])
799 \f
800 ;; -------------------------------------------------------------------------
801 ;; DImode unsigned integer comparisons
802 ;; -------------------------------------------------------------------------
803
804 (define_insn "cmpgeudi_t"
805 [(set (reg:SI T_REG)
806 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
807 (match_operand:DI 1 "arith_reg_operand" "r")))]
808 "TARGET_SH2"
809 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
810 [(set_attr "length" "8")
811 (set_attr "type" "arith3")])
812
813 (define_insn "cmpgtudi_t"
814 [(set (reg:SI T_REG)
815 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
816 (match_operand:DI 1 "arith_reg_operand" "r")))]
817 "TARGET_SH2"
818 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
819 [(set_attr "length" "8")
820 (set_attr "type" "arith3")])
821
822 (define_insn "cmpeqdi_media"
823 [(set (match_operand:DI 0 "register_operand" "=r")
824 (eq:DI (match_operand:DI 1 "register_operand" "%r")
825 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
826 "TARGET_SHMEDIA"
827 "cmpeq %1, %N2, %0"
828 [(set_attr "type" "cmp_media")])
829
830 (define_insn "cmpgtdi_media"
831 [(set (match_operand:DI 0 "register_operand" "=r")
832 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
834 "TARGET_SHMEDIA"
835 "cmpgt %N1, %N2, %0"
836 [(set_attr "type" "cmp_media")])
837
838 (define_insn "cmpgtudi_media"
839 [(set (match_operand:DI 0 "register_operand" "=r")
840 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
841 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
842 "TARGET_SHMEDIA"
843 "cmpgtu %N1, %N2, %0"
844 [(set_attr "type" "cmp_media")])
845
846 ;; We save the compare operands in the cmpxx patterns and use them when
847 ;; we generate the branch.
848
849 (define_expand "cmpdi"
850 [(set (reg:SI T_REG)
851 (compare (match_operand:DI 0 "arith_operand" "")
852 (match_operand:DI 1 "arith_operand" "")))]
853 "TARGET_SH2 || TARGET_SHMEDIA"
854 "
855 {
856 sh_compare_op0 = operands[0];
857 sh_compare_op1 = operands[1];
858 DONE;
859 }")
860 ;; -------------------------------------------------------------------------
861 ;; Conditional move instructions
862 ;; -------------------------------------------------------------------------
863
864 ;; The insn names may seem reversed, but note that cmveq performs the move
865 ;; if op1 == 0, and cmvne does it if op1 != 0.
866
867 (define_insn "movdicc_false"
868 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
869 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
870 (const_int 0))
871 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
872 (match_operand:DI 3 "arith_reg_operand" "0")))]
873 "TARGET_SHMEDIA"
874 "cmveq %1, %N2, %0"
875 [(set_attr "type" "arith_media")])
876
877 (define_insn "movdicc_true"
878 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
879 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
880 (const_int 0))
881 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
882 (match_operand:DI 3 "arith_reg_operand" "0")))]
883 "TARGET_SHMEDIA"
884 "cmvne %1, %N2, %0"
885 [(set_attr "type" "arith_media")])
886
887 (define_expand "movdicc"
888 [(set (match_operand:DI 0 "register_operand" "")
889 (if_then_else:DI (match_operand 1 "comparison_operator" "")
890 (match_operand:DI 2 "register_operand" "")
891 (match_operand:DI 3 "register_operand" "")))]
892 "TARGET_SHMEDIA"
893 "
894 {
895 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
896 && GET_MODE (sh_compare_op0) == DImode
897 && sh_compare_op1 == const0_rtx)
898 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
899 sh_compare_op0, sh_compare_op1);
900 else
901 {
902 rtx tmp;
903
904 if (no_new_pseudos)
905 FAIL;
906
907 tmp = gen_reg_rtx (DImode);
908
909 switch (GET_CODE (operands[1]))
910 {
911 case EQ:
912 emit_insn (gen_seq (tmp));
913 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
914 break;
915
916 case NE:
917 emit_insn (gen_seq (tmp));
918 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
919 break;
920
921 case GT:
922 emit_insn (gen_sgt (tmp));
923 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
924 break;
925
926 case LT:
927 emit_insn (gen_slt (tmp));
928 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
929 break;
930
931 case GE:
932 emit_insn (gen_slt (tmp));
933 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
934 break;
935
936 case LE:
937 emit_insn (gen_sgt (tmp));
938 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
939 break;
940
941 case GTU:
942 emit_insn (gen_sgtu (tmp));
943 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944 break;
945
946 case LTU:
947 emit_insn (gen_sltu (tmp));
948 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
949 break;
950
951 case GEU:
952 emit_insn (gen_sltu (tmp));
953 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
954 break;
955
956 case LEU:
957 emit_insn (gen_sgtu (tmp));
958 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
959 break;
960
961 case UNORDERED:
962 emit_insn (gen_sunordered (tmp));
963 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
964 break;
965
966 case ORDERED:
967 emit_insn (gen_sunordered (tmp));
968 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
969 break;
970
971 case UNEQ:
972 case UNGE:
973 case UNGT:
974 case UNLE:
975 case UNLT:
976 case LTGT:
977 FAIL;
978
979 default:
980 abort ();
981 }
982 }
983 }")
984 \f
985 ;; -------------------------------------------------------------------------
986 ;; Addition instructions
987 ;; -------------------------------------------------------------------------
988
989 (define_expand "adddi3"
990 [(set (match_operand:DI 0 "arith_reg_operand" "")
991 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
992 (match_operand:DI 2 "arith_operand" "")))]
993 ""
994 "
995 {
996 if (TARGET_SH1)
997 {
998 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
999 FAIL;
1000 operands[2] = force_reg (DImode, operands[2]);
1001 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1002 DONE;
1003 }
1004 }")
1005
1006 (define_insn "*adddi3_media"
1007 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1008 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1009 (match_operand:DI 2 "arith_operand" "r,I10")))]
1010 "TARGET_SHMEDIA"
1011 "@
1012 add %1, %2, %0
1013 addi %1, %2, %0"
1014 [(set_attr "type" "arith_media")])
1015
1016 (define_insn "adddi3z_media"
1017 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1018 (zero_extend:DI
1019 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1020 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1021 "TARGET_SHMEDIA"
1022 "addz.l %1, %N2, %0"
1023 [(set_attr "type" "arith_media")])
1024
1025 (define_insn "adddi3_compact"
1026 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1027 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1028 (match_operand:DI 2 "arith_reg_operand" "r")))
1029 (clobber (reg:SI T_REG))]
1030 "TARGET_SH1"
1031 "#"
1032 [(set_attr "length" "6")])
1033
1034 (define_split
1035 [(set (match_operand:DI 0 "arith_reg_operand" "")
1036 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1037 (match_operand:DI 2 "arith_reg_operand" "")))
1038 (clobber (reg:SI T_REG))]
1039 "TARGET_SH1 && reload_completed"
1040 [(const_int 0)]
1041 "
1042 {
1043 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1044 high0 = gen_rtx_REG (SImode,
1045 true_regnum (operands[0])
1046 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1047 high2 = gen_rtx_REG (SImode,
1048 true_regnum (operands[2])
1049 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050 emit_insn (gen_clrt ());
1051 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1052 emit_insn (gen_addc1 (high0, high0, high2));
1053 DONE;
1054 }")
1055
1056 (define_insn "addc"
1057 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1058 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1059 (match_operand:SI 2 "arith_reg_operand" "r"))
1060 (reg:SI T_REG)))
1061 (set (reg:SI T_REG)
1062 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1063 "TARGET_SH1"
1064 "addc %2,%0"
1065 [(set_attr "type" "arith")])
1066
1067 (define_insn "addc1"
1068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1069 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1070 (match_operand:SI 2 "arith_reg_operand" "r"))
1071 (reg:SI T_REG)))
1072 (clobber (reg:SI T_REG))]
1073 "TARGET_SH1"
1074 "addc %2,%0"
1075 [(set_attr "type" "arith")])
1076
1077 (define_expand "addsi3"
1078 [(set (match_operand:SI 0 "arith_reg_operand" "")
1079 (plus:SI (match_operand:SI 1 "arith_operand" "")
1080 (match_operand:SI 2 "arith_operand" "")))]
1081 ""
1082 "
1083 {
1084 if (TARGET_SHMEDIA)
1085 operands[1] = force_reg (SImode, operands[1]);
1086 }")
1087
1088 (define_insn "addsi3_media"
1089 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1090 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1091 (match_operand:SI 2 "arith_operand" "r,I10")))]
1092 "TARGET_SHMEDIA"
1093 "@
1094 add.l %1, %2, %0
1095 addi.l %1, %2, %0"
1096 [(set_attr "type" "arith_media")])
1097
1098 (define_insn "*addsi3_compact"
1099 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1100 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1101 (match_operand:SI 2 "arith_operand" "rI08")))]
1102 "TARGET_SH1"
1103 "add %2,%0"
1104 [(set_attr "type" "arith")])
1105
1106 ;; -------------------------------------------------------------------------
1107 ;; Subtraction instructions
1108 ;; -------------------------------------------------------------------------
1109
1110 (define_expand "subdi3"
1111 [(set (match_operand:DI 0 "arith_reg_operand" "")
1112 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1113 (match_operand:DI 2 "arith_reg_operand" "")))]
1114 ""
1115 "
1116 {
1117 if (TARGET_SH1)
1118 {
1119 operands[1] = force_reg (DImode, operands[1]);
1120 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1121 DONE;
1122 }
1123 }")
1124
1125 (define_insn "*subdi3_media"
1126 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1127 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1128 (match_operand:DI 2 "arith_reg_operand" "r")))]
1129 "TARGET_SHMEDIA"
1130 "sub %N1, %2, %0"
1131 [(set_attr "type" "arith_media")])
1132
1133 (define_insn "subdi3_compact"
1134 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1135 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1136 (match_operand:DI 2 "arith_reg_operand" "r")))
1137 (clobber (reg:SI T_REG))]
1138 "TARGET_SH1"
1139 "#"
1140 [(set_attr "length" "6")])
1141
1142 (define_split
1143 [(set (match_operand:DI 0 "arith_reg_operand" "")
1144 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1145 (match_operand:DI 2 "arith_reg_operand" "")))
1146 (clobber (reg:SI T_REG))]
1147 "TARGET_SH1 && reload_completed"
1148 [(const_int 0)]
1149 "
1150 {
1151 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1152 high0 = gen_rtx_REG (SImode,
1153 true_regnum (operands[0])
1154 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1155 high2 = gen_rtx_REG (SImode,
1156 true_regnum (operands[2])
1157 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158 emit_insn (gen_clrt ());
1159 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1160 emit_insn (gen_subc1 (high0, high0, high2));
1161 DONE;
1162 }")
1163
1164 (define_insn "subc"
1165 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1166 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1167 (match_operand:SI 2 "arith_reg_operand" "r"))
1168 (reg:SI T_REG)))
1169 (set (reg:SI T_REG)
1170 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1171 "TARGET_SH1"
1172 "subc %2,%0"
1173 [(set_attr "type" "arith")])
1174
1175 (define_insn "subc1"
1176 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1177 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1178 (match_operand:SI 2 "arith_reg_operand" "r"))
1179 (reg:SI T_REG)))
1180 (clobber (reg:SI T_REG))]
1181 "TARGET_SH1"
1182 "subc %2,%0"
1183 [(set_attr "type" "arith")])
1184
1185 (define_insn "*subsi3_internal"
1186 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1187 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1188 (match_operand:SI 2 "arith_reg_operand" "r")))]
1189 "TARGET_SH1"
1190 "sub %2,%0"
1191 [(set_attr "type" "arith")])
1192
1193 (define_insn "*subsi3_media"
1194 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1195 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1196 (match_operand:SI 2 "extend_reg_operand" "r")))]
1197 "TARGET_SHMEDIA"
1198 "sub.l %N1, %2, %0"
1199 [(set_attr "type" "arith_media")])
1200
1201 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1202 ;; will sometimes save one instruction. Otherwise we might get
1203 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1204 ;; are the same.
1205
1206 (define_expand "subsi3"
1207 [(set (match_operand:SI 0 "arith_reg_operand" "")
1208 (minus:SI (match_operand:SI 1 "arith_operand" "")
1209 (match_operand:SI 2 "arith_reg_operand" "")))]
1210 ""
1211 "
1212 {
1213 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1214 {
1215 emit_insn (gen_negsi2 (operands[0], operands[2]));
1216 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1217 DONE;
1218 }
1219 if (TARGET_SHMEDIA)
1220 {
1221 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1222 FAIL;
1223 if (operands[1] != const0_rtx)
1224 operands[1] = force_reg (SImode, operands[1]);
1225 }
1226 }")
1227 \f
1228 ;; -------------------------------------------------------------------------
1229 ;; Division instructions
1230 ;; -------------------------------------------------------------------------
1231
1232 ;; We take advantage of the library routines which don't clobber as many
1233 ;; registers as a normal function call would.
1234
1235 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1236 ;; also has an effect on the register that holds the address of the sfunc.
1237 ;; To make this work, we have an extra dummy insn that shows the use
1238 ;; of this register for reorg.
1239
1240 (define_insn "use_sfunc_addr"
1241 [(set (reg:SI PR_REG)
1242 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1243 "TARGET_SH1"
1244 ""
1245 [(set_attr "length" "0")])
1246
1247 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1248 ;; hard register 0. If we used hard register 0, then the next instruction
1249 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1250 ;; gets allocated to a stack slot that needs its address reloaded, then
1251 ;; there is nothing to prevent reload from using r0 to reload the address.
1252 ;; This reload would clobber the value in r0 we are trying to store.
1253 ;; If we let reload allocate r0, then this problem can never happen.
1254
1255 (define_insn "udivsi3_i1"
1256 [(set (match_operand:SI 0 "register_operand" "=z")
1257 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258 (clobber (reg:SI T_REG))
1259 (clobber (reg:SI PR_REG))
1260 (clobber (reg:SI R4_REG))
1261 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1262 "TARGET_SH1 && ! TARGET_SH4"
1263 "jsr @%1%#"
1264 [(set_attr "type" "sfunc")
1265 (set_attr "needs_delay_slot" "yes")])
1266
1267 ; Since shmedia-nofpu code could be linked against shcompact code, and
1268 ; the udivsi3 libcall has the same name, we must consider all registers
1269 ; clobbered that are in the union of the registers clobbered by the
1270 ; shmedia and the shcompact implementation. Note, if the shcompact
1271 ; implementation actually used shcompact code, we'd need to clobber
1272 ; also r23 and fr23.
1273 (define_insn "udivsi3_i1_media"
1274 [(set (match_operand:SI 0 "register_operand" "=z")
1275 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1276 (clobber (reg:SI T_MEDIA_REG))
1277 (clobber (reg:SI PR_MEDIA_REG))
1278 (clobber (reg:SI R20_REG))
1279 (clobber (reg:SI R21_REG))
1280 (clobber (reg:SI R22_REG))
1281 (clobber (reg:DI TR0_REG))
1282 (clobber (reg:DI TR1_REG))
1283 (clobber (reg:DI TR2_REG))
1284 (use (match_operand:DI 1 "target_operand" "b"))]
1285 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1286 "blink %1, r18"
1287 [(set_attr "type" "sfunc")
1288 (set_attr "needs_delay_slot" "yes")])
1289
1290 (define_expand "udivsi3_i4_media"
1291 [(set (match_dup 3)
1292 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1293 (set (match_dup 4)
1294 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1295 (set (match_dup 5) (float:DF (match_dup 3)))
1296 (set (match_dup 6) (float:DF (match_dup 4)))
1297 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1298 (set (match_dup 8) (fix:DI (match_dup 7)))
1299 (set (match_operand:SI 0 "register_operand" "")
1300 (truncate:SI (match_dup 8)))]
1301 "TARGET_SHMEDIA_FPU"
1302 "
1303 {
1304 operands[3] = gen_reg_rtx (DImode);
1305 operands[4] = gen_reg_rtx (DImode);
1306 operands[5] = gen_reg_rtx (DFmode);
1307 operands[6] = gen_reg_rtx (DFmode);
1308 operands[7] = gen_reg_rtx (DFmode);
1309 operands[8] = gen_reg_rtx (DImode);
1310 }")
1311
1312 (define_insn "udivsi3_i4"
1313 [(set (match_operand:SI 0 "register_operand" "=y")
1314 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1315 (clobber (reg:SI T_REG))
1316 (clobber (reg:SI PR_REG))
1317 (clobber (reg:DF DR0_REG))
1318 (clobber (reg:DF DR2_REG))
1319 (clobber (reg:DF DR4_REG))
1320 (clobber (reg:SI R0_REG))
1321 (clobber (reg:SI R1_REG))
1322 (clobber (reg:SI R4_REG))
1323 (clobber (reg:SI R5_REG))
1324 (use (reg:PSI FPSCR_REG))
1325 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1326 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1327 "jsr @%1%#"
1328 [(set_attr "type" "sfunc")
1329 (set_attr "fp_mode" "double")
1330 (set_attr "needs_delay_slot" "yes")])
1331
1332 (define_insn "udivsi3_i4_single"
1333 [(set (match_operand:SI 0 "register_operand" "=y")
1334 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1335 (clobber (reg:SI T_REG))
1336 (clobber (reg:SI PR_REG))
1337 (clobber (reg:DF DR0_REG))
1338 (clobber (reg:DF DR2_REG))
1339 (clobber (reg:DF DR4_REG))
1340 (clobber (reg:SI R0_REG))
1341 (clobber (reg:SI R1_REG))
1342 (clobber (reg:SI R4_REG))
1343 (clobber (reg:SI R5_REG))
1344 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1345 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1346 "jsr @%1%#"
1347 [(set_attr "type" "sfunc")
1348 (set_attr "needs_delay_slot" "yes")])
1349
1350 (define_expand "udivsi3"
1351 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1352 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1353 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1354 (parallel [(set (match_operand:SI 0 "register_operand" "")
1355 (udiv:SI (reg:SI R4_REG)
1356 (reg:SI R5_REG)))
1357 (clobber (reg:SI T_REG))
1358 (clobber (reg:SI PR_REG))
1359 (clobber (reg:SI R4_REG))
1360 (use (match_dup 3))])]
1361 ""
1362 "
1363 {
1364 rtx first, last;
1365
1366 operands[3] = gen_reg_rtx (Pmode);
1367 /* Emit the move of the address to a pseudo outside of the libcall. */
1368 if (TARGET_HARD_SH4 && TARGET_SH2E)
1369 {
1370 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1371 if (TARGET_FPU_SINGLE)
1372 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1373 else
1374 last = gen_udivsi3_i4 (operands[0], operands[3]);
1375 }
1376 else if (TARGET_SHMEDIA_FPU)
1377 {
1378 operands[1] = force_reg (SImode, operands[1]);
1379 operands[2] = force_reg (SImode, operands[2]);
1380 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1381 DONE;
1382 }
1383 else if (TARGET_SH5)
1384 {
1385 emit_move_insn (operands[3],
1386 function_symbol (TARGET_FPU_ANY
1387 ? \"__udivsi3_i4\"
1388 : \"__udivsi3\"));
1389
1390 if (TARGET_SHMEDIA)
1391 last = gen_udivsi3_i1_media (operands[0],
1392 Pmode == DImode
1393 ? operands[3]
1394 : gen_rtx_SUBREG (DImode, operands[3],
1395 0));
1396 else if (TARGET_FPU_ANY)
1397 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1398 else
1399 last = gen_udivsi3_i1 (operands[0], operands[3]);
1400 }
1401 else
1402 {
1403 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1404 last = gen_udivsi3_i1 (operands[0], operands[3]);
1405 }
1406 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1407 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1408 last = emit_insn (last);
1409 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1410 invariant code motion can move it. */
1411 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1412 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1413 DONE;
1414 }")
1415
1416 (define_insn "divsi3_i1"
1417 [(set (match_operand:SI 0 "register_operand" "=z")
1418 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419 (clobber (reg:SI T_REG))
1420 (clobber (reg:SI PR_REG))
1421 (clobber (reg:SI R1_REG))
1422 (clobber (reg:SI R2_REG))
1423 (clobber (reg:SI R3_REG))
1424 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1425 "TARGET_SH1 && ! TARGET_SH4"
1426 "jsr @%1%#"
1427 [(set_attr "type" "sfunc")
1428 (set_attr "needs_delay_slot" "yes")])
1429
1430 ; Since shmedia-nofpu code could be linked against shcompact code, and
1431 ; the sdivsi3 libcall has the same name, we must consider all registers
1432 ; clobbered that are in the union of the registers clobbered by the
1433 ; shmedia and the shcompact implementation. Note, if the shcompact
1434 ; implementation actually used shcompact code, we'd need to clobber
1435 ; also r22, r23 and fr23.
1436 (define_insn "divsi3_i1_media"
1437 [(set (match_operand:SI 0 "register_operand" "=z")
1438 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1439 (clobber (reg:SI T_MEDIA_REG))
1440 (clobber (reg:SI PR_MEDIA_REG))
1441 (clobber (reg:SI R1_REG))
1442 (clobber (reg:SI R2_REG))
1443 (clobber (reg:SI R3_REG))
1444 (clobber (reg:SI R20_REG))
1445 (clobber (reg:SI R21_REG))
1446 (clobber (reg:DI TR0_REG))
1447 (clobber (reg:DI TR1_REG))
1448 (clobber (reg:DI TR2_REG))
1449 (use (match_operand:DI 1 "target_operand" "b"))]
1450 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1451 "blink %1, r18"
1452 [(set_attr "type" "sfunc")])
1453
1454 (define_expand "divsi3_i4_media"
1455 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1456 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1457 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1458 (set (match_operand:SI 0 "register_operand" "=r")
1459 (fix:SI (match_dup 5)))]
1460 "TARGET_SHMEDIA_FPU"
1461 "
1462 {
1463 operands[3] = gen_reg_rtx (DFmode);
1464 operands[4] = gen_reg_rtx (DFmode);
1465 operands[5] = gen_reg_rtx (DFmode);
1466 }")
1467
1468 (define_insn "divsi3_i4"
1469 [(set (match_operand:SI 0 "register_operand" "=y")
1470 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471 (clobber (reg:SI PR_REG))
1472 (clobber (reg:DF DR0_REG))
1473 (clobber (reg:DF DR2_REG))
1474 (use (reg:PSI FPSCR_REG))
1475 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1477 "jsr @%1%#"
1478 [(set_attr "type" "sfunc")
1479 (set_attr "fp_mode" "double")
1480 (set_attr "needs_delay_slot" "yes")])
1481
1482 (define_insn "divsi3_i4_single"
1483 [(set (match_operand:SI 0 "register_operand" "=y")
1484 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1485 (clobber (reg:SI PR_REG))
1486 (clobber (reg:DF DR0_REG))
1487 (clobber (reg:DF DR2_REG))
1488 (clobber (reg:SI R2_REG))
1489 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1490 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1491 "jsr @%1%#"
1492 [(set_attr "type" "sfunc")
1493 (set_attr "needs_delay_slot" "yes")])
1494
1495 (define_expand "divsi3"
1496 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1497 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1498 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1499 (parallel [(set (match_operand:SI 0 "register_operand" "")
1500 (div:SI (reg:SI R4_REG)
1501 (reg:SI R5_REG)))
1502 (clobber (reg:SI T_REG))
1503 (clobber (reg:SI PR_REG))
1504 (clobber (reg:SI R1_REG))
1505 (clobber (reg:SI R2_REG))
1506 (clobber (reg:SI R3_REG))
1507 (use (match_dup 3))])]
1508 ""
1509 "
1510 {
1511 rtx first, last;
1512
1513 operands[3] = gen_reg_rtx (Pmode);
1514 /* Emit the move of the address to a pseudo outside of the libcall. */
1515 if (TARGET_HARD_SH4 && TARGET_SH2E)
1516 {
1517 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1518 if (TARGET_FPU_SINGLE)
1519 last = gen_divsi3_i4_single (operands[0], operands[3]);
1520 else
1521 last = gen_divsi3_i4 (operands[0], operands[3]);
1522 }
1523 else if (TARGET_SHMEDIA_FPU)
1524 {
1525 operands[1] = force_reg (SImode, operands[1]);
1526 operands[2] = force_reg (SImode, operands[2]);
1527 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1528 DONE;
1529 }
1530 else if (TARGET_SH5)
1531 {
1532 emit_move_insn (operands[3],
1533 function_symbol (TARGET_FPU_ANY
1534 ? \"__sdivsi3_i4\"
1535 : \"__sdivsi3\"));
1536
1537 if (TARGET_SHMEDIA)
1538 last = gen_divsi3_i1_media (operands[0],
1539 Pmode == DImode
1540 ? operands[3]
1541 : gen_rtx_SUBREG (DImode, operands[3],
1542 0));
1543 else if (TARGET_FPU_ANY)
1544 last = gen_divsi3_i4_single (operands[0], operands[3]);
1545 else
1546 last = gen_divsi3_i1 (operands[0], operands[3]);
1547 }
1548 else
1549 {
1550 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1551 last = gen_divsi3_i1 (operands[0], operands[3]);
1552 }
1553 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1554 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1555 last = emit_insn (last);
1556 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1557 invariant code motion can move it. */
1558 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1559 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1560 DONE;
1561 }")
1562 \f
1563 ;; -------------------------------------------------------------------------
1564 ;; Multiplication instructions
1565 ;; -------------------------------------------------------------------------
1566
1567 (define_insn "umulhisi3_i"
1568 [(set (reg:SI MACL_REG)
1569 (mult:SI (zero_extend:SI
1570 (match_operand:HI 0 "arith_reg_operand" "r"))
1571 (zero_extend:SI
1572 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1573 "TARGET_SH1"
1574 "mulu.w %1,%0"
1575 [(set_attr "type" "smpy")])
1576
1577 (define_insn "mulhisi3_i"
1578 [(set (reg:SI MACL_REG)
1579 (mult:SI (sign_extend:SI
1580 (match_operand:HI 0 "arith_reg_operand" "r"))
1581 (sign_extend:SI
1582 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1583 "TARGET_SH1"
1584 "muls.w %1,%0"
1585 [(set_attr "type" "smpy")])
1586
1587 (define_expand "mulhisi3"
1588 [(set (reg:SI MACL_REG)
1589 (mult:SI (sign_extend:SI
1590 (match_operand:HI 1 "arith_reg_operand" ""))
1591 (sign_extend:SI
1592 (match_operand:HI 2 "arith_reg_operand" ""))))
1593 (set (match_operand:SI 0 "arith_reg_operand" "")
1594 (reg:SI MACL_REG))]
1595 "TARGET_SH1"
1596 "
1597 {
1598 rtx first, last;
1599
1600 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1601 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1602 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1603 invariant code motion can move it. */
1604 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1605 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1606 /* expand_binop can't find a suitable code in umul_widen_optab to
1607 make a REG_EQUAL note from, so make one here.
1608 See also smulsi3_highpart.
1609 ??? Alternatively, we could put this at the calling site of expand_binop,
1610 i.e. expand_expr. */
1611 REG_NOTES (last)
1612 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1613 REG_NOTES (last));
1614 DONE;
1615 }")
1616
1617 (define_expand "umulhisi3"
1618 [(set (reg:SI MACL_REG)
1619 (mult:SI (zero_extend:SI
1620 (match_operand:HI 1 "arith_reg_operand" ""))
1621 (zero_extend:SI
1622 (match_operand:HI 2 "arith_reg_operand" ""))))
1623 (set (match_operand:SI 0 "arith_reg_operand" "")
1624 (reg:SI MACL_REG))]
1625 "TARGET_SH1"
1626 "
1627 {
1628 rtx first, last;
1629
1630 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1631 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1632 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1633 invariant code motion can move it. */
1634 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1635 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1636 /* expand_binop can't find a suitable code in umul_widen_optab to
1637 make a REG_EQUAL note from, so make one here.
1638 See also smulsi3_highpart.
1639 ??? Alternatively, we could put this at the calling site of expand_binop,
1640 i.e. expand_expr. */
1641 REG_NOTES (last)
1642 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1643 REG_NOTES (last));
1644 DONE;
1645 }")
1646
1647 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1648 ;; a call to a routine which clobbers known registers.
1649
1650 (define_insn ""
1651 [(set (match_operand:SI 1 "register_operand" "=z")
1652 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1653 (clobber (reg:SI MACL_REG))
1654 (clobber (reg:SI T_REG))
1655 (clobber (reg:SI PR_REG))
1656 (clobber (reg:SI R3_REG))
1657 (clobber (reg:SI R2_REG))
1658 (clobber (reg:SI R1_REG))
1659 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1660 "TARGET_SH1"
1661 "jsr @%0%#"
1662 [(set_attr "type" "sfunc")
1663 (set_attr "needs_delay_slot" "yes")])
1664
1665 (define_expand "mulsi3_call"
1666 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1667 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1668 (parallel[(set (match_operand:SI 0 "register_operand" "")
1669 (mult:SI (reg:SI R4_REG)
1670 (reg:SI R5_REG)))
1671 (clobber (reg:SI MACL_REG))
1672 (clobber (reg:SI T_REG))
1673 (clobber (reg:SI PR_REG))
1674 (clobber (reg:SI R3_REG))
1675 (clobber (reg:SI R2_REG))
1676 (clobber (reg:SI R1_REG))
1677 (use (match_operand:SI 3 "register_operand" ""))])]
1678 "TARGET_SH1"
1679 "")
1680
1681 (define_insn "mul_l"
1682 [(set (reg:SI MACL_REG)
1683 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1684 (match_operand:SI 1 "arith_reg_operand" "r")))]
1685 "TARGET_SH2"
1686 "mul.l %1,%0"
1687 [(set_attr "type" "dmpy")])
1688
1689 (define_expand "mulsi3"
1690 [(set (reg:SI MACL_REG)
1691 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1692 (match_operand:SI 2 "arith_reg_operand" "")))
1693 (set (match_operand:SI 0 "arith_reg_operand" "")
1694 (reg:SI MACL_REG))]
1695 "TARGET_SH1"
1696 "
1697 {
1698 rtx first, last;
1699
1700 if (!TARGET_SH2)
1701 {
1702 /* The address must be set outside the libcall,
1703 since it goes into a pseudo. */
1704 rtx sym = function_symbol (\"__mulsi3\");
1705 rtx addr = force_reg (SImode, sym);
1706 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1707 operands[2], addr);
1708 first = insns;
1709 last = emit_insn (insns);
1710 }
1711 else
1712 {
1713 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1714
1715 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1716 /* consec_sets_giv can only recognize the first insn that sets a
1717 giv as the giv insn. So we must tag this also with a REG_EQUAL
1718 note. */
1719 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1720 }
1721 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1722 invariant code motion can move it. */
1723 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1724 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1725 DONE;
1726 }")
1727
1728 (define_insn "mulsidi3_i"
1729 [(set (reg:SI MACH_REG)
1730 (truncate:SI
1731 (lshiftrt:DI
1732 (mult:DI
1733 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1734 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1735 (const_int 32))))
1736 (set (reg:SI MACL_REG)
1737 (mult:SI (match_dup 0)
1738 (match_dup 1)))]
1739 "TARGET_SH2"
1740 "dmuls.l %1,%0"
1741 [(set_attr "type" "dmpy")])
1742
1743 (define_expand "mulsidi3"
1744 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1745 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1746 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1747 "TARGET_SH2 || TARGET_SHMEDIA"
1748 "
1749 {
1750 if (TARGET_SH2)
1751 {
1752 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1753 operands[2]));
1754 DONE;
1755 }
1756 }")
1757
1758 (define_insn "mulsidi3_media"
1759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1760 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1761 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1762 "TARGET_SHMEDIA"
1763 "muls.l %1, %2, %0"
1764 [(set_attr "type" "dmpy_media")])
1765
1766 (define_insn "mulsidi3_compact"
1767 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1768 (mult:DI
1769 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1770 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1771 (clobber (reg:SI MACH_REG))
1772 (clobber (reg:SI MACL_REG))]
1773 "TARGET_SH2"
1774 "#")
1775
1776 (define_split
1777 [(set (match_operand:DI 0 "arith_reg_operand" "")
1778 (mult:DI
1779 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1780 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1781 (clobber (reg:SI MACH_REG))
1782 (clobber (reg:SI MACL_REG))]
1783 "TARGET_SH2"
1784 [(const_int 0)]
1785 "
1786 {
1787 rtx low_dst = gen_lowpart (SImode, operands[0]);
1788 rtx high_dst = gen_highpart (SImode, operands[0]);
1789
1790 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1791
1792 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1793 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1794 /* We need something to tag the possible REG_EQUAL notes on to. */
1795 emit_move_insn (operands[0], operands[0]);
1796 DONE;
1797 }")
1798
1799 (define_insn "umulsidi3_i"
1800 [(set (reg:SI MACH_REG)
1801 (truncate:SI
1802 (lshiftrt:DI
1803 (mult:DI
1804 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1805 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1806 (const_int 32))))
1807 (set (reg:SI MACL_REG)
1808 (mult:SI (match_dup 0)
1809 (match_dup 1)))]
1810 "TARGET_SH2"
1811 "dmulu.l %1,%0"
1812 [(set_attr "type" "dmpy")])
1813
1814 (define_expand "umulsidi3"
1815 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1816 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1817 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1818 "TARGET_SH2 || TARGET_SHMEDIA"
1819 "
1820 {
1821 if (TARGET_SH2)
1822 {
1823 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1824 operands[2]));
1825 DONE;
1826 }
1827 }")
1828
1829 (define_insn "umulsidi3_media"
1830 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1831 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1832 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1833 "TARGET_SHMEDIA"
1834 "mulu.l %1, %2, %0"
1835 [(set_attr "type" "dmpy_media")])
1836
1837 (define_insn "umulsidi3_compact"
1838 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1839 (mult:DI
1840 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1841 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1842 (clobber (reg:SI MACH_REG))
1843 (clobber (reg:SI MACL_REG))]
1844 "TARGET_SH2"
1845 "#")
1846
1847 (define_split
1848 [(set (match_operand:DI 0 "arith_reg_operand" "")
1849 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1850 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1851 (clobber (reg:SI MACH_REG))
1852 (clobber (reg:SI MACL_REG))]
1853 "TARGET_SH2"
1854 [(const_int 0)]
1855 "
1856 {
1857 rtx low_dst = gen_lowpart (SImode, operands[0]);
1858 rtx high_dst = gen_highpart (SImode, operands[0]);
1859
1860 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1861
1862 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1863 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1864 /* We need something to tag the possible REG_EQUAL notes on to. */
1865 emit_move_insn (operands[0], operands[0]);
1866 DONE;
1867 }")
1868
1869 (define_insn "smulsi3_highpart_i"
1870 [(set (reg:SI MACH_REG)
1871 (truncate:SI
1872 (lshiftrt:DI
1873 (mult:DI
1874 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1875 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1876 (const_int 32))))
1877 (clobber (reg:SI MACL_REG))]
1878 "TARGET_SH2"
1879 "dmuls.l %1,%0"
1880 [(set_attr "type" "dmpy")])
1881
1882 (define_expand "smulsi3_highpart"
1883 [(parallel
1884 [(set (reg:SI MACH_REG)
1885 (truncate:SI
1886 (lshiftrt:DI
1887 (mult:DI
1888 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1889 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1890 (const_int 32))))
1891 (clobber (reg:SI MACL_REG))])
1892 (set (match_operand:SI 0 "arith_reg_operand" "")
1893 (reg:SI MACH_REG))]
1894 "TARGET_SH2"
1895 "
1896 {
1897 rtx first, last;
1898
1899 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1900 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1901 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1902 invariant code motion can move it. */
1903 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1904 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1905 /* expand_binop can't find a suitable code in mul_highpart_optab to
1906 make a REG_EQUAL note from, so make one here.
1907 See also {,u}mulhisi.
1908 ??? Alternatively, we could put this at the calling site of expand_binop,
1909 i.e. expand_mult_highpart. */
1910 REG_NOTES (last)
1911 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1912 REG_NOTES (last));
1913 DONE;
1914 }")
1915
1916 (define_insn "umulsi3_highpart_i"
1917 [(set (reg:SI MACH_REG)
1918 (truncate:SI
1919 (lshiftrt:DI
1920 (mult:DI
1921 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1922 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1923 (const_int 32))))
1924 (clobber (reg:SI MACL_REG))]
1925 "TARGET_SH2"
1926 "dmulu.l %1,%0"
1927 [(set_attr "type" "dmpy")])
1928
1929 (define_expand "umulsi3_highpart"
1930 [(parallel
1931 [(set (reg:SI MACH_REG)
1932 (truncate:SI
1933 (lshiftrt:DI
1934 (mult:DI
1935 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1936 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1937 (const_int 32))))
1938 (clobber (reg:SI MACL_REG))])
1939 (set (match_operand:SI 0 "arith_reg_operand" "")
1940 (reg:SI MACH_REG))]
1941 "TARGET_SH2"
1942 "
1943 {
1944 rtx first, last;
1945
1946 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1947 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1948 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1949 invariant code motion can move it. */
1950 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1951 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1952 DONE;
1953 }")
1954 \f
1955 ;; -------------------------------------------------------------------------
1956 ;; Logical operations
1957 ;; -------------------------------------------------------------------------
1958
1959 (define_insn "*andsi3_compact"
1960 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1961 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1962 (match_operand:SI 2 "logical_operand" "r,K08")))]
1963 "TARGET_SH1"
1964 "and %2,%0"
1965 [(set_attr "type" "arith")])
1966
1967 ;; If the constant is 255, then emit an extu.b instruction instead of an
1968 ;; and, since that will give better code.
1969
1970 (define_expand "andsi3"
1971 [(set (match_operand:SI 0 "arith_reg_operand" "")
1972 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1973 (match_operand:SI 2 "logical_operand" "")))]
1974 "TARGET_SH1"
1975 "
1976 {
1977 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1978 {
1979 emit_insn (gen_zero_extendqisi2 (operands[0],
1980 gen_lowpart (QImode, operands[1])));
1981 DONE;
1982 }
1983 }")
1984
1985 (define_insn_and_split "anddi3"
1986 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1987 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1988 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1989 "TARGET_SHMEDIA"
1990 "@
1991 and %1, %2, %0
1992 andi %1, %2, %0
1993 #"
1994 "reload_completed
1995 && ! logical_operand (operands[2], DImode)"
1996 [(const_int 0)]
1997 "
1998 {
1999 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2000 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2001 else
2002 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2003 DONE;
2004 }"
2005 [(set_attr "type" "arith_media")])
2006
2007 (define_insn "andcdi3"
2008 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2009 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2010 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2011 "TARGET_SHMEDIA"
2012 "andc %1,%2,%0"
2013 [(set_attr "type" "arith_media")])
2014
2015 (define_insn "iorsi3"
2016 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2017 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2018 (match_operand:SI 2 "logical_operand" "r,K08")))]
2019 "TARGET_SH1"
2020 "or %2,%0"
2021 [(set_attr "type" "arith")])
2022
2023 (define_insn "iordi3"
2024 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2025 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2026 (match_operand:DI 2 "logical_operand" "r,I10")))]
2027 "TARGET_SHMEDIA"
2028 "@
2029 or %1, %2, %0
2030 ori %1, %2, %0"
2031 [(set_attr "type" "arith_media")])
2032
2033 (define_insn "xorsi3"
2034 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2035 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2036 (match_operand:SI 2 "logical_operand" "K08,r")))]
2037 "TARGET_SH1"
2038 "xor %2,%0"
2039 [(set_attr "type" "arith")])
2040
2041 (define_insn "xordi3"
2042 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2043 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2044 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2045 "TARGET_SHMEDIA"
2046 "@
2047 xor %1, %2, %0
2048 xori %1, %2, %0"
2049 [(set_attr "type" "arith_media")])
2050
2051 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2052 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2053 (define_split
2054 [(set (match_operand:DI 0 "arith_reg_operand" "")
2055 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2056 [(match_operand 1 "any_register_operand" "")
2057 (match_operand 2 "any_register_operand" "")])))]
2058 "TARGET_SHMEDIA"
2059 [(set (match_dup 5) (match_dup 4))
2060 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2061 "
2062 {
2063 enum machine_mode inmode = GET_MODE (operands[1]);
2064 int offset = 0;
2065
2066 if (GET_CODE (operands[0]) == SUBREG)
2067 {
2068 offset = SUBREG_BYTE (operands[0]);
2069 operands[0] = SUBREG_REG (operands[0]);
2070 }
2071 if (GET_CODE (operands[0]) != REG)
2072 abort ();
2073 if (! TARGET_LITTLE_ENDIAN)
2074 offset += 8 - GET_MODE_SIZE (inmode);
2075 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2076 }")
2077 \f
2078 ;; -------------------------------------------------------------------------
2079 ;; Shifts and rotates
2080 ;; -------------------------------------------------------------------------
2081
2082 (define_expand "rotldi3"
2083 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2084 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2085 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2086 "TARGET_SHMEDIA"
2087 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2088
2089 (define_insn "rotldi3_mextr"
2090 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2091 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2092 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2093 "TARGET_SHMEDIA"
2094 "*
2095 {
2096 static char templ[16];
2097
2098 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2099 8 - (int) (INTVAL (operands[2]) >> 3));
2100 return templ;
2101 }"
2102 [(set_attr "type" "arith_media")])
2103
2104 (define_expand "rotrdi3"
2105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2106 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2107 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2108 "TARGET_SHMEDIA"
2109 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2110
2111 (define_insn "rotrdi3_mextr"
2112 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2113 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2114 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2115 "TARGET_SHMEDIA"
2116 "*
2117 {
2118 static char templ[16];
2119
2120 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2121 return templ;
2122 }"
2123 [(set_attr "type" "arith_media")])
2124
2125 (define_insn "rotlsi3_1"
2126 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2127 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2128 (const_int 1)))
2129 (set (reg:SI T_REG)
2130 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2131 "TARGET_SH1"
2132 "rotl %0"
2133 [(set_attr "type" "arith")])
2134
2135 (define_insn "rotlsi3_31"
2136 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2138 (const_int 31)))
2139 (clobber (reg:SI T_REG))]
2140 "TARGET_SH1"
2141 "rotr %0"
2142 [(set_attr "type" "arith")])
2143
2144 (define_insn "rotlsi3_16"
2145 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2146 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2147 (const_int 16)))]
2148 "TARGET_SH1"
2149 "swap.w %1,%0"
2150 [(set_attr "type" "arith")])
2151
2152 (define_expand "rotlsi3"
2153 [(set (match_operand:SI 0 "arith_reg_operand" "")
2154 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2155 (match_operand:SI 2 "immediate_operand" "")))]
2156 "TARGET_SH1"
2157 "
2158 {
2159 static const char rot_tab[] = {
2160 000, 000, 000, 000, 000, 000, 010, 001,
2161 001, 001, 011, 013, 003, 003, 003, 003,
2162 003, 003, 003, 003, 003, 013, 012, 002,
2163 002, 002, 010, 000, 000, 000, 000, 000,
2164 };
2165
2166 int count, choice;
2167
2168 if (GET_CODE (operands[2]) != CONST_INT)
2169 FAIL;
2170 count = INTVAL (operands[2]);
2171 choice = rot_tab[count];
2172 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2173 FAIL;
2174 choice &= 7;
2175 switch (choice)
2176 {
2177 case 0:
2178 emit_move_insn (operands[0], operands[1]);
2179 count -= (count & 16) * 2;
2180 break;
2181 case 3:
2182 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2183 count -= 16;
2184 break;
2185 case 1:
2186 case 2:
2187 {
2188 rtx parts[2];
2189 parts[0] = gen_reg_rtx (SImode);
2190 parts[1] = gen_reg_rtx (SImode);
2191 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2192 parts[choice-1] = operands[1];
2193 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2194 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2195 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2196 count = (count & ~16) - 8;
2197 }
2198 }
2199
2200 for (; count > 0; count--)
2201 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2202 for (; count < 0; count++)
2203 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2204
2205 DONE;
2206 }")
2207
2208 (define_insn "*rotlhi3_8"
2209 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2210 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2211 (const_int 8)))]
2212 "TARGET_SH1"
2213 "swap.b %1,%0"
2214 [(set_attr "type" "arith")])
2215
2216 (define_expand "rotlhi3"
2217 [(set (match_operand:HI 0 "arith_reg_operand" "")
2218 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2219 (match_operand:HI 2 "immediate_operand" "")))]
2220 "TARGET_SH1"
2221 "
2222 {
2223 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2224 FAIL;
2225 }")
2226
2227 ;;
2228 ;; shift left
2229
2230 ;; This pattern is used by init_expmed for computing the costs of shift
2231 ;; insns.
2232
2233 (define_insn_and_split "ashlsi3_std"
2234 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2235 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2236 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2237 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2238 "TARGET_SH3
2239 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2240 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2241 "@
2242 shld %2,%0
2243 add %0,%0
2244 shll%O2 %0
2245 #"
2246 "TARGET_SH3
2247 && reload_completed
2248 && GET_CODE (operands[2]) == CONST_INT
2249 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2250 [(set (match_dup 3) (match_dup 2))
2251 (parallel
2252 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2253 (clobber (match_dup 4))])]
2254 "operands[4] = gen_rtx_SCRATCH (SImode);"
2255 [(set_attr "length" "*,*,*,4")
2256 (set_attr "type" "dyn_shift,arith,arith,arith")])
2257
2258 (define_insn "ashlhi3_k"
2259 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2260 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2261 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2262 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2263 "@
2264 add %0,%0
2265 shll%O2 %0"
2266 [(set_attr "type" "arith")])
2267
2268 (define_insn "ashlsi3_n"
2269 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2270 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2271 (match_operand:SI 2 "const_int_operand" "n")))
2272 (clobber (reg:SI T_REG))]
2273 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2274 "#"
2275 [(set (attr "length")
2276 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2277 (const_string "2")
2278 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2279 (const_string "4")
2280 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2281 (const_string "6")]
2282 (const_string "8")))
2283 (set_attr "type" "arith")])
2284
2285 (define_split
2286 [(set (match_operand:SI 0 "arith_reg_operand" "")
2287 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2288 (match_operand:SI 2 "const_int_operand" "")))
2289 (clobber (reg:SI T_REG))]
2290 "TARGET_SH1 && reload_completed"
2291 [(use (reg:SI R0_REG))]
2292 "
2293 {
2294 gen_shifty_op (ASHIFT, operands);
2295 DONE;
2296 }")
2297
2298 (define_insn "ashlsi3_media"
2299 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2300 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2301 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2302 "TARGET_SHMEDIA"
2303 "@
2304 shlld.l %1, %2, %0
2305 shlli.l %1, %2, %0"
2306 [(set_attr "type" "arith_media")])
2307
2308 (define_expand "ashlsi3"
2309 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2310 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2311 (match_operand:SI 2 "nonmemory_operand" "")))
2312 (clobber (reg:SI T_REG))])]
2313 ""
2314 "
2315 {
2316 if (TARGET_SHMEDIA)
2317 {
2318 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2319 DONE;
2320 }
2321 if (GET_CODE (operands[2]) == CONST_INT
2322 && sh_dynamicalize_shift_p (operands[2]))
2323 operands[2] = force_reg (SImode, operands[2]);
2324 if (TARGET_SH3)
2325 {
2326 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2327 DONE;
2328 }
2329 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2330 FAIL;
2331 }")
2332
2333 (define_insn "ashlhi3"
2334 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2335 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2336 (match_operand:HI 2 "const_int_operand" "n")))
2337 (clobber (reg:SI T_REG))]
2338 "TARGET_SH1"
2339 "#"
2340 [(set (attr "length")
2341 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2342 (const_string "2")
2343 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2344 (const_string "4")]
2345 (const_string "6")))
2346 (set_attr "type" "arith")])
2347
2348 (define_split
2349 [(set (match_operand:HI 0 "arith_reg_operand" "")
2350 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2351 (match_operand:HI 2 "const_int_operand" "")))
2352 (clobber (reg:SI T_REG))]
2353 "TARGET_SH1 && reload_completed"
2354 [(use (reg:SI R0_REG))]
2355 "
2356 {
2357 gen_shifty_hi_op (ASHIFT, operands);
2358 DONE;
2359 }")
2360
2361 ;
2362 ; arithmetic shift right
2363 ;
2364
2365 (define_insn "ashrsi3_k"
2366 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2367 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2368 (match_operand:SI 2 "const_int_operand" "M")))
2369 (clobber (reg:SI T_REG))]
2370 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2371 "shar %0"
2372 [(set_attr "type" "arith")])
2373
2374 ;; We can't do HImode right shifts correctly unless we start out with an
2375 ;; explicit zero / sign extension; doing that would result in worse overall
2376 ;; code, so just let the machine independent code widen the mode.
2377 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2378
2379
2380 ;; ??? This should be a define expand.
2381
2382 (define_insn "ashrsi2_16"
2383 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2384 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2385 (const_int 16)))]
2386 "TARGET_SH1"
2387 "#"
2388 [(set_attr "length" "4")])
2389
2390 (define_split
2391 [(set (match_operand:SI 0 "arith_reg_operand" "")
2392 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2393 (const_int 16)))]
2394 "TARGET_SH1"
2395 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2396 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2397 "operands[2] = gen_lowpart (HImode, operands[0]);")
2398
2399 ;; ??? This should be a define expand.
2400
2401 (define_insn "ashrsi2_31"
2402 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2403 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2404 (const_int 31)))
2405 (clobber (reg:SI T_REG))]
2406 "TARGET_SH1"
2407 "#"
2408 [(set_attr "length" "4")])
2409
2410 (define_split
2411 [(set (match_operand:SI 0 "arith_reg_operand" "")
2412 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2413 (const_int 31)))
2414 (clobber (reg:SI T_REG))]
2415 "TARGET_SH1"
2416 [(const_int 0)]
2417 "
2418 {
2419 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2420 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2421 DONE;
2422 }")
2423
2424 (define_insn "ashlsi_c"
2425 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2427 (set (reg:SI T_REG)
2428 (lt:SI (match_dup 1) (const_int 0)))]
2429 "TARGET_SH1"
2430 "shll %0"
2431 [(set_attr "type" "arith")])
2432
2433 (define_insn "ashrsi3_d"
2434 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2435 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2436 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2437 "TARGET_SH3"
2438 "shad %2,%0"
2439 [(set_attr "type" "dyn_shift")])
2440
2441 (define_insn "ashrsi3_n"
2442 [(set (reg:SI R4_REG)
2443 (ashiftrt:SI (reg:SI R4_REG)
2444 (match_operand:SI 0 "const_int_operand" "i")))
2445 (clobber (reg:SI T_REG))
2446 (clobber (reg:SI PR_REG))
2447 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2448 "TARGET_SH1"
2449 "jsr @%1%#"
2450 [(set_attr "type" "sfunc")
2451 (set_attr "needs_delay_slot" "yes")])
2452
2453 (define_insn "ashrsi3_media"
2454 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2455 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2456 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2457 "TARGET_SHMEDIA"
2458 "@
2459 shard.l %1, %2, %0
2460 shari.l %1, %2, %0"
2461 [(set_attr "type" "arith_media")])
2462
2463 (define_expand "ashrsi3"
2464 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2465 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2466 (match_operand:SI 2 "nonmemory_operand" "")))
2467 (clobber (reg:SI T_REG))])]
2468 ""
2469 "
2470 {
2471 if (TARGET_SHMEDIA)
2472 {
2473 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2474 DONE;
2475 }
2476 if (expand_ashiftrt (operands))
2477 DONE;
2478 else
2479 FAIL;
2480 }")
2481
2482 ;; logical shift right
2483
2484 (define_insn "lshrsi3_d"
2485 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2488 "TARGET_SH3"
2489 "shld %2,%0"
2490 [(set_attr "type" "dyn_shift")])
2491
2492 ;; Only the single bit shift clobbers the T bit.
2493
2494 (define_insn "lshrsi3_m"
2495 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2497 (match_operand:SI 2 "const_int_operand" "M")))
2498 (clobber (reg:SI T_REG))]
2499 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2500 "shlr %0"
2501 [(set_attr "type" "arith")])
2502
2503 (define_insn "lshrsi3_k"
2504 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2506 (match_operand:SI 2 "const_int_operand" "P27")))]
2507 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2508 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2509 "shlr%O2 %0"
2510 [(set_attr "type" "arith")])
2511
2512 (define_insn "lshrsi3_n"
2513 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2514 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2515 (match_operand:SI 2 "const_int_operand" "n")))
2516 (clobber (reg:SI T_REG))]
2517 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2518 "#"
2519 [(set (attr "length")
2520 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2521 (const_string "2")
2522 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2523 (const_string "4")
2524 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2525 (const_string "6")]
2526 (const_string "8")))
2527 (set_attr "type" "arith")])
2528
2529 (define_split
2530 [(set (match_operand:SI 0 "arith_reg_operand" "")
2531 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2532 (match_operand:SI 2 "const_int_operand" "")))
2533 (clobber (reg:SI T_REG))]
2534 "TARGET_SH1 && reload_completed"
2535 [(use (reg:SI R0_REG))]
2536 "
2537 {
2538 gen_shifty_op (LSHIFTRT, operands);
2539 DONE;
2540 }")
2541
2542 (define_insn "lshrsi3_media"
2543 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2544 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2545 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2546 "TARGET_SHMEDIA"
2547 "@
2548 shlrd.l %1, %2, %0
2549 shlri.l %1, %2, %0"
2550 [(set_attr "type" "arith_media")])
2551
2552 (define_expand "lshrsi3"
2553 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2554 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2555 (match_operand:SI 2 "nonmemory_operand" "")))
2556 (clobber (reg:SI T_REG))])]
2557 ""
2558 "
2559 {
2560 if (TARGET_SHMEDIA)
2561 {
2562 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2563 DONE;
2564 }
2565 if (GET_CODE (operands[2]) == CONST_INT
2566 && sh_dynamicalize_shift_p (operands[2]))
2567 operands[2] = force_reg (SImode, operands[2]);
2568 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2569 {
2570 rtx count = copy_to_mode_reg (SImode, operands[2]);
2571 emit_insn (gen_negsi2 (count, count));
2572 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2573 DONE;
2574 }
2575 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2576 FAIL;
2577 }")
2578
2579 ;; ??? This should be a define expand.
2580
2581 (define_insn "ashldi3_k"
2582 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2583 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2584 (const_int 1)))
2585 (clobber (reg:SI T_REG))]
2586 "TARGET_SH1"
2587 "shll %R0\;rotcl %S0"
2588 [(set_attr "length" "4")
2589 (set_attr "type" "arith")])
2590
2591 (define_insn "ashldi3_media"
2592 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2593 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2594 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2595 "TARGET_SHMEDIA"
2596 "@
2597 shlld %1, %2, %0
2598 shlli %1, %2, %0"
2599 [(set_attr "type" "arith_media")])
2600
2601 (define_expand "ashldi3"
2602 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2603 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2604 (match_operand:DI 2 "immediate_operand" "")))
2605 (clobber (reg:SI T_REG))])]
2606 ""
2607 "
2608 {
2609 if (TARGET_SHMEDIA)
2610 {
2611 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2612 DONE;
2613 }
2614 if (GET_CODE (operands[2]) != CONST_INT
2615 || INTVAL (operands[2]) != 1)
2616 FAIL;
2617 }")
2618
2619 ;; ??? This should be a define expand.
2620
2621 (define_insn "lshrdi3_k"
2622 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2623 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2624 (const_int 1)))
2625 (clobber (reg:SI T_REG))]
2626 "TARGET_SH1"
2627 "shlr %S0\;rotcr %R0"
2628 [(set_attr "length" "4")
2629 (set_attr "type" "arith")])
2630
2631 (define_insn "lshrdi3_media"
2632 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2633 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2634 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2635 "TARGET_SHMEDIA"
2636 "@
2637 shlrd %1, %2, %0
2638 shlri %1, %2, %0"
2639 [(set_attr "type" "arith_media")])
2640
2641 (define_expand "lshrdi3"
2642 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2643 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2644 (match_operand:DI 2 "immediate_operand" "")))
2645 (clobber (reg:SI T_REG))])]
2646 ""
2647 "
2648 {
2649 if (TARGET_SHMEDIA)
2650 {
2651 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2652 DONE;
2653 }
2654 if (GET_CODE (operands[2]) != CONST_INT
2655 || INTVAL (operands[2]) != 1)
2656 FAIL;
2657 }")
2658
2659 ;; ??? This should be a define expand.
2660
2661 (define_insn "ashrdi3_k"
2662 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2663 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2664 (const_int 1)))
2665 (clobber (reg:SI T_REG))]
2666 "TARGET_SH1"
2667 "shar %S0\;rotcr %R0"
2668 [(set_attr "length" "4")
2669 (set_attr "type" "arith")])
2670
2671 (define_insn "ashrdi3_media"
2672 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2673 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2674 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2675 "TARGET_SHMEDIA"
2676 "@
2677 shard %1, %2, %0
2678 shari %1, %2, %0"
2679 [(set_attr "type" "arith_media")])
2680
2681 (define_expand "ashrdi3"
2682 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2683 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2684 (match_operand:DI 2 "immediate_operand" "")))
2685 (clobber (reg:SI T_REG))])]
2686 ""
2687 "
2688 {
2689 if (TARGET_SHMEDIA)
2690 {
2691 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2692 DONE;
2693 }
2694 if (GET_CODE (operands[2]) != CONST_INT
2695 || INTVAL (operands[2]) != 1)
2696 FAIL;
2697 }")
2698
2699 ;; combined left/right shift
2700
2701 (define_split
2702 [(set (match_operand:SI 0 "register_operand" "")
2703 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2704 (match_operand:SI 2 "const_int_operand" ""))
2705 (match_operand:SI 3 "const_int_operand" "")))]
2706 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2707 [(use (reg:SI R0_REG))]
2708 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2709 DONE;")
2710
2711 (define_split
2712 [(set (match_operand:SI 0 "register_operand" "")
2713 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2714 (match_operand:SI 2 "const_int_operand" ""))
2715 (match_operand:SI 3 "const_int_operand" "")))
2716 (clobber (reg:SI T_REG))]
2717 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2718 [(use (reg:SI R0_REG))]
2719 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2720 DONE;")
2721
2722 (define_insn ""
2723 [(set (match_operand:SI 0 "register_operand" "=r")
2724 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2725 (match_operand:SI 2 "const_int_operand" "n"))
2726 (match_operand:SI 3 "const_int_operand" "n")))
2727 (clobber (reg:SI T_REG))]
2728 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2729 "#"
2730 [(set (attr "length")
2731 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2732 (const_string "4")
2733 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2734 (const_string "6")
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2736 (const_string "8")
2737 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2738 (const_string "10")
2739 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2740 (const_string "12")
2741 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2742 (const_string "14")
2743 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2744 (const_string "16")]
2745 (const_string "18")))
2746 (set_attr "type" "arith")])
2747
2748 (define_insn ""
2749 [(set (match_operand:SI 0 "register_operand" "=z")
2750 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2751 (match_operand:SI 2 "const_int_operand" "n"))
2752 (match_operand:SI 3 "const_int_operand" "n")))
2753 (clobber (reg:SI T_REG))]
2754 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2755 "#"
2756 [(set (attr "length")
2757 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2758 (const_string "4")
2759 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2760 (const_string "6")
2761 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2762 (const_string "8")]
2763 (const_string "10")))
2764 (set_attr "type" "arith")])
2765
2766 ;; shift left / and combination with a scratch register: The combine pass
2767 ;; does not accept the individual instructions, even though they are
2768 ;; cheap. But it needs a precise description so that it is usable after
2769 ;; reload.
2770 (define_insn "and_shl_scratch"
2771 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2772 (lshiftrt:SI
2773 (ashift:SI
2774 (and:SI
2775 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2776 (match_operand:SI 2 "const_int_operand" "N,n"))
2777 (match_operand:SI 3 "" "0,r"))
2778 (match_operand:SI 4 "const_int_operand" "n,n"))
2779 (match_operand:SI 5 "const_int_operand" "n,n")))
2780 (clobber (reg:SI T_REG))]
2781 "TARGET_SH1"
2782 "#"
2783 [(set (attr "length")
2784 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2785 (const_string "4")
2786 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2787 (const_string "6")
2788 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2789 (const_string "8")
2790 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2791 (const_string "10")]
2792 (const_string "12")))
2793 (set_attr "type" "arith")])
2794
2795 (define_split
2796 [(set (match_operand:SI 0 "register_operand" "")
2797 (lshiftrt:SI
2798 (ashift:SI
2799 (and:SI
2800 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2801 (match_operand:SI 2 "const_int_operand" ""))
2802 (match_operand:SI 3 "register_operand" ""))
2803 (match_operand:SI 4 "const_int_operand" ""))
2804 (match_operand:SI 5 "const_int_operand" "")))
2805 (clobber (reg:SI T_REG))]
2806 "TARGET_SH1"
2807 [(use (reg:SI R0_REG))]
2808 "
2809 {
2810 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2811
2812 if (INTVAL (operands[2]))
2813 {
2814 gen_shifty_op (LSHIFTRT, operands);
2815 }
2816 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2817 operands[2] = operands[4];
2818 gen_shifty_op (ASHIFT, operands);
2819 if (INTVAL (operands[5]))
2820 {
2821 operands[2] = operands[5];
2822 gen_shifty_op (LSHIFTRT, operands);
2823 }
2824 DONE;
2825 }")
2826
2827 ;; signed left/right shift combination.
2828 (define_split
2829 [(set (match_operand:SI 0 "register_operand" "")
2830 (sign_extract:SI
2831 (ashift:SI (match_operand:SI 1 "register_operand" "")
2832 (match_operand:SI 2 "const_int_operand" ""))
2833 (match_operand:SI 3 "const_int_operand" "")
2834 (const_int 0)))
2835 (clobber (reg:SI T_REG))]
2836 "TARGET_SH1"
2837 [(use (reg:SI R0_REG))]
2838 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2839 DONE;")
2840
2841 (define_insn "shl_sext_ext"
2842 [(set (match_operand:SI 0 "register_operand" "=r")
2843 (sign_extract:SI
2844 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2845 (match_operand:SI 2 "const_int_operand" "n"))
2846 (match_operand:SI 3 "const_int_operand" "n")
2847 (const_int 0)))
2848 (clobber (reg:SI T_REG))]
2849 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2850 "#"
2851 [(set (attr "length")
2852 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2853 (const_string "2")
2854 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2855 (const_string "4")
2856 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2857 (const_string "6")
2858 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2859 (const_string "8")
2860 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2861 (const_string "10")
2862 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2863 (const_string "12")
2864 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2865 (const_string "14")
2866 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2867 (const_string "16")]
2868 (const_string "18")))
2869 (set_attr "type" "arith")])
2870
2871 (define_insn "shl_sext_sub"
2872 [(set (match_operand:SI 0 "register_operand" "=z")
2873 (sign_extract:SI
2874 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2875 (match_operand:SI 2 "const_int_operand" "n"))
2876 (match_operand:SI 3 "const_int_operand" "n")
2877 (const_int 0)))
2878 (clobber (reg:SI T_REG))]
2879 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2880 "#"
2881 [(set (attr "length")
2882 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2883 (const_string "6")
2884 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2885 (const_string "8")
2886 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2887 (const_string "10")
2888 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2889 (const_string "12")]
2890 (const_string "14")))
2891 (set_attr "type" "arith")])
2892
2893 ;; These patterns are found in expansions of DImode shifts by 16, and
2894 ;; allow the xtrct instruction to be generated from C source.
2895
2896 (define_insn "xtrct_left"
2897 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2899 (const_int 16))
2900 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2901 (const_int 16))))]
2902 "TARGET_SH1"
2903 "xtrct %1,%0"
2904 [(set_attr "type" "arith")])
2905
2906 (define_insn "xtrct_right"
2907 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2908 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2909 (const_int 16))
2910 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2911 (const_int 16))))]
2912 "TARGET_SH1"
2913 "xtrct %2,%0"
2914 [(set_attr "type" "arith")])
2915
2916 ;; -------------------------------------------------------------------------
2917 ;; Unary arithmetic
2918 ;; -------------------------------------------------------------------------
2919
2920 (define_insn "negc"
2921 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2922 (neg:SI (plus:SI (reg:SI T_REG)
2923 (match_operand:SI 1 "arith_reg_operand" "r"))))
2924 (set (reg:SI T_REG)
2925 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2926 (const_int 0)))]
2927 "TARGET_SH1"
2928 "negc %1,%0"
2929 [(set_attr "type" "arith")])
2930
2931 (define_insn "*negdi_media"
2932 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2933 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2934 "TARGET_SHMEDIA"
2935 "sub r63, %1, %0"
2936 [(set_attr "type" "arith_media")])
2937
2938 (define_expand "negdi2"
2939 [(set (match_operand:DI 0 "arith_reg_operand" "")
2940 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2941 ""
2942 "
2943 {
2944 if (TARGET_SH1)
2945 {
2946 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2947 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2948
2949 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2950 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2951
2952 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2953 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2954
2955 emit_insn (gen_clrt ());
2956 emit_insn (gen_negc (low_dst, low_src));
2957 emit_insn (gen_negc (high_dst, high_src));
2958 DONE;
2959 }
2960 }")
2961
2962 (define_insn "negsi2"
2963 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2964 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2965 "TARGET_SH1"
2966 "neg %1,%0"
2967 [(set_attr "type" "arith")])
2968
2969 (define_insn "one_cmplsi2"
2970 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2971 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2972 "TARGET_SH1"
2973 "not %1,%0"
2974 [(set_attr "type" "arith")])
2975
2976 (define_expand "one_cmpldi2"
2977 [(set (match_operand:DI 0 "arith_reg_operand" "")
2978 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2979 (const_int -1)))]
2980 "TARGET_SHMEDIA" "")
2981 \f
2982 ;; -------------------------------------------------------------------------
2983 ;; Zero extension instructions
2984 ;; -------------------------------------------------------------------------
2985
2986 (define_insn "zero_extendsidi2"
2987 [(set (match_operand:DI 0 "register_operand" "=r")
2988 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2989 "TARGET_SHMEDIA"
2990 "addz.l %1, r63, %0"
2991 [(set_attr "type" "arith_media")])
2992
2993 (define_insn "zero_extendhidi2"
2994 [(set (match_operand:DI 0 "register_operand" "=r,r")
2995 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2996 "TARGET_SHMEDIA"
2997 "@
2998 #
2999 ld%M1.uw %m1, %0"
3000 [(set_attr "type" "*,load_media")])
3001
3002 (define_split
3003 [(set (match_operand:DI 0 "register_operand" "")
3004 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3005 "TARGET_SHMEDIA && reload_completed"
3006 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3007 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3008 "
3009 {
3010 if (GET_CODE (operands[1]) == TRUNCATE)
3011 operands[1] = XEXP (operands[1], 0);
3012 }")
3013
3014 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3015 ;; reload the entire truncate expression.
3016 (define_insn_and_split "*loaddi_trunc"
3017 [(set (match_operand 0 "int_gpr_dest" "=r")
3018 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3019 "TARGET_SHMEDIA && reload_completed"
3020 "#"
3021 "TARGET_SHMEDIA && reload_completed"
3022 [(set (match_dup 0) (match_dup 1))]
3023 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3024
3025 (define_insn "zero_extendqidi2"
3026 [(set (match_operand:DI 0 "register_operand" "=r,r")
3027 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3028 "TARGET_SHMEDIA"
3029 "@
3030 andi %1, 255, %0
3031 ld%M1.ub %m1, %0"
3032 [(set_attr "type" "arith_media,load_media")])
3033
3034 (define_expand "zero_extendhisi2"
3035 [(set (match_operand:SI 0 "arith_reg_operand" "")
3036 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3037 ""
3038 "
3039 {
3040 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3041 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3042 }")
3043
3044 (define_insn "*zero_extendhisi2_compact"
3045 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3046 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3047 "TARGET_SH1"
3048 "extu.w %1,%0"
3049 [(set_attr "type" "arith")])
3050
3051 (define_insn "*zero_extendhisi2_media"
3052 [(set (match_operand:SI 0 "register_operand" "=r,r")
3053 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3054 "TARGET_SHMEDIA"
3055 "@
3056 #
3057 ld%M1.uw %m1, %0"
3058 [(set_attr "type" "arith_media,load_media")])
3059
3060 (define_split
3061 [(set (match_operand:SI 0 "register_operand" "")
3062 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3063 "TARGET_SHMEDIA && reload_completed"
3064 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3065 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3066 "
3067 {
3068 if (GET_CODE (operands[1]) == TRUNCATE)
3069 operands[1] = XEXP (operands[1], 0);
3070 }")
3071
3072 (define_expand "zero_extendqisi2"
3073 [(set (match_operand:SI 0 "arith_reg_operand" "")
3074 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3075 ""
3076 "
3077 {
3078 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3079 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3080 }")
3081
3082 (define_insn "*zero_extendqisi2_compact"
3083 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3084 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3085 "TARGET_SH1"
3086 "extu.b %1,%0"
3087 [(set_attr "type" "arith")])
3088
3089 (define_insn "*zero_extendqisi2_media"
3090 [(set (match_operand:SI 0 "register_operand" "=r,r")
3091 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3092 "TARGET_SHMEDIA"
3093 "@
3094 andi %1, 255, %0
3095 ld%M1.ub %m1, %0"
3096 [(set_attr "type" "arith_media,load_media")])
3097
3098 (define_insn "zero_extendqihi2"
3099 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3100 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3101 "TARGET_SH1"
3102 "extu.b %1,%0"
3103 [(set_attr "type" "arith")])
3104
3105 ;; -------------------------------------------------------------------------
3106 ;; Sign extension instructions
3107 ;; -------------------------------------------------------------------------
3108
3109 ;; ??? This should be a define expand.
3110 ;; ??? Or perhaps it should be dropped?
3111
3112 ;; convert_move generates good code for SH[1-4].
3113 (define_insn "extendsidi2"
3114 [(set (match_operand:DI 0 "register_operand" "=r,r")
3115 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3116 "TARGET_SHMEDIA"
3117 "@
3118 add.l %1, r63, %0
3119 ld%M1.l %m1, %0"
3120 [(set_attr "type" "arith_media,load_media")])
3121
3122 (define_insn "extendhidi2"
3123 [(set (match_operand:DI 0 "register_operand" "=r,r")
3124 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3125 "TARGET_SHMEDIA"
3126 "@
3127 #
3128 ld%M1.w %m1, %0"
3129 [(set_attr "type" "*,load_media")])
3130
3131 (define_split
3132 [(set (match_operand:DI 0 "register_operand" "")
3133 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3134 "TARGET_SHMEDIA && reload_completed"
3135 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3136 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3137 "
3138 {
3139 if (GET_CODE (operands[1]) == TRUNCATE)
3140 operands[1] = XEXP (operands[1], 0);
3141 }")
3142
3143 (define_insn "extendqidi2"
3144 [(set (match_operand:DI 0 "register_operand" "=r,r")
3145 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3146 "TARGET_SHMEDIA"
3147 "@
3148 #
3149 ld%M1.b %m1, %0"
3150 [(set_attr "type" "*,load_media")])
3151
3152 (define_split
3153 [(set (match_operand:DI 0 "register_operand" "")
3154 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3155 "TARGET_SHMEDIA && reload_completed"
3156 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3157 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3158 "
3159 {
3160 if (GET_CODE (operands[1]) == TRUNCATE)
3161 operands[1] = XEXP (operands[1], 0);
3162 }")
3163
3164 (define_expand "extendhisi2"
3165 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3166 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3167 ""
3168 "")
3169
3170 (define_insn "*extendhisi2_compact"
3171 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3172 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3173 "TARGET_SH1"
3174 "@
3175 exts.w %1,%0
3176 mov.w %1,%0"
3177 [(set_attr "type" "arith,load")])
3178
3179 (define_insn "*extendhisi2_media"
3180 [(set (match_operand:SI 0 "register_operand" "=r,r")
3181 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3182 "TARGET_SHMEDIA"
3183 "@
3184 #
3185 ld%M1.w %m1, %0"
3186 [(set_attr "type" "arith_media,load_media")])
3187
3188 (define_split
3189 [(set (match_operand:SI 0 "register_operand" "")
3190 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3191 "TARGET_SHMEDIA && reload_completed"
3192 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3193 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3194 "
3195 {
3196 if (GET_CODE (operands[1]) == TRUNCATE)
3197 operands[1] = XEXP (operands[1], 0);
3198 }")
3199
3200 (define_expand "extendqisi2"
3201 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3202 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3203 ""
3204 "")
3205
3206 (define_insn "*extendqisi2_compact"
3207 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3208 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3209 "TARGET_SH1"
3210 "@
3211 exts.b %1,%0
3212 mov.b %1,%0"
3213 [(set_attr "type" "arith,load")])
3214
3215 (define_insn "*extendqisi2_media"
3216 [(set (match_operand:SI 0 "register_operand" "=r,r")
3217 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3218 "TARGET_SHMEDIA"
3219 "@
3220 #
3221 ld%M1.b %m1, %0"
3222 [(set_attr "type" "arith_media,load_media")])
3223
3224 (define_split
3225 [(set (match_operand:SI 0 "register_operand" "")
3226 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3227 "TARGET_SHMEDIA && reload_completed"
3228 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3229 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3230 "
3231 {
3232 if (GET_CODE (operands[1]) == TRUNCATE)
3233 operands[1] = XEXP (operands[1], 0);
3234 }")
3235
3236 (define_insn "extendqihi2"
3237 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3238 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3239 "TARGET_SH1"
3240 "@
3241 exts.b %1,%0
3242 mov.b %1,%0"
3243 [(set_attr "type" "arith,load")])
3244
3245 /* It would seem useful to combine the truncXi patterns into the movXi
3246 patterns, but unary operators are ignored when matching constraints,
3247 so we need separate patterns. */
3248 (define_insn "truncdisi2"
3249 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3250 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3251 "TARGET_SHMEDIA"
3252 "@
3253 add.l %1, r63, %0
3254 st%M0.l %m0, %1
3255 fst%M0.s %m0, %T1
3256 fmov.ls %1, %0
3257 fmov.sl %T1, %0
3258 fmov.s %T1, %0"
3259 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3260
3261
3262 (define_insn "truncdihi2"
3263 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3264 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3265 "TARGET_SHMEDIA"
3266 "@
3267 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3268 st%M0.w %m0, %1"
3269 [(set_attr "type" "arith_media,store_media")
3270 (set_attr "length" "8,4")])
3271
3272 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3273 ; Because we use zero extension, we can't provide signed QImode compares
3274 ; using a simple compare or conditional banch insn.
3275 (define_insn "truncdiqi2"
3276 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3277 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3278 "TARGET_SHMEDIA"
3279 "@
3280 andi %1, 255, %0
3281 st%M0.b %m0, %1"
3282 [(set_attr "type" "arith_media,store")])
3283
3284 ;; -------------------------------------------------------------------------
3285 ;; Move instructions
3286 ;; -------------------------------------------------------------------------
3287
3288 ;; define push and pop so it is easy for sh.c
3289 ;; We can't use push and pop on SHcompact because the stack must always
3290 ;; be 8-byte aligned.
3291
3292 (define_expand "push"
3293 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3294 (match_operand:SI 0 "register_operand" "r,l,x"))]
3295 "TARGET_SH1 && ! TARGET_SH5"
3296 "")
3297
3298 (define_expand "pop"
3299 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3300 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3301 "TARGET_SH1 && ! TARGET_SH5"
3302 "")
3303
3304 (define_expand "push_e"
3305 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3306 (match_operand:SF 0 "" ""))
3307 (use (reg:PSI FPSCR_REG))
3308 (clobber (scratch:SI))])]
3309 "TARGET_SH1 && ! TARGET_SH5"
3310 "")
3311
3312 (define_insn "push_fpul"
3313 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3314 "TARGET_SH2E && ! TARGET_SH5"
3315 "sts.l fpul,@-r15"
3316 [(set_attr "type" "store")
3317 (set_attr "late_fp_use" "yes")
3318 (set_attr "hit_stack" "yes")])
3319
3320 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3321 ;; so use that.
3322 (define_expand "push_4"
3323 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3324 (match_operand:DF 0 "" ""))
3325 (use (reg:PSI FPSCR_REG))
3326 (clobber (scratch:SI))])]
3327 "TARGET_SH1 && ! TARGET_SH5"
3328 "")
3329
3330 (define_expand "pop_e"
3331 [(parallel [(set (match_operand:SF 0 "" "")
3332 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3333 (use (reg:PSI FPSCR_REG))
3334 (clobber (scratch:SI))])]
3335 "TARGET_SH1 && ! TARGET_SH5"
3336 "")
3337
3338 (define_insn "pop_fpul"
3339 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3340 "TARGET_SH2E && ! TARGET_SH5"
3341 "lds.l @r15+,fpul"
3342 [(set_attr "type" "load")
3343 (set_attr "hit_stack" "yes")])
3344
3345 (define_expand "pop_4"
3346 [(parallel [(set (match_operand:DF 0 "" "")
3347 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3348 (use (reg:PSI FPSCR_REG))
3349 (clobber (scratch:SI))])]
3350 "TARGET_SH1 && ! TARGET_SH5"
3351 "")
3352
3353 (define_expand "push_fpscr"
3354 [(const_int 0)]
3355 "TARGET_SH2E"
3356 "
3357 {
3358 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3359 gen_rtx (PRE_DEC, Pmode,
3360 stack_pointer_rtx)),
3361 get_fpscr_rtx ()));
3362 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3363 DONE;
3364 }")
3365
3366 (define_expand "pop_fpscr"
3367 [(const_int 0)]
3368 "TARGET_SH2E"
3369 "
3370 {
3371 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3372 gen_rtx (MEM, PSImode,
3373 gen_rtx (POST_INC, Pmode,
3374 stack_pointer_rtx))));
3375 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3376 DONE;
3377 }")
3378
3379 ;; These two patterns can happen as the result of optimization, when
3380 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3381 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3382
3383 (define_insn "clrt"
3384 [(set (reg:SI T_REG) (const_int 0))]
3385 "TARGET_SH1"
3386 "clrt")
3387
3388 (define_insn "sett"
3389 [(set (reg:SI T_REG) (const_int 1))]
3390 "TARGET_SH1"
3391 "sett")
3392
3393 ;; t/r must come after r/r, lest reload will try to reload stuff like
3394 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3395 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3396 (define_insn "movsi_i"
3397 [(set (match_operand:SI 0 "general_movdst_operand"
3398 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3399 (match_operand:SI 1 "general_movsrc_operand"
3400 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3401 "TARGET_SH1
3402 && ! TARGET_SH2E
3403 && (register_operand (operands[0], SImode)
3404 || register_operand (operands[1], SImode))"
3405 "@
3406 mov.l %1,%0
3407 mov %1,%0
3408 cmp/pl %1
3409 mov.l %1,%0
3410 sts %1,%0
3411 sts %1,%0
3412 movt %0
3413 mov.l %1,%0
3414 sts.l %1,%0
3415 sts.l %1,%0
3416 lds %1,%0
3417 lds %1,%0
3418 lds.l %1,%0
3419 lds.l %1,%0
3420 fake %1,%0"
3421 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3422 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3423
3424 ;; t/r must come after r/r, lest reload will try to reload stuff like
3425 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3426 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3427 ;; will require a reload.
3428 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3429 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3430 (define_insn "movsi_ie"
3431 [(set (match_operand:SI 0 "general_movdst_operand"
3432 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3433 (match_operand:SI 1 "general_movsrc_operand"
3434 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3435 "TARGET_SH2E
3436 && (register_operand (operands[0], SImode)
3437 || register_operand (operands[1], SImode))"
3438 "@
3439 mov.l %1,%0
3440 mov %1,%0
3441 cmp/pl %1
3442 mov.l %1,%0
3443 sts %1,%0
3444 sts %1,%0
3445 movt %0
3446 mov.l %1,%0
3447 sts.l %1,%0
3448 sts.l %1,%0
3449 lds %1,%0
3450 lds %1,%0
3451 lds.l %1,%0
3452 lds.l %1,%0
3453 lds.l %1,%0
3454 sts.l %1,%0
3455 fake %1,%0
3456 lds %1,%0
3457 sts %1,%0
3458 fsts fpul,%0
3459 flds %1,fpul
3460 fmov %1,%0
3461 ! move optimized away"
3462 [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3463 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3464 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3465
3466 (define_insn "movsi_i_lowpart"
3467 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3468 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3469 "TARGET_SH1
3470 && (register_operand (operands[0], SImode)
3471 || register_operand (operands[1], SImode))"
3472 "@
3473 mov.l %1,%0
3474 mov %1,%0
3475 mov.l %1,%0
3476 sts %1,%0
3477 sts %1,%0
3478 movt %0
3479 mov.l %1,%0
3480 fake %1,%0"
3481 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3482
3483 (define_insn_and_split "load_ra"
3484 [(set (match_operand:SI 0 "general_movdst_operand" "")
3485 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3486 "TARGET_SH1"
3487 "#"
3488 "&& ! rtx_equal_function_value_matters"
3489 [(set (match_dup 0) (match_dup 1))]
3490 "
3491 {
3492 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3493 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3494 }")
3495
3496 (define_insn "*movsi_media"
3497 [(set (match_operand:SI 0 "general_movdst_operand"
3498 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3499 (match_operand:SI 1 "general_movsrc_operand"
3500 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3501 "TARGET_SHMEDIA_FPU
3502 && (register_operand (operands[0], SImode)
3503 || sh_register_operand (operands[1], SImode))"
3504 "@
3505 add.l %1, r63, %0
3506 movi %1, %0
3507 #
3508 ld%M1.l %m1, %0
3509 st%M0.l %m0, %N1
3510 fld%M1.s %m1, %0
3511 fst%M0.s %m0, %1
3512 fmov.ls %N1, %0
3513 fmov.sl %1, %0
3514 fmov.s %1, %0
3515 ptabs %1, %0
3516 gettr %1, %0
3517 pt %1, %0"
3518 [(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")
3519 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3520
3521 (define_insn "*movsi_media_nofpu"
3522 [(set (match_operand:SI 0 "general_movdst_operand"
3523 "=r,r,r,r,m,*b,r,b")
3524 (match_operand:SI 1 "general_movsrc_operand"
3525 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3526 "TARGET_SHMEDIA
3527 && (register_operand (operands[0], SImode)
3528 || sh_register_operand (operands[1], SImode))"
3529 "@
3530 add.l %1, r63, %0
3531 movi %1, %0
3532 #
3533 ld%M1.l %m1, %0
3534 st%M0.l %m0, %N1
3535 ptabs %1, %0
3536 gettr %1, %0
3537 pt %1, %0"
3538 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3539 (set_attr "length" "4,4,8,4,4,4,4,12")])
3540
3541 (define_split
3542 [(set (match_operand:SI 0 "arith_reg_operand" "")
3543 (match_operand:SI 1 "immediate_operand" ""))]
3544 "TARGET_SHMEDIA && reload_completed
3545 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3546 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3547 "
3548 {
3549 operands[2] = shallow_copy_rtx (operands[1]);
3550 PUT_MODE (operands[2], DImode);
3551 }")
3552
3553 (define_split
3554 [(set (match_operand:SI 0 "register_operand" "")
3555 (match_operand:SI 1 "immediate_operand" ""))]
3556 "TARGET_SHMEDIA && reload_completed
3557 && ((GET_CODE (operands[1]) == CONST_INT
3558 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3559 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3560 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3561
3562 (define_expand "movsi"
3563 [(set (match_operand:SI 0 "general_movdst_operand" "")
3564 (match_operand:SI 1 "general_movsrc_operand" ""))]
3565 ""
3566 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3567
3568 (define_expand "ic_invalidate_line"
3569 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3570 (match_dup 1)] UNSPEC_ICACHE)
3571 (clobber (scratch:SI))])]
3572 "TARGET_HARD_SH4 || TARGET_SH5"
3573 "
3574 {
3575 if (TARGET_SHMEDIA)
3576 {
3577 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3578 DONE;
3579 }
3580 else if (TARGET_SHCOMPACT)
3581 {
3582 operands[1] = function_symbol (\"__ic_invalidate\");
3583 operands[1] = force_reg (Pmode, operands[1]);
3584 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3585 DONE;
3586 }
3587 operands[0] = force_reg (Pmode, operands[0]);
3588 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3589 Pmode)));
3590 }")
3591
3592 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3593 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3594 ;; the requirement *1*00 for associative address writes. The alignment of
3595 ;; %0 implies that its least significant bit is cleared,
3596 ;; thus we clear the V bit of a matching entry if there is one.
3597 (define_insn "ic_invalidate_line_i"
3598 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3599 (match_operand:SI 1 "register_operand" "r")]
3600 UNSPEC_ICACHE)
3601 (clobber (match_scratch:SI 2 "=&r"))]
3602 "TARGET_HARD_SH4"
3603 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3604 [(set_attr "length" "8")
3605 (set_attr "type" "cwb")])
3606
3607 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3608 ;; an add in the code that calculates the address.
3609 (define_insn "ic_invalidate_line_media"
3610 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3611 UNSPEC_ICACHE)]
3612 "TARGET_SHMEDIA"
3613 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3614 [(set_attr "length" "16")
3615 (set_attr "type" "invalidate_line_media")])
3616
3617 (define_insn "ic_invalidate_line_compact"
3618 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3619 (match_operand:SI 1 "register_operand" "r")]
3620 UNSPEC_ICACHE)
3621 (clobber (reg:SI PR_REG))]
3622 "TARGET_SHCOMPACT"
3623 "jsr @%1%#"
3624 [(set_attr "type" "sfunc")
3625 (set_attr "needs_delay_slot" "yes")])
3626
3627 (define_expand "initialize_trampoline"
3628 [(match_operand:SI 0 "" "")
3629 (match_operand:SI 1 "" "")
3630 (match_operand:SI 2 "" "")]
3631 "TARGET_SHCOMPACT"
3632 "
3633 {
3634 rtx sfun, tramp;
3635
3636 tramp = force_reg (Pmode, operands[0]);
3637 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3638 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3639 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3640
3641 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3642 DONE;
3643 }")
3644
3645 (define_insn "initialize_trampoline_compact"
3646 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3647 (match_operand:SI 1 "register_operand" "r")
3648 (reg:SI R2_REG) (reg:SI R3_REG)]
3649 UNSPEC_INIT_TRAMP)
3650
3651 (clobber (reg:SI PR_REG))]
3652 "TARGET_SHCOMPACT"
3653 "jsr @%1%#"
3654 [(set_attr "type" "sfunc")
3655 (set_attr "needs_delay_slot" "yes")])
3656
3657 (define_insn "movqi_i"
3658 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3659 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3660 "TARGET_SH1
3661 && (arith_reg_operand (operands[0], QImode)
3662 || arith_reg_operand (operands[1], QImode))"
3663 "@
3664 mov %1,%0
3665 mov.b %1,%0
3666 mov.b %1,%0
3667 movt %0
3668 sts %1,%0
3669 lds %1,%0"
3670 [(set_attr "type" "move,load,store,move,move,move")])
3671
3672 (define_insn "*movqi_media"
3673 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3674 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3675 "TARGET_SHMEDIA
3676 && (arith_reg_operand (operands[0], QImode)
3677 || arith_reg_or_0_operand (operands[1], QImode))"
3678 "@
3679 add.l %1, r63, %0
3680 movi %1, %0
3681 ld%M1.ub %m1, %0
3682 st%M0.b %m0, %N1"
3683 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3684
3685 (define_expand "movqi"
3686 [(set (match_operand:QI 0 "general_operand" "")
3687 (match_operand:QI 1 "general_operand" ""))]
3688 ""
3689 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3690
3691 (define_expand "reload_inqi"
3692 [(set (match_operand:SI 2 "" "=&r")
3693 (match_operand:QI 1 "inqhi_operand" ""))
3694 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3695 (truncate:QI (match_dup 3)))]
3696 "TARGET_SHMEDIA"
3697 "
3698 {
3699 rtx inner = XEXP (operands[1], 0);
3700 int regno = REGNO (inner);
3701
3702 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3703 operands[1] = gen_rtx_REG (SImode, regno);
3704 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3705 }")
3706
3707 /* When storing r0, we have to avoid reg+reg addressing. */
3708 (define_insn "movhi_i"
3709 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3710 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3711 "TARGET_SH1
3712 && (arith_reg_operand (operands[0], HImode)
3713 || arith_reg_operand (operands[1], HImode))
3714 && (GET_CODE (operands[0]) != MEM
3715 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3716 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3717 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3718 "@
3719 mov.w %1,%0
3720 mov %1,%0
3721 mov.w %1,%0
3722 movt %0
3723 mov.w %1,%0
3724 sts %1,%0
3725 lds %1,%0
3726 fake %1,%0"
3727 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3728
3729 (define_insn "*movhi_media"
3730 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3731 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3732 "TARGET_SHMEDIA
3733 && (arith_reg_operand (operands[0], HImode)
3734 || arith_reg_or_0_operand (operands[1], HImode))"
3735 "@
3736 add.l %1, r63, %0
3737 movi %1, %0
3738 #
3739 ld%M1.w %m1, %0
3740 st%M0.w %m0, %N1"
3741 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3742
3743 (define_split
3744 [(set (match_operand:HI 0 "register_operand" "")
3745 (match_operand:HI 1 "immediate_operand" ""))]
3746 "TARGET_SHMEDIA && reload_completed
3747 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3748 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3749
3750 (define_expand "movhi"
3751 [(set (match_operand:HI 0 "general_movdst_operand" "")
3752 (match_operand:HI 1 "general_movsrc_operand" ""))]
3753 ""
3754 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3755
3756 (define_expand "reload_inhi"
3757 [(set (match_operand:SI 2 "" "=&r")
3758 (match_operand:HI 1 "inqhi_operand" ""))
3759 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3760 (truncate:HI (match_dup 3)))]
3761 "TARGET_SHMEDIA"
3762 "
3763 {
3764 rtx inner = XEXP (operands[1], 0);
3765 int regno = REGNO (inner);
3766
3767 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3768 operands[1] = gen_rtx_REG (SImode, regno);
3769 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3770 }")
3771
3772 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3773 ;; compiled with -m2 -ml -O3 -funroll-loops
3774 (define_insn "*movdi_i"
3775 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3776 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3777 "TARGET_SH1
3778 && (arith_reg_operand (operands[0], DImode)
3779 || arith_reg_operand (operands[1], DImode))"
3780 "* return output_movedouble (insn, operands, DImode);"
3781 [(set_attr "length" "4")
3782 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3783
3784 ;; If the output is a register and the input is memory or a register, we have
3785 ;; to be careful and see which word needs to be loaded first.
3786
3787 (define_split
3788 [(set (match_operand:DI 0 "general_movdst_operand" "")
3789 (match_operand:DI 1 "general_movsrc_operand" ""))]
3790 "TARGET_SH1 && reload_completed"
3791 [(set (match_dup 2) (match_dup 3))
3792 (set (match_dup 4) (match_dup 5))]
3793 "
3794 {
3795 int regno;
3796
3797 if ((GET_CODE (operands[0]) == MEM
3798 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3799 || (GET_CODE (operands[1]) == MEM
3800 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3801 FAIL;
3802
3803 if (GET_CODE (operands[0]) == REG)
3804 regno = REGNO (operands[0]);
3805 else if (GET_CODE (operands[0]) == SUBREG)
3806 regno = subreg_regno (operands[0]);
3807 else if (GET_CODE (operands[0]) == MEM)
3808 regno = -1;
3809 else
3810 abort ();
3811
3812 if (regno == -1
3813 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3814 {
3815 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3816 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3817 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3818 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3819 }
3820 else
3821 {
3822 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3823 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3824 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3825 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3826 }
3827
3828 if (operands[2] == 0 || operands[3] == 0
3829 || operands[4] == 0 || operands[5] == 0)
3830 FAIL;
3831 }")
3832
3833 (define_insn "*movdi_media"
3834 [(set (match_operand:DI 0 "general_movdst_operand"
3835 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3836 (match_operand:DI 1 "general_movsrc_operand"
3837 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3838 "TARGET_SHMEDIA_FPU
3839 && (register_operand (operands[0], DImode)
3840 || sh_register_operand (operands[1], DImode))"
3841 "@
3842 add %1, r63, %0
3843 movi %1, %0
3844 #
3845 ld%M1.q %m1, %0
3846 st%M0.q %m0, %N1
3847 fld%M1.d %m1, %0
3848 fst%M0.d %m0, %1
3849 fmov.qd %N1, %0
3850 fmov.dq %1, %0
3851 fmov.d %1, %0
3852 ptabs %1, %0
3853 gettr %1, %0
3854 pt %1, %0"
3855 [(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")
3856 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3857
3858 (define_insn "*movdi_media_nofpu"
3859 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3860 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3861 "TARGET_SHMEDIA
3862 && (register_operand (operands[0], DImode)
3863 || sh_register_operand (operands[1], DImode))"
3864 "@
3865 add %1, r63, %0
3866 movi %1, %0
3867 #
3868 ld%M1.q %m1, %0
3869 st%M0.q %m0, %N1
3870 ptabs %1, %0
3871 gettr %1, %0
3872 pt %1, %0"
3873 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3874 (set_attr "length" "4,4,16,4,4,4,4,*")])
3875
3876 (define_split
3877 [(set (match_operand:DI 0 "arith_reg_operand" "")
3878 (match_operand:DI 1 "immediate_operand" ""))]
3879 "TARGET_SHMEDIA && reload_completed
3880 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3881 [(set (match_dup 0) (match_dup 1))]
3882 "
3883 {
3884 rtx insn;
3885
3886 if (TARGET_SHMEDIA64)
3887 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3888 else
3889 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3890
3891 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3892 REG_NOTES (insn));
3893
3894 DONE;
3895 }")
3896
3897 (define_expand "movdi_const"
3898 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3899 (const:DI (sign_extend:DI
3900 (truncate:HI
3901 (ashiftrt:DI
3902 (match_operand:DI 1 "immediate_operand" "s")
3903 (const_int 48))))))
3904 (set (match_dup 0)
3905 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3906 (zero_extend:DI
3907 (truncate:HI
3908 (const:DI
3909 (sign_extend:DI
3910 (truncate:HI
3911 (ashiftrt:SI
3912 (match_dup 1)
3913 (const_int 32)))))))))
3914 (set (match_dup 0)
3915 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3916 (zero_extend:DI
3917 (truncate:HI
3918 (const:DI
3919 (sign_extend:DI
3920 (truncate:HI
3921 (ashiftrt:SI
3922 (match_dup 1)
3923 (const_int 16)))))))))
3924 (set (match_dup 0)
3925 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3926 (zero_extend:DI
3927 (truncate:HI
3928 (const:DI
3929 (sign_extend:DI
3930 (truncate:HI
3931 (match_dup 1))))))))]
3932 "TARGET_SHMEDIA64 && reload_completed
3933 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3934 "
3935 {
3936 sh_mark_label (operands[1], 4);
3937 }")
3938
3939 (define_expand "movdi_const_32bit"
3940 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3941 (const:DI (sign_extend:DI
3942 (truncate:HI
3943 (ashiftrt:DI
3944 (match_operand:DI 1 "immediate_operand" "s")
3945 (const_int 16))))))
3946 (set (match_dup 0)
3947 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3948 (zero_extend:DI
3949 (truncate:HI
3950 (const:DI
3951 (sign_extend:DI
3952 (truncate:HI
3953 (match_dup 1))))))))]
3954 "TARGET_SHMEDIA32 && reload_completed
3955 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3956 "
3957 {
3958 sh_mark_label (operands[1], 2);
3959 }")
3960
3961 (define_expand "movdi_const_16bit"
3962 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3963 (const:DI (sign_extend:DI
3964 (truncate:HI
3965 (match_operand:DI 1 "immediate_operand" "s")))))]
3966 "TARGET_SHMEDIA && flag_pic && reload_completed
3967 && GET_CODE (operands[1]) == SYMBOL_REF"
3968 "")
3969
3970 (define_split
3971 [(set (match_operand:DI 0 "arith_reg_operand" "")
3972 (match_operand:DI 1 "immediate_operand" ""))]
3973 "TARGET_SHMEDIA && reload_completed
3974 && GET_CODE (operands[1]) == CONST_INT
3975 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3976 [(set (match_dup 0) (match_dup 2))
3977 (match_dup 1)]
3978 "
3979 {
3980 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3981 unsigned HOST_WIDE_INT low = val;
3982 unsigned HOST_WIDE_INT high = val;
3983 unsigned HOST_WIDE_INT sign;
3984 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3985
3986 /* Sign-extend the 16 least-significant bits. */
3987 low &= 0xffff;
3988 low ^= 0x8000;
3989 low -= 0x8000;
3990
3991 /* Arithmetic shift right the word by 16 bits. */
3992 high >>= 16;
3993 sign = 1;
3994 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3995 high ^= sign;
3996 high -= sign;
3997 do
3998 {
3999 /* If we can't generate the constant with a two-insn movi / shori
4000 sequence, try some other strategies. */
4001 if (! CONST_OK_FOR_I16 (high))
4002 {
4003 /* Try constant load / left shift. We know VAL != 0. */
4004 val2 = val ^ (val-1);
4005 if (val2 > 0x1ffff)
4006 {
4007 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4008
4009 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4010 || (! CONST_OK_FOR_I16 (high >> 16)
4011 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4012 {
4013 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4014 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4015 GEN_INT (trailing_zeroes));
4016 break;
4017 }
4018 }
4019 /* Try constant load / right shift. */
4020 val2 = (val >> 15) + 1;
4021 if (val2 == (val2 & -val2))
4022 {
4023 int shift = 49 - exact_log2 (val2);
4024
4025 val2 = trunc_int_for_mode (val << shift, DImode);
4026 if (CONST_OK_FOR_I16 (val2))
4027 {
4028 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4029 GEN_INT (shift));
4030 break;
4031 }
4032 }
4033 /* Try mperm.w . */
4034 val2 = val & 0xffff;
4035 if ((val >> 16 & 0xffff) == val2
4036 && (val >> 32 & 0xffff) == val2
4037 && (val >> 48 & 0xffff) == val2)
4038 {
4039 val2 = (HOST_WIDE_INT) val >> 48;
4040 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4041 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4042 break;
4043 }
4044 /* Try movi / mshflo.l */
4045 val2 = (HOST_WIDE_INT) val >> 32;
4046 if (val2 == trunc_int_for_mode (val, SImode))
4047 {
4048 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4049 operands[0]);
4050 break;
4051 }
4052 /* Try movi / mshflo.l w/ r63. */
4053 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4054 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4055 {
4056 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4057 GEN_INT (0));
4058 break;
4059 }
4060 }
4061 val2 = high;
4062 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4063 }
4064 while (0);
4065 operands[2] = GEN_INT (val2);
4066 }")
4067
4068 (define_split
4069 [(set (match_operand:DI 0 "arith_reg_operand" "")
4070 (match_operand:DI 1 "immediate_operand" ""))]
4071 "TARGET_SHMEDIA && reload_completed
4072 && GET_CODE (operands[1]) == CONST_DOUBLE"
4073 [(set (match_dup 0) (match_dup 2))
4074 (set (match_dup 0)
4075 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4076 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4077 "
4078 {
4079 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4080 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4081 unsigned HOST_WIDE_INT val = low;
4082 unsigned HOST_WIDE_INT sign;
4083
4084 /* Sign-extend the 16 least-significant bits. */
4085 val &= 0xffff;
4086 val ^= 0x8000;
4087 val -= 0x8000;
4088 operands[1] = GEN_INT (val);
4089
4090 /* Arithmetic shift right the double-word by 16 bits. */
4091 low >>= 16;
4092 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4093 high >>= 16;
4094 sign = 1;
4095 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4096 high ^= sign;
4097 high -= sign;
4098
4099 /* This will only be true if high is a sign-extension of low, i.e.,
4100 it must be either 0 or (unsigned)-1, and be zero iff the
4101 most-significant bit of low is set. */
4102 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4103 operands[2] = GEN_INT (low);
4104 else
4105 operands[2] = immed_double_const (low, high, DImode);
4106 }")
4107
4108 (define_insn "shori_media"
4109 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4110 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4111 (const_int 16))
4112 (zero_extend:DI
4113 (truncate:HI
4114 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4115 "TARGET_SHMEDIA"
4116 "@
4117 shori %u2, %0
4118 #"
4119 [(set_attr "type" "arith_media,*")])
4120
4121 (define_expand "movdi"
4122 [(set (match_operand:DI 0 "general_movdst_operand" "")
4123 (match_operand:DI 1 "general_movsrc_operand" ""))]
4124 ""
4125 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4126
4127 (define_insn "movdf_media"
4128 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4129 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4130 "TARGET_SHMEDIA_FPU
4131 && (register_operand (operands[0], DFmode)
4132 || sh_register_operand (operands[1], DFmode))"
4133 "@
4134 fmov.d %1, %0
4135 fmov.qd %N1, %0
4136 fmov.dq %1, %0
4137 add %1, r63, %0
4138 #
4139 fld%M1.d %m1, %0
4140 fst%M0.d %m0, %1
4141 ld%M1.q %m1, %0
4142 st%M0.q %m0, %N1"
4143 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4144
4145 (define_insn "movdf_media_nofpu"
4146 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4147 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4148 "TARGET_SHMEDIA
4149 && (register_operand (operands[0], DFmode)
4150 || sh_register_operand (operands[1], DFmode))"
4151 "@
4152 add %1, r63, %0
4153 #
4154 ld%M1.q %m1, %0
4155 st%M0.q %m0, %N1"
4156 [(set_attr "type" "arith_media,*,load_media,store_media")])
4157
4158 (define_split
4159 [(set (match_operand:DF 0 "arith_reg_operand" "")
4160 (match_operand:DF 1 "immediate_operand" ""))]
4161 "TARGET_SHMEDIA && reload_completed"
4162 [(set (match_dup 3) (match_dup 2))]
4163 "
4164 {
4165 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4166 long values[2];
4167 REAL_VALUE_TYPE value;
4168
4169 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4170 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4171
4172 if (HOST_BITS_PER_WIDE_INT >= 64)
4173 operands[2] = immed_double_const ((unsigned long) values[endian]
4174 | ((HOST_WIDE_INT) values[1 - endian]
4175 << 32), 0, DImode);
4176 else if (HOST_BITS_PER_WIDE_INT == 32)
4177 operands[2] = immed_double_const (values[endian], values[1 - endian],
4178 DImode);
4179 else
4180 abort ();
4181
4182 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4183 }")
4184
4185 ;; ??? This should be a define expand.
4186
4187 (define_insn "movdf_k"
4188 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4189 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4190 "TARGET_SH1
4191 && (! TARGET_SH4 || reload_completed
4192 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4193 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4194 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4195 && (arith_reg_operand (operands[0], DFmode)
4196 || arith_reg_operand (operands[1], DFmode))"
4197 "* return output_movedouble (insn, operands, DFmode);"
4198 [(set_attr "length" "4")
4199 (set_attr "type" "move,pcload,load,store")])
4200
4201 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4202 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4203 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4204 ;; the d/m/c/X alternative, which is split later into single-precision
4205 ;; instructions. And when not optimizing, no splits are done before fixing
4206 ;; up pcloads, so we need usable length information for that.
4207 (define_insn "movdf_i4"
4208 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4209 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4210 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4211 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4212 "TARGET_SH4
4213 && (arith_reg_operand (operands[0], DFmode)
4214 || arith_reg_operand (operands[1], DFmode))"
4215 "@
4216 fmov %1,%0
4217 #
4218 #
4219 fmov.d %1,%0
4220 fmov.d %1,%0
4221 #
4222 #
4223 #
4224 #
4225 #"
4226 [(set_attr_alternative "length"
4227 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4228 (const_int 4)
4229 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4230 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4231 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4232 (const_int 4)
4233 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4234 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4235 ;; increment or decrement r15 explicitly.
4236 (if_then_else
4237 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4238 (const_int 10) (const_int 8))
4239 (if_then_else
4240 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4241 (const_int 10) (const_int 8))])
4242 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4243 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4244 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4245 (const_string "double")
4246 (const_string "none")))])
4247
4248 ;; Moving DFmode between fp/general registers through memory
4249 ;; (the top of the stack) is faster than moving through fpul even for
4250 ;; little endian. Because the type of an instruction is important for its
4251 ;; scheduling, it is beneficial to split these operations, rather than
4252 ;; emitting them in one single chunk, even if this will expose a stack
4253 ;; use that will prevent scheduling of other stack accesses beyond this
4254 ;; instruction.
4255 (define_split
4256 [(set (match_operand:DF 0 "register_operand" "")
4257 (match_operand:DF 1 "register_operand" ""))
4258 (use (match_operand:PSI 2 "fpscr_operand" ""))
4259 (clobber (match_scratch:SI 3 "=X"))]
4260 "TARGET_SH4 && reload_completed
4261 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4262 [(const_int 0)]
4263 "
4264 {
4265 rtx insn, tos;
4266
4267 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4268 {
4269 emit_move_insn (stack_pointer_rtx,
4270 plus_constant (stack_pointer_rtx, -8));
4271 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4272 }
4273 else
4274 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4275 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4276 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4277 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4278 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4279 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4280 else
4281 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4282 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4283 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4284 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4285 else
4286 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4287 DONE;
4288 }")
4289
4290 ;; local-alloc sometimes allocates scratch registers even when not required,
4291 ;; so we must be prepared to handle these.
4292
4293 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4294 (define_split
4295 [(set (match_operand:DF 0 "general_movdst_operand" "")
4296 (match_operand:DF 1 "general_movsrc_operand" ""))
4297 (use (match_operand:PSI 2 "fpscr_operand" ""))
4298 (clobber (match_scratch:SI 3 ""))]
4299 "TARGET_SH4
4300 && reload_completed
4301 && true_regnum (operands[0]) < 16
4302 && true_regnum (operands[1]) < 16"
4303 [(set (match_dup 0) (match_dup 1))]
4304 "
4305 {
4306 /* If this was a reg <-> mem operation with base + index reg addressing,
4307 we have to handle this in a special way. */
4308 rtx mem = operands[0];
4309 int store_p = 1;
4310 if (! memory_operand (mem, DFmode))
4311 {
4312 mem = operands[1];
4313 store_p = 0;
4314 }
4315 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4316 mem = SUBREG_REG (mem);
4317 if (GET_CODE (mem) == MEM)
4318 {
4319 rtx addr = XEXP (mem, 0);
4320 if (GET_CODE (addr) == PLUS
4321 && GET_CODE (XEXP (addr, 0)) == REG
4322 && GET_CODE (XEXP (addr, 1)) == REG)
4323 {
4324 int offset;
4325 rtx reg0 = gen_rtx (REG, Pmode, 0);
4326 rtx regop = operands[store_p], word0 ,word1;
4327
4328 if (GET_CODE (regop) == SUBREG)
4329 alter_subreg (&regop);
4330 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4331 offset = 2;
4332 else
4333 offset = 4;
4334 mem = copy_rtx (mem);
4335 PUT_MODE (mem, SImode);
4336 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4337 alter_subreg (&word0);
4338 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4339 alter_subreg (&word1);
4340 if (store_p || ! refers_to_regno_p (REGNO (word0),
4341 REGNO (word0) + 1, addr, 0))
4342 {
4343 emit_insn (store_p
4344 ? gen_movsi_ie (mem, word0)
4345 : gen_movsi_ie (word0, mem));
4346 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4347 mem = copy_rtx (mem);
4348 emit_insn (store_p
4349 ? gen_movsi_ie (mem, word1)
4350 : gen_movsi_ie (word1, mem));
4351 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4352 }
4353 else
4354 {
4355 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4356 emit_insn (gen_movsi_ie (word1, mem));
4357 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4358 mem = copy_rtx (mem);
4359 emit_insn (gen_movsi_ie (word0, mem));
4360 }
4361 DONE;
4362 }
4363 }
4364 }")
4365
4366 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4367 (define_split
4368 [(set (match_operand:DF 0 "register_operand" "")
4369 (match_operand:DF 1 "memory_operand" ""))
4370 (use (match_operand:PSI 2 "fpscr_operand" ""))
4371 (clobber (reg:SI R0_REG))]
4372 "TARGET_SH4 && reload_completed"
4373 [(parallel [(set (match_dup 0) (match_dup 1))
4374 (use (match_dup 2))
4375 (clobber (scratch:SI))])]
4376 "")
4377
4378 (define_expand "reload_indf"
4379 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4380 (match_operand:DF 1 "immediate_operand" "FQ"))
4381 (use (reg:PSI FPSCR_REG))
4382 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4383 "TARGET_SH1"
4384 "")
4385
4386 (define_expand "reload_outdf"
4387 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4388 (match_operand:DF 1 "register_operand" "af,r"))
4389 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4390 "TARGET_SH1"
4391 "")
4392
4393 ;; Simplify no-op moves.
4394 (define_split
4395 [(set (match_operand:SF 0 "register_operand" "")
4396 (match_operand:SF 1 "register_operand" ""))
4397 (use (match_operand:PSI 2 "fpscr_operand" ""))
4398 (clobber (match_scratch:SI 3 ""))]
4399 "TARGET_SH2E && reload_completed
4400 && true_regnum (operands[0]) == true_regnum (operands[1])"
4401 [(set (match_dup 0) (match_dup 0))]
4402 "")
4403
4404 ;; fmovd substitute post-reload splits
4405 (define_split
4406 [(set (match_operand:DF 0 "register_operand" "")
4407 (match_operand:DF 1 "register_operand" ""))
4408 (use (match_operand:PSI 2 "fpscr_operand" ""))
4409 (clobber (match_scratch:SI 3 ""))]
4410 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4411 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4412 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4413 [(const_int 0)]
4414 "
4415 {
4416 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4417 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4418 gen_rtx (REG, SFmode, src), operands[2]));
4419 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4420 gen_rtx (REG, SFmode, src + 1), operands[2]));
4421 DONE;
4422 }")
4423
4424 (define_split
4425 [(set (match_operand:DF 0 "register_operand" "")
4426 (mem:DF (match_operand:SI 1 "register_operand" "")))
4427 (use (match_operand:PSI 2 "fpscr_operand" ""))
4428 (clobber (match_scratch:SI 3 ""))]
4429 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4430 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4431 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4432 [(const_int 0)]
4433 "
4434 {
4435 int regno = true_regnum (operands[0]);
4436 rtx insn;
4437 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4438
4439 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4440 regno + !! TARGET_LITTLE_ENDIAN),
4441 mem2, operands[2]));
4442 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4443 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4444 regno + ! TARGET_LITTLE_ENDIAN),
4445 gen_rtx (MEM, SFmode, operands[1]),
4446 operands[2]));
4447 DONE;
4448 }")
4449
4450 (define_split
4451 [(set (match_operand:DF 0 "register_operand" "")
4452 (match_operand:DF 1 "memory_operand" ""))
4453 (use (match_operand:PSI 2 "fpscr_operand" ""))
4454 (clobber (match_scratch:SI 3 ""))]
4455 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4456 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4457 [(const_int 0)]
4458 "
4459 {
4460 int regno = true_regnum (operands[0]);
4461 rtx addr, insn, adjust = NULL_RTX;
4462 rtx mem2 = copy_rtx (operands[1]);
4463 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4464 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4465
4466 PUT_MODE (mem2, SFmode);
4467 operands[1] = copy_rtx (mem2);
4468 addr = XEXP (mem2, 0);
4469 if (GET_CODE (addr) != POST_INC)
4470 {
4471 /* If we have to modify the stack pointer, the value that we have
4472 read with post-increment might be modified by an interrupt,
4473 so write it back. */
4474 if (REGNO (addr) == STACK_POINTER_REGNUM)
4475 adjust = gen_push_e (reg0);
4476 else
4477 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4478 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4479 }
4480 addr = XEXP (addr, 0);
4481 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4482 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4483 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4484 if (adjust)
4485 emit_insn (adjust);
4486 else
4487 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4488 DONE;
4489 }")
4490
4491 (define_split
4492 [(set (match_operand:DF 0 "memory_operand" "")
4493 (match_operand:DF 1 "register_operand" ""))
4494 (use (match_operand:PSI 2 "fpscr_operand" ""))
4495 (clobber (match_scratch:SI 3 ""))]
4496 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4497 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4498 [(const_int 0)]
4499 "
4500 {
4501 int regno = true_regnum (operands[1]);
4502 rtx insn, addr, adjust = NULL_RTX;
4503
4504 operands[0] = copy_rtx (operands[0]);
4505 PUT_MODE (operands[0], SFmode);
4506 insn = emit_insn (gen_movsf_ie (operands[0],
4507 gen_rtx (REG, SFmode,
4508 regno + ! TARGET_LITTLE_ENDIAN),
4509 operands[2]));
4510 operands[0] = copy_rtx (operands[0]);
4511 addr = XEXP (operands[0], 0);
4512 if (GET_CODE (addr) != PRE_DEC)
4513 {
4514 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4515 emit_insn_before (adjust, insn);
4516 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4517 }
4518 addr = XEXP (addr, 0);
4519 if (! adjust)
4520 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4521 insn = emit_insn (gen_movsf_ie (operands[0],
4522 gen_rtx (REG, SFmode,
4523 regno + !! TARGET_LITTLE_ENDIAN),
4524 operands[2]));
4525 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4526 DONE;
4527 }")
4528
4529 ;; If the output is a register and the input is memory or a register, we have
4530 ;; to be careful and see which word needs to be loaded first.
4531
4532 (define_split
4533 [(set (match_operand:DF 0 "general_movdst_operand" "")
4534 (match_operand:DF 1 "general_movsrc_operand" ""))]
4535 "TARGET_SH1 && reload_completed"
4536 [(set (match_dup 2) (match_dup 3))
4537 (set (match_dup 4) (match_dup 5))]
4538 "
4539 {
4540 int regno;
4541
4542 if ((GET_CODE (operands[0]) == MEM
4543 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4544 || (GET_CODE (operands[1]) == MEM
4545 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4546 FAIL;
4547
4548 if (GET_CODE (operands[0]) == REG)
4549 regno = REGNO (operands[0]);
4550 else if (GET_CODE (operands[0]) == SUBREG)
4551 regno = subreg_regno (operands[0]);
4552 else if (GET_CODE (operands[0]) == MEM)
4553 regno = -1;
4554 else
4555 abort ();
4556
4557 if (regno == -1
4558 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4559 {
4560 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4561 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4562 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4563 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4564 }
4565 else
4566 {
4567 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4568 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4569 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4570 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4571 }
4572
4573 if (operands[2] == 0 || operands[3] == 0
4574 || operands[4] == 0 || operands[5] == 0)
4575 FAIL;
4576 }")
4577
4578 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4579 ;; used only once, let combine add in the index again.
4580
4581 (define_split
4582 [(set (match_operand:SI 0 "register_operand" "")
4583 (match_operand:SI 1 "" ""))
4584 (clobber (match_operand 2 "register_operand" ""))]
4585 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4586 [(use (reg:SI R0_REG))]
4587 "
4588 {
4589 rtx addr, reg, const_int;
4590
4591 if (GET_CODE (operands[1]) != MEM)
4592 FAIL;
4593 addr = XEXP (operands[1], 0);
4594 if (GET_CODE (addr) != PLUS)
4595 FAIL;
4596 reg = XEXP (addr, 0);
4597 const_int = XEXP (addr, 1);
4598 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4599 && GET_CODE (const_int) == CONST_INT))
4600 FAIL;
4601 emit_move_insn (operands[2], const_int);
4602 emit_move_insn (operands[0],
4603 change_address (operands[1], VOIDmode,
4604 gen_rtx_PLUS (SImode, reg, operands[2])));
4605 DONE;
4606 }")
4607
4608 (define_split
4609 [(set (match_operand:SI 1 "" "")
4610 (match_operand:SI 0 "register_operand" ""))
4611 (clobber (match_operand 2 "register_operand" ""))]
4612 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4613 [(use (reg:SI R0_REG))]
4614 "
4615 {
4616 rtx addr, reg, const_int;
4617
4618 if (GET_CODE (operands[1]) != MEM)
4619 FAIL;
4620 addr = XEXP (operands[1], 0);
4621 if (GET_CODE (addr) != PLUS)
4622 FAIL;
4623 reg = XEXP (addr, 0);
4624 const_int = XEXP (addr, 1);
4625 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4626 && GET_CODE (const_int) == CONST_INT))
4627 FAIL;
4628 emit_move_insn (operands[2], const_int);
4629 emit_move_insn (change_address (operands[1], VOIDmode,
4630 gen_rtx_PLUS (SImode, reg, operands[2])),
4631 operands[0]);
4632 DONE;
4633 }")
4634
4635 (define_expand "movdf"
4636 [(set (match_operand:DF 0 "general_movdst_operand" "")
4637 (match_operand:DF 1 "general_movsrc_operand" ""))]
4638 ""
4639 "
4640 {
4641 if (prepare_move_operands (operands, DFmode)) DONE;
4642 if (TARGET_SHMEDIA)
4643 {
4644 if (TARGET_SHMEDIA_FPU)
4645 emit_insn (gen_movdf_media (operands[0], operands[1]));
4646 else
4647 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4648 DONE;
4649 }
4650 if (TARGET_SH4)
4651 {
4652 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4653 DONE;
4654 }
4655 }")
4656
4657 ;;This is incompatible with the way gcc uses subregs.
4658 ;;(define_insn "movv2sf_i"
4659 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4660 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4661 ;; "TARGET_SHMEDIA_FPU
4662 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4663 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4664 ;; "@
4665 ;; #
4666 ;; fld%M1.p %m1, %0
4667 ;; fst%M0.p %m0, %1"
4668 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4669
4670 (define_insn_and_split "movv2sf_i"
4671 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4672 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4673 "TARGET_SHMEDIA_FPU"
4674 "#"
4675 "TARGET_SHMEDIA_FPU && reload_completed"
4676 [(set (match_dup 0) (match_dup 1))]
4677 "
4678 {
4679 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4680 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4681 }")
4682
4683 (define_expand "movv2sf"
4684 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4685 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4686 "TARGET_SHMEDIA_FPU"
4687 "
4688 {
4689 if (prepare_move_operands (operands, V2SFmode))
4690 DONE;
4691 }")
4692
4693 (define_expand "addv2sf3"
4694 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4695 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4696 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4697 "TARGET_SHMEDIA_FPU"
4698 "
4699 {
4700 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4701 DONE;
4702 }")
4703
4704 (define_expand "subv2sf3"
4705 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4706 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4707 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4708 "TARGET_SHMEDIA_FPU"
4709 "
4710 {
4711 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4712 DONE;
4713 }")
4714
4715 (define_expand "mulv2sf3"
4716 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4717 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4718 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4719 "TARGET_SHMEDIA_FPU"
4720 "
4721 {
4722 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4723 DONE;
4724 }")
4725
4726 (define_expand "divv2sf3"
4727 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4728 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4729 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4730 "TARGET_SHMEDIA_FPU"
4731 "
4732 {
4733 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4734 DONE;
4735 }")
4736
4737 (define_insn_and_split "*movv4sf_i"
4738 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4739 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4740 "TARGET_SHMEDIA_FPU"
4741 "#"
4742 "&& reload_completed"
4743 [(const_int 0)]
4744 "
4745 {
4746 int i;
4747
4748 for (i = 0; i < 4/2; i++)
4749 {
4750 rtx x, y;
4751
4752 if (GET_CODE (operands[0]) == MEM)
4753 x = gen_rtx_MEM (V2SFmode,
4754 plus_constant (XEXP (operands[0], 0),
4755 i * GET_MODE_SIZE (V2SFmode)));
4756 else
4757 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4758
4759 if (GET_CODE (operands[1]) == MEM)
4760 y = gen_rtx_MEM (V2SFmode,
4761 plus_constant (XEXP (operands[1], 0),
4762 i * GET_MODE_SIZE (V2SFmode)));
4763 else
4764 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4765
4766 emit_insn (gen_movv2sf_i (x, y));
4767 }
4768
4769 DONE;
4770 }"
4771 [(set_attr "length" "8")])
4772
4773 (define_expand "movv4sf"
4774 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4775 (match_operand:V4SF 1 "general_operand" ""))]
4776 "TARGET_SHMEDIA_FPU"
4777 "
4778 {
4779 if (prepare_move_operands (operands, V4SFmode))
4780 DONE;
4781 }")
4782
4783 (define_insn_and_split "*movv16sf_i"
4784 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4785 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4786 "TARGET_SHMEDIA_FPU"
4787 "#"
4788 "&& reload_completed"
4789 [(const_int 0)]
4790 "
4791 {
4792 int i;
4793
4794 for (i = 0; i < 16/2; i++)
4795 {
4796 rtx x,y;
4797
4798 if (GET_CODE (operands[0]) == MEM)
4799 x = gen_rtx_MEM (V2SFmode,
4800 plus_constant (XEXP (operands[0], 0),
4801 i * GET_MODE_SIZE (V2SFmode)));
4802 else
4803 {
4804 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4805 alter_subreg (&x);
4806 }
4807
4808 if (GET_CODE (operands[1]) == MEM)
4809 y = gen_rtx_MEM (V2SFmode,
4810 plus_constant (XEXP (operands[1], 0),
4811 i * GET_MODE_SIZE (V2SFmode)));
4812 else
4813 {
4814 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4815 alter_subreg (&y);
4816 }
4817
4818 emit_insn (gen_movv2sf_i (x, y));
4819 }
4820
4821 DONE;
4822 }"
4823 [(set_attr "length" "32")])
4824
4825 (define_expand "movv16sf"
4826 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4827 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4828 "TARGET_SHMEDIA_FPU"
4829 "
4830 {
4831 if (prepare_move_operands (operands, V16SFmode))
4832 DONE;
4833 }")
4834
4835 (define_insn "movsf_media"
4836 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4837 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4838 "TARGET_SHMEDIA_FPU
4839 && (register_operand (operands[0], SFmode)
4840 || sh_register_operand (operands[1], SFmode))"
4841 "@
4842 fmov.s %1, %0
4843 fmov.ls %N1, %0
4844 fmov.sl %1, %0
4845 add.l %1, r63, %0
4846 #
4847 fld%M1.s %m1, %0
4848 fst%M0.s %m0, %1
4849 ld%M1.l %m1, %0
4850 st%M0.l %m0, %N1"
4851 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4852
4853 (define_insn "movsf_media_nofpu"
4854 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4855 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4856 "TARGET_SHMEDIA
4857 && (register_operand (operands[0], SFmode)
4858 || sh_register_operand (operands[1], SFmode))"
4859 "@
4860 add.l %1, r63, %0
4861 #
4862 ld%M1.l %m1, %0
4863 st%M0.l %m0, %N1"
4864 [(set_attr "type" "arith_media,*,load_media,store_media")])
4865
4866 (define_split
4867 [(set (match_operand:SF 0 "arith_reg_operand" "")
4868 (match_operand:SF 1 "immediate_operand" ""))]
4869 "TARGET_SHMEDIA && reload_completed
4870 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4871 [(set (match_dup 3) (match_dup 2))]
4872 "
4873 {
4874 long values;
4875 REAL_VALUE_TYPE value;
4876
4877 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4878 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4879 operands[2] = GEN_INT (values);
4880
4881 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4882 }")
4883
4884 (define_insn "movsf_i"
4885 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4886 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4887 "TARGET_SH1
4888 && (! TARGET_SH2E
4889 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4890 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4891 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4892 && (arith_reg_operand (operands[0], SFmode)
4893 || arith_reg_operand (operands[1], SFmode))"
4894 "@
4895 mov %1,%0
4896 mov #0,%0
4897 mov.l %1,%0
4898 mov.l %1,%0
4899 mov.l %1,%0
4900 lds %1,%0
4901 sts %1,%0"
4902 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4903
4904 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4905 ;; update_flow_info would not know where to put REG_EQUAL notes
4906 ;; when the destination changes mode.
4907 (define_insn "movsf_ie"
4908 [(set (match_operand:SF 0 "general_movdst_operand"
4909 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4910 (match_operand:SF 1 "general_movsrc_operand"
4911 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4912 (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"))
4913 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4914
4915 "TARGET_SH2E
4916 && (arith_reg_operand (operands[0], SFmode)
4917 || arith_reg_operand (operands[1], SFmode)
4918 || arith_reg_operand (operands[3], SImode)
4919 || (fpul_operand (operands[0], SFmode)
4920 && memory_operand (operands[1], SFmode)
4921 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4922 || (fpul_operand (operands[1], SFmode)
4923 && memory_operand (operands[0], SFmode)
4924 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4925 "@
4926 fmov %1,%0
4927 mov %1,%0
4928 fldi0 %0
4929 fldi1 %0
4930 #
4931 fmov.s %1,%0
4932 fmov.s %1,%0
4933 mov.l %1,%0
4934 mov.l %1,%0
4935 mov.l %1,%0
4936 fsts fpul,%0
4937 flds %1,fpul
4938 lds.l %1,%0
4939 #
4940 sts %1,%0
4941 lds %1,%0
4942 sts.l %1,%0
4943 lds.l %1,%0
4944 ! move optimized away"
4945 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4946 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4947 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4948 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4949 (const_string "single")
4950 (const_string "none")))])
4951
4952 (define_split
4953 [(set (match_operand:SF 0 "register_operand" "")
4954 (match_operand:SF 1 "register_operand" ""))
4955 (use (match_operand:PSI 2 "fpscr_operand" ""))
4956 (clobber (reg:SI FPUL_REG))]
4957 "TARGET_SH1"
4958 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4959 (use (match_dup 2))
4960 (clobber (scratch:SI))])
4961 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4962 (use (match_dup 2))
4963 (clobber (scratch:SI))])]
4964 "")
4965
4966 (define_expand "movsf"
4967 [(set (match_operand:SF 0 "general_movdst_operand" "")
4968 (match_operand:SF 1 "general_movsrc_operand" ""))]
4969 ""
4970 "
4971 {
4972 if (prepare_move_operands (operands, SFmode))
4973 DONE;
4974 if (TARGET_SHMEDIA)
4975 {
4976 if (TARGET_SHMEDIA_FPU)
4977 emit_insn (gen_movsf_media (operands[0], operands[1]));
4978 else
4979 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4980 DONE;
4981 }
4982 if (TARGET_SH2E)
4983 {
4984 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4985 DONE;
4986 }
4987 }")
4988
4989 (define_insn "mov_nop"
4990 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4991 "TARGET_SH2E"
4992 ""
4993 [(set_attr "length" "0")
4994 (set_attr "type" "nil")])
4995
4996 (define_expand "reload_insf"
4997 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4998 (match_operand:SF 1 "immediate_operand" "FQ"))
4999 (use (reg:PSI FPSCR_REG))
5000 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5001 "TARGET_SH1"
5002 "")
5003
5004 (define_expand "reload_insi"
5005 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5006 (match_operand:SF 1 "immediate_operand" "FQ"))
5007 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5008 "TARGET_SH1"
5009 "")
5010
5011 (define_insn "*movsi_y"
5012 [(set (match_operand:SI 0 "register_operand" "=y,y")
5013 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5014 (clobber (match_scratch:SI 2 "=&z,r"))]
5015 "TARGET_SH2E
5016 && (reload_in_progress || reload_completed)"
5017 "#"
5018 [(set_attr "length" "4")
5019 (set_attr "type" "pcload,move")])
5020
5021 (define_split
5022 [(set (match_operand:SI 0 "register_operand" "")
5023 (match_operand:SI 1 "immediate_operand" ""))
5024 (clobber (match_operand:SI 2 "register_operand" ""))]
5025 "TARGET_SH1"
5026 [(set (match_dup 2) (match_dup 1))
5027 (set (match_dup 0) (match_dup 2))]
5028 "")
5029
5030 (define_split
5031 [(set (match_operand:SI 0 "register_operand" "")
5032 (match_operand:SI 1 "memory_operand" ""))
5033 (clobber (reg:SI R0_REG))]
5034 "TARGET_SH1"
5035 [(set (match_dup 0) (match_dup 1))]
5036 "")
5037 \f
5038 ;; ------------------------------------------------------------------------
5039 ;; Define the real conditional branch instructions.
5040 ;; ------------------------------------------------------------------------
5041
5042 (define_insn "branch_true"
5043 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5044 (label_ref (match_operand 0 "" ""))
5045 (pc)))]
5046 "TARGET_SH1"
5047 "* return output_branch (1, insn, operands);"
5048 [(set_attr "type" "cbranch")])
5049
5050 (define_insn "branch_false"
5051 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5052 (label_ref (match_operand 0 "" ""))
5053 (pc)))]
5054 "TARGET_SH1"
5055 "* return output_branch (0, insn, operands);"
5056 [(set_attr "type" "cbranch")])
5057
5058 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5059 ;; which destination is too far away.
5060 ;; The const_int_operand is distinct for each branch target; it avoids
5061 ;; unwanted matches with redundant_insn.
5062 (define_insn "block_branch_redirect"
5063 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5064 "TARGET_SH1"
5065 ""
5066 [(set_attr "length" "0")])
5067
5068 ;; This one has the additional purpose to record a possible scratch register
5069 ;; for the following branch.
5070 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5071 ;; because the insn then might be deemed dead and deleted. And we can't
5072 ;; make the use in the jump insn explicit because that would disable
5073 ;; delay slot scheduling from the target.
5074 (define_insn "indirect_jump_scratch"
5075 [(set (match_operand:SI 0 "register_operand" "=r")
5076 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5077 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5078 "TARGET_SH1"
5079 ""
5080 [(set_attr "length" "0")])
5081
5082 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5083 ;; being pulled into the delay slot of a condbranch that has been made to
5084 ;; jump around the unconditional jump because it was out of range.
5085 (define_insn "stuff_delay_slot"
5086 [(set (pc)
5087 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5088 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5089 "TARGET_SH1"
5090 ""
5091 [(set_attr "length" "0")
5092 (set_attr "cond_delay_slot" "yes")])
5093 \f
5094 ;; Conditional branch insns
5095
5096 (define_expand "beq_media"
5097 [(set (pc)
5098 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5099 (match_operand:DI 2 "arith_operand" "r,I06"))
5100 (label_ref:DI (match_operand 0 "" ""))
5101 (pc)))]
5102 "TARGET_SHMEDIA"
5103 "")
5104
5105 (define_insn "*beq_media_i"
5106 [(set (pc)
5107 (if_then_else (match_operator 3 "equality_comparison_operator"
5108 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5109 (match_operand:DI 2 "arith_operand" "r,I06")])
5110 (match_operand:DI 0 "target_operand" "b,b")
5111 (pc)))]
5112 "TARGET_SHMEDIA"
5113 "@
5114 b%o3%' %1, %2, %0
5115 b%o3i%' %1, %2, %0"
5116 [(set_attr "type" "cbranch_media")])
5117
5118 (define_expand "bne_media"
5119 [(set (pc)
5120 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5121 (match_operand:DI 2 "arith_operand" "r,I06"))
5122 (label_ref:DI (match_operand 0 "" ""))
5123 (pc)))]
5124 "TARGET_SHMEDIA"
5125 "")
5126
5127 (define_expand "bgt_media"
5128 [(set (pc)
5129 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5130 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5131 (label_ref:DI (match_operand 0 "" ""))
5132 (pc)))]
5133 "TARGET_SHMEDIA"
5134 "")
5135
5136 (define_expand "bge_media"
5137 [(set (pc)
5138 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5139 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5140 (label_ref:DI (match_operand 0 "" ""))
5141 (pc)))]
5142 "TARGET_SHMEDIA"
5143 "")
5144
5145 (define_expand "bgtu_media"
5146 [(set (pc)
5147 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5148 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5149 (label_ref:DI (match_operand 0 "" ""))
5150 (pc)))]
5151 "TARGET_SHMEDIA"
5152 "")
5153
5154 (define_expand "bgeu_media"
5155 [(set (pc)
5156 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5157 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5158 (label_ref:DI (match_operand 0 "" ""))
5159 (pc)))]
5160 "TARGET_SHMEDIA"
5161 "")
5162
5163 (define_insn "*bgt_media_i"
5164 [(set (pc)
5165 (if_then_else (match_operator 3 "greater_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%' %N1, %N2, %0"
5172 [(set_attr "type" "cbranch_media")])
5173
5174 ;; These are only needed to make invert_jump() happy.
5175 (define_insn "*blt_media_i"
5176 [(set (pc)
5177 (if_then_else (match_operator 3 "less_comparison_operator"
5178 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5179 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5180 (match_operand:DI 0 "target_operand" "b")
5181 (pc)))]
5182 "TARGET_SHMEDIA"
5183 "b%o3%' %N2, %N1, %0"
5184 [(set_attr "type" "cbranch_media")])
5185
5186 (define_expand "beq"
5187 [(set (pc)
5188 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5189 (label_ref (match_operand 0 "" ""))
5190 (pc)))]
5191 ""
5192 "
5193 {
5194 if (TARGET_SHMEDIA)
5195 {
5196 if (GET_MODE (sh_compare_op0) != DImode)
5197 {
5198 rtx tmp = gen_reg_rtx (DImode);
5199
5200 emit_insn (gen_seq (tmp));
5201 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5202 DONE;
5203 }
5204
5205 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5206 emit_jump_insn (gen_beq_media (operands[0],
5207 sh_compare_op0, sh_compare_op1));
5208 DONE;
5209 }
5210
5211 from_compare (operands, EQ);
5212 }")
5213
5214 (define_expand "bne"
5215 [(set (pc)
5216 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5217 (label_ref (match_operand 0 "" ""))
5218 (pc)))]
5219 ""
5220 "
5221 {
5222 if (TARGET_SHMEDIA)
5223 {
5224 if (GET_MODE (sh_compare_op0) != DImode)
5225 {
5226 rtx tmp = gen_reg_rtx (DImode);
5227
5228 emit_insn (gen_seq (tmp));
5229 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5230 DONE;
5231 }
5232
5233 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5234 emit_jump_insn (gen_bne_media (operands[0],
5235 sh_compare_op0, sh_compare_op1));
5236 DONE;
5237 }
5238
5239 from_compare (operands, EQ);
5240 }")
5241
5242 (define_expand "bgt"
5243 [(set (pc)
5244 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5245 (label_ref (match_operand 0 "" ""))
5246 (pc)))]
5247 ""
5248 "
5249 {
5250 if (TARGET_SHMEDIA)
5251 {
5252 if (GET_MODE (sh_compare_op0) != DImode)
5253 {
5254 rtx tmp = gen_reg_rtx (DImode);
5255
5256 emit_insn (gen_sgt (tmp));
5257 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5258 DONE;
5259 }
5260
5261 if (sh_compare_op0 != const0_rtx)
5262 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5263 if (sh_compare_op1 != const0_rtx)
5264 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5265 emit_jump_insn (gen_bgt_media (operands[0],
5266 sh_compare_op0, sh_compare_op1));
5267 DONE;
5268 }
5269
5270 from_compare (operands, GT);
5271 }")
5272
5273 (define_expand "blt"
5274 [(set (pc)
5275 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5276 (label_ref (match_operand 0 "" ""))
5277 (pc)))]
5278 ""
5279 "
5280 {
5281 if (TARGET_SHMEDIA)
5282 {
5283 if (GET_MODE (sh_compare_op0) != DImode)
5284 {
5285 rtx tmp = gen_reg_rtx (DImode);
5286
5287 emit_insn (gen_slt (tmp));
5288 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5289 DONE;
5290 }
5291
5292 if (sh_compare_op0 != const0_rtx)
5293 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5294 if (sh_compare_op1 != const0_rtx)
5295 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5296 emit_jump_insn (gen_bgt_media (operands[0],
5297 sh_compare_op1, sh_compare_op0));
5298 DONE;
5299 }
5300
5301 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5302 {
5303 rtx tmp = sh_compare_op0;
5304 sh_compare_op0 = sh_compare_op1;
5305 sh_compare_op1 = tmp;
5306 emit_insn (gen_bgt (operands[0]));
5307 DONE;
5308 }
5309 from_compare (operands, GE);
5310 }")
5311
5312 (define_expand "ble"
5313 [(set (pc)
5314 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5315 (label_ref (match_operand 0 "" ""))
5316 (pc)))]
5317 ""
5318 "
5319 {
5320 if (TARGET_SHMEDIA)
5321 {
5322 if (GET_MODE (sh_compare_op0) != DImode)
5323 {
5324 rtx tmp = gen_reg_rtx (DImode);
5325
5326 emit_insn (gen_sle (tmp));
5327 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5328 DONE;
5329 }
5330
5331 if (sh_compare_op0 != const0_rtx)
5332 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5333 if (sh_compare_op1 != const0_rtx)
5334 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5335 emit_jump_insn (gen_bge_media (operands[0],
5336 sh_compare_op1, sh_compare_op0));
5337 DONE;
5338 }
5339
5340 if (TARGET_SH2E
5341 && TARGET_IEEE
5342 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5343 {
5344 rtx tmp = sh_compare_op0;
5345 sh_compare_op0 = sh_compare_op1;
5346 sh_compare_op1 = tmp;
5347 emit_insn (gen_bge (operands[0]));
5348 DONE;
5349 }
5350 from_compare (operands, GT);
5351 }")
5352
5353 (define_expand "bge"
5354 [(set (pc)
5355 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5356 (label_ref (match_operand 0 "" ""))
5357 (pc)))]
5358 ""
5359 "
5360 {
5361 if (TARGET_SHMEDIA)
5362 {
5363 if (GET_MODE (sh_compare_op0) != DImode)
5364 {
5365 rtx tmp = gen_reg_rtx (DImode);
5366
5367 emit_insn (gen_sge (tmp));
5368 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5369 DONE;
5370 }
5371
5372 if (sh_compare_op0 != const0_rtx)
5373 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5374 if (sh_compare_op1 != const0_rtx)
5375 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5376 emit_jump_insn (gen_bge_media (operands[0],
5377 sh_compare_op0, sh_compare_op1));
5378 DONE;
5379 }
5380
5381 if (TARGET_SH2E
5382 && ! TARGET_IEEE
5383 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5384 {
5385 rtx tmp = sh_compare_op0;
5386 sh_compare_op0 = sh_compare_op1;
5387 sh_compare_op1 = tmp;
5388 emit_insn (gen_ble (operands[0]));
5389 DONE;
5390 }
5391 from_compare (operands, GE);
5392 }")
5393
5394 (define_expand "bgtu"
5395 [(set (pc)
5396 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5397 (label_ref (match_operand 0 "" ""))
5398 (pc)))]
5399 ""
5400 "
5401 {
5402 if (TARGET_SHMEDIA)
5403 {
5404 if (sh_compare_op0 != const0_rtx)
5405 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5406 if (sh_compare_op1 != const0_rtx)
5407 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5408 emit_jump_insn (gen_bgtu_media (operands[0],
5409 sh_compare_op0, sh_compare_op1));
5410 DONE;
5411 }
5412
5413 from_compare (operands, GTU);
5414 }")
5415
5416 (define_expand "bltu"
5417 [(set (pc)
5418 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5419 (label_ref (match_operand 0 "" ""))
5420 (pc)))]
5421 ""
5422 "
5423 {
5424 if (TARGET_SHMEDIA)
5425 {
5426 if (sh_compare_op0 != const0_rtx)
5427 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5428 if (sh_compare_op1 != const0_rtx)
5429 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5430 emit_jump_insn (gen_bgtu_media (operands[0],
5431 sh_compare_op1, sh_compare_op0));
5432 DONE;
5433 }
5434
5435 from_compare (operands, GEU);
5436 }")
5437
5438 (define_expand "bgeu"
5439 [(set (pc)
5440 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5441 (label_ref (match_operand 0 "" ""))
5442 (pc)))]
5443 ""
5444 "
5445 {
5446 if (TARGET_SHMEDIA)
5447 {
5448 if (sh_compare_op0 != const0_rtx)
5449 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5450 if (sh_compare_op1 != const0_rtx)
5451 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5452 emit_jump_insn (gen_bgeu_media (operands[0],
5453 sh_compare_op0, sh_compare_op1));
5454 DONE;
5455 }
5456
5457 from_compare (operands, GEU);
5458 }")
5459
5460 (define_expand "bleu"
5461 [(set (pc)
5462 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5463 (label_ref (match_operand 0 "" ""))
5464 (pc)))]
5465 ""
5466 "
5467 {
5468 if (TARGET_SHMEDIA)
5469 {
5470 if (sh_compare_op0 != const0_rtx)
5471 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5472 if (sh_compare_op1 != const0_rtx)
5473 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5474 emit_jump_insn (gen_bgeu_media (operands[0],
5475 sh_compare_op1, sh_compare_op0));
5476 DONE;
5477 }
5478
5479 from_compare (operands, GTU);
5480 }")
5481
5482 (define_expand "bunordered"
5483 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5484 (set (pc)
5485 (if_then_else (ne (match_dup 1) (const_int 0))
5486 (label_ref:DI (match_operand 0 "" ""))
5487 (pc)))]
5488 "TARGET_SHMEDIA"
5489 "
5490 {
5491 operands[1] = gen_reg_rtx (DImode);
5492 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5493 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5494 }")
5495 \f
5496 ;; ------------------------------------------------------------------------
5497 ;; Jump and linkage insns
5498 ;; ------------------------------------------------------------------------
5499
5500 (define_insn "jump_compact"
5501 [(set (pc)
5502 (label_ref (match_operand 0 "" "")))]
5503 "TARGET_SH1"
5504 "*
5505 {
5506 /* The length is 16 if the delay slot is unfilled. */
5507 if (get_attr_length(insn) > 4)
5508 return output_far_jump(insn, operands[0]);
5509 else
5510 return \"bra %l0%#\";
5511 }"
5512 [(set_attr "type" "jump")
5513 (set_attr "needs_delay_slot" "yes")])
5514
5515 ;; ??? It would be much saner to explicitly use the scratch register
5516 ;; in the jump insn, and have indirect_jump_scratch only set it,
5517 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5518 ;; from the target then, as it uses simplejump_p.
5519 ;;(define_insn "jump_compact_far"
5520 ;; [(set (pc)
5521 ;; (label_ref (match_operand 0 "" "")))
5522 ;; (use (match_operand 1 "register_operand" "r")]
5523 ;; "TARGET_SH1"
5524 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5525 ;; [(set_attr "type" "jump")
5526 ;; (set_attr "needs_delay_slot" "yes")])
5527
5528 (define_insn "jump_media"
5529 [(set (pc)
5530 (match_operand:DI 0 "target_operand" "b"))]
5531 "TARGET_SHMEDIA"
5532 "blink %0, r63"
5533 [(set_attr "type" "jump_media")])
5534
5535 (define_expand "jump"
5536 [(set (pc)
5537 (label_ref (match_operand 0 "" "")))]
5538 ""
5539 "
5540 {
5541 if (TARGET_SH1)
5542 emit_jump_insn (gen_jump_compact (operands[0]));
5543 else if (TARGET_SHMEDIA)
5544 {
5545 if (reload_in_progress || reload_completed)
5546 FAIL;
5547 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5548 operands[0])));
5549 }
5550 DONE;
5551 }")
5552
5553 (define_insn "force_mode_for_call"
5554 [(use (reg:PSI FPSCR_REG))]
5555 "TARGET_SHCOMPACT"
5556 ""
5557 [(set_attr "length" "0")
5558 (set (attr "fp_mode")
5559 (if_then_else (eq_attr "fpu_single" "yes")
5560 (const_string "single") (const_string "double")))])
5561
5562 (define_insn "calli"
5563 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5564 (match_operand 1 "" ""))
5565 (use (reg:PSI FPSCR_REG))
5566 (clobber (reg:SI PR_REG))]
5567 "TARGET_SH1"
5568 "jsr @%0%#"
5569 [(set_attr "type" "call")
5570 (set (attr "fp_mode")
5571 (if_then_else (eq_attr "fpu_single" "yes")
5572 (const_string "single") (const_string "double")))
5573 (set_attr "needs_delay_slot" "yes")
5574 (set_attr "fp_set" "unknown")])
5575
5576 ;; This is a pc-rel call, using bsrf, for use with PIC.
5577
5578 (define_insn "calli_pcrel"
5579 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5580 (match_operand 1 "" ""))
5581 (use (reg:PSI FPSCR_REG))
5582 (use (reg:SI PIC_REG))
5583 (use (match_operand 2 "" ""))
5584 (clobber (reg:SI PR_REG))]
5585 "TARGET_SH2"
5586 "bsrf %0\\n%O2:%#"
5587 [(set_attr "type" "call")
5588 (set (attr "fp_mode")
5589 (if_then_else (eq_attr "fpu_single" "yes")
5590 (const_string "single") (const_string "double")))
5591 (set_attr "needs_delay_slot" "yes")
5592 (set_attr "fp_set" "unknown")])
5593
5594 (define_insn_and_split "call_pcrel"
5595 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5596 (match_operand 1 "" ""))
5597 (use (reg:PSI FPSCR_REG))
5598 (use (reg:SI PIC_REG))
5599 (clobber (reg:SI PR_REG))
5600 (clobber (match_scratch:SI 2 "=r"))]
5601 "TARGET_SH2"
5602 "#"
5603 "reload_completed"
5604 [(const_int 0)]
5605 "
5606 {
5607 rtx lab = PATTERN (gen_call_site ());
5608
5609 if (SYMBOL_REF_LOCAL_P (operands[0]))
5610 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5611 else
5612 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5613 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5614 DONE;
5615 }"
5616 [(set_attr "type" "call")
5617 (set (attr "fp_mode")
5618 (if_then_else (eq_attr "fpu_single" "yes")
5619 (const_string "single") (const_string "double")))
5620 (set_attr "needs_delay_slot" "yes")
5621 (set_attr "fp_set" "unknown")])
5622
5623 (define_insn "call_compact"
5624 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5625 (match_operand 1 "" ""))
5626 (match_operand 2 "immediate_operand" "n")
5627 (use (reg:SI R0_REG))
5628 (use (reg:SI R1_REG))
5629 (use (reg:PSI FPSCR_REG))
5630 (clobber (reg:SI PR_REG))]
5631 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5632 "jsr @%0%#"
5633 [(set_attr "type" "call")
5634 (set (attr "fp_mode")
5635 (if_then_else (eq_attr "fpu_single" "yes")
5636 (const_string "single") (const_string "double")))
5637 (set_attr "needs_delay_slot" "yes")])
5638
5639 (define_insn "call_compact_rettramp"
5640 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5641 (match_operand 1 "" ""))
5642 (match_operand 2 "immediate_operand" "n")
5643 (use (reg:SI R0_REG))
5644 (use (reg:SI R1_REG))
5645 (use (reg:PSI FPSCR_REG))
5646 (clobber (reg:SI R10_REG))
5647 (clobber (reg:SI PR_REG))]
5648 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5649 "jsr @%0%#"
5650 [(set_attr "type" "call")
5651 (set (attr "fp_mode")
5652 (if_then_else (eq_attr "fpu_single" "yes")
5653 (const_string "single") (const_string "double")))
5654 (set_attr "needs_delay_slot" "yes")])
5655
5656 (define_insn "call_media"
5657 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5658 (match_operand 1 "" ""))
5659 (clobber (reg:DI PR_MEDIA_REG))]
5660 "TARGET_SHMEDIA"
5661 "blink %0, r18"
5662 [(set_attr "type" "jump_media")])
5663
5664 (define_insn "call_valuei"
5665 [(set (match_operand 0 "" "=rf")
5666 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5667 (match_operand 2 "" "")))
5668 (use (reg:PSI FPSCR_REG))
5669 (clobber (reg:SI PR_REG))]
5670 "TARGET_SH1"
5671 "jsr @%1%#"
5672 [(set_attr "type" "call")
5673 (set (attr "fp_mode")
5674 (if_then_else (eq_attr "fpu_single" "yes")
5675 (const_string "single") (const_string "double")))
5676 (set_attr "needs_delay_slot" "yes")
5677 (set_attr "fp_set" "unknown")])
5678
5679 (define_insn "call_valuei_pcrel"
5680 [(set (match_operand 0 "" "=rf")
5681 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5682 (match_operand 2 "" "")))
5683 (use (reg:PSI FPSCR_REG))
5684 (use (reg:SI PIC_REG))
5685 (use (match_operand 3 "" ""))
5686 (clobber (reg:SI PR_REG))]
5687 "TARGET_SH2"
5688 "bsrf %1\\n%O3:%#"
5689 [(set_attr "type" "call")
5690 (set (attr "fp_mode")
5691 (if_then_else (eq_attr "fpu_single" "yes")
5692 (const_string "single") (const_string "double")))
5693 (set_attr "needs_delay_slot" "yes")
5694 (set_attr "fp_set" "unknown")])
5695
5696 (define_insn_and_split "call_value_pcrel"
5697 [(set (match_operand 0 "" "=rf")
5698 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5699 (match_operand 2 "" "")))
5700 (use (reg:PSI FPSCR_REG))
5701 (use (reg:SI PIC_REG))
5702 (clobber (reg:SI PR_REG))
5703 (clobber (match_scratch:SI 3 "=r"))]
5704 "TARGET_SH2"
5705 "#"
5706 "reload_completed"
5707 [(const_int 0)]
5708 "
5709 {
5710 rtx lab = PATTERN (gen_call_site ());
5711
5712 if (SYMBOL_REF_LOCAL_P (operands[1]))
5713 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5714 else
5715 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5716 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5717 operands[2], lab));
5718 DONE;
5719 }"
5720 [(set_attr "type" "call")
5721 (set (attr "fp_mode")
5722 (if_then_else (eq_attr "fpu_single" "yes")
5723 (const_string "single") (const_string "double")))
5724 (set_attr "needs_delay_slot" "yes")
5725 (set_attr "fp_set" "unknown")])
5726
5727 (define_insn "call_value_compact"
5728 [(set (match_operand 0 "" "=rf")
5729 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5730 (match_operand 2 "" "")))
5731 (match_operand 3 "immediate_operand" "n")
5732 (use (reg:SI R0_REG))
5733 (use (reg:SI R1_REG))
5734 (use (reg:PSI FPSCR_REG))
5735 (clobber (reg:SI PR_REG))]
5736 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5737 "jsr @%1%#"
5738 [(set_attr "type" "call")
5739 (set (attr "fp_mode")
5740 (if_then_else (eq_attr "fpu_single" "yes")
5741 (const_string "single") (const_string "double")))
5742 (set_attr "needs_delay_slot" "yes")])
5743
5744 (define_insn "call_value_compact_rettramp"
5745 [(set (match_operand 0 "" "=rf")
5746 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5747 (match_operand 2 "" "")))
5748 (match_operand 3 "immediate_operand" "n")
5749 (use (reg:SI R0_REG))
5750 (use (reg:SI R1_REG))
5751 (use (reg:PSI FPSCR_REG))
5752 (clobber (reg:SI R10_REG))
5753 (clobber (reg:SI PR_REG))]
5754 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5755 "jsr @%1%#"
5756 [(set_attr "type" "call")
5757 (set (attr "fp_mode")
5758 (if_then_else (eq_attr "fpu_single" "yes")
5759 (const_string "single") (const_string "double")))
5760 (set_attr "needs_delay_slot" "yes")])
5761
5762 (define_insn "call_value_media"
5763 [(set (match_operand 0 "" "=rf")
5764 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5765 (match_operand 2 "" "")))
5766 (clobber (reg:DI PR_MEDIA_REG))]
5767 "TARGET_SHMEDIA"
5768 "blink %1, r18"
5769 [(set_attr "type" "jump_media")])
5770
5771 (define_expand "call"
5772 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5773 (match_operand 1 "" ""))
5774 (match_operand 2 "" "")
5775 (use (reg:PSI FPSCR_REG))
5776 (clobber (reg:SI PR_REG))])]
5777 ""
5778 "
5779 {
5780 if (TARGET_SHMEDIA)
5781 {
5782 operands[0] = XEXP (operands[0], 0);
5783 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5784 {
5785 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5786 {
5787 rtx reg = gen_reg_rtx (Pmode);
5788
5789 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5790 operands[0] = reg;
5791 }
5792 else
5793 {
5794 operands[0] = gen_sym2PIC (operands[0]);
5795 PUT_MODE (operands[0], Pmode);
5796 }
5797 }
5798 if (GET_MODE (operands[0]) == SImode)
5799 {
5800 if (GET_CODE (operands[0]) == REG)
5801 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5802 else if (GET_CODE (operands[0]) == SUBREG)
5803 {
5804 operands[0] = SUBREG_REG (operands[0]);
5805 if (GET_MODE (operands[0]) != DImode)
5806 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5807 }
5808 else
5809 {
5810 operands[0] = shallow_copy_rtx (operands[0]);
5811 PUT_MODE (operands[0], DImode);
5812 }
5813 }
5814 if (! target_reg_operand (operands[0], DImode))
5815 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5816 emit_call_insn (gen_call_media (operands[0], operands[1]));
5817 DONE;
5818 }
5819 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5820 {
5821 rtx cookie_rtx = operands[2];
5822 long cookie = INTVAL (cookie_rtx);
5823 rtx func = XEXP (operands[0], 0);
5824 rtx r0, r1;
5825
5826 if (flag_pic)
5827 {
5828 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5829 {
5830 rtx reg = gen_reg_rtx (Pmode);
5831
5832 emit_insn (gen_symGOTPLT2reg (reg, func));
5833 func = reg;
5834 }
5835 else
5836 func = legitimize_pic_address (func, Pmode, 0);
5837 }
5838
5839 r0 = gen_rtx_REG (SImode, R0_REG);
5840 r1 = gen_rtx_REG (SImode, R1_REG);
5841
5842 /* Since such a call function may use all call-clobbered
5843 registers, we force a mode switch earlier, so that we don't
5844 run out of registers when adjusting fpscr for the call. */
5845 emit_insn (gen_force_mode_for_call ());
5846
5847 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5848 if (flag_pic)
5849 {
5850 rtx reg = gen_reg_rtx (Pmode);
5851
5852 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5853 operands[0] = reg;
5854 }
5855 operands[0] = force_reg (SImode, operands[0]);
5856
5857 emit_move_insn (r0, func);
5858 emit_move_insn (r1, cookie_rtx);
5859
5860 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5861 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5862 operands[2]));
5863 else
5864 emit_call_insn (gen_call_compact (operands[0], operands[1],
5865 operands[2]));
5866
5867 DONE;
5868 }
5869 else if (TARGET_SHCOMPACT && flag_pic
5870 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5871 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5872 {
5873 rtx reg = gen_reg_rtx (Pmode);
5874
5875 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5876 XEXP (operands[0], 0) = reg;
5877 }
5878 if (flag_pic && TARGET_SH2
5879 && GET_CODE (operands[0]) == MEM
5880 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5881 {
5882 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5883 DONE;
5884 }
5885 else
5886 {
5887 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5888 operands[1] = operands[2];
5889 }
5890
5891 emit_call_insn (gen_calli (operands[0], operands[1]));
5892 DONE;
5893 }")
5894
5895 (define_insn "call_pop_compact"
5896 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5897 (match_operand 1 "" ""))
5898 (match_operand 2 "immediate_operand" "n")
5899 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5900 (match_operand 3 "immediate_operand" "n")))
5901 (use (reg:SI R0_REG))
5902 (use (reg:SI R1_REG))
5903 (use (reg:PSI FPSCR_REG))
5904 (clobber (reg:SI PR_REG))]
5905 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5906 "jsr @%0%#"
5907 [(set_attr "type" "call")
5908 (set (attr "fp_mode")
5909 (if_then_else (eq_attr "fpu_single" "yes")
5910 (const_string "single") (const_string "double")))
5911 (set_attr "needs_delay_slot" "yes")])
5912
5913 (define_insn "call_pop_compact_rettramp"
5914 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5915 (match_operand 1 "" ""))
5916 (match_operand 2 "immediate_operand" "n")
5917 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5918 (match_operand 3 "immediate_operand" "n")))
5919 (use (reg:SI R0_REG))
5920 (use (reg:SI R1_REG))
5921 (use (reg:PSI FPSCR_REG))
5922 (clobber (reg:SI R10_REG))
5923 (clobber (reg:SI PR_REG))]
5924 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5925 "jsr @%0%#"
5926 [(set_attr "type" "call")
5927 (set (attr "fp_mode")
5928 (if_then_else (eq_attr "fpu_single" "yes")
5929 (const_string "single") (const_string "double")))
5930 (set_attr "needs_delay_slot" "yes")])
5931
5932 (define_expand "call_pop"
5933 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5934 (match_operand 1 "" ""))
5935 (match_operand 2 "" "")
5936 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5937 (match_operand 3 "" "")))])]
5938 "TARGET_SHCOMPACT"
5939 "
5940 {
5941 if (operands[2] && INTVAL (operands[2]))
5942 {
5943 rtx cookie_rtx = operands[2];
5944 long cookie = INTVAL (cookie_rtx);
5945 rtx func = XEXP (operands[0], 0);
5946 rtx r0, r1;
5947
5948 if (flag_pic)
5949 {
5950 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5951 {
5952 rtx reg = gen_reg_rtx (Pmode);
5953
5954 emit_insn (gen_symGOTPLT2reg (reg, func));
5955 func = reg;
5956 }
5957 else
5958 func = legitimize_pic_address (func, Pmode, 0);
5959 }
5960
5961 r0 = gen_rtx_REG (SImode, R0_REG);
5962 r1 = gen_rtx_REG (SImode, R1_REG);
5963
5964 /* Since such a call function may use all call-clobbered
5965 registers, we force a mode switch earlier, so that we don't
5966 run out of registers when adjusting fpscr for the call. */
5967 emit_insn (gen_force_mode_for_call ());
5968
5969 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5970 if (flag_pic)
5971 {
5972 rtx reg = gen_reg_rtx (Pmode);
5973
5974 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5975 operands[0] = reg;
5976 }
5977 operands[0] = force_reg (SImode, operands[0]);
5978
5979 emit_move_insn (r0, func);
5980 emit_move_insn (r1, cookie_rtx);
5981
5982 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5983 emit_call_insn (gen_call_pop_compact_rettramp
5984 (operands[0], operands[1], operands[2], operands[3]));
5985 else
5986 emit_call_insn (gen_call_pop_compact
5987 (operands[0], operands[1], operands[2], operands[3]));
5988
5989 DONE;
5990 }
5991
5992 abort ();
5993 }")
5994
5995 (define_expand "call_value"
5996 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5997 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5998 (match_operand 2 "" "")))
5999 (match_operand 3 "" "")
6000 (use (reg:PSI FPSCR_REG))
6001 (clobber (reg:SI PR_REG))])]
6002 ""
6003 "
6004 {
6005 if (TARGET_SHMEDIA)
6006 {
6007 operands[1] = XEXP (operands[1], 0);
6008 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6009 {
6010 if (! SYMBOL_REF_LOCAL_P (operands[1]))
6011 {
6012 rtx reg = gen_reg_rtx (Pmode);
6013
6014 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6015 operands[1] = reg;
6016 }
6017 else
6018 {
6019 operands[1] = gen_sym2PIC (operands[1]);
6020 PUT_MODE (operands[1], Pmode);
6021 }
6022 }
6023 if (GET_MODE (operands[1]) == SImode)
6024 {
6025 if (GET_CODE (operands[1]) == REG)
6026 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6027 else if (GET_CODE (operands[1]) == SUBREG)
6028 {
6029 operands[1] = SUBREG_REG (operands[1]);
6030 if (GET_MODE (operands[1]) != DImode)
6031 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6032 }
6033 else
6034 {
6035 operands[1] = shallow_copy_rtx (operands[1]);
6036 PUT_MODE (operands[1], DImode);
6037 }
6038 }
6039 if (! target_reg_operand (operands[1], DImode))
6040 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6041 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6042 operands[2]));
6043 DONE;
6044 }
6045 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6046 {
6047 rtx cookie_rtx = operands[3];
6048 long cookie = INTVAL (cookie_rtx);
6049 rtx func = XEXP (operands[1], 0);
6050 rtx r0, r1;
6051
6052 if (flag_pic)
6053 {
6054 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6055 {
6056 rtx reg = gen_reg_rtx (Pmode);
6057
6058 emit_insn (gen_symGOTPLT2reg (reg, func));
6059 func = reg;
6060 }
6061 else
6062 func = legitimize_pic_address (func, Pmode, 0);
6063 }
6064
6065 r0 = gen_rtx_REG (SImode, R0_REG);
6066 r1 = gen_rtx_REG (SImode, R1_REG);
6067
6068 /* Since such a call function may use all call-clobbered
6069 registers, we force a mode switch earlier, so that we don't
6070 run out of registers when adjusting fpscr for the call. */
6071 emit_insn (gen_force_mode_for_call ());
6072
6073 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6074 if (flag_pic)
6075 {
6076 rtx reg = gen_reg_rtx (Pmode);
6077
6078 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6079 operands[1] = reg;
6080 }
6081 operands[1] = force_reg (SImode, operands[1]);
6082
6083 emit_move_insn (r0, func);
6084 emit_move_insn (r1, cookie_rtx);
6085
6086 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6087 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6088 operands[1],
6089 operands[2],
6090 operands[3]));
6091 else
6092 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6093 operands[2], operands[3]));
6094
6095 DONE;
6096 }
6097 else if (TARGET_SHCOMPACT && flag_pic
6098 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6099 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6100 {
6101 rtx reg = gen_reg_rtx (Pmode);
6102
6103 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6104 XEXP (operands[1], 0) = reg;
6105 }
6106 if (flag_pic && TARGET_SH2
6107 && GET_CODE (operands[1]) == MEM
6108 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6109 {
6110 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6111 operands[2]));
6112 DONE;
6113 }
6114 else
6115 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6116
6117 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6118 DONE;
6119 }")
6120
6121 (define_insn "sibcalli"
6122 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6123 (match_operand 1 "" ""))
6124 (use (reg:PSI FPSCR_REG))
6125 (return)]
6126 "TARGET_SH1"
6127 "jmp @%0%#"
6128 [(set_attr "needs_delay_slot" "yes")
6129 (set (attr "fp_mode")
6130 (if_then_else (eq_attr "fpu_single" "yes")
6131 (const_string "single") (const_string "double")))
6132 (set_attr "type" "jump_ind")])
6133
6134 (define_insn "sibcalli_pcrel"
6135 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6136 (match_operand 1 "" ""))
6137 (use (match_operand 2 "" ""))
6138 (use (reg:PSI FPSCR_REG))
6139 (return)]
6140 "TARGET_SH2"
6141 "braf %0\\n%O2:%#"
6142 [(set_attr "needs_delay_slot" "yes")
6143 (set (attr "fp_mode")
6144 (if_then_else (eq_attr "fpu_single" "yes")
6145 (const_string "single") (const_string "double")))
6146 (set_attr "type" "jump_ind")])
6147
6148 (define_insn_and_split "sibcall_pcrel"
6149 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6150 (match_operand 1 "" ""))
6151 (use (reg:PSI FPSCR_REG))
6152 (clobber (match_scratch:SI 2 "=k"))
6153 (return)]
6154 "TARGET_SH2"
6155 "#"
6156 "reload_completed"
6157 [(const_int 0)]
6158 "
6159 {
6160 rtx lab = PATTERN (gen_call_site ());
6161 rtx call_insn;
6162
6163 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6164 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6165 lab));
6166 SIBLING_CALL_P (call_insn) = 1;
6167 DONE;
6168 }"
6169 [(set_attr "needs_delay_slot" "yes")
6170 (set (attr "fp_mode")
6171 (if_then_else (eq_attr "fpu_single" "yes")
6172 (const_string "single") (const_string "double")))
6173 (set_attr "type" "jump_ind")])
6174
6175 (define_insn "sibcall_compact"
6176 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6177 (match_operand 1 "" ""))
6178 (return)
6179 (use (match_operand:SI 2 "register_operand" "z,x"))
6180 (use (reg:SI R1_REG))
6181 (use (reg:PSI FPSCR_REG))
6182 ;; We want to make sure the `x' above will only match MACH_REG
6183 ;; because sibcall_epilogue may clobber MACL_REG.
6184 (clobber (reg:SI MACL_REG))]
6185 "TARGET_SHCOMPACT"
6186 "@
6187 jmp @%0%#
6188 jmp @%0\\n sts %2, r0"
6189 [(set_attr "needs_delay_slot" "yes,no")
6190 (set_attr "length" "2,4")
6191 (set (attr "fp_mode") (const_string "single"))
6192 (set_attr "type" "jump_ind")])
6193
6194 (define_insn "sibcall_media"
6195 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6196 (match_operand 1 "" ""))
6197 (use (reg:SI PR_MEDIA_REG))
6198 (return)]
6199 "TARGET_SHMEDIA"
6200 "blink %0, r63"
6201 [(set_attr "type" "jump_media")])
6202
6203 (define_expand "sibcall"
6204 [(parallel
6205 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6206 (match_operand 1 "" ""))
6207 (match_operand 2 "" "")
6208 (use (reg:PSI FPSCR_REG))
6209 (return)])]
6210 ""
6211 "
6212 {
6213 if (TARGET_SHMEDIA)
6214 {
6215 operands[0] = XEXP (operands[0], 0);
6216 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6217 {
6218 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6219 {
6220 rtx reg = gen_reg_rtx (Pmode);
6221
6222 /* We must not use GOTPLT for sibcalls, because PIC_REG
6223 must be restored before the PLT code gets to run. */
6224 emit_insn (gen_symGOT2reg (reg, operands[0]));
6225 operands[0] = reg;
6226 }
6227 else
6228 {
6229 operands[0] = gen_sym2PIC (operands[0]);
6230 PUT_MODE (operands[0], Pmode);
6231 }
6232 }
6233 if (GET_MODE (operands[0]) == SImode)
6234 {
6235 if (GET_CODE (operands[0]) == REG)
6236 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6237 else if (GET_CODE (operands[0]) == SUBREG)
6238 {
6239 operands[0] = SUBREG_REG (operands[0]);
6240 if (GET_MODE (operands[0]) != DImode)
6241 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6242 }
6243 else
6244 {
6245 operands[0] = shallow_copy_rtx (operands[0]);
6246 PUT_MODE (operands[0], DImode);
6247 }
6248 }
6249 if (! target_reg_operand (operands[0], DImode))
6250 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6251 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6252 DONE;
6253 }
6254 else if (TARGET_SHCOMPACT && operands[2]
6255 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6256 {
6257 rtx cookie_rtx = operands[2];
6258 long cookie = INTVAL (cookie_rtx);
6259 rtx func = XEXP (operands[0], 0);
6260 rtx mach, r1;
6261
6262 if (flag_pic)
6263 {
6264 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6265 {
6266 rtx reg = gen_reg_rtx (Pmode);
6267
6268 emit_insn (gen_symGOT2reg (reg, func));
6269 func = reg;
6270 }
6271 else
6272 func = legitimize_pic_address (func, Pmode, 0);
6273 }
6274
6275 /* FIXME: if we could tell whether all argument registers are
6276 already taken, we could decide whether to force the use of
6277 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6278 simple way to tell. We could use the CALL_COOKIE, but we
6279 can't currently tell a register used for regular argument
6280 passing from one that is unused. If we leave it up to reload
6281 to decide which register to use, it seems to always choose
6282 R0_REG, which leaves no available registers in SIBCALL_REGS
6283 to hold the address of the trampoline. */
6284 mach = gen_rtx_REG (SImode, MACH_REG);
6285 r1 = gen_rtx_REG (SImode, R1_REG);
6286
6287 /* Since such a call function may use all call-clobbered
6288 registers, we force a mode switch earlier, so that we don't
6289 run out of registers when adjusting fpscr for the call. */
6290 emit_insn (gen_force_mode_for_call ());
6291
6292 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6293 if (flag_pic)
6294 {
6295 rtx reg = gen_reg_rtx (Pmode);
6296
6297 emit_insn (gen_symGOT2reg (reg, operands[0]));
6298 operands[0] = reg;
6299 }
6300 operands[0] = force_reg (SImode, operands[0]);
6301
6302 /* We don't need a return trampoline, since the callee will
6303 return directly to the upper caller. */
6304 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6305 {
6306 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6307 cookie_rtx = GEN_INT (cookie);
6308 }
6309
6310 emit_move_insn (mach, func);
6311 emit_move_insn (r1, cookie_rtx);
6312
6313 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6314 DONE;
6315 }
6316 else if (TARGET_SHCOMPACT && flag_pic
6317 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6318 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6319 {
6320 rtx reg = gen_reg_rtx (Pmode);
6321
6322 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6323 XEXP (operands[0], 0) = reg;
6324 }
6325 if (flag_pic && TARGET_SH2
6326 && GET_CODE (operands[0]) == MEM
6327 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6328 /* The PLT needs the PIC register, but the epilogue would have
6329 to restore it, so we can only use PC-relative PIC calls for
6330 static functions. */
6331 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6332 {
6333 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6334 DONE;
6335 }
6336 else
6337 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6338
6339 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6340 DONE;
6341 }")
6342
6343 (define_expand "sibcall_value"
6344 [(set (match_operand 0 "" "")
6345 (call (match_operand 1 "" "")
6346 (match_operand 2 "" "")))
6347 (match_operand 3 "" "")]
6348 ""
6349 "
6350 {
6351 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6352 DONE;
6353 }")
6354
6355 (define_insn "call_value_pop_compact"
6356 [(set (match_operand 0 "" "=rf")
6357 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6358 (match_operand 2 "" "")))
6359 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6360 (match_operand 4 "immediate_operand" "n")))
6361 (match_operand 3 "immediate_operand" "n")
6362 (use (reg:SI R0_REG))
6363 (use (reg:SI R1_REG))
6364 (use (reg:PSI FPSCR_REG))
6365 (clobber (reg:SI PR_REG))]
6366 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6367 "jsr @%1%#"
6368 [(set_attr "type" "call")
6369 (set (attr "fp_mode")
6370 (if_then_else (eq_attr "fpu_single" "yes")
6371 (const_string "single") (const_string "double")))
6372 (set_attr "needs_delay_slot" "yes")])
6373
6374 (define_insn "call_value_pop_compact_rettramp"
6375 [(set (match_operand 0 "" "=rf")
6376 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6377 (match_operand 2 "" "")))
6378 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6379 (match_operand 4 "immediate_operand" "n")))
6380 (match_operand 3 "immediate_operand" "n")
6381 (use (reg:SI R0_REG))
6382 (use (reg:SI R1_REG))
6383 (use (reg:PSI FPSCR_REG))
6384 (clobber (reg:SI R10_REG))
6385 (clobber (reg:SI PR_REG))]
6386 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6387 "jsr @%1%#"
6388 [(set_attr "type" "call")
6389 (set (attr "fp_mode")
6390 (if_then_else (eq_attr "fpu_single" "yes")
6391 (const_string "single") (const_string "double")))
6392 (set_attr "needs_delay_slot" "yes")])
6393
6394 (define_expand "call_value_pop"
6395 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6396 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6397 (match_operand 2 "" "")))
6398 (match_operand 3 "" "")
6399 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6400 (match_operand 4 "" "")))])]
6401 "TARGET_SHCOMPACT"
6402 "
6403 {
6404 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6405 {
6406 rtx cookie_rtx = operands[3];
6407 long cookie = INTVAL (cookie_rtx);
6408 rtx func = XEXP (operands[1], 0);
6409 rtx r0, r1;
6410
6411 if (flag_pic)
6412 {
6413 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6414 {
6415 rtx reg = gen_reg_rtx (Pmode);
6416
6417 emit_insn (gen_symGOTPLT2reg (reg, func));
6418 func = reg;
6419 }
6420 else
6421 func = legitimize_pic_address (func, Pmode, 0);
6422 }
6423
6424 r0 = gen_rtx_REG (SImode, R0_REG);
6425 r1 = gen_rtx_REG (SImode, R1_REG);
6426
6427 /* Since such a call function may use all call-clobbered
6428 registers, we force a mode switch earlier, so that we don't
6429 run out of registers when adjusting fpscr for the call. */
6430 emit_insn (gen_force_mode_for_call ());
6431
6432 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6433 if (flag_pic)
6434 {
6435 rtx reg = gen_reg_rtx (Pmode);
6436
6437 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6438 operands[1] = reg;
6439 }
6440 operands[1] = force_reg (SImode, operands[1]);
6441
6442 emit_move_insn (r0, func);
6443 emit_move_insn (r1, cookie_rtx);
6444
6445 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6446 emit_call_insn (gen_call_value_pop_compact_rettramp
6447 (operands[0], operands[1], operands[2],
6448 operands[3], operands[4]));
6449 else
6450 emit_call_insn (gen_call_value_pop_compact
6451 (operands[0], operands[1], operands[2],
6452 operands[3], operands[4]));
6453
6454 DONE;
6455 }
6456
6457 abort ();
6458 }")
6459
6460 (define_expand "sibcall_epilogue"
6461 [(return)]
6462 ""
6463 "
6464 {
6465 sh_expand_epilogue ();
6466 if (TARGET_SHCOMPACT)
6467 {
6468 rtx insn, set;
6469
6470 /* If epilogue clobbers r0, preserve it in macl. */
6471 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6472 if ((set = single_set (insn))
6473 && GET_CODE (SET_DEST (set)) == REG
6474 && REGNO (SET_DEST (set)) == R0_REG)
6475 {
6476 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6477 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6478 rtx i;
6479
6480 /* We can't tell at this point whether the sibcall is a
6481 sibcall_compact and, if it is, whether it uses r0 or
6482 mach as operand 2, so let the instructions that
6483 preserve r0 be optimized away if r0 turns out to be
6484 dead. */
6485 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6486 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6487 REG_NOTES (i));
6488 i = emit_move_insn (r0, tmp);
6489 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6490 REG_NOTES (i));
6491 break;
6492 }
6493 }
6494 DONE;
6495 }")
6496
6497 (define_insn "indirect_jump_compact"
6498 [(set (pc)
6499 (match_operand:SI 0 "arith_reg_operand" "r"))]
6500 "TARGET_SH1"
6501 "jmp @%0%#"
6502 [(set_attr "needs_delay_slot" "yes")
6503 (set_attr "type" "jump_ind")])
6504
6505 (define_expand "indirect_jump"
6506 [(set (pc)
6507 (match_operand 0 "register_operand" ""))]
6508 ""
6509 "
6510 {
6511 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6512 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6513 }")
6514
6515 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6516 ;; which can be present in structured code from indirect jumps which can not
6517 ;; be present in structured code. This allows -fprofile-arcs to work.
6518
6519 ;; For SH1 processors.
6520 (define_insn "casesi_jump_1"
6521 [(set (pc)
6522 (match_operand:SI 0 "register_operand" "r"))
6523 (use (label_ref (match_operand 1 "" "")))]
6524 "TARGET_SH1"
6525 "jmp @%0%#"
6526 [(set_attr "needs_delay_slot" "yes")
6527 (set_attr "type" "jump_ind")])
6528
6529 ;; For all later processors.
6530 (define_insn "casesi_jump_2"
6531 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6532 (label_ref (match_operand 1 "" ""))))
6533 (use (label_ref (match_operand 2 "" "")))]
6534 "TARGET_SH2
6535 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6536 "braf %0%#"
6537 [(set_attr "needs_delay_slot" "yes")
6538 (set_attr "type" "jump_ind")])
6539
6540 (define_insn "casesi_jump_media"
6541 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6542 (use (label_ref (match_operand 1 "" "")))]
6543 "TARGET_SHMEDIA"
6544 "blink %0, r63"
6545 [(set_attr "type" "jump_media")])
6546
6547 ;; Call subroutine returning any type.
6548 ;; ??? This probably doesn't work.
6549
6550 (define_expand "untyped_call"
6551 [(parallel [(call (match_operand 0 "" "")
6552 (const_int 0))
6553 (match_operand 1 "" "")
6554 (match_operand 2 "" "")])]
6555 "TARGET_SH2E || TARGET_SHMEDIA"
6556 "
6557 {
6558 int i;
6559
6560 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6561
6562 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6563 {
6564 rtx set = XVECEXP (operands[2], 0, i);
6565 emit_move_insn (SET_DEST (set), SET_SRC (set));
6566 }
6567
6568 /* The optimizer does not know that the call sets the function value
6569 registers we stored in the result block. We avoid problems by
6570 claiming that all hard registers are used and clobbered at this
6571 point. */
6572 emit_insn (gen_blockage ());
6573
6574 DONE;
6575 }")
6576 \f
6577 ;; ------------------------------------------------------------------------
6578 ;; Misc insns
6579 ;; ------------------------------------------------------------------------
6580
6581 (define_insn "dect"
6582 [(set (reg:SI T_REG)
6583 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6584 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6585 "TARGET_SH2"
6586 "dt %0"
6587 [(set_attr "type" "arith")])
6588
6589 (define_insn "nop"
6590 [(const_int 0)]
6591 ""
6592 "nop")
6593
6594 ;; Load address of a label. This is only generated by the casesi expand,
6595 ;; and by machine_dependent_reorg (fixing up fp moves).
6596 ;; This must use unspec, because this only works for labels that are
6597 ;; within range,
6598
6599 (define_insn "mova"
6600 [(set (reg:SI R0_REG)
6601 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6602 "TARGET_SH1"
6603 "mova %O0,r0"
6604 [(set_attr "in_delay_slot" "no")
6605 (set_attr "type" "arith")])
6606
6607 ;; machine_dependent_reorg will make this a `mova'.
6608 (define_insn "mova_const"
6609 [(set (reg:SI R0_REG)
6610 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6611 "TARGET_SH1"
6612 "#"
6613 [(set_attr "in_delay_slot" "no")
6614 (set_attr "type" "arith")])
6615
6616 (define_expand "GOTaddr2picreg"
6617 [(set (reg:SI R0_REG)
6618 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6619 UNSPEC_MOVA))
6620 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6621 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6622 "" "
6623 {
6624 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6625 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6626
6627 if (TARGET_SH5)
6628 operands[1] = gen_datalabel_ref (operands[1]);
6629
6630 if (TARGET_SHMEDIA)
6631 {
6632 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6633 rtx dipic = operands[0];
6634 rtx lab = PATTERN (gen_call_site ());
6635 rtx insn, equiv;
6636
6637 equiv = operands[1];
6638 operands[1] = gen_rtx_MINUS (DImode,
6639 operands[1],
6640 gen_rtx_CONST
6641 (DImode,
6642 gen_rtx_MINUS (DImode,
6643 gen_rtx_CONST (DImode,
6644 lab),
6645 pc_rtx)));
6646 operands[1] = gen_sym2PIC (operands[1]);
6647 PUT_MODE (operands[1], DImode);
6648
6649 if (GET_MODE (dipic) != DImode)
6650 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6651
6652 if (TARGET_SHMEDIA64)
6653 emit_insn (gen_movdi_const (dipic, operands[1]));
6654 else
6655 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6656
6657 emit_insn (gen_ptrel (tr, dipic, lab));
6658
6659 if (GET_MODE (operands[0]) != GET_MODE (tr))
6660 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6661
6662 insn = emit_move_insn (operands[0], tr);
6663
6664 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6665 REG_NOTES (insn));
6666
6667 DONE;
6668 }
6669 }
6670 ")
6671
6672 (define_insn "*ptb"
6673 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6674 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6675 UNSPEC_DATALABEL)))]
6676 "TARGET_SHMEDIA && flag_pic
6677 && EXTRA_CONSTRAINT_Csy (operands[1])"
6678 "ptb/u datalabel %1, %0"
6679 [(set_attr "type" "pt_media")
6680 (set_attr "length" "*")])
6681
6682 (define_insn "ptrel"
6683 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6684 (plus:DI (match_operand:DI 1 "register_operand" "r")
6685 (pc)))
6686 (match_operand:DI 2 "" "")]
6687 "TARGET_SHMEDIA"
6688 "%O2: ptrel/u %1, %0"
6689 [(set_attr "type" "ptabs_media")])
6690
6691 (define_expand "builtin_setjmp_receiver"
6692 [(match_operand 0 "" "")]
6693 "flag_pic"
6694 "
6695 {
6696 emit_insn (gen_GOTaddr2picreg ());
6697 DONE;
6698 }")
6699
6700 (define_expand "call_site"
6701 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6702 "TARGET_SH1"
6703 "
6704 {
6705 static HOST_WIDE_INT i = 0;
6706 operands[0] = GEN_INT (i);
6707 i++;
6708 }")
6709
6710 (define_expand "sym_label2reg"
6711 [(set (match_operand:SI 0 "" "")
6712 (const:SI (minus:SI
6713 (const:SI
6714 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6715 (const:SI
6716 (plus:SI
6717 (match_operand:SI 2 "" "")
6718 (const_int 2))))))]
6719 "TARGET_SH1" "")
6720
6721 (define_expand "symGOT_load"
6722 [(set (match_dup 2) (match_operand 1 "" ""))
6723 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6724 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6725 ""
6726 "
6727 {
6728 rtx insn;
6729
6730 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6731 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6732
6733 if (TARGET_SHMEDIA)
6734 {
6735 rtx reg = operands[2];
6736
6737 if (GET_MODE (reg) != DImode)
6738 reg = gen_rtx_SUBREG (DImode, reg, 0);
6739
6740 if (flag_pic > 1)
6741 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6742 else
6743 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6744 }
6745 else
6746 emit_move_insn (operands[2], operands[1]);
6747
6748 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6749 operands[2],
6750 gen_rtx_REG (Pmode, PIC_REG)));
6751
6752 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6753
6754 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6755 0), 0, 0),
6756 REG_NOTES (insn));
6757
6758 DONE;
6759 }")
6760
6761 (define_expand "sym2GOT"
6762 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6763 ""
6764 "")
6765
6766 (define_expand "symGOT2reg"
6767 [(match_operand 0 "" "") (match_operand 1 "" "")]
6768 ""
6769 "
6770 {
6771 rtx gotsym, insn;
6772
6773 gotsym = gen_sym2GOT (operands[1]);
6774 PUT_MODE (gotsym, Pmode);
6775 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6776
6777 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6778
6779 DONE;
6780 }")
6781
6782 (define_expand "sym2GOTPLT"
6783 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6784 ""
6785 "")
6786
6787 (define_expand "symGOTPLT2reg"
6788 [(match_operand 0 "" "") (match_operand 1 "" "")]
6789 ""
6790 "
6791 {
6792 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6793 DONE;
6794 }")
6795
6796 (define_expand "sym2GOTOFF"
6797 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6798 ""
6799 "")
6800
6801 (define_expand "symGOTOFF2reg"
6802 [(match_operand 0 "" "") (match_operand 1 "" "")]
6803 ""
6804 "
6805 {
6806 rtx gotoffsym, insn;
6807 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6808
6809 gotoffsym = gen_sym2GOTOFF (operands[1]);
6810 PUT_MODE (gotoffsym, Pmode);
6811 emit_move_insn (t, gotoffsym);
6812 insn = emit_move_insn (operands[0],
6813 gen_rtx_PLUS (Pmode, t,
6814 gen_rtx_REG (Pmode, PIC_REG)));
6815
6816 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6817 REG_NOTES (insn));
6818
6819 DONE;
6820 }")
6821
6822 (define_expand "symPLT_label2reg"
6823 [(set (match_operand:SI 0 "" "")
6824 (const:SI (minus:SI
6825 (const:SI
6826 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6827 (const:SI
6828 (minus:SI
6829 (const:SI (plus:SI
6830 (match_operand:SI 2 "" "")
6831 (const_int 2)))
6832 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6833 ;; Even though the PIC register is not really used by the call
6834 ;; sequence in which this is expanded, the PLT code assumes the PIC
6835 ;; register is set, so we must not skip its initialization. Since
6836 ;; we only use this expand as part of calling sequences, and never
6837 ;; to take the address of a function, this is the best point to
6838 ;; insert the (use). Using the PLT to take the address of a
6839 ;; function would be wrong, not only because the PLT entry could
6840 ;; then be called from a function that doesn't initialize the PIC
6841 ;; register to the proper GOT, but also because pointers to the
6842 ;; same function might not compare equal, should they be set by
6843 ;; different shared libraries.
6844 (use (reg:SI PIC_REG))]
6845 "TARGET_SH1"
6846 "")
6847
6848 (define_expand "sym2PIC"
6849 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6850 ""
6851 "")
6852
6853 ;; TLS code generation.
6854 ;; ??? this should be a define_insn_and_split
6855 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6856 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6857 ;; for details.
6858
6859 (define_insn "tls_global_dynamic"
6860 [(set (match_operand:SI 0 "register_operand" "=&z")
6861 (unspec:SI [(match_operand:SI 1 "" "")]
6862 UNSPEC_TLSGD))
6863 (use (reg:PSI FPSCR_REG))
6864 (use (reg:SI PIC_REG))
6865 (clobber (reg:SI PR_REG))
6866 (clobber (scratch:SI))]
6867 "TARGET_SH1"
6868 "*
6869 {
6870 return \"\\
6871 mov.l\\t1f,r4\\n\\
6872 \\tmova\\t2f,r0\\n\\
6873 \\tmov.l\\t2f,r1\\n\\
6874 \\tadd\\tr0,r1\\n\\
6875 \\tjsr\\t@r1\\n\\
6876 \\tadd\\tr12,r4\\n\\
6877 \\tbra\\t3f\\n\\
6878 \\tnop\\n\\
6879 \\t.align\\t2\\n\\
6880 1:\\t.long\\t%a1@TLSGD\\n\\
6881 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6882 3:\";
6883 }"
6884 [(set_attr "type" "tls_load")
6885 (set_attr "length" "26")])
6886
6887 (define_insn "tls_local_dynamic"
6888 [(set (match_operand:SI 0 "register_operand" "=&z")
6889 (unspec:SI [(match_operand:SI 1 "" "")]
6890 UNSPEC_TLSLDM))
6891 (use (reg:PSI FPSCR_REG))
6892 (use (reg:SI PIC_REG))
6893 (clobber (reg:SI PR_REG))
6894 (clobber (scratch:SI))]
6895 "TARGET_SH1"
6896 "*
6897 {
6898 return \"\\
6899 mov.l\\t1f,r4\\n\\
6900 \\tmova\\t2f,r0\\n\\
6901 \\tmov.l\\t2f,r1\\n\\
6902 \\tadd\\tr0,r1\\n\\
6903 \\tjsr\\t@r1\\n\\
6904 \\tadd\\tr12,r4\\n\\
6905 \\tbra\\t3f\\n\\
6906 \\tnop\\n\\
6907 \\t.align\\t2\\n\\
6908 1:\\t.long\\t%a1@TLSLDM\\n\\
6909 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6910 3:\";
6911 }"
6912 [(set_attr "type" "tls_load")
6913 (set_attr "length" "26")])
6914
6915 (define_expand "sym2DTPOFF"
6916 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6917 ""
6918 "")
6919
6920 (define_expand "symDTPOFF2reg"
6921 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6922 ""
6923 "
6924 {
6925 rtx dtpoffsym, insn;
6926 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6927
6928 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6929 PUT_MODE (dtpoffsym, Pmode);
6930 emit_move_insn (t, dtpoffsym);
6931 insn = emit_move_insn (operands[0],
6932 gen_rtx_PLUS (Pmode, t, operands[2]));
6933 DONE;
6934 }")
6935
6936 (define_expand "sym2GOTTPOFF"
6937 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6938 ""
6939 "")
6940
6941 (define_insn "tls_initial_exec"
6942 [(set (match_operand:SI 0 "register_operand" "=&r")
6943 (unspec:SI [(match_operand:SI 1 "" "")]
6944 UNSPEC_TLSIE))
6945 (use (reg:SI GBR_REG))
6946 (use (reg:SI PIC_REG))
6947 (clobber (reg:SI R0_REG))]
6948 ""
6949 "*
6950 {
6951 return \"\\
6952 mov.l\\t1f,r0\\n\\
6953 \\tstc\\tgbr,%0\\n\\
6954 \\tmov.l\\t@(r0,r12),r0\\n\\
6955 \\tbra\\t2f\\n\\
6956 \\tadd\\tr0,%0\\n\\
6957 \\t.align\\t2\\n\\
6958 1:\\t.long\\t%a1\\n\\
6959 2:\";
6960 }"
6961 [(set_attr "type" "tls_load")
6962 (set_attr "length" "16")])
6963
6964 (define_expand "sym2TPOFF"
6965 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6966 ""
6967 "")
6968
6969 (define_expand "symTPOFF2reg"
6970 [(match_operand 0 "" "") (match_operand 1 "" "")]
6971 ""
6972 "
6973 {
6974 rtx tpoffsym, insn;
6975
6976 tpoffsym = gen_sym2TPOFF (operands[1]);
6977 PUT_MODE (tpoffsym, Pmode);
6978 insn = emit_move_insn (operands[0], tpoffsym);
6979 DONE;
6980 }")
6981
6982 (define_insn "load_gbr"
6983 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6984 (use (reg:SI GBR_REG))]
6985 ""
6986 "stc gbr,%0"
6987 [(set_attr "type" "tls_load")])
6988
6989 ;; case instruction for switch statements.
6990
6991 ;; Operand 0 is index
6992 ;; operand 1 is the minimum bound
6993 ;; operand 2 is the maximum bound - minimum bound + 1
6994 ;; operand 3 is CODE_LABEL for the table;
6995 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6996
6997 (define_expand "casesi"
6998 [(match_operand:SI 0 "arith_reg_operand" "")
6999 (match_operand:SI 1 "arith_reg_operand" "")
7000 (match_operand:SI 2 "arith_reg_operand" "")
7001 (match_operand 3 "" "") (match_operand 4 "" "")]
7002 ""
7003 "
7004 {
7005 rtx reg = gen_reg_rtx (SImode);
7006 rtx reg2 = gen_reg_rtx (SImode);
7007 if (TARGET_SHMEDIA)
7008 {
7009 rtx reg = gen_reg_rtx (DImode);
7010 rtx reg2 = gen_reg_rtx (DImode);
7011 rtx reg3 = gen_reg_rtx (DImode);
7012 rtx reg4 = gen_reg_rtx (DImode);
7013 rtx reg5 = gen_reg_rtx (DImode);
7014
7015 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7016 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7017 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7018
7019 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7020 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7021 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7022 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7023 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7024 (DImode, operands[3])));
7025 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7026 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7027 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7028 emit_barrier ();
7029 DONE;
7030 }
7031 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7032 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7033 /* If optimizing, casesi_worker depends on the mode of the instruction
7034 before label it 'uses' - operands[3]. */
7035 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7036 reg));
7037 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7038 if (TARGET_SH2)
7039 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7040 else
7041 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7042 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7043 operands[3], but to lab. We will fix this up in
7044 machine_dependent_reorg. */
7045 emit_barrier ();
7046 DONE;
7047 }")
7048
7049 (define_expand "casesi_0"
7050 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7051 (set (match_dup 4) (minus:SI (match_dup 4)
7052 (match_operand:SI 1 "arith_operand" "")))
7053 (set (reg:SI T_REG)
7054 (gtu:SI (match_dup 4)
7055 (match_operand:SI 2 "arith_reg_operand" "")))
7056 (set (pc)
7057 (if_then_else (ne (reg:SI T_REG)
7058 (const_int 0))
7059 (label_ref (match_operand 3 "" ""))
7060 (pc)))]
7061 "TARGET_SH1"
7062 "")
7063
7064 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7065 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7066 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7067
7068 (define_insn "casesi_worker_0"
7069 [(set (match_operand:SI 0 "register_operand" "=r,r")
7070 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7071 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7072 (clobber (match_scratch:SI 3 "=X,1"))
7073 (clobber (match_scratch:SI 4 "=&z,z"))]
7074 "TARGET_SH1"
7075 "#")
7076
7077 (define_split
7078 [(set (match_operand:SI 0 "register_operand" "")
7079 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7080 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7081 (clobber (match_scratch:SI 3 ""))
7082 (clobber (match_scratch:SI 4 ""))]
7083 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7084 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7085 (parallel [(set (match_dup 0)
7086 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7087 (label_ref (match_dup 2))] UNSPEC_CASESI))
7088 (clobber (match_dup 3))])
7089 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7090 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7091
7092 (define_split
7093 [(set (match_operand:SI 0 "register_operand" "")
7094 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7095 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7096 (clobber (match_scratch:SI 3 ""))
7097 (clobber (match_scratch:SI 4 ""))]
7098 "TARGET_SH2 && reload_completed"
7099 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7100 (parallel [(set (match_dup 0)
7101 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7102 (label_ref (match_dup 2))] UNSPEC_CASESI))
7103 (clobber (match_dup 3))])]
7104 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7105
7106 (define_insn "*casesi_worker"
7107 [(set (match_operand:SI 0 "register_operand" "=r,r")
7108 (unspec:SI [(reg:SI R0_REG)
7109 (match_operand:SI 1 "register_operand" "0,r")
7110 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7111 (clobber (match_scratch:SI 3 "=X,1"))]
7112 "TARGET_SH1"
7113 "*
7114 {
7115 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7116
7117 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7118 abort ();
7119
7120 switch (GET_MODE (diff_vec))
7121 {
7122 case SImode:
7123 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7124 case HImode:
7125 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7126 case QImode:
7127 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7128 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7129 return \"mov.b @(r0,%1),%0\";
7130 default:
7131 abort ();
7132 }
7133 }"
7134 [(set_attr "length" "4")])
7135
7136 (define_insn "casesi_shift_media"
7137 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7138 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7139 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7140 UNSPEC_CASESI)))]
7141 "TARGET_SHMEDIA"
7142 "*
7143 {
7144 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7145
7146 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7147 abort ();
7148
7149 switch (GET_MODE (diff_vec))
7150 {
7151 case SImode:
7152 return \"shlli %1, 2, %0\";
7153 case HImode:
7154 return \"shlli %1, 1, %0\";
7155 case QImode:
7156 if (rtx_equal_p (operands[0], operands[1]))
7157 return \"\";
7158 return \"add %1, r63, %0\";
7159 default:
7160 abort ();
7161 }
7162 }"
7163 [(set_attr "type" "arith_media")])
7164
7165 (define_insn "casesi_load_media"
7166 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7167 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7168 (match_operand 2 "arith_reg_operand" "r")
7169 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7170 "TARGET_SHMEDIA"
7171 "*
7172 {
7173 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7174
7175 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7176 abort ();
7177
7178 switch (GET_MODE (diff_vec))
7179 {
7180 case SImode:
7181 return \"ldx.l %1, %2, %0\";
7182 case HImode:
7183 #if 0
7184 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7185 return \"ldx.uw %1, %2, %0\";
7186 #endif
7187 return \"ldx.w %1, %2, %0\";
7188 case QImode:
7189 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7190 return \"ldx.ub %1, %2, %0\";
7191 return \"ldx.b %1, %2, %0\";
7192 default:
7193 abort ();
7194 }
7195 }"
7196 [(set_attr "type" "load_media")])
7197
7198 (define_expand "return"
7199 [(return)]
7200 "reload_completed && ! sh_need_epilogue ()"
7201 "
7202 {
7203 if (TARGET_SHMEDIA)
7204 {
7205 emit_jump_insn (gen_return_media ());
7206 DONE;
7207 }
7208
7209 if (TARGET_SHCOMPACT
7210 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7211 {
7212 emit_jump_insn (gen_shcompact_return_tramp ());
7213 DONE;
7214 }
7215 }")
7216
7217 (define_insn "*return_i"
7218 [(return)]
7219 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7220 && (current_function_args_info.call_cookie
7221 & CALL_COOKIE_RET_TRAMP (1)))
7222 && reload_completed"
7223 "%@ %#"
7224 [(set_attr "type" "return")
7225 (set_attr "needs_delay_slot" "yes")])
7226
7227 (define_expand "shcompact_return_tramp"
7228 [(return)]
7229 "TARGET_SHCOMPACT
7230 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7231 "
7232 {
7233 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7234 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7235
7236 if (flag_pic)
7237 emit_insn (gen_symGOTPLT2reg (reg, sym));
7238 else
7239 emit_move_insn (reg, sym);
7240
7241 emit_jump_insn (gen_shcompact_return_tramp_i ());
7242 DONE;
7243 }")
7244
7245 (define_insn "shcompact_return_tramp_i"
7246 [(parallel [(return) (use (reg:SI R0_REG))])]
7247 "TARGET_SHCOMPACT
7248 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7249 "jmp @r0%#"
7250 [(set_attr "type" "jump_ind")
7251 (set_attr "needs_delay_slot" "yes")])
7252
7253 (define_insn "return_media_i"
7254 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7255 "TARGET_SHMEDIA && reload_completed"
7256 "blink %0, r63"
7257 [(set_attr "type" "jump_media")])
7258
7259 (define_insn "return_media_rte"
7260 [(return)]
7261 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7262 "rte"
7263 [(set_attr "type" "jump_media")])
7264
7265 (define_expand "return_media"
7266 [(return)]
7267 "TARGET_SHMEDIA && reload_completed"
7268 "
7269 {
7270 int tr_regno = sh_media_register_for_return ();
7271 rtx tr;
7272
7273 if (current_function_interrupt)
7274 {
7275 emit_jump_insn (gen_return_media_rte ());
7276 DONE;
7277 }
7278 if (tr_regno < 0)
7279 {
7280 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7281
7282 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7283 abort ();
7284 tr_regno = TR0_REG;
7285 tr = gen_rtx_REG (DImode, tr_regno);
7286 emit_move_insn (tr, r18);
7287 }
7288 else
7289 tr = gen_rtx_REG (DImode, tr_regno);
7290
7291 emit_jump_insn (gen_return_media_i (tr));
7292 DONE;
7293 }")
7294
7295 (define_insn "shcompact_preserve_incoming_args"
7296 [(set (match_operand:SI 0 "register_operand" "+r")
7297 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7298 "TARGET_SHCOMPACT"
7299 ""
7300 [(set_attr "length" "0")])
7301
7302 (define_insn "shcompact_incoming_args"
7303 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7304 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7305 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7306 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7307 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7308 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7309 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7310 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7311 (set (mem:BLK (reg:SI MACL_REG))
7312 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7313 (use (reg:SI R0_REG))
7314 (clobber (reg:SI R0_REG))
7315 (clobber (reg:SI MACL_REG))
7316 (clobber (reg:SI MACH_REG))
7317 (clobber (reg:SI PR_REG))]
7318 "TARGET_SHCOMPACT"
7319 "jsr @r0%#"
7320 [(set_attr "needs_delay_slot" "yes")])
7321
7322 (define_insn "shmedia_save_restore_regs_compact"
7323 [(set (reg:SI SP_REG)
7324 (plus:SI (reg:SI SP_REG)
7325 (match_operand:SI 0 "immediate_operand" "i")))
7326 (use (reg:SI R0_REG))
7327 (clobber (reg:SI PR_REG))]
7328 "TARGET_SHCOMPACT
7329 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7330 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7331 "jsr @r0%#"
7332 [(set_attr "needs_delay_slot" "yes")])
7333
7334 (define_expand "prologue"
7335 [(const_int 0)]
7336 ""
7337 "sh_expand_prologue (); DONE;")
7338
7339 (define_expand "epilogue"
7340 [(return)]
7341 ""
7342 "
7343 {
7344 sh_expand_epilogue ();
7345 emit_jump_insn (gen_return ());
7346 DONE;
7347 }")
7348
7349 (define_expand "eh_return"
7350 [(use (match_operand 0 "register_operand" ""))]
7351 ""
7352 {
7353 rtx tmp, ra = operands[0];
7354
7355 if (TARGET_SHMEDIA64)
7356 emit_insn (gen_eh_set_ra_di (ra));
7357 else
7358 emit_insn (gen_eh_set_ra_si (ra));
7359
7360 DONE;
7361 })
7362
7363 ;; Clobber the return address on the stack. We can't expand this
7364 ;; until we know where it will be put in the stack frame.
7365
7366 (define_insn "eh_set_ra_si"
7367 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7368 (clobber (match_scratch:SI 1 "=&r"))]
7369 "! TARGET_SHMEDIA64"
7370 "#")
7371
7372 (define_insn "eh_set_ra_di"
7373 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7374 (clobber (match_scratch:DI 1 "=&r"))]
7375 "TARGET_SHMEDIA64"
7376 "#")
7377
7378 (define_split
7379 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7380 (clobber (match_scratch 1 ""))]
7381 "reload_completed"
7382 [(const_int 0)]
7383 "
7384 {
7385 sh_set_return_address (operands[0], operands[1]);
7386 DONE;
7387 }")
7388
7389 (define_insn "blockage"
7390 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7391 ""
7392 ""
7393 [(set_attr "length" "0")])
7394 \f
7395 ;; ------------------------------------------------------------------------
7396 ;; Scc instructions
7397 ;; ------------------------------------------------------------------------
7398
7399 (define_insn "movt"
7400 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7401 (eq:SI (reg:SI T_REG) (const_int 1)))]
7402 "TARGET_SH1"
7403 "movt %0"
7404 [(set_attr "type" "arith")])
7405
7406 (define_expand "seq"
7407 [(set (match_operand:SI 0 "arith_reg_operand" "")
7408 (match_dup 1))]
7409 ""
7410 "
7411 {
7412 if (TARGET_SHMEDIA)
7413 {
7414 if (GET_MODE (operands[0]) != DImode)
7415 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7416 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7417 if (sh_compare_op1 != const0_rtx)
7418 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7419 ? GET_MODE (sh_compare_op0)
7420 : GET_MODE (sh_compare_op1),
7421 sh_compare_op1);
7422
7423 switch (GET_MODE (sh_compare_op0))
7424 {
7425 case DImode:
7426 emit_insn (gen_cmpeqdi_media (operands[0],
7427 sh_compare_op0, sh_compare_op1));
7428 break;
7429
7430 case SFmode:
7431 if (! TARGET_SHMEDIA_FPU)
7432 FAIL;
7433 emit_insn (gen_cmpeqsf_media (operands[0],
7434 sh_compare_op0, sh_compare_op1));
7435 break;
7436
7437 case DFmode:
7438 if (! TARGET_SHMEDIA_FPU)
7439 FAIL;
7440 emit_insn (gen_cmpeqdf_media (operands[0],
7441 sh_compare_op0, sh_compare_op1));
7442 break;
7443
7444 default:
7445 FAIL;
7446 }
7447 DONE;
7448 }
7449 operands[1] = prepare_scc_operands (EQ);
7450 }")
7451
7452 (define_expand "slt"
7453 [(set (match_operand:SI 0 "arith_reg_operand" "")
7454 (match_dup 1))]
7455 ""
7456 "
7457 {
7458 if (TARGET_SHMEDIA)
7459 {
7460 if (GET_MODE (operands[0]) != DImode)
7461 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7462 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7463 if (sh_compare_op1 != const0_rtx)
7464 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7465 ? GET_MODE (sh_compare_op0)
7466 : GET_MODE (sh_compare_op1),
7467 sh_compare_op1);
7468
7469 switch (GET_MODE (sh_compare_op0))
7470 {
7471 case DImode:
7472 emit_insn (gen_cmpgtdi_media (operands[0],
7473 sh_compare_op1, sh_compare_op0));
7474 break;
7475
7476 case SFmode:
7477 if (! TARGET_SHMEDIA_FPU)
7478 FAIL;
7479 emit_insn (gen_cmpgtsf_media (operands[0],
7480 sh_compare_op1, sh_compare_op0));
7481 break;
7482
7483 case DFmode:
7484 if (! TARGET_SHMEDIA_FPU)
7485 FAIL;
7486 emit_insn (gen_cmpgtdf_media (operands[0],
7487 sh_compare_op1, sh_compare_op0));
7488 break;
7489
7490 default:
7491 FAIL;
7492 }
7493 DONE;
7494 }
7495 operands[1] = prepare_scc_operands (LT);
7496 }")
7497
7498 (define_expand "sle"
7499 [(match_operand:SI 0 "arith_reg_operand" "")]
7500 ""
7501 "
7502 {
7503 rtx tmp = sh_compare_op0;
7504
7505 if (TARGET_SHMEDIA)
7506 {
7507 if (GET_MODE (operands[0]) != DImode)
7508 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7509 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7510 if (sh_compare_op1 != const0_rtx)
7511 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7512 ? GET_MODE (sh_compare_op0)
7513 : GET_MODE (sh_compare_op1),
7514 sh_compare_op1);
7515
7516 switch (GET_MODE (sh_compare_op0))
7517 {
7518 case DImode:
7519 {
7520 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7521
7522 emit_insn (gen_cmpgtdi_media (tmp,
7523 sh_compare_op0, sh_compare_op1));
7524 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7525 break;
7526 }
7527
7528 case SFmode:
7529 if (! TARGET_SHMEDIA_FPU)
7530 FAIL;
7531 emit_insn (gen_cmpgesf_media (operands[0],
7532 sh_compare_op1, sh_compare_op0));
7533 break;
7534
7535 case DFmode:
7536 if (! TARGET_SHMEDIA_FPU)
7537 FAIL;
7538 emit_insn (gen_cmpgedf_media (operands[0],
7539 sh_compare_op1, sh_compare_op0));
7540 break;
7541
7542 default:
7543 FAIL;
7544 }
7545 DONE;
7546 }
7547
7548 sh_compare_op0 = sh_compare_op1;
7549 sh_compare_op1 = tmp;
7550 emit_insn (gen_sge (operands[0]));
7551 DONE;
7552 }")
7553
7554 (define_expand "sgt"
7555 [(set (match_operand:SI 0 "arith_reg_operand" "")
7556 (match_dup 1))]
7557 ""
7558 "
7559 {
7560 if (TARGET_SHMEDIA)
7561 {
7562 if (GET_MODE (operands[0]) != DImode)
7563 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7564 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7565 if (sh_compare_op1 != const0_rtx)
7566 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7567 ? GET_MODE (sh_compare_op0)
7568 : GET_MODE (sh_compare_op1),
7569 sh_compare_op1);
7570
7571 switch (GET_MODE (sh_compare_op0))
7572 {
7573 case DImode:
7574 emit_insn (gen_cmpgtdi_media (operands[0],
7575 sh_compare_op0, sh_compare_op1));
7576 break;
7577
7578 case SFmode:
7579 if (! TARGET_SHMEDIA_FPU)
7580 FAIL;
7581 emit_insn (gen_cmpgtsf_media (operands[0],
7582 sh_compare_op0, sh_compare_op1));
7583 break;
7584
7585 case DFmode:
7586 if (! TARGET_SHMEDIA_FPU)
7587 FAIL;
7588 emit_insn (gen_cmpgtdf_media (operands[0],
7589 sh_compare_op0, sh_compare_op1));
7590 break;
7591
7592 default:
7593 FAIL;
7594 }
7595 DONE;
7596 }
7597 operands[1] = prepare_scc_operands (GT);
7598 }")
7599
7600 (define_expand "sge"
7601 [(set (match_operand:SI 0 "arith_reg_operand" "")
7602 (match_dup 1))]
7603 ""
7604 "
7605 {
7606 if (TARGET_SHMEDIA)
7607 {
7608 if (GET_MODE (operands[0]) != DImode)
7609 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7610 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7611 if (sh_compare_op1 != const0_rtx)
7612 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7613 ? GET_MODE (sh_compare_op0)
7614 : GET_MODE (sh_compare_op1),
7615 sh_compare_op1);
7616
7617 switch (GET_MODE (sh_compare_op0))
7618 {
7619 case DImode:
7620 {
7621 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7622
7623 emit_insn (gen_cmpgtdi_media (tmp,
7624 sh_compare_op1, sh_compare_op0));
7625 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7626 break;
7627 }
7628
7629 case SFmode:
7630 if (! TARGET_SHMEDIA_FPU)
7631 FAIL;
7632 emit_insn (gen_cmpgesf_media (operands[0],
7633 sh_compare_op0, sh_compare_op1));
7634 break;
7635
7636 case DFmode:
7637 if (! TARGET_SHMEDIA_FPU)
7638 FAIL;
7639 emit_insn (gen_cmpgedf_media (operands[0],
7640 sh_compare_op0, sh_compare_op1));
7641 break;
7642
7643 default:
7644 FAIL;
7645 }
7646 DONE;
7647 }
7648
7649 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7650 {
7651 if (TARGET_IEEE)
7652 {
7653 rtx lab = gen_label_rtx ();
7654 prepare_scc_operands (EQ);
7655 emit_jump_insn (gen_branch_true (lab));
7656 prepare_scc_operands (GT);
7657 emit_label (lab);
7658 emit_insn (gen_movt (operands[0]));
7659 }
7660 else
7661 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7662 DONE;
7663 }
7664 operands[1] = prepare_scc_operands (GE);
7665 }")
7666
7667 (define_expand "sgtu"
7668 [(set (match_operand:SI 0 "arith_reg_operand" "")
7669 (match_dup 1))]
7670 ""
7671 "
7672 {
7673 if (TARGET_SHMEDIA)
7674 {
7675 if (GET_MODE (operands[0]) != DImode)
7676 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7677 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7678 if (sh_compare_op1 != const0_rtx)
7679 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7680 ? GET_MODE (sh_compare_op0)
7681 : GET_MODE (sh_compare_op1),
7682 sh_compare_op1);
7683
7684 emit_insn (gen_cmpgtudi_media (operands[0],
7685 sh_compare_op0, sh_compare_op1));
7686 DONE;
7687 }
7688 operands[1] = prepare_scc_operands (GTU);
7689 }")
7690
7691 (define_expand "sltu"
7692 [(set (match_operand:SI 0 "arith_reg_operand" "")
7693 (match_dup 1))]
7694 ""
7695 "
7696 {
7697 if (TARGET_SHMEDIA)
7698 {
7699 if (GET_MODE (operands[0]) != DImode)
7700 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7701 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7702 if (sh_compare_op1 != const0_rtx)
7703 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7704 ? GET_MODE (sh_compare_op0)
7705 : GET_MODE (sh_compare_op1),
7706 sh_compare_op1);
7707
7708 emit_insn (gen_cmpgtudi_media (operands[0],
7709 sh_compare_op1, sh_compare_op0));
7710 DONE;
7711 }
7712 operands[1] = prepare_scc_operands (LTU);
7713 }")
7714
7715 (define_expand "sleu"
7716 [(set (match_operand:SI 0 "arith_reg_operand" "")
7717 (match_dup 1))]
7718 ""
7719 "
7720 {
7721 if (TARGET_SHMEDIA)
7722 {
7723 rtx tmp;
7724
7725 if (GET_MODE (operands[0]) != DImode)
7726 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7727 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7728 if (sh_compare_op1 != const0_rtx)
7729 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7730 ? GET_MODE (sh_compare_op0)
7731 : GET_MODE (sh_compare_op1),
7732 sh_compare_op1);
7733
7734 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7735
7736 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7737 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7738
7739 DONE;
7740 }
7741 operands[1] = prepare_scc_operands (LEU);
7742 }")
7743
7744 (define_expand "sgeu"
7745 [(set (match_operand:SI 0 "arith_reg_operand" "")
7746 (match_dup 1))]
7747 ""
7748 "
7749 {
7750 if (TARGET_SHMEDIA)
7751 {
7752 rtx tmp;
7753
7754 if (GET_MODE (operands[0]) != DImode)
7755 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7756 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7757 if (sh_compare_op1 != const0_rtx)
7758 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7759 ? GET_MODE (sh_compare_op0)
7760 : GET_MODE (sh_compare_op1),
7761 sh_compare_op1);
7762
7763 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7764
7765 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7766 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7767
7768 DONE;
7769 }
7770
7771 operands[1] = prepare_scc_operands (GEU);
7772 }")
7773
7774 ;; sne moves the complement of the T reg to DEST like this:
7775 ;; cmp/eq ...
7776 ;; mov #-1,temp
7777 ;; negc temp,dest
7778 ;; This is better than xoring compare result with 1 because it does
7779 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7780 ;; loop.
7781
7782 (define_expand "sne"
7783 [(set (match_dup 2) (const_int -1))
7784 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7785 (neg:SI (plus:SI (match_dup 1)
7786 (match_dup 2))))
7787 (set (reg:SI T_REG)
7788 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7789 (const_int 0)))])]
7790 ""
7791 "
7792 {
7793 if (TARGET_SHMEDIA)
7794 {
7795 rtx tmp;
7796
7797 if (GET_MODE (operands[0]) != DImode)
7798 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7799
7800 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7801 FAIL;
7802
7803 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7804 if (sh_compare_op1 != const0_rtx)
7805 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7806 ? GET_MODE (sh_compare_op0)
7807 : GET_MODE (sh_compare_op1),
7808 sh_compare_op1);
7809
7810 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7811
7812 emit_insn (gen_seq (tmp));
7813 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7814
7815 DONE;
7816 }
7817
7818 operands[1] = prepare_scc_operands (EQ);
7819 operands[2] = gen_reg_rtx (SImode);
7820 }")
7821
7822 (define_expand "sunordered"
7823 [(set (match_operand:DI 0 "arith_reg_operand" "")
7824 (unordered:DI (match_dup 1) (match_dup 2)))]
7825 "TARGET_SHMEDIA_FPU"
7826 "
7827 {
7828 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7829 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7830 }")
7831
7832 ;; Use the same trick for FP sle / sge
7833 (define_expand "movnegt"
7834 [(set (match_dup 2) (const_int -1))
7835 (parallel [(set (match_operand 0 "" "")
7836 (neg:SI (plus:SI (match_dup 1)
7837 (match_dup 2))))
7838 (set (reg:SI T_REG)
7839 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7840 (const_int 0)))])]
7841 "TARGET_SH1"
7842 "operands[2] = gen_reg_rtx (SImode);")
7843
7844 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7845 ;; This prevents a regression that occurred when we switched from xor to
7846 ;; mov/neg for sne.
7847
7848 (define_split
7849 [(set (match_operand:SI 0 "arith_reg_operand" "")
7850 (plus:SI (reg:SI T_REG)
7851 (const_int -1)))]
7852 "TARGET_SH1"
7853 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7854 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7855 "")
7856
7857 ;; -------------------------------------------------------------------------
7858 ;; Instructions to cope with inline literal tables
7859 ;; -------------------------------------------------------------------------
7860
7861 ; 2 byte integer in line
7862
7863 (define_insn "consttable_2"
7864 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7865 (match_operand 1 "" "")]
7866 UNSPECV_CONST2)]
7867 ""
7868 "*
7869 {
7870 if (operands[1] != const0_rtx)
7871 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7872 return \"\";
7873 }"
7874 [(set_attr "length" "2")
7875 (set_attr "in_delay_slot" "no")])
7876
7877 ; 4 byte integer in line
7878
7879 (define_insn "consttable_4"
7880 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7881 (match_operand 1 "" "")]
7882 UNSPECV_CONST4)]
7883 ""
7884 "*
7885 {
7886 if (operands[1] != const0_rtx)
7887 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7888 return \"\";
7889 }"
7890 [(set_attr "length" "4")
7891 (set_attr "in_delay_slot" "no")])
7892
7893 ; 8 byte integer in line
7894
7895 (define_insn "consttable_8"
7896 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7897 (match_operand 1 "" "")]
7898 UNSPECV_CONST8)]
7899 ""
7900 "*
7901 {
7902 if (operands[1] != const0_rtx)
7903 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7904 return \"\";
7905 }"
7906 [(set_attr "length" "8")
7907 (set_attr "in_delay_slot" "no")])
7908
7909 ; 4 byte floating point
7910
7911 (define_insn "consttable_sf"
7912 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7913 (match_operand 1 "" "")]
7914 UNSPECV_CONST4)]
7915 ""
7916 "*
7917 {
7918 if (operands[1] != const0_rtx)
7919 {
7920 REAL_VALUE_TYPE d;
7921 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7922 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7923 }
7924 return \"\";
7925 }"
7926 [(set_attr "length" "4")
7927 (set_attr "in_delay_slot" "no")])
7928
7929 ; 8 byte floating point
7930
7931 (define_insn "consttable_df"
7932 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7933 (match_operand 1 "" "")]
7934 UNSPECV_CONST8)]
7935 ""
7936 "*
7937 {
7938 if (operands[1] != const0_rtx)
7939 {
7940 REAL_VALUE_TYPE d;
7941 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7942 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7943 }
7944 return \"\";
7945 }"
7946 [(set_attr "length" "8")
7947 (set_attr "in_delay_slot" "no")])
7948
7949 ;; Alignment is needed for some constant tables; it may also be added for
7950 ;; Instructions at the start of loops, or after unconditional branches.
7951 ;; ??? We would get more accurate lengths if we did instruction
7952 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7953 ;; here is too conservative.
7954
7955 ; align to a two byte boundary
7956
7957 (define_expand "align_2"
7958 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7959 ""
7960 "")
7961
7962 ; align to a four byte boundary
7963 ;; align_4 and align_log are instructions for the starts of loops, or
7964 ;; after unconditional branches, which may take up extra room.
7965
7966 (define_expand "align_4"
7967 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7968 ""
7969 "")
7970
7971 ; align to a cache line boundary
7972
7973 (define_insn "align_log"
7974 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7975 ""
7976 ""
7977 [(set_attr "length" "0")
7978 (set_attr "in_delay_slot" "no")])
7979
7980 ; emitted at the end of the literal table, used to emit the
7981 ; 32bit branch labels if needed.
7982
7983 (define_insn "consttable_end"
7984 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7985 ""
7986 "* return output_jump_label_table ();"
7987 [(set_attr "in_delay_slot" "no")])
7988
7989 ; emitted at the end of the window in the literal table.
7990
7991 (define_insn "consttable_window_end"
7992 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7993 ""
7994 ""
7995 [(set_attr "length" "0")
7996 (set_attr "in_delay_slot" "no")])
7997
7998 ;; -------------------------------------------------------------------------
7999 ;; Misc
8000 ;; -------------------------------------------------------------------------
8001
8002 ;; String/block move insn.
8003
8004 (define_expand "movstrsi"
8005 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8006 (mem:BLK (match_operand:BLK 1 "" "")))
8007 (use (match_operand:SI 2 "nonmemory_operand" ""))
8008 (use (match_operand:SI 3 "immediate_operand" ""))
8009 (clobber (reg:SI PR_REG))
8010 (clobber (reg:SI R4_REG))
8011 (clobber (reg:SI R5_REG))
8012 (clobber (reg:SI R0_REG))])]
8013 "TARGET_SH1 && ! TARGET_SH5"
8014 "
8015 {
8016 if(expand_block_move (operands))
8017 DONE;
8018 else FAIL;
8019 }")
8020
8021 (define_insn "block_move_real"
8022 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8023 (mem:BLK (reg:SI R5_REG)))
8024 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8025 (clobber (reg:SI PR_REG))
8026 (clobber (reg:SI R0_REG))])]
8027 "TARGET_SH1 && ! TARGET_HARD_SH4"
8028 "jsr @%0%#"
8029 [(set_attr "type" "sfunc")
8030 (set_attr "needs_delay_slot" "yes")])
8031
8032 (define_insn "block_lump_real"
8033 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8034 (mem:BLK (reg:SI R5_REG)))
8035 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8036 (use (reg:SI R6_REG))
8037 (clobber (reg:SI PR_REG))
8038 (clobber (reg:SI T_REG))
8039 (clobber (reg:SI R4_REG))
8040 (clobber (reg:SI R5_REG))
8041 (clobber (reg:SI R6_REG))
8042 (clobber (reg:SI R0_REG))])]
8043 "TARGET_SH1 && ! TARGET_HARD_SH4"
8044 "jsr @%0%#"
8045 [(set_attr "type" "sfunc")
8046 (set_attr "needs_delay_slot" "yes")])
8047
8048 (define_insn "block_move_real_i4"
8049 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8050 (mem:BLK (reg:SI R5_REG)))
8051 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8052 (clobber (reg:SI PR_REG))
8053 (clobber (reg:SI R0_REG))
8054 (clobber (reg:SI R1_REG))
8055 (clobber (reg:SI R2_REG))])]
8056 "TARGET_HARD_SH4"
8057 "jsr @%0%#"
8058 [(set_attr "type" "sfunc")
8059 (set_attr "needs_delay_slot" "yes")])
8060
8061 (define_insn "block_lump_real_i4"
8062 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8063 (mem:BLK (reg:SI R5_REG)))
8064 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8065 (use (reg:SI R6_REG))
8066 (clobber (reg:SI PR_REG))
8067 (clobber (reg:SI T_REG))
8068 (clobber (reg:SI R4_REG))
8069 (clobber (reg:SI R5_REG))
8070 (clobber (reg:SI R6_REG))
8071 (clobber (reg:SI R0_REG))
8072 (clobber (reg:SI R1_REG))
8073 (clobber (reg:SI R2_REG))
8074 (clobber (reg:SI R3_REG))])]
8075 "TARGET_HARD_SH4"
8076 "jsr @%0%#"
8077 [(set_attr "type" "sfunc")
8078 (set_attr "needs_delay_slot" "yes")])
8079 \f
8080 ;; -------------------------------------------------------------------------
8081 ;; Floating point instructions.
8082 ;; -------------------------------------------------------------------------
8083
8084 ;; ??? All patterns should have a type attribute.
8085
8086 (define_expand "fpu_switch0"
8087 [(set (match_operand:SI 0 "" "") (match_dup 2))
8088 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8089 "TARGET_SH4"
8090 "
8091 {
8092 operands[1] = get_fpscr_rtx ();
8093 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8094 if (flag_pic)
8095 operands[2] = legitimize_pic_address (operands[2], SImode,
8096 no_new_pseudos ? operands[0] : 0);
8097 }")
8098
8099 (define_expand "fpu_switch1"
8100 [(set (match_operand:SI 0 "" "") (match_dup 2))
8101 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8102 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8103 "TARGET_SH4"
8104 "
8105 {
8106 operands[1] = get_fpscr_rtx ();
8107 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8108 if (flag_pic)
8109 operands[2] = legitimize_pic_address (operands[2], SImode,
8110 no_new_pseudos ? operands[0] : 0);
8111 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8112 }")
8113
8114 (define_expand "movpsi"
8115 [(set (match_operand:PSI 0 "register_operand" "")
8116 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8117 "TARGET_SH4"
8118 "")
8119
8120 ;; The c / m alternative is a fake to guide reload to load directly into
8121 ;; fpscr, since reload doesn't know how to use post-increment.
8122 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8123 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8124 ;; predicate after reload.
8125 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8126 ;; like a mac -> gpr move.
8127 (define_insn "fpu_switch"
8128 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8129 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8130 "TARGET_SH2E
8131 && (! reload_completed
8132 || true_regnum (operands[0]) != FPSCR_REG
8133 || GET_CODE (operands[1]) != MEM
8134 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8135 "@
8136 ! precision stays the same
8137 lds.l %1,fpscr
8138 mov.l %1,%0
8139 #
8140 lds %1,fpscr
8141 mov %1,%0
8142 mov.l %1,%0
8143 sts fpscr,%0
8144 sts.l fpscr,%0"
8145 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8146 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8147
8148 (define_split
8149 [(set (reg:PSI FPSCR_REG)
8150 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8151 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8152 [(set (match_dup 0) (match_dup 0))]
8153 "
8154 {
8155 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8156 gen_rtx (MEM, PSImode,
8157 gen_rtx (POST_INC, Pmode,
8158 operands[0]))));
8159 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8160 }")
8161
8162 (define_split
8163 [(set (reg:PSI FPSCR_REG)
8164 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8165 "TARGET_SH4"
8166 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8167 "
8168 {
8169 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8170 gen_rtx (MEM, PSImode,
8171 gen_rtx (POST_INC, Pmode,
8172 operands[0]))));
8173 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8174 }")
8175
8176 ;; ??? This uses the fp unit, but has no type indicating that.
8177 ;; If we did that, this would either give a bogus latency or introduce
8178 ;; a bogus FIFO constraint.
8179 ;; Since this insn is currently only used for prologues/epilogues,
8180 ;; it is probably best to claim no function unit, which matches the
8181 ;; current setting.
8182 (define_insn "toggle_sz"
8183 [(set (reg:PSI FPSCR_REG)
8184 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8185 "TARGET_SH4"
8186 "fschg"
8187 [(set_attr "fp_set" "unknown")])
8188
8189 (define_expand "addsf3"
8190 [(set (match_operand:SF 0 "arith_reg_operand" "")
8191 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8192 (match_operand:SF 2 "arith_reg_operand" "")))]
8193 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8194 "
8195 {
8196 if (TARGET_SH2E)
8197 {
8198 expand_sf_binop (&gen_addsf3_i, operands);
8199 DONE;
8200 }
8201 }")
8202
8203 (define_insn "*addsf3_media"
8204 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8205 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8206 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8207 "TARGET_SHMEDIA_FPU"
8208 "fadd.s %1, %2, %0"
8209 [(set_attr "type" "fparith_media")])
8210
8211 (define_insn_and_split "unary_sf_op"
8212 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8213 (vec_select:V2SF
8214 (vec_concat:V2SF
8215 (vec_select:SF
8216 (match_dup 0)
8217 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8218 (match_operator:SF 2 "unary_float_operator"
8219 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8220 (parallel [(match_operand 4
8221 "const_int_operand" "n")]))]))
8222 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8223 "TARGET_SHMEDIA_FPU"
8224 "#"
8225 "TARGET_SHMEDIA_FPU && reload_completed"
8226 [(set (match_dup 5) (match_dup 6))]
8227 "
8228 {
8229 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8230 rtx op1 = gen_rtx_REG (SFmode,
8231 (true_regnum (operands[1])
8232 + (INTVAL (operands[4]) ^ endian)));
8233
8234 operands[7] = gen_rtx_REG (SFmode,
8235 (true_regnum (operands[0])
8236 + (INTVAL (operands[3]) ^ endian)));
8237 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8238 }"
8239 [(set_attr "type" "fparith_media")])
8240
8241 (define_insn_and_split "binary_sf_op"
8242 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8243 (vec_select:V2SF
8244 (vec_concat:V2SF
8245 (vec_select:SF
8246 (match_dup 0)
8247 (parallel [(match_operand 7 "const_int_operand" "n")]))
8248 (match_operator:SF 3 "binary_float_operator"
8249 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8250 (parallel [(match_operand 5
8251 "const_int_operand" "n")]))
8252 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8253 (parallel [(match_operand 6
8254 "const_int_operand" "n")]))]))
8255 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8256 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8257 "#"
8258 "&& reload_completed"
8259 [(set (match_dup 8) (match_dup 9))]
8260 "
8261 {
8262 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8263 rtx op1 = gen_rtx_REG (SFmode,
8264 (true_regnum (operands[1])
8265 + (INTVAL (operands[5]) ^ endian)));
8266 rtx op2 = gen_rtx_REG (SFmode,
8267 (true_regnum (operands[2])
8268 + (INTVAL (operands[6]) ^ endian)));
8269
8270 operands[8] = gen_rtx_REG (SFmode,
8271 (true_regnum (operands[0])
8272 + (INTVAL (operands[4]) ^ endian)));
8273 operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8274 }"
8275 [(set_attr "type" "fparith_media")])
8276
8277 (define_insn "addsf3_i"
8278 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8279 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8280 (match_operand:SF 2 "arith_reg_operand" "f")))
8281 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8282 "TARGET_SH2E"
8283 "fadd %2,%0"
8284 [(set_attr "type" "fp")
8285 (set_attr "fp_mode" "single")])
8286
8287 (define_expand "subsf3"
8288 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8289 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8290 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8291 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8292 "
8293 {
8294 if (TARGET_SH2E)
8295 {
8296 expand_sf_binop (&gen_subsf3_i, operands);
8297 DONE;
8298 }
8299 }")
8300
8301 (define_insn "*subsf3_media"
8302 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8303 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8304 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8305 "TARGET_SHMEDIA_FPU"
8306 "fsub.s %1, %2, %0"
8307 [(set_attr "type" "fparith_media")])
8308
8309 (define_insn "subsf3_i"
8310 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8311 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8312 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8313 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8314 "TARGET_SH2E"
8315 "fsub %2,%0"
8316 [(set_attr "type" "fp")
8317 (set_attr "fp_mode" "single")])
8318
8319 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8320 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8321 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8322 ;; SH3E, we use a separate insn for SH3E mulsf3.
8323
8324 (define_expand "mulsf3"
8325 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8326 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8327 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8328 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8329 "
8330 {
8331 if (TARGET_SH4)
8332 expand_sf_binop (&gen_mulsf3_i4, operands);
8333 else if (TARGET_SH2E)
8334 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8335 if (! TARGET_SHMEDIA)
8336 DONE;
8337 }")
8338
8339 (define_insn "*mulsf3_media"
8340 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8341 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8342 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8343 "TARGET_SHMEDIA_FPU"
8344 "fmul.s %1, %2, %0"
8345 [(set_attr "type" "fparith_media")])
8346
8347 (define_insn "mulsf3_i4"
8348 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8349 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8350 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8351 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8352 "TARGET_SH2E"
8353 "fmul %2,%0"
8354 [(set_attr "type" "fp")
8355 (set_attr "fp_mode" "single")])
8356
8357 (define_insn "mulsf3_ie"
8358 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8359 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8360 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8361 "TARGET_SH2E && ! TARGET_SH4"
8362 "fmul %2,%0"
8363 [(set_attr "type" "fp")])
8364
8365 (define_insn "*mac_media"
8366 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8367 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8368 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8369 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8370 "TARGET_SHMEDIA_FPU"
8371 "fmac.s %1, %2, %0"
8372 [(set_attr "type" "fparith_media")])
8373
8374 (define_insn "*macsf3"
8375 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8376 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8377 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8378 (match_operand:SF 3 "arith_reg_operand" "0")))
8379 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8380 "TARGET_SH2E && ! TARGET_SH4"
8381 "fmac fr0,%2,%0"
8382 [(set_attr "type" "fp")
8383 (set_attr "fp_mode" "single")])
8384
8385 (define_expand "divsf3"
8386 [(set (match_operand:SF 0 "arith_reg_operand" "")
8387 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8388 (match_operand:SF 2 "arith_reg_operand" "")))]
8389 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8390 "
8391 {
8392 if (TARGET_SH2E)
8393 {
8394 expand_sf_binop (&gen_divsf3_i, operands);
8395 DONE;
8396 }
8397 }")
8398
8399 (define_insn "*divsf3_media"
8400 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8401 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8402 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8403 "TARGET_SHMEDIA_FPU"
8404 "fdiv.s %1, %2, %0"
8405 [(set_attr "type" "fdiv_media")])
8406
8407 (define_insn "divsf3_i"
8408 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8409 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8410 (match_operand:SF 2 "arith_reg_operand" "f")))
8411 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8412 "TARGET_SH2E"
8413 "fdiv %2,%0"
8414 [(set_attr "type" "fdiv")
8415 (set_attr "fp_mode" "single")])
8416
8417 (define_insn "floatdisf2"
8418 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8419 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8420 "TARGET_SHMEDIA_FPU"
8421 "float.qs %1, %0"
8422 [(set_attr "type" "fpconv_media")])
8423
8424 (define_expand "floatsisf2"
8425 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8426 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8427 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8428 "
8429 {
8430 if (TARGET_SH4)
8431 {
8432 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8433 DONE;
8434 }
8435 }")
8436
8437 (define_insn "*floatsisf2_media"
8438 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8439 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8440 "TARGET_SHMEDIA_FPU"
8441 "float.ls %1, %0"
8442 [(set_attr "type" "fpconv_media")])
8443
8444 (define_insn "floatsisf2_i4"
8445 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8446 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8447 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8448 "TARGET_SH4"
8449 "float %1,%0"
8450 [(set_attr "type" "fp")
8451 (set_attr "fp_mode" "single")])
8452
8453 (define_insn "*floatsisf2_ie"
8454 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8455 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8456 "TARGET_SH2E && ! TARGET_SH4"
8457 "float %1,%0"
8458 [(set_attr "type" "fp")])
8459
8460 (define_insn "fix_truncsfdi2"
8461 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8462 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8463 "TARGET_SHMEDIA_FPU"
8464 "ftrc.sq %1, %0"
8465 [(set_attr "type" "fpconv_media")])
8466
8467 (define_expand "fix_truncsfsi2"
8468 [(set (match_operand:SI 0 "fpul_operand" "=y")
8469 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8470 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8471 "
8472 {
8473 if (TARGET_SH4)
8474 {
8475 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8476 DONE;
8477 }
8478 }")
8479
8480 (define_insn "*fix_truncsfsi2_media"
8481 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8482 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8483 "TARGET_SHMEDIA_FPU"
8484 "ftrc.sl %1, %0"
8485 [(set_attr "type" "fpconv_media")])
8486
8487 (define_insn "fix_truncsfsi2_i4"
8488 [(set (match_operand:SI 0 "fpul_operand" "=y")
8489 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8490 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8491 "TARGET_SH4"
8492 "ftrc %1,%0"
8493 [(set_attr "type" "ftrc_s")
8494 (set_attr "fp_mode" "single")])
8495
8496 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8497 ;; fix_truncsfsi2_i4.
8498 ;; (define_insn "fix_truncsfsi2_i4_2"
8499 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8500 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8501 ;; (use (reg:PSI FPSCR_REG))
8502 ;; (clobber (reg:SI FPUL_REG))]
8503 ;; "TARGET_SH4"
8504 ;; "#"
8505 ;; [(set_attr "length" "4")
8506 ;; (set_attr "fp_mode" "single")])
8507
8508 ;;(define_split
8509 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8510 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8511 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8512 ;; (clobber (reg:SI FPUL_REG))]
8513 ;; "TARGET_SH4"
8514 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8515 ;; (use (match_dup 2))])
8516 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8517
8518 (define_insn "*fixsfsi"
8519 [(set (match_operand:SI 0 "fpul_operand" "=y")
8520 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8521 "TARGET_SH2E && ! TARGET_SH4"
8522 "ftrc %1,%0"
8523 [(set_attr "type" "fp")])
8524
8525 (define_insn "cmpgtsf_t"
8526 [(set (reg:SI T_REG)
8527 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8528 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8529 "TARGET_SH2E && ! TARGET_SH4"
8530 "fcmp/gt %1,%0"
8531 [(set_attr "type" "fp")
8532 (set_attr "fp_mode" "single")])
8533
8534 (define_insn "cmpeqsf_t"
8535 [(set (reg:SI T_REG)
8536 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8537 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8538 "TARGET_SH2E && ! TARGET_SH4"
8539 "fcmp/eq %1,%0"
8540 [(set_attr "type" "fp")
8541 (set_attr "fp_mode" "single")])
8542
8543 (define_insn "ieee_ccmpeqsf_t"
8544 [(set (reg:SI T_REG)
8545 (ior:SI (reg:SI T_REG)
8546 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8547 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8548 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8549 "* return output_ieee_ccmpeq (insn, operands);"
8550 [(set_attr "length" "4")])
8551
8552
8553 (define_insn "cmpgtsf_t_i4"
8554 [(set (reg:SI T_REG)
8555 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8556 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8557 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8558 "TARGET_SH4"
8559 "fcmp/gt %1,%0"
8560 [(set_attr "type" "fp")
8561 (set_attr "fp_mode" "single")])
8562
8563 (define_insn "cmpeqsf_t_i4"
8564 [(set (reg:SI T_REG)
8565 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8566 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8567 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8568 "TARGET_SH4"
8569 "fcmp/eq %1,%0"
8570 [(set_attr "type" "fp")
8571 (set_attr "fp_mode" "single")])
8572
8573 (define_insn "*ieee_ccmpeqsf_t_4"
8574 [(set (reg:SI T_REG)
8575 (ior:SI (reg:SI T_REG)
8576 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8577 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8578 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8579 "TARGET_IEEE && TARGET_SH4"
8580 "* return output_ieee_ccmpeq (insn, operands);"
8581 [(set_attr "length" "4")
8582 (set_attr "fp_mode" "single")])
8583
8584 (define_insn "cmpeqsf_media"
8585 [(set (match_operand:DI 0 "register_operand" "=r")
8586 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8587 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8588 "TARGET_SHMEDIA_FPU"
8589 "fcmpeq.s %1, %2, %0"
8590 [(set_attr "type" "fcmp_media")])
8591
8592 (define_insn "cmpgtsf_media"
8593 [(set (match_operand:DI 0 "register_operand" "=r")
8594 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8595 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8596 "TARGET_SHMEDIA_FPU"
8597 "fcmpgt.s %1, %2, %0"
8598 [(set_attr "type" "fcmp_media")])
8599
8600 (define_insn "cmpgesf_media"
8601 [(set (match_operand:DI 0 "register_operand" "=r")
8602 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8603 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8604 "TARGET_SHMEDIA_FPU"
8605 "fcmpge.s %1, %2, %0"
8606 [(set_attr "type" "fcmp_media")])
8607
8608 (define_insn "cmpunsf_media"
8609 [(set (match_operand:DI 0 "register_operand" "=r")
8610 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8611 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8612 "TARGET_SHMEDIA_FPU"
8613 "fcmpun.s %1, %2, %0"
8614 [(set_attr "type" "fcmp_media")])
8615
8616 (define_expand "cmpsf"
8617 [(set (reg:SI T_REG)
8618 (compare (match_operand:SF 0 "arith_operand" "")
8619 (match_operand:SF 1 "arith_operand" "")))]
8620 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8621 "
8622 {
8623 sh_compare_op0 = operands[0];
8624 sh_compare_op1 = operands[1];
8625 DONE;
8626 }")
8627
8628 (define_expand "negsf2"
8629 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8630 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8631 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8632 "
8633 {
8634 if (TARGET_SH2E)
8635 {
8636 expand_sf_unop (&gen_negsf2_i, operands);
8637 DONE;
8638 }
8639 }")
8640
8641 (define_insn "*negsf2_media"
8642 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8643 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8644 "TARGET_SHMEDIA_FPU"
8645 "fneg.s %1, %0"
8646 [(set_attr "type" "fmove_media")])
8647
8648 (define_insn "negsf2_i"
8649 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8650 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8651 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8652 "TARGET_SH2E"
8653 "fneg %0"
8654 [(set_attr "type" "fmove")
8655 (set_attr "fp_mode" "single")])
8656
8657 (define_expand "sqrtsf2"
8658 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8659 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8660 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8661 "
8662 {
8663 if (TARGET_SH3E)
8664 {
8665 expand_sf_unop (&gen_sqrtsf2_i, operands);
8666 DONE;
8667 }
8668 }")
8669
8670 (define_insn "*sqrtsf2_media"
8671 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8672 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8673 "TARGET_SHMEDIA_FPU"
8674 "fsqrt.s %1, %0"
8675 [(set_attr "type" "fdiv_media")])
8676
8677 (define_insn "sqrtsf2_i"
8678 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8679 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8680 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8681 "TARGET_SH3E"
8682 "fsqrt %0"
8683 [(set_attr "type" "fdiv")
8684 (set_attr "fp_mode" "single")])
8685
8686 (define_expand "abssf2"
8687 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8688 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8689 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8690 "
8691 {
8692 if (TARGET_SH2E)
8693 {
8694 expand_sf_unop (&gen_abssf2_i, operands);
8695 DONE;
8696 }
8697 }")
8698
8699 (define_insn "*abssf2_media"
8700 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8701 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8702 "TARGET_SHMEDIA_FPU"
8703 "fabs.s %1, %0"
8704 [(set_attr "type" "fmove_media")])
8705
8706 (define_insn "abssf2_i"
8707 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8708 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8709 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8710 "TARGET_SH2E"
8711 "fabs %0"
8712 [(set_attr "type" "fmove")
8713 (set_attr "fp_mode" "single")])
8714
8715 (define_expand "adddf3"
8716 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8717 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8718 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8719 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8720 "
8721 {
8722 if (TARGET_SH4)
8723 {
8724 expand_df_binop (&gen_adddf3_i, operands);
8725 DONE;
8726 }
8727 }")
8728
8729 (define_insn "*adddf3_media"
8730 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8731 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8732 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8733 "TARGET_SHMEDIA_FPU"
8734 "fadd.d %1, %2, %0"
8735 [(set_attr "type" "dfparith_media")])
8736
8737 (define_insn "adddf3_i"
8738 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8739 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8740 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8741 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8742 "TARGET_SH4"
8743 "fadd %2,%0"
8744 [(set_attr "type" "dfp_arith")
8745 (set_attr "fp_mode" "double")])
8746
8747 (define_expand "subdf3"
8748 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8749 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8750 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8751 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8752 "
8753 {
8754 if (TARGET_SH4)
8755 {
8756 expand_df_binop (&gen_subdf3_i, operands);
8757 DONE;
8758 }
8759 }")
8760
8761 (define_insn "*subdf3_media"
8762 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8763 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8764 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8765 "TARGET_SHMEDIA_FPU"
8766 "fsub.d %1, %2, %0"
8767 [(set_attr "type" "dfparith_media")])
8768
8769 (define_insn "subdf3_i"
8770 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8771 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8772 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8773 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8774 "TARGET_SH4"
8775 "fsub %2,%0"
8776 [(set_attr "type" "dfp_arith")
8777 (set_attr "fp_mode" "double")])
8778
8779 (define_expand "muldf3"
8780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8781 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8782 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8783 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8784 "
8785 {
8786 if (TARGET_SH4)
8787 {
8788 expand_df_binop (&gen_muldf3_i, operands);
8789 DONE;
8790 }
8791 }")
8792
8793 (define_insn "*muldf3_media"
8794 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8795 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8796 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8797 "TARGET_SHMEDIA_FPU"
8798 "fmul.d %1, %2, %0"
8799 [(set_attr "type" "dfmul_media")])
8800
8801 (define_insn "muldf3_i"
8802 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8803 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8804 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8805 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8806 "TARGET_SH4"
8807 "fmul %2,%0"
8808 [(set_attr "type" "dfp_arith")
8809 (set_attr "fp_mode" "double")])
8810
8811 (define_expand "divdf3"
8812 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8813 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8814 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8815 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8816 "
8817 {
8818 if (TARGET_SH4)
8819 {
8820 expand_df_binop (&gen_divdf3_i, operands);
8821 DONE;
8822 }
8823 }")
8824
8825 (define_insn "*divdf3_media"
8826 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8827 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8828 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8829 "TARGET_SHMEDIA_FPU"
8830 "fdiv.d %1, %2, %0"
8831 [(set_attr "type" "dfdiv_media")])
8832
8833 (define_insn "divdf3_i"
8834 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8835 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8836 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8837 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8838 "TARGET_SH4"
8839 "fdiv %2,%0"
8840 [(set_attr "type" "dfdiv")
8841 (set_attr "fp_mode" "double")])
8842
8843 (define_insn "floatdidf2"
8844 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8845 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8846 "TARGET_SHMEDIA_FPU"
8847 "float.qd %1, %0"
8848 [(set_attr "type" "dfpconv_media")])
8849
8850 (define_expand "floatsidf2"
8851 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8852 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8853 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8854 "
8855 {
8856 if (TARGET_SH4)
8857 {
8858 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8859 get_fpscr_rtx ()));
8860 DONE;
8861 }
8862 }")
8863
8864 (define_insn "*floatsidf2_media"
8865 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8866 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8867 "TARGET_SHMEDIA_FPU"
8868 "float.ld %1, %0"
8869 [(set_attr "type" "dfpconv_media")])
8870
8871 (define_insn "floatsidf2_i"
8872 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8873 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8874 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8875 "TARGET_SH4"
8876 "float %1,%0"
8877 [(set_attr "type" "dfp_conv")
8878 (set_attr "fp_mode" "double")])
8879
8880 (define_insn "fix_truncdfdi2"
8881 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8882 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8883 "TARGET_SHMEDIA_FPU"
8884 "ftrc.dq %1, %0"
8885 [(set_attr "type" "dfpconv_media")])
8886
8887 (define_expand "fix_truncdfsi2"
8888 [(set (match_operand:SI 0 "fpul_operand" "")
8889 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8890 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8891 "
8892 {
8893 if (TARGET_SH4)
8894 {
8895 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8896 get_fpscr_rtx ()));
8897 DONE;
8898 }
8899 }")
8900
8901 (define_insn "*fix_truncdfsi2_media"
8902 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8903 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8904 "TARGET_SHMEDIA_FPU"
8905 "ftrc.dl %1, %0"
8906 [(set_attr "type" "dfpconv_media")])
8907
8908 (define_insn "fix_truncdfsi2_i"
8909 [(set (match_operand:SI 0 "fpul_operand" "=y")
8910 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8911 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8912 "TARGET_SH4"
8913 "ftrc %1,%0"
8914 [(set_attr "type" "dfp_conv")
8915 (set_attr "dfp_comp" "no")
8916 (set_attr "fp_mode" "double")])
8917
8918 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8919 ;; fix_truncdfsi2_i.
8920 ;; (define_insn "fix_truncdfsi2_i4"
8921 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8922 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8923 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8924 ;; (clobber (reg:SI FPUL_REG))]
8925 ;; "TARGET_SH4"
8926 ;; "#"
8927 ;; [(set_attr "length" "4")
8928 ;; (set_attr "fp_mode" "double")])
8929 ;;
8930 ;; (define_split
8931 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8932 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8933 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8934 ;; (clobber (reg:SI FPUL_REG))]
8935 ;; "TARGET_SH4"
8936 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8937 ;; (use (match_dup 2))])
8938 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8939
8940 (define_insn "cmpgtdf_t"
8941 [(set (reg:SI T_REG)
8942 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8943 (match_operand:DF 1 "arith_reg_operand" "f")))
8944 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8945 "TARGET_SH4"
8946 "fcmp/gt %1,%0"
8947 [(set_attr "type" "dfp_cmp")
8948 (set_attr "fp_mode" "double")])
8949
8950 (define_insn "cmpeqdf_t"
8951 [(set (reg:SI T_REG)
8952 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8953 (match_operand:DF 1 "arith_reg_operand" "f")))
8954 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8955 "TARGET_SH4"
8956 "fcmp/eq %1,%0"
8957 [(set_attr "type" "dfp_cmp")
8958 (set_attr "fp_mode" "double")])
8959
8960 (define_insn "*ieee_ccmpeqdf_t"
8961 [(set (reg:SI T_REG)
8962 (ior:SI (reg:SI T_REG)
8963 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8964 (match_operand:DF 1 "arith_reg_operand" "f"))))
8965 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8966 "TARGET_IEEE && TARGET_SH4"
8967 "* return output_ieee_ccmpeq (insn, operands);"
8968 [(set_attr "length" "4")
8969 (set_attr "fp_mode" "double")])
8970
8971 (define_insn "cmpeqdf_media"
8972 [(set (match_operand:DI 0 "register_operand" "=r")
8973 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8974 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8975 "TARGET_SHMEDIA_FPU"
8976 "fcmpeq.d %1,%2,%0"
8977 [(set_attr "type" "fcmp_media")])
8978
8979 (define_insn "cmpgtdf_media"
8980 [(set (match_operand:DI 0 "register_operand" "=r")
8981 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8982 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8983 "TARGET_SHMEDIA_FPU"
8984 "fcmpgt.d %1,%2,%0"
8985 [(set_attr "type" "fcmp_media")])
8986
8987 (define_insn "cmpgedf_media"
8988 [(set (match_operand:DI 0 "register_operand" "=r")
8989 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8990 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8991 "TARGET_SHMEDIA_FPU"
8992 "fcmpge.d %1,%2,%0"
8993 [(set_attr "type" "fcmp_media")])
8994
8995 (define_insn "cmpundf_media"
8996 [(set (match_operand:DI 0 "register_operand" "=r")
8997 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8998 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8999 "TARGET_SHMEDIA_FPU"
9000 "fcmpun.d %1,%2,%0"
9001 [(set_attr "type" "fcmp_media")])
9002
9003 (define_expand "cmpdf"
9004 [(set (reg:SI T_REG)
9005 (compare (match_operand:DF 0 "arith_operand" "")
9006 (match_operand:DF 1 "arith_operand" "")))]
9007 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9008 "
9009 {
9010 sh_compare_op0 = operands[0];
9011 sh_compare_op1 = operands[1];
9012 DONE;
9013 }")
9014
9015 (define_expand "negdf2"
9016 [(set (match_operand:DF 0 "arith_reg_operand" "")
9017 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9018 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9019 "
9020 {
9021 if (TARGET_SH4)
9022 {
9023 expand_df_unop (&gen_negdf2_i, operands);
9024 DONE;
9025 }
9026 }")
9027
9028 (define_insn "*negdf2_media"
9029 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9030 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9031 "TARGET_SHMEDIA_FPU"
9032 "fneg.d %1, %0"
9033 [(set_attr "type" "fmove_media")])
9034
9035 (define_insn "negdf2_i"
9036 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9037 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9038 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9039 "TARGET_SH4"
9040 "fneg %0"
9041 [(set_attr "type" "fmove")
9042 (set_attr "fp_mode" "double")])
9043
9044 (define_expand "sqrtdf2"
9045 [(set (match_operand:DF 0 "arith_reg_operand" "")
9046 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9047 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9048 "
9049 {
9050 if (TARGET_SH4)
9051 {
9052 expand_df_unop (&gen_sqrtdf2_i, operands);
9053 DONE;
9054 }
9055 }")
9056
9057 (define_insn "*sqrtdf2_media"
9058 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9059 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9060 "TARGET_SHMEDIA_FPU"
9061 "fsqrt.d %1, %0"
9062 [(set_attr "type" "dfdiv_media")])
9063
9064 (define_insn "sqrtdf2_i"
9065 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9066 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9067 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9068 "TARGET_SH4"
9069 "fsqrt %0"
9070 [(set_attr "type" "dfdiv")
9071 (set_attr "fp_mode" "double")])
9072
9073 (define_expand "absdf2"
9074 [(set (match_operand:DF 0 "arith_reg_operand" "")
9075 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9076 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9077 "
9078 {
9079 if (TARGET_SH4)
9080 {
9081 expand_df_unop (&gen_absdf2_i, operands);
9082 DONE;
9083 }
9084 }")
9085
9086 (define_insn "*absdf2_media"
9087 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9088 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9089 "TARGET_SHMEDIA_FPU"
9090 "fabs.d %1, %0"
9091 [(set_attr "type" "fmove_media")])
9092
9093 (define_insn "absdf2_i"
9094 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9095 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9096 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9097 "TARGET_SH4"
9098 "fabs %0"
9099 [(set_attr "type" "fmove")
9100 (set_attr "fp_mode" "double")])
9101
9102 (define_expand "extendsfdf2"
9103 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9104 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9105 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9106 "
9107 {
9108 if (TARGET_SH4)
9109 {
9110 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9111 get_fpscr_rtx ()));
9112 DONE;
9113 }
9114 }")
9115
9116 (define_insn "*extendsfdf2_media"
9117 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9118 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9119 "TARGET_SHMEDIA_FPU"
9120 "fcnv.sd %1, %0"
9121 [(set_attr "type" "dfpconv_media")])
9122
9123 (define_insn "extendsfdf2_i4"
9124 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9125 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9126 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9127 "TARGET_SH4"
9128 "fcnvsd %1,%0"
9129 [(set_attr "type" "fp")
9130 (set_attr "fp_mode" "double")])
9131
9132 (define_expand "truncdfsf2"
9133 [(set (match_operand:SF 0 "fpul_operand" "")
9134 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9135 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9136 "
9137 {
9138 if (TARGET_SH4)
9139 {
9140 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9141 get_fpscr_rtx ()));
9142 DONE;
9143 }
9144 }")
9145
9146 (define_insn "*truncdfsf2_media"
9147 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9148 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9149 "TARGET_SHMEDIA_FPU"
9150 "fcnv.ds %1, %0"
9151 [(set_attr "type" "dfpconv_media")])
9152
9153 (define_insn "truncdfsf2_i4"
9154 [(set (match_operand:SF 0 "fpul_operand" "=y")
9155 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9156 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9157 "TARGET_SH4"
9158 "fcnvds %1,%0"
9159 [(set_attr "type" "fp")
9160 (set_attr "fp_mode" "double")])
9161 \f
9162 ;; Bit field extract patterns. These give better code for packed bitfields,
9163 ;; because they allow auto-increment addresses to be generated.
9164
9165 (define_expand "insv"
9166 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9167 (match_operand:SI 1 "immediate_operand" "")
9168 (match_operand:SI 2 "immediate_operand" ""))
9169 (match_operand:SI 3 "general_operand" ""))]
9170 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9171 "
9172 {
9173 rtx addr_target, orig_address, shift_reg, qi_val;
9174 HOST_WIDE_INT bitsize, size, v;
9175 rtx x = operands[3];
9176
9177 /* ??? expmed doesn't care for non-register predicates. */
9178 if (! memory_operand (operands[0], VOIDmode)
9179 || ! immediate_operand (operands[1], VOIDmode)
9180 || ! immediate_operand (operands[2], VOIDmode)
9181 || ! general_operand (x, VOIDmode))
9182 FAIL;
9183 /* If this isn't a 16 / 24 / 32 bit field, or if
9184 it doesn't start on a byte boundary, then fail. */
9185 bitsize = INTVAL (operands[1]);
9186 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9187 || (INTVAL (operands[2]) % 8) != 0)
9188 FAIL;
9189
9190 size = bitsize / 8;
9191 orig_address = XEXP (operands[0], 0);
9192 shift_reg = gen_reg_rtx (SImode);
9193 if (GET_CODE (x) == CONST_INT)
9194 {
9195 v = INTVAL (x);
9196 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9197 }
9198 else
9199 {
9200 emit_insn (gen_movsi (shift_reg, operands[3]));
9201 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9202 }
9203 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9204
9205 operands[0] = replace_equiv_address (operands[0], addr_target);
9206 emit_insn (gen_movqi (operands[0], qi_val));
9207
9208 while (size -= 1)
9209 {
9210 if (GET_CODE (x) == CONST_INT)
9211 qi_val
9212 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9213 else
9214 {
9215 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9216 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9217 }
9218 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9219 emit_insn (gen_movqi (operands[0], qi_val));
9220 }
9221
9222 DONE;
9223 }")
9224 \f
9225 ;; -------------------------------------------------------------------------
9226 ;; Peepholes
9227 ;; -------------------------------------------------------------------------
9228
9229 ;; This matches cases where a stack pointer increment at the start of the
9230 ;; epilogue combines with a stack slot read loading the return value.
9231
9232 (define_peephole
9233 [(set (match_operand:SI 0 "arith_reg_operand" "")
9234 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9235 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9236 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9237 "mov.l @%1+,%0")
9238
9239 ;; See the comment on the dt combiner pattern above.
9240
9241 (define_peephole
9242 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9243 (plus:SI (match_dup 0)
9244 (const_int -1)))
9245 (set (reg:SI T_REG)
9246 (eq:SI (match_dup 0)
9247 (const_int 0)))]
9248 "TARGET_SH2"
9249 "dt %0")
9250
9251 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9252 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9253 ;; reload when the constant is too large for a reg+offset address.
9254
9255 ;; ??? We would get much better code if this was done in reload. This would
9256 ;; require modifying find_reloads_address to recognize that if the constant
9257 ;; is out-of-range for an immediate add, then we get better code by reloading
9258 ;; the constant into a register than by reloading the sum into a register,
9259 ;; since the former is one instruction shorter if the address does not need
9260 ;; to be offsettable. Unfortunately this does not work, because there is
9261 ;; only one register, r0, that can be used as an index register. This register
9262 ;; is also the function return value register. So, if we try to force reload
9263 ;; to use double-reg addresses, then we end up with some instructions that
9264 ;; need to use r0 twice. The only way to fix this is to change the calling
9265 ;; convention so that r0 is not used to return values.
9266
9267 (define_peephole
9268 [(set (match_operand:SI 0 "register_operand" "=r")
9269 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9270 (set (mem:SI (match_dup 0))
9271 (match_operand:SI 2 "general_movsrc_operand" ""))]
9272 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9273 "mov.l %2,@(%0,%1)")
9274
9275 (define_peephole
9276 [(set (match_operand:SI 0 "register_operand" "=r")
9277 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9278 (set (match_operand:SI 2 "general_movdst_operand" "")
9279 (mem:SI (match_dup 0)))]
9280 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9281 "mov.l @(%0,%1),%2")
9282
9283 (define_peephole
9284 [(set (match_operand:SI 0 "register_operand" "=r")
9285 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9286 (set (mem:HI (match_dup 0))
9287 (match_operand:HI 2 "general_movsrc_operand" ""))]
9288 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9289 "mov.w %2,@(%0,%1)")
9290
9291 (define_peephole
9292 [(set (match_operand:SI 0 "register_operand" "=r")
9293 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9294 (set (match_operand:HI 2 "general_movdst_operand" "")
9295 (mem:HI (match_dup 0)))]
9296 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9297 "mov.w @(%0,%1),%2")
9298
9299 (define_peephole
9300 [(set (match_operand:SI 0 "register_operand" "=r")
9301 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9302 (set (mem:QI (match_dup 0))
9303 (match_operand:QI 2 "general_movsrc_operand" ""))]
9304 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9305 "mov.b %2,@(%0,%1)")
9306
9307 (define_peephole
9308 [(set (match_operand:SI 0 "register_operand" "=r")
9309 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9310 (set (match_operand:QI 2 "general_movdst_operand" "")
9311 (mem:QI (match_dup 0)))]
9312 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9313 "mov.b @(%0,%1),%2")
9314
9315 (define_peephole
9316 [(set (match_operand:SI 0 "register_operand" "=r")
9317 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9318 (set (mem:SF (match_dup 0))
9319 (match_operand:SF 2 "general_movsrc_operand" ""))]
9320 "TARGET_SH1 && REGNO (operands[0]) == 0
9321 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9322 || (GET_CODE (operands[2]) == SUBREG
9323 && REGNO (SUBREG_REG (operands[2])) < 16))
9324 && reg_unused_after (operands[0], insn)"
9325 "mov.l %2,@(%0,%1)")
9326
9327 (define_peephole
9328 [(set (match_operand:SI 0 "register_operand" "=r")
9329 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9330 (set (match_operand:SF 2 "general_movdst_operand" "")
9331
9332 (mem:SF (match_dup 0)))]
9333 "TARGET_SH1 && REGNO (operands[0]) == 0
9334 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9335 || (GET_CODE (operands[2]) == SUBREG
9336 && REGNO (SUBREG_REG (operands[2])) < 16))
9337 && reg_unused_after (operands[0], insn)"
9338 "mov.l @(%0,%1),%2")
9339
9340 (define_peephole
9341 [(set (match_operand:SI 0 "register_operand" "=r")
9342 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9343 (set (mem:SF (match_dup 0))
9344 (match_operand:SF 2 "general_movsrc_operand" ""))]
9345 "TARGET_SH2E && REGNO (operands[0]) == 0
9346 && ((GET_CODE (operands[2]) == REG
9347 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9348 || (GET_CODE (operands[2]) == SUBREG
9349 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9350 && reg_unused_after (operands[0], insn)"
9351 "fmov{.s|} %2,@(%0,%1)")
9352
9353 (define_peephole
9354 [(set (match_operand:SI 0 "register_operand" "=r")
9355 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9356 (set (match_operand:SF 2 "general_movdst_operand" "")
9357
9358 (mem:SF (match_dup 0)))]
9359 "TARGET_SH2E && REGNO (operands[0]) == 0
9360 && ((GET_CODE (operands[2]) == REG
9361 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9362 || (GET_CODE (operands[2]) == SUBREG
9363 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9364 && reg_unused_after (operands[0], insn)"
9365 "fmov{.s|} @(%0,%1),%2")
9366
9367 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9368 (define_insn "sp_switch_1"
9369 [(const_int 1)]
9370 "TARGET_SH1"
9371 "*
9372 {
9373 rtx xoperands[1];
9374
9375 xoperands[0] = sp_switch;
9376 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9377 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9378 return \"mov r0,r15\";
9379 }"
9380 [(set_attr "length" "10")])
9381
9382 ;; Switch back to the original stack for interrupt functions with the
9383 ;; sp_switch attribute. */
9384 (define_insn "sp_switch_2"
9385 [(const_int 2)]
9386 "TARGET_SH1"
9387 "mov.l @r15+,r15\;mov.l @r15+,r0"
9388 [(set_attr "length" "4")])
9389
9390 ;; Integer vector moves
9391
9392 (define_expand "movv8qi"
9393 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9394 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9395 "TARGET_SHMEDIA"
9396 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9397
9398 (define_insn "movv8qi_i"
9399 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9400 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9401 "TARGET_SHMEDIA
9402 && (register_operand (operands[0], V8QImode)
9403 || sh_register_operand (operands[1], V8QImode))"
9404 "@
9405 add %1, r63, %0
9406 movi %1, %0
9407 #
9408 ld%M1.q %m1, %0
9409 st%M0.q %m0, %N1"
9410 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9411 (set_attr "length" "4,4,16,4,4")])
9412
9413 (define_split
9414 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9415 (subreg:V8QI (const_int 0) 0))]
9416 "TARGET_SHMEDIA"
9417 [(set (match_dup 0)
9418 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9419 (const_int 0) (const_int 0) (const_int 0)
9420 (const_int 0) (const_int 0)]))])
9421
9422 (define_split
9423 [(set (match_operand 0 "arith_reg_dest" "")
9424 (match_operand 1 "sh_rep_vec" ""))]
9425 "TARGET_SHMEDIA && reload_completed
9426 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9427 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9428 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9429 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9430 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9431 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9432 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9433 [(set (match_dup 0) (match_dup 1))
9434 (match_dup 2)]
9435 "
9436 {
9437 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9438 rtx elt1 = XVECEXP (operands[1], 0, 1);
9439
9440 if (unit_size > 2)
9441 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9442 else
9443 {
9444 if (unit_size < 2)
9445 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9446 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9447 }
9448 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9449 operands[1] = XVECEXP (operands[1], 0, 0);
9450 if (unit_size < 2)
9451 {
9452 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9453 operands[1]
9454 = GEN_INT (TARGET_LITTLE_ENDIAN
9455 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9456 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9457 else
9458 {
9459 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9460 operands[1]
9461 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9462 }
9463 }
9464 }")
9465
9466 (define_split
9467 [(set (match_operand 0 "arith_reg_dest" "")
9468 (match_operand 1 "sh_const_vec" ""))]
9469 "TARGET_SHMEDIA && reload_completed
9470 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9471 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9472 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9473 [(set (match_dup 0) (match_dup 1))]
9474 "
9475 {
9476 rtx v = operands[1];
9477 enum machine_mode new_mode
9478 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9479
9480 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9481 operands[1]
9482 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9483 }")
9484
9485 (define_expand "movv2hi"
9486 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9487 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9488 "TARGET_SHMEDIA"
9489 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9490
9491 (define_insn "movv2hi_i"
9492 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9493 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9494 "TARGET_SHMEDIA
9495 && (register_operand (operands[0], V2HImode)
9496 || sh_register_operand (operands[1], V2HImode))"
9497 "@
9498 addz.l %1, r63, %0
9499 movi %1, %0
9500 #
9501 ld%M1.l %m1, %0
9502 st%M0.l %m0, %N1"
9503 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9504 (set_attr "length" "4,4,16,4,4")])
9505
9506 (define_expand "movv4hi"
9507 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9508 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9509 "TARGET_SHMEDIA"
9510 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9511
9512 (define_insn "movv4hi_i"
9513 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9514 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9515 "TARGET_SHMEDIA
9516 && (register_operand (operands[0], V4HImode)
9517 || sh_register_operand (operands[1], V4HImode))"
9518 "@
9519 add %1, r63, %0
9520 movi %1, %0
9521 #
9522 ld%M1.q %m1, %0
9523 st%M0.q %m0, %N1"
9524 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9525 (set_attr "length" "4,4,16,4,4")])
9526
9527 (define_expand "movv2si"
9528 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9529 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9530 "TARGET_SHMEDIA"
9531 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9532
9533 (define_insn "movv2si_i"
9534 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9535 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9536 "TARGET_SHMEDIA
9537 && (register_operand (operands[0], V2SImode)
9538 || sh_register_operand (operands[1], V2SImode))"
9539 "@
9540 add %1, r63, %0
9541 #
9542 #
9543 ld%M1.q %m1, %0
9544 st%M0.q %m0, %N1"
9545 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9546 (set_attr "length" "4,4,16,4,4")])
9547
9548 ;; Multimedia Intrinsics
9549
9550 (define_insn "absv2si2"
9551 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9552 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9553 "TARGET_SHMEDIA"
9554 "mabs.l %1, %0"
9555 [(set_attr "type" "mcmp_media")])
9556
9557 (define_insn "absv4hi2"
9558 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9559 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9560 "TARGET_SHMEDIA"
9561 "mabs.w %1, %0"
9562 [(set_attr "type" "mcmp_media")])
9563
9564 (define_insn "addv2si3"
9565 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9566 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9567 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9568 "TARGET_SHMEDIA"
9569 "madd.l %1, %2, %0"
9570 [(set_attr "type" "arith_media")])
9571
9572 (define_insn "addv4hi3"
9573 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9574 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9575 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9576 "TARGET_SHMEDIA"
9577 "madd.w %1, %2, %0"
9578 [(set_attr "type" "arith_media")])
9579
9580 (define_insn "ssaddv2si3"
9581 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9582 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9583 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9584 "TARGET_SHMEDIA"
9585 "madds.l %1, %2, %0"
9586 [(set_attr "type" "mcmp_media")])
9587
9588 (define_insn "usaddv8qi3"
9589 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9590 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9591 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9592 "TARGET_SHMEDIA"
9593 "madds.ub %1, %2, %0"
9594 [(set_attr "type" "mcmp_media")])
9595
9596 (define_insn "ssaddv4hi3"
9597 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9598 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9599 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9600 "TARGET_SHMEDIA"
9601 "madds.w %1, %2, %0"
9602 [(set_attr "type" "mcmp_media")])
9603
9604 (define_insn "negcmpeqv8qi"
9605 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9606 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9607 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9608 "TARGET_SHMEDIA"
9609 "mcmpeq.b %N1, %N2, %0"
9610 [(set_attr "type" "mcmp_media")])
9611
9612 (define_insn "negcmpeqv2si"
9613 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9614 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9615 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9616 "TARGET_SHMEDIA"
9617 "mcmpeq.l %N1, %N2, %0"
9618 [(set_attr "type" "mcmp_media")])
9619
9620 (define_insn "negcmpeqv4hi"
9621 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9622 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9623 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9624 "TARGET_SHMEDIA"
9625 "mcmpeq.w %N1, %N2, %0"
9626 [(set_attr "type" "mcmp_media")])
9627
9628 (define_insn "negcmpgtuv8qi"
9629 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9630 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9631 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9632 "TARGET_SHMEDIA"
9633 "mcmpgt.ub %N1, %N2, %0"
9634 [(set_attr "type" "mcmp_media")])
9635
9636 (define_insn "negcmpgtv2si"
9637 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9638 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9639 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9640 "TARGET_SHMEDIA"
9641 "mcmpgt.l %N1, %N2, %0"
9642 [(set_attr "type" "mcmp_media")])
9643
9644 (define_insn "negcmpgtv4hi"
9645 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9646 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9647 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9648 "TARGET_SHMEDIA"
9649 "mcmpgt.w %N1, %N2, %0"
9650 [(set_attr "type" "mcmp_media")])
9651
9652 (define_insn "mcmv"
9653 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9654 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9655 (match_operand:DI 2 "arith_reg_operand" "r"))
9656 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9657 (not:DI (match_dup 2)))))]
9658 "TARGET_SHMEDIA"
9659 "mcmv %N1, %2, %0"
9660 [(set_attr "type" "arith_media")])
9661
9662 (define_insn "mcnvs_lw"
9663 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9664 (vec_concat:V4HI
9665 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9666 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9667 "TARGET_SHMEDIA"
9668 "mcnvs.lw %N1, %N2, %0"
9669 [(set_attr "type" "mcmp_media")])
9670
9671 (define_insn "mcnvs_wb"
9672 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9673 (vec_concat:V8QI
9674 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9675 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9676 "TARGET_SHMEDIA"
9677 "mcnvs.wb %N1, %N2, %0"
9678 [(set_attr "type" "mcmp_media")])
9679
9680 (define_insn "mcnvs_wub"
9681 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9682 (vec_concat:V8QI
9683 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9684 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9685 "TARGET_SHMEDIA"
9686 "mcnvs.wub %N1, %N2, %0"
9687 [(set_attr "type" "mcmp_media")])
9688
9689 (define_insn "mextr_rl"
9690 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9691 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9692 (match_operand:HI 3 "mextr_bit_offset" "i"))
9693 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9694 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9695 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9696 "*
9697 {
9698 static char templ[16];
9699
9700 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9701 (int) INTVAL (operands[3]) >> 3);
9702 return templ;
9703 }"
9704 [(set_attr "type" "arith_media")])
9705
9706 (define_insn "*mextr_lr"
9707 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9708 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9709 (match_operand:HI 3 "mextr_bit_offset" "i"))
9710 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9711 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9712 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9713 "*
9714 {
9715 static char templ[16];
9716
9717 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9718 (int) INTVAL (operands[4]) >> 3);
9719 return templ;
9720 }"
9721 [(set_attr "type" "arith_media")])
9722
9723 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9724 ; vector then varies depending on endianness.
9725 (define_expand "mextr1"
9726 [(match_operand:DI 0 "arith_reg_dest" "")
9727 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9728 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9729 "TARGET_SHMEDIA"
9730 "
9731 {
9732 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9733 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9734 DONE;
9735 }")
9736
9737 (define_expand "mextr2"
9738 [(match_operand:DI 0 "arith_reg_dest" "")
9739 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9740 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9741 "TARGET_SHMEDIA"
9742 "
9743 {
9744 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9745 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9746 DONE;
9747 }")
9748
9749 (define_expand "mextr3"
9750 [(match_operand:DI 0 "arith_reg_dest" "")
9751 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9752 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9753 "TARGET_SHMEDIA"
9754 "
9755 {
9756 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9757 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9758 DONE;
9759 }")
9760
9761 (define_expand "mextr4"
9762 [(match_operand:DI 0 "arith_reg_dest" "")
9763 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9764 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9765 "TARGET_SHMEDIA"
9766 "
9767 {
9768 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9769 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9770 DONE;
9771 }")
9772
9773 (define_expand "mextr5"
9774 [(match_operand:DI 0 "arith_reg_dest" "")
9775 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9776 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9777 "TARGET_SHMEDIA"
9778 "
9779 {
9780 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9781 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9782 DONE;
9783 }")
9784
9785 (define_expand "mextr6"
9786 [(match_operand:DI 0 "arith_reg_dest" "")
9787 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9788 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9789 "TARGET_SHMEDIA"
9790 "
9791 {
9792 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9793 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9794 DONE;
9795 }")
9796
9797 (define_expand "mextr7"
9798 [(match_operand:DI 0 "arith_reg_dest" "")
9799 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9800 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9801 "TARGET_SHMEDIA"
9802 "
9803 {
9804 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9805 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9806 DONE;
9807 }")
9808
9809 (define_expand "mmacfx_wl"
9810 [(match_operand:V2SI 0 "arith_reg_dest" "")
9811 (match_operand:V2HI 1 "extend_reg_operand" "")
9812 (match_operand:V2HI 2 "extend_reg_operand" "")
9813 (match_operand:V2SI 3 "arith_reg_operand" "")]
9814 "TARGET_SHMEDIA"
9815 "
9816 {
9817 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9818 operands[1], operands[2]));
9819 DONE;
9820 }")
9821
9822 (define_insn "mmacfx_wl_i"
9823 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9824 (ss_plus:V2SI
9825 (match_operand:V2SI 1 "arith_reg_operand" "0")
9826 (ss_truncate:V2SI
9827 (ashift:V2DI
9828 (sign_extend:V2DI
9829 (mult:V2SI
9830 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9831 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9832 (const_int 1)))))]
9833 "TARGET_SHMEDIA"
9834 "mmacfx.wl %2, %3, %0"
9835 [(set_attr "type" "mac_media")])
9836
9837 (define_expand "mmacnfx_wl"
9838 [(match_operand:V2SI 0 "arith_reg_dest" "")
9839 (match_operand:V2HI 1 "extend_reg_operand" "")
9840 (match_operand:V2HI 2 "extend_reg_operand" "")
9841 (match_operand:V2SI 3 "arith_reg_operand" "")]
9842 "TARGET_SHMEDIA"
9843 "
9844 {
9845 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9846 operands[1], operands[2]));
9847 DONE;
9848 }")
9849
9850 (define_insn "mmacnfx_wl_i"
9851 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9852 (ss_minus:V2SI
9853 (match_operand:V2SI 1 "arith_reg_operand" "0")
9854 (ss_truncate:V2SI
9855 (ashift:V2DI
9856 (sign_extend:V2DI
9857 (mult:V2SI
9858 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9859 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9860 (const_int 1)))))]
9861 "TARGET_SHMEDIA"
9862 "mmacnfx.wl %2, %3, %0"
9863 [(set_attr "type" "mac_media")])
9864
9865 (define_insn "mulv2si3"
9866 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9867 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9868 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9869 "TARGET_SHMEDIA"
9870 "mmul.l %1, %2, %0"
9871 [(set_attr "type" "d2mpy_media")])
9872
9873 (define_insn "mulv4hi3"
9874 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9875 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9876 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9877 "TARGET_SHMEDIA"
9878 "mmul.w %1, %2, %0"
9879 [(set_attr "type" "dmpy_media")])
9880
9881 (define_insn "mmulfx_l"
9882 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9883 (ss_truncate:V2SI
9884 (ashiftrt:V2DI
9885 (mult:V2DI
9886 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9887 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9888 (const_int 31))))]
9889 "TARGET_SHMEDIA"
9890 "mmulfx.l %1, %2, %0"
9891 [(set_attr "type" "d2mpy_media")])
9892
9893 (define_insn "mmulfx_w"
9894 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9895 (ss_truncate:V4HI
9896 (ashiftrt:V4SI
9897 (mult:V4SI
9898 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9899 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9900 (const_int 15))))]
9901 "TARGET_SHMEDIA"
9902 "mmulfx.w %1, %2, %0"
9903 [(set_attr "type" "dmpy_media")])
9904
9905 (define_insn "mmulfxrp_w"
9906 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9907 (ss_truncate:V4HI
9908 (ashiftrt:V4SI
9909 (plus:V4SI
9910 (mult:V4SI
9911 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9912 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9913 (const_int 16384))
9914 (const_int 15))))]
9915 "TARGET_SHMEDIA"
9916 "mmulfxrp.w %1, %2, %0"
9917 [(set_attr "type" "dmpy_media")])
9918
9919 (define_expand "mmulhi_wl"
9920 [(match_operand:V2SI 0 "arith_reg_dest" "")
9921 (match_operand:V4HI 1 "arith_reg_operand" "")
9922 (match_operand:V4HI 2 "arith_reg_operand" "")]
9923 "TARGET_SHMEDIA"
9924 "
9925 {
9926 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9927 (operands[0], operands[1], operands[2]));
9928 DONE;
9929 }")
9930
9931 (define_expand "mmullo_wl"
9932 [(match_operand:V2SI 0 "arith_reg_dest" "")
9933 (match_operand:V4HI 1 "arith_reg_operand" "")
9934 (match_operand:V4HI 2 "arith_reg_operand" "")]
9935 "TARGET_SHMEDIA"
9936 "
9937 {
9938 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9939 (operands[0], operands[1], operands[2]));
9940 DONE;
9941 }")
9942
9943 (define_insn "mmul23_wl"
9944 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9945 (vec_select:V2SI
9946 (mult:V4SI
9947 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9948 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9949 (parallel [(const_int 2) (const_int 3)])))]
9950 "TARGET_SHMEDIA"
9951 "* return (TARGET_LITTLE_ENDIAN
9952 ? \"mmulhi.wl %1, %2, %0\"
9953 : \"mmullo.wl %1, %2, %0\");"
9954 [(set_attr "type" "dmpy_media")])
9955
9956 (define_insn "mmul01_wl"
9957 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9958 (vec_select:V2SI
9959 (mult:V4SI
9960 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9961 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9962 (parallel [(const_int 0) (const_int 1)])))]
9963 "TARGET_SHMEDIA"
9964 "* return (TARGET_LITTLE_ENDIAN
9965 ? \"mmullo.wl %1, %2, %0\"
9966 : \"mmulhi.wl %1, %2, %0\");"
9967 [(set_attr "type" "dmpy_media")])
9968
9969 (define_expand "mmulsum_wq"
9970 [(match_operand:DI 0 "arith_reg_dest" "")
9971 (match_operand:V4HI 1 "arith_reg_operand" "")
9972 (match_operand:V4HI 2 "arith_reg_operand" "")
9973 (match_operand:DI 3 "arith_reg_operand" "")]
9974 "TARGET_SHMEDIA"
9975 "
9976 {
9977 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9978 operands[1], operands[2]));
9979 DONE;
9980 }")
9981
9982 (define_insn "mmulsum_wq_i"
9983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9984 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9985 (plus:DI
9986 (plus:DI
9987 (vec_select:DI
9988 (mult:V4DI
9989 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9990 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9991 (parallel [(const_int 0)]))
9992 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9993 (sign_extend:V4DI (match_dup 3)))
9994 (parallel [(const_int 1)])))
9995 (plus:DI
9996 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9997 (sign_extend:V4DI (match_dup 3)))
9998 (parallel [(const_int 2)]))
9999 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10000 (sign_extend:V4DI (match_dup 3)))
10001 (parallel [(const_int 3)]))))))]
10002 "TARGET_SHMEDIA"
10003 "mmulsum.wq %2, %3, %0"
10004 [(set_attr "type" "mac_media")])
10005
10006 (define_expand "mperm_w"
10007 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10008 (match_operand:V4HI 1 "arith_reg_operand" "r")
10009 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10010 "TARGET_SHMEDIA"
10011 "
10012 {
10013 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10014 (operands[0], operands[1], operands[2]));
10015 DONE;
10016 }")
10017
10018 ; This use of vec_select isn't exactly correct according to rtl.texi
10019 ; (because not constant), but it seems a straightforward extension.
10020 (define_insn "mperm_w_little"
10021 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10022 (vec_select:V4HI
10023 (match_operand:V4HI 1 "arith_reg_operand" "r")
10024 (parallel
10025 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10026 (const_int 2) (const_int 0))
10027 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10028 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10029 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10030 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10031 "mperm.w %1, %N2, %0"
10032 [(set_attr "type" "arith_media")])
10033
10034 (define_insn "mperm_w_big"
10035 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10036 (vec_select:V4HI
10037 (match_operand:V4HI 1 "arith_reg_operand" "r")
10038 (parallel
10039 [(zero_extract:QI (not:QI (match_operand:QI 2
10040 "extend_reg_or_0_operand" "rZ"))
10041 (const_int 2) (const_int 0))
10042 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10043 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10044 (zero_extract:QI (not:QI (match_dup 2))
10045 (const_int 2) (const_int 6))])))]
10046 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10047 "mperm.w %1, %N2, %0"
10048 [(set_attr "type" "arith_media")])
10049
10050 (define_insn "mperm_w0"
10051 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10052 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10053 "trunc_hi_operand" "r"))))]
10054 "TARGET_SHMEDIA"
10055 "mperm.w %1, r63, %0"
10056 [(set_attr "type" "arith_media")])
10057
10058 (define_expand "msad_ubq"
10059 [(match_operand:DI 0 "arith_reg_dest" "")
10060 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10061 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10062 (match_operand:DI 3 "arith_reg_operand" "")]
10063 "TARGET_SHMEDIA"
10064 "
10065 {
10066 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10067 operands[1], operands[2]));
10068 DONE;
10069 }")
10070
10071 (define_insn "msad_ubq_i"
10072 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10073 (plus:DI
10074 (plus:DI
10075 (plus:DI
10076 (plus:DI
10077 (match_operand:DI 1 "arith_reg_operand" "0")
10078 (abs:DI (vec_select:DI
10079 (minus:V8DI
10080 (zero_extend:V8DI
10081 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10082 (zero_extend:V8DI
10083 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10084 (parallel [(const_int 0)]))))
10085 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10086 (zero_extend:V8DI (match_dup 3)))
10087 (parallel [(const_int 1)]))))
10088 (plus:DI
10089 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10090 (zero_extend:V8DI (match_dup 3)))
10091 (parallel [(const_int 2)])))
10092 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10093 (zero_extend:V8DI (match_dup 3)))
10094 (parallel [(const_int 3)])))))
10095 (plus:DI
10096 (plus:DI
10097 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10098 (zero_extend:V8DI (match_dup 3)))
10099 (parallel [(const_int 4)])))
10100 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10101 (zero_extend:V8DI (match_dup 3)))
10102 (parallel [(const_int 5)]))))
10103 (plus:DI
10104 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10105 (zero_extend:V8DI (match_dup 3)))
10106 (parallel [(const_int 6)])))
10107 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10108 (zero_extend:V8DI (match_dup 3)))
10109 (parallel [(const_int 7)])))))))]
10110 "TARGET_SHMEDIA"
10111 "msad.ubq %N2, %N3, %0"
10112 [(set_attr "type" "mac_media")])
10113
10114 (define_insn "mshalds_l"
10115 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10116 (ss_truncate:V2SI
10117 (ashift:V2DI
10118 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10119 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10120 (const_int 31)))))]
10121 "TARGET_SHMEDIA"
10122 "mshalds.l %1, %2, %0"
10123 [(set_attr "type" "mcmp_media")])
10124
10125 (define_insn "mshalds_w"
10126 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10127 (ss_truncate:V4HI
10128 (ashift:V4SI
10129 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10130 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10131 (const_int 15)))))]
10132 "TARGET_SHMEDIA"
10133 "mshalds.w %1, %2, %0"
10134 [(set_attr "type" "mcmp_media")])
10135
10136 (define_insn "ashrv2si3"
10137 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10138 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10139 (match_operand:DI 2 "arith_reg_operand" "r")))]
10140 "TARGET_SHMEDIA"
10141 "mshard.l %1, %2, %0"
10142 [(set_attr "type" "arith_media")])
10143
10144 (define_insn "ashrv4hi3"
10145 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10146 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10147 (match_operand:DI 2 "arith_reg_operand" "r")))]
10148 "TARGET_SHMEDIA"
10149 "mshard.w %1, %2, %0"
10150 [(set_attr "type" "arith_media")])
10151
10152 (define_insn "mshards_q"
10153 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10154 (ss_truncate:HI
10155 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10156 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10157 "TARGET_SHMEDIA"
10158 "mshards.q %1, %N2, %0"
10159 [(set_attr "type" "mcmp_media")])
10160
10161 (define_expand "mshfhi_b"
10162 [(match_operand:V8QI 0 "arith_reg_dest" "")
10163 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10164 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10165 "TARGET_SHMEDIA"
10166 "
10167 {
10168 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10169 (operands[0], operands[1], operands[2]));
10170 DONE;
10171 }")
10172
10173 (define_expand "mshflo_b"
10174 [(match_operand:V8QI 0 "arith_reg_dest" "")
10175 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10176 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10177 "TARGET_SHMEDIA"
10178 "
10179 {
10180 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10181 (operands[0], operands[1], operands[2]));
10182 DONE;
10183 }")
10184
10185 (define_insn "mshf4_b"
10186 [(set
10187 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10188 (vec_select:V8QI
10189 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10190 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10191 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10192 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10193 "TARGET_SHMEDIA"
10194 "* return (TARGET_LITTLE_ENDIAN
10195 ? \"mshfhi.b %N1, %N2, %0\"
10196 : \"mshflo.b %N1, %N2, %0\");"
10197 [(set_attr "type" "arith_media")])
10198
10199 (define_insn "mshf0_b"
10200 [(set
10201 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10202 (vec_select:V8QI
10203 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10204 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10205 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10206 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10207 "TARGET_SHMEDIA"
10208 "* return (TARGET_LITTLE_ENDIAN
10209 ? \"mshflo.b %N1, %N2, %0\"
10210 : \"mshfhi.b %N1, %N2, %0\");"
10211 [(set_attr "type" "arith_media")])
10212
10213 (define_expand "mshfhi_l"
10214 [(match_operand:V2SI 0 "arith_reg_dest" "")
10215 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10216 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10217 "TARGET_SHMEDIA"
10218 "
10219 {
10220 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10221 (operands[0], operands[1], operands[2]));
10222 DONE;
10223 }")
10224
10225 (define_expand "mshflo_l"
10226 [(match_operand:V2SI 0 "arith_reg_dest" "")
10227 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10228 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10229 "TARGET_SHMEDIA"
10230 "
10231 {
10232 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10233 (operands[0], operands[1], operands[2]));
10234 DONE;
10235 }")
10236
10237 (define_insn "mshf4_l"
10238 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10239 (vec_select:V2SI
10240 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10241 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10242 (parallel [(const_int 1) (const_int 3)])))]
10243 "TARGET_SHMEDIA"
10244 "* return (TARGET_LITTLE_ENDIAN
10245 ? \"mshfhi.l %N1, %N2, %0\"
10246 : \"mshflo.l %N1, %N2, %0\");"
10247 [(set_attr "type" "arith_media")])
10248
10249 (define_insn "mshf0_l"
10250 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10251 (vec_select:V2SI
10252 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10253 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10254 (parallel [(const_int 0) (const_int 2)])))]
10255 "TARGET_SHMEDIA"
10256 "* return (TARGET_LITTLE_ENDIAN
10257 ? \"mshflo.l %N1, %N2, %0\"
10258 : \"mshfhi.l %N1, %N2, %0\");"
10259 [(set_attr "type" "arith_media")])
10260
10261 (define_expand "mshfhi_w"
10262 [(match_operand:V4HI 0 "arith_reg_dest" "")
10263 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10264 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10265 "TARGET_SHMEDIA"
10266 "
10267 {
10268 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10269 (operands[0], operands[1], operands[2]));
10270 DONE;
10271 }")
10272
10273 (define_expand "mshflo_w"
10274 [(match_operand:V4HI 0 "arith_reg_dest" "")
10275 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10276 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10277 "TARGET_SHMEDIA"
10278 "
10279 {
10280 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10281 (operands[0], operands[1], operands[2]));
10282 DONE;
10283 }")
10284
10285 (define_insn "mshf4_w"
10286 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10287 (vec_select:V4HI
10288 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10289 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10290 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10291 "TARGET_SHMEDIA"
10292 "* return (TARGET_LITTLE_ENDIAN
10293 ? \"mshfhi.w %N1, %N2, %0\"
10294 : \"mshflo.w %N1, %N2, %0\");"
10295 [(set_attr "type" "arith_media")])
10296
10297 (define_insn "mshf0_w"
10298 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10299 (vec_select:V4HI
10300 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10301 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10302 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10303 "TARGET_SHMEDIA"
10304 "* return (TARGET_LITTLE_ENDIAN
10305 ? \"mshflo.w %N1, %N2, %0\"
10306 : \"mshfhi.w %N1, %N2, %0\");"
10307 [(set_attr "type" "arith_media")])
10308
10309 (define_insn "mshflo_w_x"
10310 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10311 (vec_select:V4HI
10312 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10313 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10314 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10315 "TARGET_SHMEDIA"
10316 "mshflo.w %N1, %N2, %0"
10317 [(set_attr "type" "arith_media")])
10318
10319 /* These are useful to expand ANDs and as combiner patterns. */
10320 (define_insn_and_split "mshfhi_l_di"
10321 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10322 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10323 (const_int 32))
10324 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10325 (const_int -4294967296))))]
10326 "TARGET_SHMEDIA"
10327 "@
10328 mshfhi.l %N1, %N2, %0
10329 #"
10330 "TARGET_SHMEDIA && reload_completed
10331 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10332 [(set (match_dup 3) (match_dup 4))
10333 (set (match_dup 5) (match_dup 6))]
10334 "
10335 {
10336 operands[3] = gen_lowpart (SImode, operands[0]);
10337 operands[4] = gen_highpart (SImode, operands[1]);
10338 operands[5] = gen_highpart (SImode, operands[0]);
10339 operands[6] = gen_highpart (SImode, operands[2]);
10340 }"
10341 [(set_attr "type" "arith_media")])
10342
10343 (define_insn "*mshfhi_l_di_rev"
10344 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10345 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10346 (const_int -4294967296))
10347 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10348 (const_int 32))))]
10349 "TARGET_SHMEDIA"
10350 "mshfhi.l %N2, %N1, %0"
10351 [(set_attr "type" "arith_media")])
10352
10353 (define_split
10354 [(set (match_operand:DI 0 "arith_reg_dest" "")
10355 (ior:DI (zero_extend:DI (match_operand:SI 1
10356 "extend_reg_or_0_operand" ""))
10357 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10358 (const_int -4294967296))))
10359 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10360 "TARGET_SHMEDIA"
10361 [(const_int 0)]
10362 "
10363 {
10364 emit_insn (gen_ashldi3_media (operands[3],
10365 simplify_gen_subreg (DImode, operands[1],
10366 SImode, 0),
10367 GEN_INT (32)));
10368 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10369 DONE;
10370 }")
10371
10372 (define_insn "mshflo_l_di"
10373 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10374 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10375 (const_int 4294967295))
10376 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10377 (const_int 32))))]
10378
10379 "TARGET_SHMEDIA"
10380 "mshflo.l %N1, %N2, %0"
10381 [(set_attr "type" "arith_media")])
10382
10383 (define_insn "*mshflo_l_di_rev"
10384 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10385 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10386 (const_int 32))
10387 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10388 (const_int 4294967295))))]
10389
10390 "TARGET_SHMEDIA"
10391 "mshflo.l %N2, %N1, %0"
10392 [(set_attr "type" "arith_media")])
10393
10394 ;; Combiner pattern for trampoline initialization.
10395 (define_insn_and_split "*double_shori"
10396 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10397 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10398 (const_int 32))
10399 (match_operand:DI 2 "const_int_operand" "n")))]
10400 "TARGET_SHMEDIA
10401 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10402 "#"
10403 "rtx_equal_p (operands[0], operands[1])"
10404 [(const_int 0)]
10405 "
10406 {
10407 HOST_WIDE_INT v = INTVAL (operands[2]);
10408
10409 emit_insn (gen_shori_media (operands[0], operands[0],
10410 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10411 emit_insn (gen_shori_media (operands[0], operands[0],
10412 gen_int_mode (v, HImode)));
10413 DONE;
10414 }")
10415
10416
10417 (define_insn "*mshflo_l_di_x"
10418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10419 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10420 "rZ"))
10421 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10422 (const_int 32))))]
10423
10424 "TARGET_SHMEDIA"
10425 "mshflo.l %N1, %N2, %0"
10426 [(set_attr "type" "arith_media")])
10427
10428 (define_insn_and_split "concat_v2sf"
10429 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10430 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10431 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10432 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10433
10434 "TARGET_SHMEDIA"
10435 "@
10436 mshflo.l %N1, %N2, %0
10437 #
10438 #"
10439 "TARGET_SHMEDIA && reload_completed
10440 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10441 [(set (match_dup 3) (match_dup 1))
10442 (set (match_dup 4) (match_dup 2))]
10443 "
10444 {
10445 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10446 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10447 }"
10448 [(set_attr "type" "arith_media")])
10449
10450 (define_insn "*mshflo_l_di_x_rev"
10451 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10452 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10453 (const_int 32))
10454 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10455
10456 "TARGET_SHMEDIA"
10457 "mshflo.l %N2, %N1, %0"
10458 [(set_attr "type" "arith_media")])
10459
10460 (define_insn "ashlv2si3"
10461 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10462 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10463 (match_operand:DI 2 "arith_reg_operand" "r")))]
10464 "TARGET_SHMEDIA"
10465 "mshlld.l %1, %2, %0"
10466 [(set_attr "type" "arith_media")])
10467
10468 (define_insn "ashlv4hi3"
10469 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10470 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10471 (match_operand:DI 2 "arith_reg_operand" "r")))]
10472 "TARGET_SHMEDIA"
10473 "mshlld.w %1, %2, %0"
10474 [(set_attr "type" "arith_media")])
10475
10476 (define_insn "lshrv2si3"
10477 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10478 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10479 (match_operand:DI 2 "arith_reg_operand" "r")))]
10480 "TARGET_SHMEDIA"
10481 "mshlrd.l %1, %2, %0"
10482 [(set_attr "type" "arith_media")])
10483
10484 (define_insn "lshrv4hi3"
10485 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10486 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10487 (match_operand:DI 2 "arith_reg_operand" "r")))]
10488 "TARGET_SHMEDIA"
10489 "mshlrd.w %1, %2, %0"
10490 [(set_attr "type" "arith_media")])
10491
10492 (define_insn "subv2si3"
10493 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10494 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10496 "TARGET_SHMEDIA"
10497 "msub.l %N1, %2, %0"
10498 [(set_attr "type" "arith_media")])
10499
10500 (define_insn "subv4hi3"
10501 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10502 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10503 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10504 "TARGET_SHMEDIA"
10505 "msub.w %N1, %2, %0"
10506 [(set_attr "type" "arith_media")])
10507
10508 (define_insn "sssubv2si3"
10509 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10510 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10511 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10512 "TARGET_SHMEDIA"
10513 "msubs.l %N1, %2, %0"
10514 [(set_attr "type" "mcmp_media")])
10515
10516 (define_insn "ussubv8qi3"
10517 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10518 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10519 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10520 "TARGET_SHMEDIA"
10521 "msubs.ub %1, %2, %0"
10522 [(set_attr "type" "mcmp_media")])
10523
10524 (define_insn "sssubv4hi3"
10525 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10526 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10527 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10528 "TARGET_SHMEDIA"
10529 "msubs.w %N1, %2, %0"
10530 [(set_attr "type" "mcmp_media")])
10531
10532 ;; Floating Point Intrinsics
10533
10534 (define_insn "fcosa_s"
10535 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10537 UNSPEC_FCOSA))]
10538 "TARGET_SHMEDIA"
10539 "fcosa.s %1, %0"
10540 [(set_attr "type" "atrans_media")])
10541
10542 (define_insn "fsina_s"
10543 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10544 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10545 UNSPEC_FSINA))]
10546 "TARGET_SHMEDIA"
10547 "fsina.s %1, %0"
10548 [(set_attr "type" "atrans_media")])
10549
10550 (define_insn "fipr"
10551 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10552 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10553 "fp_arith_reg_operand" "f")
10554 (match_operand:V4SF 2
10555 "fp_arith_reg_operand" "f"))
10556 (parallel [(const_int 0)]))
10557 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10558 (parallel [(const_int 1)])))
10559 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10560 (parallel [(const_int 2)]))
10561 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10562 (parallel [(const_int 3)])))))]
10563 "TARGET_SHMEDIA"
10564 "fipr.s %1, %2, %0"
10565 [(set_attr "type" "fparith_media")])
10566
10567 (define_insn "fsrra_s"
10568 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10569 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10570 UNSPEC_FSRRA))]
10571 "TARGET_SHMEDIA"
10572 "fsrra.s %1, %0"
10573 [(set_attr "type" "atrans_media")])
10574
10575 (define_insn "ftrv"
10576 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10577 (plus:V4SF
10578 (plus:V4SF
10579 (mult:V4SF
10580 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10581 (parallel [(const_int 0) (const_int 5)
10582 (const_int 10) (const_int 15)]))
10583 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10584 (mult:V4SF
10585 (vec_select:V4SF (match_dup 1)
10586 (parallel [(const_int 4) (const_int 9)
10587 (const_int 14) (const_int 3)]))
10588 (vec_select:V4SF (match_dup 2)
10589 (parallel [(const_int 1) (const_int 2)
10590 (const_int 3) (const_int 0)]))))
10591 (plus:V4SF
10592 (mult:V4SF
10593 (vec_select:V4SF (match_dup 1)
10594 (parallel [(const_int 8) (const_int 13)
10595 (const_int 2) (const_int 7)]))
10596 (vec_select:V4SF (match_dup 2)
10597 (parallel [(const_int 2) (const_int 3)
10598 (const_int 0) (const_int 1)])))
10599 (mult:V4SF
10600 (vec_select:V4SF (match_dup 1)
10601 (parallel [(const_int 12) (const_int 1)
10602 (const_int 6) (const_int 11)]))
10603 (vec_select:V4SF (match_dup 2)
10604 (parallel [(const_int 3) (const_int 0)
10605 (const_int 1) (const_int 2)]))))))]
10606 "TARGET_SHMEDIA"
10607 "ftrv.s %1, %2, %0"
10608 [(set_attr "type" "fparith_media")])
10609
10610 (define_insn "nsb"
10611 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10612 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10613 UNSPEC_NSB))]
10614 "TARGET_SHMEDIA"
10615 "nsb %1, %0"
10616 [(set_attr "type" "arith_media")])
10617
10618 (define_insn "nsbsi"
10619 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10620 (zero_extend:SI
10621 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10622 UNSPEC_NSB)))]
10623 "TARGET_SHMEDIA"
10624 "nsb %1, %0"
10625 [(set_attr "type" "arith_media")])
10626
10627 (define_insn "nsbdi"
10628 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10629 (zero_extend:DI
10630 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10631 UNSPEC_NSB)))]
10632 "TARGET_SHMEDIA"
10633 "nsb %1, %0"
10634 [(set_attr "type" "arith_media")])
10635
10636 (define_expand "ffsdi2"
10637 [(set (match_operand:DI 0 "arith_reg_dest" "")
10638 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10639 "TARGET_SHMEDIA"
10640 "
10641 {
10642 rtx scratch = gen_reg_rtx (DImode);
10643 rtx last;
10644
10645 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10646 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10647 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10648 emit_insn (gen_nsbdi (scratch, scratch));
10649 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10650 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10651 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10652 REG_NOTES (last)
10653 = gen_rtx_EXPR_LIST (REG_EQUAL,
10654 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10655 DONE;
10656 }")
10657
10658 (define_expand "ffssi2"
10659 [(set (match_operand:SI 0 "arith_reg_dest" "")
10660 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10661 "TARGET_SHMEDIA"
10662 "
10663 {
10664 rtx scratch = gen_reg_rtx (SImode);
10665 rtx discratch = gen_reg_rtx (DImode);
10666 rtx last;
10667
10668 emit_insn (gen_adddi3 (discratch,
10669 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10670 GEN_INT (-1)));
10671 emit_insn (gen_andcdi3 (discratch,
10672 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10673 discratch));
10674 emit_insn (gen_nsbsi (scratch, discratch));
10675 last = emit_insn (gen_subsi3 (operands[0],
10676 force_reg (SImode, GEN_INT (63)), scratch));
10677 REG_NOTES (last)
10678 = gen_rtx_EXPR_LIST (REG_EQUAL,
10679 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10680 DONE;
10681 }")
10682
10683 (define_insn "byterev"
10684 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10685 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10686 (parallel [(const_int 7) (const_int 6) (const_int 5)
10687 (const_int 4) (const_int 3) (const_int 2)
10688 (const_int 1) (const_int 0)])))]
10689 "TARGET_SHMEDIA"
10690 "byterev %1, %0"
10691 [(set_attr "type" "arith_media")])
10692
10693 (define_insn "prefetch"
10694 [(prefetch (match_operand:QI 0 "address_operand" "p")
10695 (match_operand:SI 1 "const_int_operand" "n")
10696 (match_operand:SI 2 "const_int_operand" "n"))]
10697 "TARGET_SHMEDIA"
10698 "*
10699 {
10700 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10701 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10702 return \"\";
10703 }"
10704 [(set_attr "type" "other")])
10705
10706 ;; The following description models the
10707 ;; SH4 pipeline using the DFA based scheduler.
10708 ;; The DFA based description is better way to model
10709 ;; a superscalar pipeline as compared to function unit
10710 ;; reservation model.
10711 ;; 1. The function unit based model is oriented to describe at most one
10712 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10713 ;; pipeline units by same insn. This can be done using DFA based description.
10714 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10715 ;; 3. Writing all unit reservations for an instruction class is more natural description
10716 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10717 ;; old function unit based model.
10718 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10719
10720
10721 ;; Two automata are defined to reduce number of states
10722 ;; which a single large automaton will have.(Factoring)
10723
10724 (define_automaton "inst_pipeline,fpu_pipe")
10725
10726 ;; This unit is basically the decode unit of the processor.
10727 ;; Since SH4 is a dual issue machine,it is as if there are two
10728 ;; units so that any insn can be processed by either one
10729 ;; of the decoding unit.
10730
10731 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10732
10733
10734 ;; The fixed point arithmetic calculator(?? EX Unit).
10735
10736 (define_cpu_unit "int" "inst_pipeline")
10737
10738 ;; f1_1 and f1_2 are floating point units.Actually there is
10739 ;; a f1 unit which can overlap with other f1 unit but
10740 ;; not another F1 unit.It is as though there were two
10741 ;; f1 units.
10742
10743 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10744
10745 ;; The floating point units (except FS - F2 always precedes it.)
10746
10747 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10748
10749 ;; This is basically the MA unit of SH4
10750 ;; used in LOAD/STORE pipeline.
10751
10752 (define_cpu_unit "memory" "inst_pipeline")
10753
10754 ;; However, there are LS group insns that don't use it, even ones that
10755 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10756 (define_cpu_unit "load_store" "inst_pipeline")
10757
10758 ;; The address calculator used for branch instructions.
10759 ;; This will be reserved after "issue" of branch instructions
10760 ;; and this is to make sure that no two branch instructions
10761 ;; can be issued in parallel.
10762
10763 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10764
10765 ;; ----------------------------------------------------
10766 ;; This reservation is to simplify the dual issue description.
10767
10768 (define_reservation "issue" "pipe_01|pipe_02")
10769
10770 ;; This is to express the locking of D stage.
10771 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10772
10773 (define_reservation "d_lock" "pipe_01+pipe_02")
10774
10775 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10776 (define_reservation "F01" "F0+F1")
10777
10778 ;; This is to simplify description where F1,F2,FS
10779 ;; are used simultaneously.
10780
10781 (define_reservation "fpu" "F1+F2")
10782
10783 ;; This is to highlight the fact that f1
10784 ;; cannot overlap with F1.
10785
10786 (exclusion_set "f1_1,f1_2" "F1")
10787
10788 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10789
10790 ;; Although reg moves have a latency of zero
10791 ;; we need to highlight that they use D stage
10792 ;; for one cycle.
10793
10794 ;; Group: MT
10795
10796 (define_insn_reservation "reg_mov" 0
10797 (and (eq_attr "pipe_model" "sh4")
10798 (eq_attr "type" "move"))
10799 "issue")
10800
10801 ;; Group: LS
10802
10803 (define_insn_reservation "freg_mov" 0
10804 (and (eq_attr "pipe_model" "sh4")
10805 (eq_attr "type" "fmove"))
10806 "issue+load_store")
10807
10808 ;; We don't model all pipeline stages; we model the issue ('D') stage
10809 ;; inasmuch as we allow only two instructions to issue simultaneously,
10810 ;; and CO instructions prevent any simultaneous issue of another instruction.
10811 ;; (This uses pipe_01 and pipe_02).
10812 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10813 ;; Double issue of EX / BR insns is prevented by using the int unit /
10814 ;; pcr_addrcalc unit in the EX stage.
10815 ;; Double issue of BR / LS instructions is prevented by using the
10816 ;; pcr_addrcalc / load_store unit in the issue cycle.
10817 ;; Double issue of FE instructions is prevented by using F0 in the first
10818 ;; pipeline stage after the first D stage.
10819 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10820 ;; (except in the cases outlined above), nor to describe the FS stage after
10821 ;; the F2 stage.
10822
10823 ;; Other MT group instructions(1 step operations)
10824 ;; Group: MT
10825 ;; Latency: 1
10826 ;; Issue Rate: 1
10827
10828 (define_insn_reservation "mt" 1
10829 (and (eq_attr "pipe_model" "sh4")
10830 (eq_attr "type" "mt_group"))
10831 "issue")
10832
10833 ;; Fixed Point Arithmetic Instructions(1 step operations)
10834 ;; Group: EX
10835 ;; Latency: 1
10836 ;; Issue Rate: 1
10837
10838 (define_insn_reservation "sh4_simple_arith" 1
10839 (and (eq_attr "pipe_model" "sh4")
10840 (eq_attr "insn_class" "ex_group"))
10841 "issue,int")
10842
10843 ;; Load and store instructions have no alignment peculiarities for the SH4,
10844 ;; but they use the load-store unit, which they share with the fmove type
10845 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10846 ;; Loads have a latency of two.
10847 ;; However, call insns can only paired with a preceding insn, and have
10848 ;; a delay slot, so that we want two more insns to be scheduled between the
10849 ;; load of the function address and the call. This is equivalent to a
10850 ;; latency of three.
10851 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10852 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10853 ;; We only do this for SImode loads of general registers, to make the work
10854 ;; for ADJUST_COST easier.
10855
10856 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10857 ;; Group: LS
10858 ;; Latency: 2
10859 ;; Issue Rate: 1
10860
10861 (define_insn_reservation "sh4_load" 2
10862 (and (eq_attr "pipe_model" "sh4")
10863 (eq_attr "type" "load,pcload"))
10864 "issue+load_store,nothing,memory")
10865
10866 ;; calls / sfuncs need an extra instruction for their delay slot.
10867 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10868 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10869 ;; count of a dynamic shift.
10870 (define_insn_reservation "sh4_load_si" 3
10871 (and (eq_attr "pipe_model" "sh4")
10872 (eq_attr "type" "load_si,pcload_si"))
10873 "issue+load_store,nothing,memory")
10874
10875 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10876
10877 ;; The load latency is upped to three higher if the dependent insn does
10878 ;; double precision computation. We want the 'default' latency to reflect
10879 ;; that increased latency because otherwise the insn priorities won't
10880 ;; allow proper scheduling.
10881 (define_insn_reservation "sh4_fload" 3
10882 (and (eq_attr "pipe_model" "sh4")
10883 (eq_attr "type" "fload,pcfload"))
10884 "issue+load_store,nothing,memory")
10885
10886 ;; (define_bypass 2 "sh4_fload" "!")
10887
10888 (define_insn_reservation "sh4_store" 1
10889 (and (eq_attr "pipe_model" "sh4")
10890 (eq_attr "type" "store"))
10891 "issue+load_store,nothing,memory")
10892
10893 ;; Load Store instructions.
10894 ;; Group: LS
10895 ;; Latency: 1
10896 ;; Issue Rate: 1
10897
10898 (define_insn_reservation "sh4_gp_fpul" 1
10899 (and (eq_attr "pipe_model" "sh4")
10900 (eq_attr "type" "gp_fpul"))
10901 "issue+load_store")
10902
10903 ;; Load Store instructions.
10904 ;; Group: LS
10905 ;; Latency: 3
10906 ;; Issue Rate: 1
10907
10908 (define_insn_reservation "sh4_fpul_gp" 3
10909 (and (eq_attr "pipe_model" "sh4")
10910 (eq_attr "type" "fpul_gp"))
10911 "issue+load_store")
10912
10913 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10914 ;; Group: BR
10915 ;; Latency when taken: 2 (or 1)
10916 ;; Issue Rate: 1
10917 ;; The latency is 1 when displacement is 0.
10918 ;; We can't really do much with the latency, even if we could express it,
10919 ;; but the pairing restrictions are useful to take into account.
10920 ;; ??? If the branch is likely, we might want to fill the delay slot;
10921 ;; if the branch is likely, but not very likely, should we pretend to use
10922 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10923
10924 (define_insn_reservation "sh4_branch" 1
10925 (and (eq_attr "pipe_model" "sh4")
10926 (eq_attr "type" "cbranch,jump"))
10927 "issue+pcr_addrcalc")
10928
10929 ;; Branch Far (JMP,RTS,BRAF)
10930 ;; Group: CO
10931 ;; Latency: 3
10932 ;; Issue Rate: 2
10933 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10934 ;; can't be distinguished from bra for the "jump" pattern.
10935
10936 (define_insn_reservation "sh4_return" 3
10937 (and (eq_attr "pipe_model" "sh4")
10938 (eq_attr "type" "return,jump_ind"))
10939 "d_lock*2")
10940
10941 ;; RTE
10942 ;; Group: CO
10943 ;; Latency: 5
10944 ;; Issue Rate: 5
10945 ;; this instruction can be executed in any of the pipelines
10946 ;; and blocks the pipeline for next 4 stages.
10947
10948 (define_insn_reservation "sh4_return_from_exp" 5
10949 (and (eq_attr "pipe_model" "sh4")
10950 (eq_attr "type" "rte"))
10951 "d_lock*5")
10952
10953 ;; OCBP, OCBWB
10954 ;; Group: CO
10955 ;; Latency: 1-5
10956 ;; Issue Rate: 1
10957
10958 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10959 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10960 (define_insn_reservation "ocbwb" 6
10961 (and (eq_attr "pipe_model" "sh4")
10962 (eq_attr "type" "cwb"))
10963 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10964
10965 ;; LDS to PR,JSR
10966 ;; Group: CO
10967 ;; Latency: 3
10968 ;; Issue Rate: 2
10969 ;; The SX stage is blocked for last 2 cycles.
10970 ;; OTOH, the only time that has an effect for insns generated by the compiler
10971 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10972 ;; or when we are doing a function call - and we don't do inter-function
10973 ;; scheduling. For the function call case, it's really best that we end with
10974 ;; something that models an rts.
10975
10976 (define_insn_reservation "sh4_lds_to_pr" 3
10977 (and (eq_attr "pipe_model" "sh4")
10978 (eq_attr "type" "prset") )
10979 "d_lock*2")
10980
10981 ;; calls introduce a longisch delay that is likely to flush the pipelines
10982 ;; of the caller's instructions. Ordinary functions tend to end with a
10983 ;; load to restore a register (in the delay slot of rts), while sfuncs
10984 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10985 ;; since there are no instructions that contend for memory access early.
10986 ;; We could, of course, provide exact scheduling information for specific
10987 ;; sfuncs, if that should prove useful.
10988
10989 (define_insn_reservation "sh4_call" 16
10990 (and (eq_attr "pipe_model" "sh4")
10991 (eq_attr "type" "call,sfunc"))
10992 "d_lock*16")
10993
10994 ;; LDS.L to PR
10995 ;; Group: CO
10996 ;; Latency: 3
10997 ;; Issue Rate: 2
10998 ;; The SX unit is blocked for last 2 cycles.
10999
11000 (define_insn_reservation "ldsmem_to_pr" 3
11001 (and (eq_attr "pipe_model" "sh4")
11002 (eq_attr "type" "pload"))
11003 "d_lock*2")
11004
11005 ;; STS from PR
11006 ;; Group: CO
11007 ;; Latency: 2
11008 ;; Issue Rate: 2
11009 ;; The SX unit in second and third cycles.
11010
11011 (define_insn_reservation "sts_from_pr" 2
11012 (and (eq_attr "pipe_model" "sh4")
11013 (eq_attr "type" "prget"))
11014 "d_lock*2")
11015
11016 ;; STS.L from PR
11017 ;; Group: CO
11018 ;; Latency: 2
11019 ;; Issue Rate: 2
11020
11021 (define_insn_reservation "sh4_prstore_mem" 2
11022 (and (eq_attr "pipe_model" "sh4")
11023 (eq_attr "type" "pstore"))
11024 "d_lock*2,nothing,memory")
11025
11026 ;; LDS to FPSCR
11027 ;; Group: CO
11028 ;; Latency: 4
11029 ;; Issue Rate: 1
11030 ;; F1 is blocked for last three cycles.
11031
11032 (define_insn_reservation "fpscr_load" 4
11033 (and (eq_attr "pipe_model" "sh4")
11034 (eq_attr "type" "gp_fpscr"))
11035 "d_lock,nothing,F1*3")
11036
11037 ;; LDS.L to FPSCR
11038 ;; Group: CO
11039 ;; Latency: 1 / 4
11040 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11041 ;; Issue Rate: 1
11042 ;; F1 is blocked for last three cycles.
11043
11044 (define_insn_reservation "fpscr_load_mem" 4
11045 (and (eq_attr "pipe_model" "sh4")
11046 (eq_attr "type" "mem_fpscr"))
11047 "d_lock,nothing,(F1+memory),F1*2")
11048
11049 \f
11050 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11051 ;; Group: CO
11052 ;; Latency: 4 / 4
11053 ;; Issue Rate: 1
11054
11055 (define_insn_reservation "multi" 4
11056 (and (eq_attr "pipe_model" "sh4")
11057 (eq_attr "type" "smpy,dmpy"))
11058 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11059
11060 ;; Fixed STS from MACL / MACH
11061 ;; Group: CO
11062 ;; Latency: 3
11063 ;; Issue Rate: 1
11064
11065 (define_insn_reservation "sh4_mac_gp" 3
11066 (and (eq_attr "pipe_model" "sh4")
11067 (eq_attr "type" "mac_gp"))
11068 "d_lock")
11069
11070
11071 ;; Single precision floating point computation FCMP/EQ,
11072 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11073 ;; Group: FE
11074 ;; Latency: 3/4
11075 ;; Issue Rate: 1
11076
11077 (define_insn_reservation "fp_arith" 3
11078 (and (eq_attr "pipe_model" "sh4")
11079 (eq_attr "type" "fp"))
11080 "issue,F01,F2")
11081
11082 (define_insn_reservation "fp_arith_ftrc" 3
11083 (and (eq_attr "pipe_model" "sh4")
11084 (eq_attr "type" "ftrc_s"))
11085 "issue,F01,F2")
11086
11087 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11088
11089 ;; Single Precision FDIV/SQRT
11090 ;; Group: FE
11091 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
11092 ;; Issue Rate: 1
11093 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11094
11095 (define_insn_reservation "fp_div" 12
11096 (and (eq_attr "pipe_model" "sh4")
11097 (eq_attr "type" "fdiv"))
11098 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11099
11100 ;; Double Precision floating point computation
11101 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11102 ;; Group: FE
11103 ;; Latency: (3,4)/5
11104 ;; Issue Rate: 1
11105
11106 (define_insn_reservation "dp_float" 4
11107 (and (eq_attr "pipe_model" "sh4")
11108 (eq_attr "type" "dfp_conv"))
11109 "issue,F01,F1+F2,F2")
11110
11111 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11112 ;; Group: FE
11113 ;; Latency: (7,8)/9
11114 ;; Issue Rate: 1
11115
11116 (define_insn_reservation "fp_double_arith" 8
11117 (and (eq_attr "pipe_model" "sh4")
11118 (eq_attr "type" "dfp_arith"))
11119 "issue,F01,F1+F2,fpu*4,F2")
11120
11121 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11122 ;; Group: CO
11123 ;; Latency: 3/5
11124 ;; Issue Rate: 2
11125
11126 (define_insn_reservation "fp_double_cmp" 3
11127 (and (eq_attr "pipe_model" "sh4")
11128 (eq_attr "type" "dfp_cmp"))
11129 "d_lock,(d_lock+F01),F1+F2,F2")
11130
11131 ;; Double precision FDIV/SQRT
11132 ;; Group: FE
11133 ;; Latency: (24,25)/26
11134 ;; Issue Rate: 1
11135
11136 (define_insn_reservation "dp_div" 25
11137 (and (eq_attr "pipe_model" "sh4")
11138 (eq_attr "type" "dfdiv"))
11139 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11140
11141
11142 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11143 ;; case, we'd get a d_lock instead of issue at the end.
11144 (define_insn_reservation "arith3" 3
11145 (and (eq_attr "pipe_model" "sh4")
11146 (eq_attr "type" "arith3"))
11147 "issue,d_lock+pcr_addrcalc,issue")
11148
11149 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11150 (define_insn_reservation "arith3b" 2
11151 (and (eq_attr "pipe_model" "sh4")
11152 (eq_attr "type" "arith3"))
11153 "issue,d_lock+pcr_addrcalc")
This page took 0.531625 seconds and 5 git commands to generate.