]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/sh/sh.md
host-hpux.c: Change copyright header to refer to version 3 of the GNU General Public...
[thirdparty/gcc.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004, 2005, 2006, 2007 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 3, 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 COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
26
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences. Especially the sequences for arithmetic right shifts.
29
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
31
32 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
33 ;; way to generate them.
34
35 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
36 ;; for a str* inline function.
37
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
41
42 ;; Special constraints for SH machine description:
43 ;;
44 ;; t -- T
45 ;; x -- mac
46 ;; l -- pr
47 ;; z -- r0
48 ;;
49 ;; Special formats used for outputting SH instructions:
50 ;;
51 ;; %. -- print a .s if insn needs delay slot
52 ;; %@ -- print rte/rts if is/isn't an interrupt function
53 ;; %# -- output a nop if there is nothing to put in the delay slot
54 ;; %O -- print a constant without the #
55 ;; %R -- print the lsw reg of a double
56 ;; %S -- print the msw reg of a double
57 ;; %T -- print next word of a double REG or MEM
58 ;;
59 ;; Special predicates:
60 ;;
61 ;; arith_operand -- operand is valid source for arithmetic op
62 ;; arith_reg_operand -- operand is valid register for arithmetic op
63 ;; general_movdst_operand -- operand is valid move destination
64 ;; general_movsrc_operand -- operand is valid move source
65 ;; logical_operand -- operand is valid source for logical op
66
67 ;; -------------------------------------------------------------------------
68 ;; Constants
69 ;; -------------------------------------------------------------------------
70
71 (define_constants [
72 (AP_REG 145)
73 (PR_REG 146)
74 (T_REG 147)
75 (GBR_REG 144)
76 (MACH_REG 148)
77 (MACL_REG 149)
78 (FPUL_REG 150)
79 (RAP_REG 152)
80
81 (FPSCR_REG 151)
82
83 (PIC_REG 12)
84 (FP_REG 14)
85 (SP_REG 15)
86
87 (PR_MEDIA_REG 18)
88 (T_MEDIA_REG 19)
89
90 (R0_REG 0)
91 (R1_REG 1)
92 (R2_REG 2)
93 (R3_REG 3)
94 (R4_REG 4)
95 (R5_REG 5)
96 (R6_REG 6)
97 (R7_REG 7)
98 (R8_REG 8)
99 (R9_REG 9)
100 (R10_REG 10)
101 (R20_REG 20)
102 (R21_REG 21)
103 (R22_REG 22)
104 (R23_REG 23)
105
106 (DR0_REG 64)
107 (DR2_REG 66)
108 (DR4_REG 68)
109 (FR23_REG 87)
110
111 (TR0_REG 128)
112 (TR1_REG 129)
113 (TR2_REG 130)
114
115 (XD0_REG 136)
116
117 ;; These are used with unspec.
118 (UNSPEC_COMPACT_ARGS 0)
119 (UNSPEC_MOVA 1)
120 (UNSPEC_CASESI 2)
121 (UNSPEC_DATALABEL 3)
122 (UNSPEC_BBR 4)
123 (UNSPEC_SFUNC 5)
124 (UNSPEC_PIC 6)
125 (UNSPEC_GOT 7)
126 (UNSPEC_GOTOFF 8)
127 (UNSPEC_PLT 9)
128 (UNSPEC_CALLER 10)
129 (UNSPEC_GOTPLT 11)
130 (UNSPEC_ICACHE 12)
131 (UNSPEC_INIT_TRAMP 13)
132 (UNSPEC_FCOSA 14)
133 (UNSPEC_FSRRA 15)
134 (UNSPEC_FSINA 16)
135 (UNSPEC_NSB 17)
136 (UNSPEC_ALLOCO 18)
137 (UNSPEC_TLSGD 20)
138 (UNSPEC_TLSLDM 21)
139 (UNSPEC_TLSIE 22)
140 (UNSPEC_DTPOFF 23)
141 (UNSPEC_GOTTPOFF 24)
142 (UNSPEC_TPOFF 25)
143 (UNSPEC_RA 26)
144 (UNSPEC_DIV_INV_M0 30)
145 (UNSPEC_DIV_INV_M1 31)
146 (UNSPEC_DIV_INV_M2 32)
147 (UNSPEC_DIV_INV_M3 33)
148 (UNSPEC_DIV_INV20 34)
149 (UNSPEC_DIV_INV_TABLE 37)
150 (UNSPEC_ASHIFTRT 35)
151 (UNSPEC_THUNK 36)
152 (UNSPEC_SP_SET 40)
153 (UNSPEC_SP_TEST 41)
154 (UNSPEC_MOVUA 42)
155
156 ;; These are used with unspec_volatile.
157 (UNSPECV_BLOCKAGE 0)
158 (UNSPECV_ALIGN 1)
159 (UNSPECV_CONST2 2)
160 (UNSPECV_CONST4 4)
161 (UNSPECV_CONST8 6)
162 (UNSPECV_WINDOW_END 10)
163 (UNSPECV_CONST_END 11)
164 (UNSPECV_EH_RETURN 12)
165 ])
166
167 ;; -------------------------------------------------------------------------
168 ;; Attributes
169 ;; -------------------------------------------------------------------------
170
171 ;; Target CPU.
172
173 (define_attr "cpu"
174 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175 (const (symbol_ref "sh_cpu_attr")))
176
177 (define_attr "endian" "big,little"
178 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179 (const_string "little") (const_string "big"))))
180
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184 (const_string "yes") (const_string "no"))))
185
186 (define_attr "fmovd" "yes,no"
187 (const (if_then_else (symbol_ref "TARGET_FMOVD")
188 (const_string "yes") (const_string "no"))))
189 ;; pipeline model
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
191 (const
192 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194 (const_string "sh1"))))
195
196 ;; cbranch conditional branch instructions
197 ;; jump unconditional jumps
198 ;; arith ordinary arithmetic
199 ;; arith3 a compound insn that behaves similarly to a sequence of
200 ;; three insns of type arith
201 ;; arith3b like above, but might end with a redirected branch
202 ;; load from memory
203 ;; load_si Likewise, SImode variant for general register.
204 ;; fload Likewise, but load to fp register.
205 ;; store to memory
206 ;; fstore floating point register to memory
207 ;; move general purpose register to register
208 ;; movi8 8-bit immediate to general purpose register
209 ;; mt_group other sh4 mt instructions
210 ;; fmove register to register, floating point
211 ;; smpy word precision integer multiply
212 ;; dmpy longword or doublelongword precision integer multiply
213 ;; return rts
214 ;; pload load of pr reg, which can't be put into delay slot of rts
215 ;; prset copy register to pr reg, ditto
216 ;; pstore store of pr reg, which can't be put into delay slot of jsr
217 ;; prget copy pr to register, ditto
218 ;; pcload pc relative load of constant value
219 ;; pcfload Likewise, but load to fp register.
220 ;; pcload_si Likewise, SImode variant for general register.
221 ;; rte return from exception
222 ;; sfunc special function call with known used registers
223 ;; call function call
224 ;; fp floating point
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv floating point divide (or square root)
227 ;; gp_fpul move from general purpose register to fpul
228 ;; fpul_gp move from fpul to general purpose register
229 ;; mac_gp move from mac[lh] to general purpose register
230 ;; gp_mac move from general purpose register to mac[lh]
231 ;; mac_mem move from mac[lh] to memory
232 ;; mem_mac move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s fix_truncsfsi2_i4
235 ;; dfdiv double precision floating point divide (or square root)
236 ;; cwb ic_invalidate_line_i
237 ;; movua SH4a unaligned load
238 ;; fsrra square root reciprocal approximate
239 ;; fsca sine and cosine approximate
240 ;; tls_load load TLS related address
241 ;; arith_media SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media SHmedia compare instructions
244 ;; dfdiv_media SHmedia double precision divide and square root
245 ;; dfmul_media SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media SHmedia longword multiply
249 ;; fcmp_media SHmedia floating point compare instructions
250 ;; fdiv_media SHmedia single precision divide and square root
251 ;; fload_media SHmedia floating point register load instructions
252 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media SHmedia unconditional branch instructions
259 ;; load_media SHmedia general register load instructions
260 ;; pt_media SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media SHmedia ptabs instruction
262 ;; store_media SHmedia general register store instructions
263 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media SHmedia mac-style fixed point operations
265 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil no-op move, will be deleted.
269
270 (define_attr "type"
271 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
272 (const_string "other"))
273
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
276 ;;
277 ;; mt_group SH4 "mt" group instructions.
278 ;;
279 ;; ex_group SH4 "ex" group instructions.
280 ;;
281 ;; ls_group SH4 "ls" group instructions.
282 ;;
283
284 (define_attr "insn_class"
285 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289 (eq_attr "type" "cbranch,jump") (const_string "br_group")
290 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291 (const_string "fe_group")
292 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
293 (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
297
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
299
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
301
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
305 ;; state.
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
309
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long. Something in the
312 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
315 ; 2 bytes.
316
317 ;; The maximum range used for SImode constant pool entries is 1018. A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table. That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
329 ;;
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
332
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
334 ;; inside an le.
335 (define_attr "short_cbranch_p" "no,yes"
336 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
337 (const_string "no")
338 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
339 (const_string "yes")
340 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
341 (const_string "no")
342 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
343 (const_string "yes")
344 ] (const_string "no")))
345
346 (define_attr "med_branch_p" "no,yes"
347 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
348 (const_int 1988))
349 (const_string "yes")
350 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
351 (const_string "no")
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
353 (const_int 8186))
354 (const_string "yes")
355 ] (const_string "no")))
356
357 (define_attr "med_cbranch_p" "no,yes"
358 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
359 (const_int 1986))
360 (const_string "yes")
361 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362 (const_string "no")
363 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
364 (const_int 8184))
365 (const_string "yes")
366 ] (const_string "no")))
367
368 (define_attr "braf_branch_p" "no,yes"
369 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
370 (const_string "no")
371 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
372 (const_int 20660))
373 (const_string "yes")
374 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
375 (const_string "no")
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
377 (const_int 65530))
378 (const_string "yes")
379 ] (const_string "no")))
380
381 (define_attr "braf_cbranch_p" "no,yes"
382 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
383 (const_string "no")
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
385 (const_int 20658))
386 (const_string "yes")
387 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
388 (const_string "no")
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
390 (const_int 65528))
391 (const_string "yes")
392 ] (const_string "no")))
393
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
400
401 ; All other instructions are two bytes long by default.
402
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406 (cond [(eq_attr "type" "cbranch")
407 (cond [(eq_attr "short_cbranch_p" "yes")
408 (const_int 2)
409 (eq_attr "med_cbranch_p" "yes")
410 (const_int 6)
411 (eq_attr "braf_cbranch_p" "yes")
412 (const_int 12)
413 ;; ??? using pc is not computed transitively.
414 (ne (match_dup 0) (match_dup 0))
415 (const_int 14)
416 (ne (symbol_ref ("flag_pic")) (const_int 0))
417 (const_int 24)
418 ] (const_int 16))
419 (eq_attr "type" "jump")
420 (cond [(eq_attr "med_branch_p" "yes")
421 (const_int 2)
422 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
423 (const_int 0))
424 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
425 (symbol_ref "INSN"))
426 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427 (symbol_ref "code_for_indirect_jump_scratch"))))
428 (cond [(eq_attr "braf_branch_p" "yes")
429 (const_int 6)
430 (eq (symbol_ref "flag_pic") (const_int 0))
431 (const_int 10)
432 (ne (symbol_ref "TARGET_SH2") (const_int 0))
433 (const_int 10)] (const_int 18))
434 (eq_attr "braf_branch_p" "yes")
435 (const_int 10)
436 ;; ??? using pc is not computed transitively.
437 (ne (match_dup 0) (match_dup 0))
438 (const_int 12)
439 (ne (symbol_ref ("flag_pic")) (const_int 0))
440 (const_int 22)
441 ] (const_int 14))
442 (eq_attr "type" "pt_media")
443 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444 (const_int 20) (const_int 12))
445 (and (eq_attr "type" "jump_media")
446 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
447 (const_int 8)
448 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
449 (const_int 4)
450 (const_int 2))))
451
452 ;; DFA descriptions for the pipelines
453
454 (include "sh1.md")
455 (include "shmedia.md")
456 (include "sh4.md")
457
458 (include "predicates.md")
459 (include "constraints.md")
460
461 ;; Definitions for filling delay slots
462
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
464
465 (define_attr "banked" "yes,no"
466 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
467 (const_int 1))
468 (const_string "yes")]
469 (const_string "no")))
470
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
474 (const_int 0))
475 (const_string "no")]
476 (const_string "yes")))
477
478 (define_attr "interrupt_function" "no,yes"
479 (const (symbol_ref "current_function_interrupt")))
480
481 (define_attr "in_delay_slot" "yes,no"
482 (cond [(eq_attr "type" "cbranch") (const_string "no")
483 (eq_attr "type" "pcload,pcload_si") (const_string "no")
484 (eq_attr "needs_delay_slot" "yes") (const_string "no")
485 (eq_attr "length" "2") (const_string "yes")
486 ] (const_string "no")))
487
488 (define_attr "cond_delay_slot" "yes,no"
489 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490 ] (const_string "no")))
491
492 (define_attr "is_sfunc" ""
493 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
494
495 (define_attr "is_mac_media" ""
496 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
497
498 (define_attr "branch_zero" "yes,no"
499 (cond [(eq_attr "type" "!cbranch") (const_string "no")
500 (ne (symbol_ref "(next_active_insn (insn)\
501 == (prev_active_insn\
502 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503 && get_attr_length (next_active_insn (insn)) == 2")
504 (const_int 0))
505 (const_string "yes")]
506 (const_string "no")))
507
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512 (const_string "no")))
513
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519 (const_string "yes")]
520 (const_string "no")))
521
522 (define_attr "any_int_load" "yes,no"
523 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524 (const_string "yes")]
525 (const_string "no")))
526
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528 (const_string "user"))
529
530 (define_delay
531 (eq_attr "needs_delay_slot" "yes")
532 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
533
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
538
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
541
542 (define_delay
543 (eq_attr "type" "return")
544 [(and (eq_attr "in_delay_slot" "yes")
545 (ior (and (eq_attr "interrupt_function" "no")
546 (eq_attr "type" "!pload,prset"))
547 (and (eq_attr "interrupt_function" "yes")
548 (ior
549 (eq (symbol_ref "TARGET_SH3") (const_int 0))
550 (eq_attr "hit_stack" "no")
551 (eq_attr "banked" "no"))))) (nil) (nil)])
552
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
555
556 (define_delay
557 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558 [(and (eq_attr "in_delay_slot" "yes")
559 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
560
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
563
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
567
568 (define_delay
569 (and (eq_attr "type" "cbranch")
570 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571 ;; SH2e has a hardware bug that pretty much prohibits the use of
572 ;; annuled delay slots.
573 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574 (not (eq_attr "cpu" "sh2e"))) (nil)])
575 \f
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
579
580 (define_insn ""
581 [(set (reg:SI T_REG)
582 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583 (match_operand:SI 1 "arith_operand" "K08,r"))
584 (const_int 0)))]
585 "TARGET_SH1"
586 "tst %1,%0"
587 [(set_attr "type" "mt_group")])
588
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
594
595 (define_insn "cmpeqsi_t"
596 [(set (reg:SI T_REG)
597 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
599 "TARGET_SH1"
600 "@
601 tst %0,%0
602 cmp/eq %1,%0
603 cmp/eq %1,%0"
604 [(set_attr "type" "mt_group")])
605
606 (define_insn "cmpgtsi_t"
607 [(set (reg:SI T_REG)
608 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
610 "TARGET_SH1"
611 "@
612 cmp/gt %1,%0
613 cmp/pl %0"
614 [(set_attr "type" "mt_group")])
615
616 (define_insn "cmpgesi_t"
617 [(set (reg:SI T_REG)
618 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
620 "TARGET_SH1"
621 "@
622 cmp/ge %1,%0
623 cmp/pz %0"
624 [(set_attr "type" "mt_group")])
625
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
629
630 (define_expand "cbranchsi4"
631 [(set (pc)
632 (if_then_else (match_operator 0 "comparison_operator"
633 [(match_operand:SI 1 "arith_operand" "")
634 (match_operand:SI 2 "arith_operand" "")])
635 (label_ref (match_operand 3 "" ""))
636 (pc)))
637 (clobber (reg:SI T_REG))]
638 "TARGET_CBRANCHDI4"
639 "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
640
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
644
645 (define_insn_and_split "cmpgeusi_t"
646 [(set (reg:SI T_REG)
647 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
649 "TARGET_SH1"
650 "cmp/hs %1,%0"
651 "&& operands[0] == CONST0_RTX (SImode)"
652 [(pc)]
653 "
654 {
655 emit_insn (gen_sett ());
656 DONE;
657 }"
658 [(set_attr "type" "mt_group")])
659
660 (define_insn "cmpgtusi_t"
661 [(set (reg:SI T_REG)
662 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663 (match_operand:SI 1 "arith_reg_operand" "r")))]
664 "TARGET_SH1"
665 "cmp/hi %1,%0"
666 [(set_attr "type" "mt_group")])
667
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
670
671 (define_expand "cmpsi"
672 [(set (reg:SI T_REG)
673 (compare (match_operand:SI 0 "cmpsi_operand" "")
674 (match_operand:SI 1 "arith_operand" "")))]
675 "TARGET_SH1 || TARGET_SHMEDIA"
676 "
677 {
678 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679 && GET_CODE (operands[1]) != CONST_INT)
680 operands[0] = copy_to_mode_reg (SImode, operands[0]);
681 sh_compare_op0 = operands[0];
682 sh_compare_op1 = operands[1];
683 DONE;
684 }")
685 \f
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
689
690
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
695
696 (define_expand "cbranchdi4"
697 [(set (pc)
698 (if_then_else (match_operator 0 "comparison_operator"
699 [(match_operand:DI 1 "arith_operand" "")
700 (match_operand:DI 2 "arith_operand" "")])
701 (label_ref (match_operand 3 "" ""))
702 (pc)))
703 (clobber (match_dup 4))
704 (clobber (reg:SI T_REG))]
705 "TARGET_CBRANCHDI4"
706 "
707 {
708 enum rtx_code comparison;
709
710 if (TARGET_EXPAND_CBRANCHDI4)
711 {
712 if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
713 DONE;
714 }
715 comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716 if (comparison != GET_CODE (operands[0]))
717 operands[0]
718 = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719 operands[4] = gen_rtx_SCRATCH (SImode);
720 }")
721
722 (define_insn_and_split "cbranchdi4_i"
723 [(set (pc)
724 (if_then_else (match_operator 0 "comparison_operator"
725 [(match_operand:DI 1 "arith_operand" "r,r")
726 (match_operand:DI 2 "arith_operand" "rN,i")])
727 (label_ref (match_operand 3 "" ""))
728 (pc)))
729 (clobber (match_scratch:SI 4 "=X,&r"))
730 (clobber (reg:SI T_REG))]
731 "TARGET_CBRANCHDI4"
732 "#"
733 "&& reload_completed"
734 [(pc)]
735 "
736 {
737 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
738 FAIL;
739 DONE;
740 }")
741
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
745
746 (define_insn ""
747 [(set (reg:SI T_REG)
748 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749 (match_operand:DI 1 "arith_operand" "r"))
750 (const_int 0)))]
751 "TARGET_SH1"
752 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
753 insn, operands);"
754 [(set_attr "length" "6")
755 (set_attr "type" "arith3b")])
756
757 (define_insn "cmpeqdi_t"
758 [(set (reg:SI T_REG)
759 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
761 "TARGET_SH1"
762 "@
763 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
764 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765 [(set_attr "length" "6")
766 (set_attr "type" "arith3b")])
767
768 (define_split
769 [(set (reg:SI T_REG)
770 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
774 ;; may be created.
775 "TARGET_SH1 && reload_completed && optimize"
776 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778 (label_ref (match_dup 6))
779 (pc)))
780 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
781 (match_dup 6)]
782 "
783 {
784 operands[2]
785 = gen_rtx_REG (SImode,
786 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
787 operands[3]
788 = (operands[1] == const0_rtx
789 ? const0_rtx
790 : gen_rtx_REG (SImode,
791 true_regnum (operands[1])
792 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793 operands[4] = gen_lowpart (SImode, operands[0]);
794 operands[5] = gen_lowpart (SImode, operands[1]);
795 operands[6] = gen_label_rtx ();
796 }")
797
798 (define_insn "cmpgtdi_t"
799 [(set (reg:SI T_REG)
800 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
802 "TARGET_SH2"
803 "@
804 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806 [(set_attr "length" "8")
807 (set_attr "type" "arith3")])
808
809 (define_insn "cmpgedi_t"
810 [(set (reg:SI T_REG)
811 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
813 "TARGET_SH2"
814 "@
815 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
816 cmp/pz\\t%S0"
817 [(set_attr "length" "8,2")
818 (set_attr "type" "arith3,mt_group")])
819 \f
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
823
824 (define_insn "cmpgeudi_t"
825 [(set (reg:SI T_REG)
826 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827 (match_operand:DI 1 "arith_reg_operand" "r")))]
828 "TARGET_SH2"
829 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830 [(set_attr "length" "8")
831 (set_attr "type" "arith3")])
832
833 (define_insn "cmpgtudi_t"
834 [(set (reg:SI T_REG)
835 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836 (match_operand:DI 1 "arith_reg_operand" "r")))]
837 "TARGET_SH2"
838 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839 [(set_attr "length" "8")
840 (set_attr "type" "arith3")])
841
842 (define_insn "cmpeqsi_media"
843 [(set (match_operand:SI 0 "register_operand" "=r")
844 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845 (match_operand:SI 2 "cmp_operand" "Nr")))]
846 "TARGET_SHMEDIA"
847 "cmpeq %1, %N2, %0"
848 [(set_attr "type" "cmp_media")])
849
850 (define_insn "cmpeqdi_media"
851 [(set (match_operand:SI 0 "register_operand" "=r")
852 (eq:SI (match_operand:DI 1 "register_operand" "%r")
853 (match_operand:DI 2 "cmp_operand" "Nr")))]
854 "TARGET_SHMEDIA"
855 "cmpeq %1, %N2, %0"
856 [(set_attr "type" "cmp_media")])
857
858 (define_insn "cmpgtsi_media"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861 (match_operand:SI 2 "cmp_operand" "rN")))]
862 "TARGET_SHMEDIA"
863 "cmpgt %N1, %N2, %0"
864 [(set_attr "type" "cmp_media")])
865
866 (define_insn "cmpgtdi_media"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
870 "TARGET_SHMEDIA"
871 "cmpgt %N1, %N2, %0"
872 [(set_attr "type" "cmp_media")])
873
874 (define_insn "cmpgtusi_media"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877 (match_operand:SI 2 "cmp_operand" "rN")))]
878 "TARGET_SHMEDIA"
879 "cmpgtu %N1, %N2, %0"
880 [(set_attr "type" "cmp_media")])
881
882 (define_insn "cmpgtudi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
886 "TARGET_SHMEDIA"
887 "cmpgtu %N1, %N2, %0"
888 [(set_attr "type" "cmp_media")])
889
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
894 "TARGET_SHMEDIA"
895 "cmpgtu %1,r63,%0"
896 [(set_attr "type" "cmp_media")])
897
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
900
901 (define_expand "cmpdi"
902 [(set (reg:SI T_REG)
903 (compare (match_operand:DI 0 "arith_operand" "")
904 (match_operand:DI 1 "arith_operand" "")))]
905 "TARGET_SH2 || TARGET_SHMEDIA"
906 "
907 {
908 sh_compare_op0 = operands[0];
909 sh_compare_op1 = operands[1];
910 DONE;
911 }")
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
915
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
918
919 (define_insn "movdicc_false"
920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
922 (const_int 0))
923 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924 (match_operand:DI 3 "arith_reg_operand" "0")))]
925 "TARGET_SHMEDIA"
926 "cmveq %1, %N2, %0"
927 [(set_attr "type" "arith_media")])
928
929 (define_insn "movdicc_true"
930 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
932 (const_int 0))
933 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934 (match_operand:DI 3 "arith_reg_operand" "0")))]
935 "TARGET_SHMEDIA"
936 "cmvne %1, %N2, %0"
937 [(set_attr "type" "arith_media")])
938
939 (define_peephole2
940 [(set (match_operand:DI 0 "arith_reg_dest" "")
941 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942 [(match_operand:DI 1 "arith_reg_operand" "")
943 (const_int 0)])
944 (match_operand:DI 2 "arith_reg_dest" "")
945 (match_dup 0)))
946 (set (match_dup 2) (match_dup 0))]
947 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
948 [(set (match_dup 2)
949 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
950 "
951 {
952 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953 VOIDmode, operands[1], CONST0_RTX (DImode));
954 }")
955
956 (define_peephole2
957 [(set (match_operand:DI 0 "general_movdst_operand" "")
958 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959 (set (match_operand:DI 2 "arith_reg_dest" "")
960 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961 [(match_operand:DI 3 "arith_reg_operand" "")
962 (const_int 0)])
963 (match_dup 0)
964 (match_dup 2)))]
965 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
966 [(set (match_dup 2)
967 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
968 "")
969
970 (define_expand "movdicc"
971 [(set (match_operand:DI 0 "register_operand" "")
972 (if_then_else:DI (match_operand 1 "comparison_operator" "")
973 (match_operand:DI 2 "register_operand" "")
974 (match_operand:DI 3 "register_operand" "")))]
975 "TARGET_SHMEDIA"
976 "
977 {
978 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979 && GET_MODE (sh_compare_op0) == DImode
980 && sh_compare_op1 == const0_rtx)
981 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982 sh_compare_op0, sh_compare_op1);
983 else
984 {
985 rtx tmp;
986
987 if (!can_create_pseudo_p ())
988 FAIL;
989
990 tmp = gen_reg_rtx (DImode);
991
992 switch (GET_CODE (operands[1]))
993 {
994 case EQ:
995 emit_insn (gen_seq (tmp));
996 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
997 break;
998
999 case NE:
1000 emit_insn (gen_seq (tmp));
1001 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1002 break;
1003
1004 case GT:
1005 emit_insn (gen_sgt (tmp));
1006 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1007 break;
1008
1009 case LT:
1010 emit_insn (gen_slt (tmp));
1011 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1012 break;
1013
1014 case GE:
1015 emit_insn (gen_slt (tmp));
1016 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1017 break;
1018
1019 case LE:
1020 emit_insn (gen_sgt (tmp));
1021 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1022 break;
1023
1024 case GTU:
1025 emit_insn (gen_sgtu (tmp));
1026 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1027 break;
1028
1029 case LTU:
1030 emit_insn (gen_sltu (tmp));
1031 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1032 break;
1033
1034 case GEU:
1035 emit_insn (gen_sltu (tmp));
1036 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1037 break;
1038
1039 case LEU:
1040 emit_insn (gen_sgtu (tmp));
1041 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1042 break;
1043
1044 case UNORDERED:
1045 emit_insn (gen_sunordered (tmp));
1046 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1047 break;
1048
1049 case ORDERED:
1050 emit_insn (gen_sunordered (tmp));
1051 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1052 break;
1053
1054 case UNEQ:
1055 case UNGE:
1056 case UNGT:
1057 case UNLE:
1058 case UNLT:
1059 case LTGT:
1060 FAIL;
1061
1062 default:
1063 gcc_unreachable ();
1064 }
1065 }
1066 }")
1067
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1073 (const_int 0))
1074 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075 (match_operand:SI 3 "arith_reg_operand" "0")))]
1076 "TARGET_SHMEDIA"
1077 "cmveq %1, %N2, %0"
1078 [(set_attr "type" "arith_media")])
1079
1080 (define_insn "movsicc_true"
1081 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1083 (const_int 0))
1084 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085 (match_operand:SI 3 "arith_reg_operand" "0")))]
1086 "TARGET_SHMEDIA"
1087 "cmvne %1, %N2, %0"
1088 [(set_attr "type" "arith_media")])
1089
1090 (define_peephole2
1091 [(set (match_operand:SI 0 "arith_reg_dest" "")
1092 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093 [(match_operand:SI 1 "arith_reg_operand" "")
1094 (const_int 0)])
1095 (match_operand:SI 2 "arith_reg_dest" "")
1096 (match_dup 0)))
1097 (set (match_dup 2) (match_dup 0))]
1098 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1099 [(set (match_dup 2)
1100 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1101 "
1102 {
1103 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104 VOIDmode, operands[1], CONST0_RTX (SImode));
1105 }")
1106
1107 (define_peephole2
1108 [(set (match_operand:SI 0 "general_movdst_operand" "")
1109 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110 (set (match_operand:SI 2 "arith_reg_dest" "")
1111 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112 [(match_operand:SI 3 "arith_reg_operand" "")
1113 (const_int 0)])
1114 (match_dup 0)
1115 (match_dup 2)))]
1116 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1118 [(set (match_dup 2)
1119 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1120 "
1121 {
1122 replace_rtx (operands[4], operands[0], operands[1]);
1123 }")
1124
1125 (define_peephole2
1126 [(set (match_operand 0 "any_register_operand" "")
1127 (match_operand 1 "any_register_operand" ""))
1128 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138 && (REGNO_REG_CLASS (REGNO (operands[0]))
1139 == REGNO_REG_CLASS (REGNO (operands[2])))
1140 && (REGNO_REG_CLASS (REGNO (operands[1]))
1141 == REGNO_REG_CLASS (REGNO (operands[0])))"
1142 [(set (match_dup 0) (match_dup 3))
1143 (set (match_dup 4) (match_dup 5))]
1144 "
1145 {
1146 rtx set1, set2;
1147 rtx replacements[4];
1148
1149 /* We want to replace occurrences of operands[0] with operands[1] and
1150 operands[2] with operands[0] in operands[4]/operands[5].
1151 Doing just two replace_rtx calls naively would result in the second
1152 replacement undoing all that the first did if operands[1] and operands[2]
1153 are identical, so we must do this simultaneously. */
1154 replacements[0] = operands[0];
1155 replacements[1] = operands[1];
1156 replacements[2] = operands[2];
1157 replacements[3] = operands[0];
1158 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1159 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1160 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1161 FAIL;
1162
1163 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1164 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1165 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1166 /* The operands array is aliased to recog_data.operand, which gets
1167 clobbered by extract_insn, so finish with it now. */
1168 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1169 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1170 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1171 always uses emit_insn. */
1172 /* Check that we don't violate matching constraints or earlyclobbers. */
1173 extract_insn (emit_insn (set1));
1174 if (! constrain_operands (1))
1175 goto failure;
1176 extract_insn (emit (set2));
1177 if (! constrain_operands (1))
1178 {
1179 rtx tmp;
1180 failure:
1181 tmp = replacements[0];
1182 replacements[0] = replacements[1];
1183 replacements[1] = tmp;
1184 tmp = replacements[2];
1185 replacements[2] = replacements[3];
1186 replacements[3] = tmp;
1187 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1188 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1189 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1190 FAIL;
1191 }
1192 DONE;
1193 }")
1194
1195 ;; The register allocator is rather clumsy in handling multi-way conditional
1196 ;; moves, so allow the combiner to make them, and we split them up after
1197 ;; reload. */
1198 (define_insn_and_split "*movsicc_umin"
1199 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1200 (umin:SI (if_then_else:SI
1201 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1202 (const_int 0))
1203 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1204 (match_operand:SI 3 "register_operand" "0"))
1205 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1206 (clobber (match_scratch:SI 5 "=&r"))]
1207 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1208 "#"
1209 "TARGET_SHMEDIA && reload_completed"
1210 [(pc)]
1211 "
1212 {
1213 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1214 operands[3]));
1215 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1216 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1217 operands[0]));
1218 DONE;
1219 }")
1220
1221 (define_insn "*movsicc_t_false"
1222 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1223 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1224 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1225 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1226 "TARGET_PRETEND_CMOVE
1227 && (arith_reg_operand (operands[1], SImode)
1228 || (immediate_operand (operands[1], SImode)
1229 && satisfies_constraint_I08 (operands[1])))"
1230 "bt 0f\;mov %1,%0\\n0:"
1231 [(set_attr "type" "mt_group,arith") ;; poor approximation
1232 (set_attr "length" "4")])
1233
1234 (define_insn "*movsicc_t_true"
1235 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1237 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1238 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1239 "TARGET_PRETEND_CMOVE
1240 && (arith_reg_operand (operands[1], SImode)
1241 || (immediate_operand (operands[1], SImode)
1242 && satisfies_constraint_I08 (operands[1])))"
1243 "bf 0f\;mov %1,%0\\n0:"
1244 [(set_attr "type" "mt_group,arith") ;; poor approximation
1245 (set_attr "length" "4")])
1246
1247 (define_expand "movsicc"
1248 [(set (match_operand:SI 0 "arith_reg_dest" "")
1249 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1250 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1251 (match_operand:SI 3 "arith_reg_operand" "")))]
1252 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1253 "
1254 {
1255 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1256 && GET_MODE (sh_compare_op0) == SImode
1257 && (TARGET_SHMEDIA
1258 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1259 && sh_compare_op1 == const0_rtx)
1260 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1261 sh_compare_op0, sh_compare_op1);
1262 else if (TARGET_PRETEND_CMOVE)
1263 {
1264 enum rtx_code code = GET_CODE (operands[1]);
1265 enum rtx_code new_code = code;
1266 rtx tmp;
1267
1268 if (! currently_expanding_to_rtl)
1269 FAIL;
1270 switch (code)
1271 {
1272 case LT: case LE: case LEU: case LTU:
1273 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1274 break;
1275 case NE:
1276 new_code = reverse_condition (code);
1277 break;
1278 case EQ: case GT: case GE: case GEU: case GTU:
1279 break;
1280 default:
1281 FAIL;
1282 }
1283 tmp = prepare_scc_operands (new_code);
1284 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1285 tmp, const0_rtx);
1286 }
1287 else
1288 {
1289 rtx tmp;
1290
1291 if (!can_create_pseudo_p ())
1292 FAIL;
1293
1294 tmp = gen_reg_rtx (SImode);
1295
1296 switch (GET_CODE (operands[1]))
1297 {
1298 case EQ:
1299 emit_insn (gen_seq (tmp));
1300 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1301 break;
1302
1303 case NE:
1304 emit_insn (gen_seq (tmp));
1305 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1306 break;
1307
1308 case GT:
1309 emit_insn (gen_sgt (tmp));
1310 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1311 break;
1312
1313 case LT:
1314 emit_insn (gen_slt (tmp));
1315 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1316 break;
1317
1318 case GE:
1319 emit_insn (gen_slt (tmp));
1320 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1321 break;
1322
1323 case LE:
1324 emit_insn (gen_sgt (tmp));
1325 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1326 break;
1327
1328 case GTU:
1329 emit_insn (gen_sgtu (tmp));
1330 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1331 break;
1332
1333 case LTU:
1334 emit_insn (gen_sltu (tmp));
1335 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1336 break;
1337
1338 case GEU:
1339 emit_insn (gen_sltu (tmp));
1340 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1341 break;
1342
1343 case LEU:
1344 emit_insn (gen_sgtu (tmp));
1345 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1346 break;
1347
1348 case UNORDERED:
1349 emit_insn (gen_sunordered (tmp));
1350 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1351 break;
1352
1353 case ORDERED:
1354 emit_insn (gen_sunordered (tmp));
1355 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1356 break;
1357
1358 case UNEQ:
1359 case UNGE:
1360 case UNGT:
1361 case UNLE:
1362 case UNLT:
1363 case LTGT:
1364 FAIL;
1365
1366 default:
1367 abort ();
1368 }
1369 }
1370 }")
1371
1372 (define_expand "movqicc"
1373 [(set (match_operand:QI 0 "register_operand" "")
1374 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375 (match_operand:QI 2 "register_operand" "")
1376 (match_operand:QI 3 "register_operand" "")))]
1377 "TARGET_SHMEDIA"
1378 "
1379 {
1380 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1381 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1382 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1383 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1384 DONE;
1385 }")
1386 \f
1387 ;; -------------------------------------------------------------------------
1388 ;; Addition instructions
1389 ;; -------------------------------------------------------------------------
1390
1391 (define_expand "adddi3"
1392 [(set (match_operand:DI 0 "arith_reg_operand" "")
1393 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1394 (match_operand:DI 2 "arith_operand" "")))]
1395 ""
1396 "
1397 {
1398 if (TARGET_SH1)
1399 {
1400 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1401 FAIL;
1402 operands[2] = force_reg (DImode, operands[2]);
1403 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1404 DONE;
1405 }
1406 }")
1407
1408 (define_insn "*adddi3_media"
1409 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1410 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1411 (match_operand:DI 2 "arith_operand" "r,I10")))]
1412 "TARGET_SHMEDIA"
1413 "@
1414 add %1, %2, %0
1415 addi %1, %2, %0"
1416 [(set_attr "type" "arith_media")])
1417
1418 (define_insn "*adddisi3_media"
1419 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1420 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421 (match_operand:DI 2 "arith_operand" "r,I10")))]
1422 "TARGET_SHMEDIA"
1423 "@
1424 add.l %1, %2, %0
1425 addi.l %1, %2, %0"
1426 [(set_attr "type" "arith_media")
1427 (set_attr "highpart" "ignore")])
1428
1429 (define_insn "adddi3z_media"
1430 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1431 (zero_extend:DI
1432 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1433 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1434 "TARGET_SHMEDIA"
1435 "addz.l %1, %N2, %0"
1436 [(set_attr "type" "arith_media")
1437 (set_attr "highpart" "ignore")])
1438
1439 (define_insn "adddi3_compact"
1440 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1441 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1442 (match_operand:DI 2 "arith_reg_operand" "r")))
1443 (clobber (reg:SI T_REG))]
1444 "TARGET_SH1"
1445 "#"
1446 [(set_attr "length" "6")])
1447
1448 (define_split
1449 [(set (match_operand:DI 0 "arith_reg_dest" "")
1450 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1451 (match_operand:DI 2 "arith_reg_operand" "")))
1452 (clobber (reg:SI T_REG))]
1453 "TARGET_SH1 && reload_completed"
1454 [(const_int 0)]
1455 "
1456 {
1457 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1458 high0 = gen_rtx_REG (SImode,
1459 true_regnum (operands[0])
1460 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461 high2 = gen_rtx_REG (SImode,
1462 true_regnum (operands[2])
1463 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464 emit_insn (gen_clrt ());
1465 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1466 emit_insn (gen_addc1 (high0, high0, high2));
1467 DONE;
1468 }")
1469
1470 (define_insn "addc"
1471 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1472 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1473 (match_operand:SI 2 "arith_reg_operand" "r"))
1474 (reg:SI T_REG)))
1475 (set (reg:SI T_REG)
1476 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1477 "TARGET_SH1"
1478 "addc %2,%0"
1479 [(set_attr "type" "arith")])
1480
1481 (define_insn "addc1"
1482 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1483 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1484 (match_operand:SI 2 "arith_reg_operand" "r"))
1485 (reg:SI T_REG)))
1486 (clobber (reg:SI T_REG))]
1487 "TARGET_SH1"
1488 "addc %2,%0"
1489 [(set_attr "type" "arith")])
1490
1491 (define_expand "addsi3"
1492 [(set (match_operand:SI 0 "arith_reg_operand" "")
1493 (plus:SI (match_operand:SI 1 "arith_operand" "")
1494 (match_operand:SI 2 "arith_operand" "")))]
1495 ""
1496 "
1497 {
1498 if (TARGET_SHMEDIA)
1499 operands[1] = force_reg (SImode, operands[1]);
1500 }")
1501
1502 (define_insn "addsi3_media"
1503 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1504 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1505 (match_operand:SI 2 "arith_operand" "r,I10")))]
1506 "TARGET_SHMEDIA"
1507 "@
1508 add.l %1, %2, %0
1509 addi.l %1, %2, %0"
1510 [(set_attr "type" "arith_media")
1511 (set_attr "highpart" "ignore")])
1512
1513 (define_insn "addsidi3_media"
1514 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1515 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1516 "%r,r")
1517 (match_operand:SI 2 "arith_operand"
1518 "r,I10"))))]
1519 "TARGET_SHMEDIA"
1520 "@
1521 add.l %1, %2, %0
1522 addi.l %1, %2, %0"
1523 [(set_attr "type" "arith_media")
1524 (set_attr "highpart" "ignore")])
1525
1526 (define_insn "*addsi3_compact"
1527 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1528 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1529 (match_operand:SI 2 "arith_operand" "rI08")))]
1530 "TARGET_SH1"
1531 "add %2,%0"
1532 [(set_attr "type" "arith")])
1533
1534 ;; -------------------------------------------------------------------------
1535 ;; Subtraction instructions
1536 ;; -------------------------------------------------------------------------
1537
1538 (define_expand "subdi3"
1539 [(set (match_operand:DI 0 "arith_reg_operand" "")
1540 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1541 (match_operand:DI 2 "arith_reg_operand" "")))]
1542 ""
1543 "
1544 {
1545 if (TARGET_SH1)
1546 {
1547 operands[1] = force_reg (DImode, operands[1]);
1548 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1549 DONE;
1550 }
1551 }")
1552
1553 (define_insn "*subdi3_media"
1554 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1555 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1556 (match_operand:DI 2 "arith_reg_operand" "r")))]
1557 "TARGET_SHMEDIA"
1558 "sub %N1, %2, %0"
1559 [(set_attr "type" "arith_media")])
1560
1561 (define_insn "subdisi3_media"
1562 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1563 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1564 (match_operand:DI 2 "arith_reg_operand" "r")))]
1565 "TARGET_SHMEDIA"
1566 "sub.l %N1, %2, %0"
1567 [(set_attr "type" "arith_media")
1568 (set_attr "highpart" "ignore")])
1569
1570 (define_insn "subdi3_compact"
1571 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1572 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1573 (match_operand:DI 2 "arith_reg_operand" "r")))
1574 (clobber (reg:SI T_REG))]
1575 "TARGET_SH1"
1576 "#"
1577 [(set_attr "length" "6")])
1578
1579 (define_split
1580 [(set (match_operand:DI 0 "arith_reg_dest" "")
1581 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1582 (match_operand:DI 2 "arith_reg_operand" "")))
1583 (clobber (reg:SI T_REG))]
1584 "TARGET_SH1 && reload_completed"
1585 [(const_int 0)]
1586 "
1587 {
1588 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1589 high0 = gen_rtx_REG (SImode,
1590 true_regnum (operands[0])
1591 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1592 high2 = gen_rtx_REG (SImode,
1593 true_regnum (operands[2])
1594 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595 emit_insn (gen_clrt ());
1596 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1597 emit_insn (gen_subc1 (high0, high0, high2));
1598 DONE;
1599 }")
1600
1601 (define_insn "subc"
1602 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1603 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1604 (match_operand:SI 2 "arith_reg_operand" "r"))
1605 (reg:SI T_REG)))
1606 (set (reg:SI T_REG)
1607 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1608 (reg:SI T_REG))
1609 (match_dup 1)))]
1610 "TARGET_SH1"
1611 "subc %2,%0"
1612 [(set_attr "type" "arith")])
1613
1614 (define_insn "subc1"
1615 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1616 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1617 (match_operand:SI 2 "arith_reg_operand" "r"))
1618 (reg:SI T_REG)))
1619 (clobber (reg:SI T_REG))]
1620 "TARGET_SH1"
1621 "subc %2,%0"
1622 [(set_attr "type" "arith")])
1623
1624 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1625 ;; pattern for this case. This helps multimedia applications that compute
1626 ;; the sum of absolute differences.
1627 (define_insn "mov_neg_si_t"
1628 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1629 "TARGET_SH1"
1630 "subc %0,%0"
1631 [(set_attr "type" "arith")])
1632
1633 (define_insn "*subsi3_internal"
1634 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1635 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1636 (match_operand:SI 2 "arith_reg_operand" "r")))]
1637 "TARGET_SH1"
1638 "sub %2,%0"
1639 [(set_attr "type" "arith")])
1640
1641 (define_insn_and_split "*subsi3_media"
1642 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1643 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1644 (match_operand:SI 2 "extend_reg_operand" "r")))]
1645 "TARGET_SHMEDIA
1646 && (operands[1] != constm1_rtx
1647 || (GET_CODE (operands[2]) != TRUNCATE
1648 && GET_CODE (operands[2]) != SUBREG))"
1649 "sub.l %N1, %2, %0"
1650 "operands[1] == constm1_rtx"
1651 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1652 ""
1653 [(set_attr "type" "arith_media")
1654 (set_attr "highpart" "ignore")])
1655
1656 (define_split
1657 [(set (match_operand:SI 0 "arith_reg_dest" "")
1658 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1659 "general_extend_operand"
1660 "") 0)) 0)))]
1661 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1662 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1663 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1664 "")
1665
1666 (define_split
1667 [(set (match_operand:SI 0 "arith_reg_dest" "")
1668 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669 "general_extend_operand"
1670 "") 0)) 3)))]
1671 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1672 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1674 "")
1675 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1676 ;; will sometimes save one instruction. Otherwise we might get
1677 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1678 ;; are the same.
1679
1680 (define_expand "subsi3"
1681 [(set (match_operand:SI 0 "arith_reg_operand" "")
1682 (minus:SI (match_operand:SI 1 "arith_operand" "")
1683 (match_operand:SI 2 "arith_reg_operand" "")))]
1684 ""
1685 "
1686 {
1687 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1688 {
1689 emit_insn (gen_negsi2 (operands[0], operands[2]));
1690 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1691 DONE;
1692 }
1693 if (TARGET_SHMEDIA)
1694 {
1695 if (!can_create_pseudo_p ()
1696 && ! arith_reg_or_0_operand (operands[1], SImode))
1697 FAIL;
1698 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1699 operands[1] = force_reg (SImode, operands[1]);
1700 }
1701 }")
1702 \f
1703 ;; -------------------------------------------------------------------------
1704 ;; Division instructions
1705 ;; -------------------------------------------------------------------------
1706
1707 ;; We take advantage of the library routines which don't clobber as many
1708 ;; registers as a normal function call would.
1709
1710 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1711 ;; also has an effect on the register that holds the address of the sfunc.
1712 ;; To make this work, we have an extra dummy insn that shows the use
1713 ;; of this register for reorg.
1714
1715 (define_insn "use_sfunc_addr"
1716 [(set (reg:SI PR_REG)
1717 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1718 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1719 ""
1720 [(set_attr "length" "0")])
1721
1722 (define_insn "udivsi3_sh2a"
1723 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1724 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1725 (match_operand:SI 2 "arith_reg_operand" "z")))]
1726 "TARGET_SH2A"
1727 "divu %2,%1"
1728 [(set_attr "type" "arith")
1729 (set_attr "in_delay_slot" "no")])
1730
1731 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1732 ;; hard register 0. If we used hard register 0, then the next instruction
1733 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1734 ;; gets allocated to a stack slot that needs its address reloaded, then
1735 ;; there is nothing to prevent reload from using r0 to reload the address.
1736 ;; This reload would clobber the value in r0 we are trying to store.
1737 ;; If we let reload allocate r0, then this problem can never happen.
1738
1739 (define_insn "udivsi3_i1"
1740 [(set (match_operand:SI 0 "register_operand" "=z")
1741 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1742 (clobber (reg:SI T_REG))
1743 (clobber (reg:SI PR_REG))
1744 (clobber (reg:SI R4_REG))
1745 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1746 "TARGET_SH1 && ! TARGET_SH4"
1747 "jsr @%1%#"
1748 [(set_attr "type" "sfunc")
1749 (set_attr "needs_delay_slot" "yes")])
1750
1751 ; Since shmedia-nofpu code could be linked against shcompact code, and
1752 ; the udivsi3 libcall has the same name, we must consider all registers
1753 ; clobbered that are in the union of the registers clobbered by the
1754 ; shmedia and the shcompact implementation. Note, if the shcompact
1755 ; implementation actually used shcompact code, we'd need to clobber
1756 ; also r23 and fr23.
1757 (define_insn "udivsi3_i1_media"
1758 [(set (match_operand:SI 0 "register_operand" "=z")
1759 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760 (clobber (reg:SI T_MEDIA_REG))
1761 (clobber (reg:SI PR_MEDIA_REG))
1762 (clobber (reg:SI R20_REG))
1763 (clobber (reg:SI R21_REG))
1764 (clobber (reg:SI R22_REG))
1765 (clobber (reg:DI TR0_REG))
1766 (clobber (reg:DI TR1_REG))
1767 (clobber (reg:DI TR2_REG))
1768 (use (match_operand 1 "target_reg_operand" "b"))]
1769 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1770 "blink %1, r18"
1771 [(set_attr "type" "sfunc")
1772 (set_attr "needs_delay_slot" "yes")])
1773
1774 (define_expand "udivsi3_i4_media"
1775 [(set (match_dup 3)
1776 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1777 (set (match_dup 4)
1778 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779 (set (match_dup 5) (float:DF (match_dup 3)))
1780 (set (match_dup 6) (float:DF (match_dup 4)))
1781 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1782 (set (match_dup 8) (fix:DI (match_dup 7)))
1783 (set (match_operand:SI 0 "register_operand" "")
1784 (truncate:SI (match_dup 8)))]
1785 "TARGET_SHMEDIA_FPU"
1786 "
1787 {
1788 operands[3] = gen_reg_rtx (DImode);
1789 operands[4] = gen_reg_rtx (DImode);
1790 operands[5] = gen_reg_rtx (DFmode);
1791 operands[6] = gen_reg_rtx (DFmode);
1792 operands[7] = gen_reg_rtx (DFmode);
1793 operands[8] = gen_reg_rtx (DImode);
1794 }")
1795
1796 (define_insn "udivsi3_i4"
1797 [(set (match_operand:SI 0 "register_operand" "=y")
1798 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1799 (clobber (reg:SI T_REG))
1800 (clobber (reg:SI PR_REG))
1801 (clobber (reg:DF DR0_REG))
1802 (clobber (reg:DF DR2_REG))
1803 (clobber (reg:DF DR4_REG))
1804 (clobber (reg:SI R0_REG))
1805 (clobber (reg:SI R1_REG))
1806 (clobber (reg:SI R4_REG))
1807 (clobber (reg:SI R5_REG))
1808 (use (reg:PSI FPSCR_REG))
1809 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1810 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1811 "jsr @%1%#"
1812 [(set_attr "type" "sfunc")
1813 (set_attr "fp_mode" "double")
1814 (set_attr "needs_delay_slot" "yes")])
1815
1816 (define_insn "udivsi3_i4_single"
1817 [(set (match_operand:SI 0 "register_operand" "=y")
1818 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1819 (clobber (reg:SI T_REG))
1820 (clobber (reg:SI PR_REG))
1821 (clobber (reg:DF DR0_REG))
1822 (clobber (reg:DF DR2_REG))
1823 (clobber (reg:DF DR4_REG))
1824 (clobber (reg:SI R0_REG))
1825 (clobber (reg:SI R1_REG))
1826 (clobber (reg:SI R4_REG))
1827 (clobber (reg:SI R5_REG))
1828 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1829 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1830 "jsr @%1%#"
1831 [(set_attr "type" "sfunc")
1832 (set_attr "needs_delay_slot" "yes")])
1833
1834 (define_insn "udivsi3_i4_int"
1835 [(set (match_operand:SI 0 "register_operand" "=z")
1836 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1837 (clobber (reg:SI T_REG))
1838 (clobber (reg:SI R1_REG))
1839 (clobber (reg:SI PR_REG))
1840 (clobber (reg:SI MACH_REG))
1841 (clobber (reg:SI MACL_REG))
1842 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1843 "TARGET_SH1"
1844 "jsr @%1%#"
1845 [(set_attr "type" "sfunc")
1846 (set_attr "needs_delay_slot" "yes")])
1847
1848
1849 (define_expand "udivsi3"
1850 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1851 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1852 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1853 (parallel [(set (match_operand:SI 0 "register_operand" "")
1854 (udiv:SI (reg:SI R4_REG)
1855 (reg:SI R5_REG)))
1856 (clobber (reg:SI T_REG))
1857 (clobber (reg:SI PR_REG))
1858 (clobber (reg:SI R4_REG))
1859 (use (match_dup 3))])]
1860 ""
1861 "
1862 {
1863 rtx last;
1864
1865 operands[3] = gen_reg_rtx (Pmode);
1866 /* Emit the move of the address to a pseudo outside of the libcall. */
1867 if (TARGET_DIVIDE_CALL_TABLE)
1868 {
1869 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1870 that causes problems when the divide code is supposed to come from a
1871 separate library. Division by zero is undefined, so dividing 1 can be
1872 implemented by comparing with the divisor. */
1873 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1874 {
1875 emit_insn (gen_cmpsi (operands[1], operands[2]));
1876 emit_insn (gen_sgeu (operands[0]));
1877 DONE;
1878 }
1879 else if (operands[2] == const0_rtx)
1880 {
1881 emit_move_insn (operands[0], operands[2]);
1882 DONE;
1883 }
1884 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1885 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1886 }
1887 else if (TARGET_DIVIDE_CALL_FP)
1888 {
1889 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1890 if (TARGET_FPU_SINGLE)
1891 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1892 else
1893 last = gen_udivsi3_i4 (operands[0], operands[3]);
1894 }
1895 else if (TARGET_SHMEDIA_FPU)
1896 {
1897 operands[1] = force_reg (SImode, operands[1]);
1898 operands[2] = force_reg (SImode, operands[2]);
1899 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1900 DONE;
1901 }
1902 else if (TARGET_SH2A)
1903 {
1904 operands[1] = force_reg (SImode, operands[1]);
1905 operands[2] = force_reg (SImode, operands[2]);
1906 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1907 DONE;
1908 }
1909 else if (TARGET_SH5)
1910 {
1911 function_symbol (operands[3],
1912 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1913 SFUNC_STATIC);
1914
1915 if (TARGET_SHMEDIA)
1916 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1917 else if (TARGET_FPU_ANY)
1918 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1919 else
1920 last = gen_udivsi3_i1 (operands[0], operands[3]);
1921 }
1922 else
1923 {
1924 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1925 last = gen_udivsi3_i1 (operands[0], operands[3]);
1926 }
1927 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1928 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1929 emit_insn (last);
1930 DONE;
1931 }")
1932
1933 (define_insn "divsi3_sh2a"
1934 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1935 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1936 (match_operand:SI 2 "arith_reg_operand" "z")))]
1937 "TARGET_SH2A"
1938 "divs %2,%1"
1939 [(set_attr "type" "arith")
1940 (set_attr "in_delay_slot" "no")])
1941
1942 (define_insn "divsi3_i1"
1943 [(set (match_operand:SI 0 "register_operand" "=z")
1944 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1945 (clobber (reg:SI T_REG))
1946 (clobber (reg:SI PR_REG))
1947 (clobber (reg:SI R1_REG))
1948 (clobber (reg:SI R2_REG))
1949 (clobber (reg:SI R3_REG))
1950 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1951 "TARGET_SH1 && ! TARGET_SH4"
1952 "jsr @%1%#"
1953 [(set_attr "type" "sfunc")
1954 (set_attr "needs_delay_slot" "yes")])
1955
1956 (define_insn "divsi3_i1_media"
1957 [(set (match_operand:SI 0 "register_operand" "=z")
1958 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1959 (clobber (reg:SI T_MEDIA_REG))
1960 (clobber (reg:SI PR_MEDIA_REG))
1961 (clobber (reg:SI R1_REG))
1962 (clobber (reg:SI R20_REG))
1963 (clobber (reg:SI R21_REG))
1964 (clobber (reg:SI TR0_REG))
1965 (use (match_operand 1 "target_reg_operand" "b"))]
1966 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1967 "blink %1, r18"
1968 [(set_attr "type" "sfunc")])
1969
1970 (define_insn "divsi3_media_2"
1971 [(set (match_operand:SI 0 "register_operand" "=z")
1972 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1973 (clobber (reg:SI T_MEDIA_REG))
1974 (clobber (reg:SI PR_MEDIA_REG))
1975 (clobber (reg:SI R1_REG))
1976 (clobber (reg:SI R21_REG))
1977 (clobber (reg:SI TR0_REG))
1978 (use (reg:SI R20_REG))
1979 (use (match_operand 1 "target_reg_operand" "b"))]
1980 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1981 "blink %1, r18"
1982 [(set_attr "type" "sfunc")])
1983
1984 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1985 ;; hard reg clobbers and data dependencies that we need when we want
1986 ;; to rematerialize the division into a call.
1987 (define_insn_and_split "divsi_inv_call"
1988 [(set (match_operand:SI 0 "register_operand" "=r")
1989 (div:SI (match_operand:SI 1 "register_operand" "r")
1990 (match_operand:SI 2 "register_operand" "r")))
1991 (clobber (reg:SI R4_REG))
1992 (clobber (reg:SI R5_REG))
1993 (clobber (reg:SI T_MEDIA_REG))
1994 (clobber (reg:SI PR_MEDIA_REG))
1995 (clobber (reg:SI R1_REG))
1996 (clobber (reg:SI R21_REG))
1997 (clobber (reg:SI TR0_REG))
1998 (clobber (reg:SI R20_REG))
1999 (use (match_operand:SI 3 "register_operand" "r"))]
2000 "TARGET_SHMEDIA"
2001 "#"
2002 "&& (high_life_started || reload_completed)"
2003 [(set (match_dup 0) (match_dup 3))]
2004 ""
2005 [(set_attr "highpart" "must_split")])
2006
2007 ;; This is the combiner pattern for -mdiv=inv:call .
2008 (define_insn_and_split "*divsi_inv_call_combine"
2009 [(set (match_operand:SI 0 "register_operand" "=z")
2010 (div:SI (match_operand:SI 1 "register_operand" "r")
2011 (match_operand:SI 2 "register_operand" "r")))
2012 (clobber (reg:SI R4_REG))
2013 (clobber (reg:SI R5_REG))
2014 (clobber (reg:SI T_MEDIA_REG))
2015 (clobber (reg:SI PR_MEDIA_REG))
2016 (clobber (reg:SI R1_REG))
2017 (clobber (reg:SI R21_REG))
2018 (clobber (reg:SI TR0_REG))
2019 (clobber (reg:SI R20_REG))
2020 (use (unspec:SI [(match_dup 1)
2021 (match_operand:SI 3 "" "")
2022 (unspec:SI [(match_operand:SI 4 "" "")
2023 (match_dup 3)
2024 (match_operand:DI 5 "" "")]
2025 UNSPEC_DIV_INV_M2)
2026 (match_operand:DI 6 "" "")
2027 (const_int 0)
2028 (const_int 0)]
2029 UNSPEC_DIV_INV_M3))]
2030 "TARGET_SHMEDIA"
2031 "#"
2032 "&& (high_life_started || reload_completed)"
2033 [(pc)]
2034 "
2035 {
2036 const char *name = sh_divsi3_libfunc;
2037 enum sh_function_kind kind = SFUNC_GOT;
2038 rtx sym;
2039
2040 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2041 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2042 while (TARGET_DIVIDE_INV_CALL2)
2043 {
2044 rtx x = operands[3];
2045
2046 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2047 break;
2048 x = XVECEXP (x, 0, 0);
2049 name = \"__sdivsi3_2\";
2050 kind = SFUNC_STATIC;
2051 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2052 break;
2053 }
2054 sym = function_symbol (NULL, name, kind);
2055 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2056 DONE;
2057 }"
2058 [(set_attr "highpart" "must_split")])
2059
2060 (define_expand "divsi3_i4_media"
2061 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2062 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2063 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2064 (set (match_operand:SI 0 "register_operand" "=r")
2065 (fix:SI (match_dup 5)))]
2066 "TARGET_SHMEDIA_FPU"
2067 "
2068 {
2069 operands[3] = gen_reg_rtx (DFmode);
2070 operands[4] = gen_reg_rtx (DFmode);
2071 operands[5] = gen_reg_rtx (DFmode);
2072 }")
2073
2074 (define_insn "divsi3_i4"
2075 [(set (match_operand:SI 0 "register_operand" "=y")
2076 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2077 (clobber (reg:SI PR_REG))
2078 (clobber (reg:DF DR0_REG))
2079 (clobber (reg:DF DR2_REG))
2080 (use (reg:PSI FPSCR_REG))
2081 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2082 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2083 "jsr @%1%#"
2084 [(set_attr "type" "sfunc")
2085 (set_attr "fp_mode" "double")
2086 (set_attr "needs_delay_slot" "yes")])
2087
2088 (define_insn "divsi3_i4_single"
2089 [(set (match_operand:SI 0 "register_operand" "=y")
2090 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2091 (clobber (reg:SI PR_REG))
2092 (clobber (reg:DF DR0_REG))
2093 (clobber (reg:DF DR2_REG))
2094 (clobber (reg:SI R2_REG))
2095 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2096 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2097 "jsr @%1%#"
2098 [(set_attr "type" "sfunc")
2099 (set_attr "needs_delay_slot" "yes")])
2100
2101 (define_insn "divsi3_i4_int"
2102 [(set (match_operand:SI 0 "register_operand" "=z")
2103 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2104 (clobber (reg:SI T_REG))
2105 (clobber (reg:SI PR_REG))
2106 (clobber (reg:SI R1_REG))
2107 (clobber (reg:SI MACH_REG))
2108 (clobber (reg:SI MACL_REG))
2109 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2110 "TARGET_SH1"
2111 "jsr @%1%#"
2112 [(set_attr "type" "sfunc")
2113 (set_attr "needs_delay_slot" "yes")])
2114
2115 (define_expand "divsi3"
2116 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2117 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2118 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2119 (parallel [(set (match_operand:SI 0 "register_operand" "")
2120 (div:SI (reg:SI R4_REG)
2121 (reg:SI R5_REG)))
2122 (clobber (reg:SI T_REG))
2123 (clobber (reg:SI PR_REG))
2124 (clobber (reg:SI R1_REG))
2125 (clobber (reg:SI R2_REG))
2126 (clobber (reg:SI R3_REG))
2127 (use (match_dup 3))])]
2128 ""
2129 "
2130 {
2131 rtx last;
2132
2133 operands[3] = gen_reg_rtx (Pmode);
2134 /* Emit the move of the address to a pseudo outside of the libcall. */
2135 if (TARGET_DIVIDE_CALL_TABLE)
2136 {
2137 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2138 last = gen_divsi3_i4_int (operands[0], operands[3]);
2139 }
2140 else if (TARGET_DIVIDE_CALL_FP)
2141 {
2142 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2143 if (TARGET_FPU_SINGLE)
2144 last = gen_divsi3_i4_single (operands[0], operands[3]);
2145 else
2146 last = gen_divsi3_i4 (operands[0], operands[3]);
2147 }
2148 else if (TARGET_SH2A)
2149 {
2150 operands[1] = force_reg (SImode, operands[1]);
2151 operands[2] = force_reg (SImode, operands[2]);
2152 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2153 DONE;
2154 }
2155 else if (TARGET_DIVIDE_INV)
2156 {
2157 rtx dividend = operands[1];
2158 rtx divisor = operands[2];
2159 rtx tab_base;
2160 rtx nsb_res = gen_reg_rtx (DImode);
2161 rtx norm64 = gen_reg_rtx (DImode);
2162 rtx tab_ix = gen_reg_rtx (DImode);
2163 rtx norm32 = gen_reg_rtx (SImode);
2164 rtx i92 = force_reg (DImode, GEN_INT (92));
2165 rtx scratch0a = gen_reg_rtx (DImode);
2166 rtx scratch0b = gen_reg_rtx (DImode);
2167 rtx inv0 = gen_reg_rtx (SImode);
2168 rtx scratch1a = gen_reg_rtx (DImode);
2169 rtx scratch1b = gen_reg_rtx (DImode);
2170 rtx shift = gen_reg_rtx (DImode);
2171 rtx i2p27, i43;
2172 rtx inv1 = gen_reg_rtx (SImode);
2173 rtx scratch2a = gen_reg_rtx (DImode);
2174 rtx scratch2b = gen_reg_rtx (SImode);
2175 rtx inv2 = gen_reg_rtx (SImode);
2176 rtx scratch3a = gen_reg_rtx (DImode);
2177 rtx scratch3b = gen_reg_rtx (DImode);
2178 rtx scratch3c = gen_reg_rtx (DImode);
2179 rtx scratch3d = gen_reg_rtx (SImode);
2180 rtx scratch3e = gen_reg_rtx (DImode);
2181 rtx result = gen_reg_rtx (SImode);
2182
2183 if (! arith_reg_or_0_operand (dividend, SImode))
2184 dividend = force_reg (SImode, dividend);
2185 if (! arith_reg_operand (divisor, SImode))
2186 divisor = force_reg (SImode, divisor);
2187 if (flag_pic && Pmode != DImode)
2188 {
2189 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2190 tab_base = gen_datalabel_ref (tab_base);
2191 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2192 }
2193 else
2194 {
2195 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2196 tab_base = gen_datalabel_ref (tab_base);
2197 tab_base = force_reg (DImode, tab_base);
2198 }
2199 if (TARGET_DIVIDE_INV20U)
2200 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2201 else
2202 i2p27 = GEN_INT (0);
2203 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2204 i43 = force_reg (DImode, GEN_INT (43));
2205 else
2206 i43 = GEN_INT (0);
2207 emit_insn (gen_nsbdi (nsb_res,
2208 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2209 emit_insn (gen_ashldi3_media (norm64,
2210 gen_rtx_SUBREG (DImode, divisor, 0),
2211 nsb_res));
2212 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2213 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2214 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2215 inv0, scratch0a, scratch0b,
2216 scratch1a, scratch1b));
2217 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2218 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2219 scratch2a));
2220 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2221 i2p27, i43,
2222 scratch3a, scratch3b, scratch3c,
2223 scratch2a, scratch2b, scratch3d, scratch3e));
2224 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2225 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2226 else if (TARGET_DIVIDE_INV_FP)
2227 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2228 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2229 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2230 gen_reg_rtx (DFmode)));
2231 else
2232 emit_move_insn (operands[0], result);
2233 DONE;
2234 }
2235 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2236 {
2237 operands[1] = force_reg (SImode, operands[1]);
2238 operands[2] = force_reg (SImode, operands[2]);
2239 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2240 DONE;
2241 }
2242 else if (TARGET_SH5)
2243 {
2244 if (TARGET_DIVIDE_CALL2)
2245 {
2246 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2247 tab_base = gen_datalabel_ref (tab_base);
2248 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2249 }
2250 if (TARGET_FPU_ANY && TARGET_SH1)
2251 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2252 else if (TARGET_DIVIDE_CALL2)
2253 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2254 else
2255 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2256
2257 if (TARGET_SHMEDIA)
2258 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2259 (operands[0], operands[3]));
2260 else if (TARGET_FPU_ANY)
2261 last = gen_divsi3_i4_single (operands[0], operands[3]);
2262 else
2263 last = gen_divsi3_i1 (operands[0], operands[3]);
2264 }
2265 else
2266 {
2267 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2268 last = gen_divsi3_i1 (operands[0], operands[3]);
2269 }
2270 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2271 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2272 emit_insn (last);
2273 DONE;
2274 }")
2275
2276 ;; operands: scratch, tab_base, tab_ix
2277 ;; These are unspecs because we could generate an indexed addressing mode
2278 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2279 ;; confuse reload. See PR27117.
2280
2281 (define_insn "divsi_inv_qitable"
2282 [(set (match_operand:DI 0 "register_operand" "=r")
2283 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2284 (match_operand:DI 2 "register_operand" "r")]
2285 UNSPEC_DIV_INV_TABLE)))]
2286 "TARGET_SHMEDIA"
2287 "@
2288 ldx.ub %1, %2, %0"
2289 [(set_attr "type" "load_media")
2290 (set_attr "highpart" "user")])
2291
2292 ;; operands: scratch, tab_base, tab_ix
2293 (define_insn "divsi_inv_hitable"
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2296 (match_operand:DI 2 "register_operand" "r")]
2297 UNSPEC_DIV_INV_TABLE)))]
2298 "TARGET_SHMEDIA"
2299 "@
2300 ldx.w %1, %2, %0"
2301 [(set_attr "type" "load_media")
2302 (set_attr "highpart" "user")])
2303
2304 ;; operands: inv0, tab_base, tab_ix, norm32
2305 ;; scratch equiv in sdivsi3_2: r19, r21
2306 (define_expand "divsi_inv_m0"
2307 [(set (match_operand:SI 0 "register_operand" "=r")
2308 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2309 (match_operand:DI 2 "register_operand" "r")
2310 (match_operand:SI 3 "register_operand" "r")]
2311 UNSPEC_DIV_INV_M0))
2312 (clobber (match_operand:DI 4 "register_operand" "=r"))
2313 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2314 "TARGET_SHMEDIA"
2315 "
2316 {
2317 /*
2318 tab_base: r20
2319 tab_ix: r21
2320 norm32: r25
2321 ldx.ub r20, r21, r19 // u0.8
2322 shlli r21, 1, r21
2323 muls.l r25, r19, r19 // s2.38
2324 ldx.w r20, r21, r21 // s2.14
2325 shari r19, 24, r19 // truncate to s2.14
2326 sub r21, r19, r19 // some 11 bit inverse in s1.14
2327 */
2328
2329 rtx inv0 = operands[0];
2330 rtx tab_base = operands[1];
2331 rtx tab_ix = operands[2];
2332 rtx norm32 = operands[3];
2333 rtx scratch0 = operands[4];
2334 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2335 rtx scratch1 = operands[5];
2336
2337 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2338 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2339 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2340 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2341 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2342 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2343 DONE;
2344 }")
2345
2346 ;; operands: inv1, tab_base, tab_ix, norm32
2347 (define_insn_and_split "divsi_inv_m1"
2348 [(set (match_operand:SI 0 "register_operand" "=r")
2349 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2350 (match_operand:DI 2 "register_operand" "r")
2351 (match_operand:SI 3 "register_operand" "r")]
2352 UNSPEC_DIV_INV_M1))
2353 (clobber (match_operand:SI 4 "register_operand" "=r"))
2354 (clobber (match_operand:DI 5 "register_operand" "=r"))
2355 (clobber (match_operand:DI 6 "register_operand" "=r"))
2356 (clobber (match_operand:DI 7 "register_operand" "=r"))
2357 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2358 "TARGET_SHMEDIA"
2359 "#"
2360 "&& !can_create_pseudo_p ()"
2361 [(pc)]
2362 "
2363 {
2364 /* inv0: r19
2365 muls.l r19, r19, r18 // u0.28
2366 muls.l r25, r18, r18 // s2.58
2367 shlli r19, 45, r0 // multiply by two and convert to s2.58
2368 sub r0, r18, r18
2369 shari r18, 28, r18 // some 18 bit inverse in s1.30
2370 */
2371
2372 rtx inv1 = operands[0];
2373 rtx tab_base = operands[1];
2374 rtx tab_ix = operands[2];
2375 rtx norm32 = operands[3];
2376 rtx inv0 = operands[4];
2377 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2378 rtx scratch0a = operands[5];
2379 rtx scratch0b = operands[6];
2380 rtx scratch0 = operands[7];
2381 rtx scratch1 = operands[8];
2382 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2383
2384 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2385 scratch0a, scratch0b));
2386 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2387 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2389 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2390 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2391 DONE;
2392 }")
2393
2394 ;; operands: inv2, norm32, inv1, i92
2395 (define_insn_and_split "divsi_inv_m2"
2396 [(set (match_operand:SI 0 "register_operand" "=r")
2397 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2398 (match_operand:SI 2 "register_operand" "r")
2399 (match_operand:DI 3 "register_operand" "r")]
2400 UNSPEC_DIV_INV_M2))
2401 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2402 "TARGET_SHMEDIA"
2403 "#"
2404 "&& !can_create_pseudo_p ()"
2405 [(pc)]
2406 "
2407 {
2408 /*
2409 muls.l r18, r25, r0 // s2.60
2410 shari r0, 16, r0 // s-16.44
2411 sub
2412 muls.l r0, r18, r19 // s-16.74
2413 shari r19, 30, r19 // s-16.44
2414 */
2415 rtx inv2 = operands[0];
2416 rtx norm32 = operands[1];
2417 rtx inv1 = operands[2];
2418 rtx i92 = operands[3];
2419 rtx scratch0 = operands[4];
2420 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2421
2422 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2423 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2424 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2425 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2426 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2427 DONE;
2428 }")
2429
2430 (define_insn_and_split "divsi_inv_m3"
2431 [(set (match_operand:SI 0 "register_operand" "=r")
2432 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2433 (match_operand:SI 2 "register_operand" "r")
2434 (match_operand:SI 3 "register_operand" "r")
2435 (match_operand:DI 4 "register_operand" "r")
2436 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2437 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2438 UNSPEC_DIV_INV_M3))
2439 (clobber (match_operand:DI 7 "register_operand" "=r"))
2440 (clobber (match_operand:DI 8 "register_operand" "=r"))
2441 (clobber (match_operand:DI 9 "register_operand" "=r"))
2442 (clobber (match_operand:DI 10 "register_operand" "=r"))
2443 (clobber (match_operand:SI 11 "register_operand" "=r"))
2444 (clobber (match_operand:SI 12 "register_operand" "=r"))
2445 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2446 "TARGET_SHMEDIA"
2447 "#"
2448 "&& !can_create_pseudo_p ()"
2449 [(pc)]
2450 "
2451 {
2452 /*
2453 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2454 r0: scratch0 r19: scratch1 r21: scratch2
2455
2456 muls.l r18, r4, r25 // s32.30
2457 muls.l r19, r4, r19 // s15.30
2458 shari r25, 63, r21
2459 shari r19, 14, r19 // s18.-14
2460 sub r25, r19, r0
2461 shard r0, r1, r0
2462 sub r0, r21, r0
2463 */
2464
2465 rtx result = operands[0];
2466 rtx dividend = operands[1];
2467 rtx inv1 = operands[2];
2468 rtx inv2 = operands[3];
2469 rtx shift = operands[4];
2470 rtx scratch0 = operands[7];
2471 rtx scratch1 = operands[8];
2472 rtx scratch2 = operands[9];
2473
2474 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2475 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2476 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2477 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2478 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2479 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2480 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2481 DONE;
2482 }")
2483
2484 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2485 ;; inv1: tab_base, tab_ix, norm32
2486 ;; inv2: norm32, inv1, i92
2487 (define_insn_and_split "divsi_inv_m1_3"
2488 [(set (match_operand:SI 0 "register_operand" "=r")
2489 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2490 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2491 (match_operand:DI 3 "register_operand" "r")
2492 (match_operand:SI 4 "register_operand" "r")]
2493 UNSPEC_DIV_INV_M1)
2494 (unspec:SI [(match_dup 4)
2495 (unspec:SI [(match_dup 2)
2496 (match_dup 3)
2497 (match_dup 4)] UNSPEC_DIV_INV_M1)
2498 (match_operand:SI 5 "" "")]
2499 UNSPEC_DIV_INV_M2)
2500 (match_operand:DI 6 "register_operand" "r")
2501 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2502 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2503 UNSPEC_DIV_INV_M3))
2504 (clobber (match_operand:DI 9 "register_operand" "=r"))
2505 (clobber (match_operand:DI 10 "register_operand" "=r"))
2506 (clobber (match_operand:DI 11 "register_operand" "=r"))
2507 (clobber (match_operand:DI 12 "register_operand" "=r"))
2508 (clobber (match_operand:SI 13 "register_operand" "=r"))
2509 (clobber (match_operand:SI 14 "register_operand" "=r"))
2510 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2511 "TARGET_SHMEDIA
2512 && (TARGET_DIVIDE_INV_MINLAT
2513 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2514 "#"
2515 "&& !can_create_pseudo_p ()"
2516 [(pc)]
2517 "
2518 {
2519 rtx result = operands[0];
2520 rtx dividend = operands[1];
2521 rtx tab_base = operands[2];
2522 rtx tab_ix = operands[3];
2523 rtx norm32 = operands[4];
2524 /* rtx i92 = operands[5]; */
2525 rtx shift = operands[6];
2526 rtx i2p27 = operands[7];
2527 rtx i43 = operands[8];
2528 rtx scratch0 = operands[9];
2529 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2530 rtx scratch1 = operands[10];
2531 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2532 rtx scratch2 = operands[11];
2533 rtx scratch3 = operands[12];
2534 rtx scratch4 = operands[13];
2535 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2536 rtx scratch5 = operands[14];
2537 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2538 rtx scratch6 = operands[15];
2539
2540 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2541 scratch0, scratch1));
2542 /* inv0 == scratch4 */
2543 if (! TARGET_DIVIDE_INV20U)
2544 {
2545 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2546 i2p27 = scratch0;
2547 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2548 }
2549 else
2550 {
2551 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2552 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2553 }
2554 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2555 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2556 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2557 /* inv1 == scratch4 */
2558
2559 if (TARGET_DIVIDE_INV_MINLAT)
2560 {
2561 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2562 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2563 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2564 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2565 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2566 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2567 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2568 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2569 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2570 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2571 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2572 }
2573 else
2574 {
2575 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2576 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2577 emit_insn (gen_nsbdi (scratch6,
2578 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2579 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2580 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2581 emit_insn (gen_divsi_inv20 (scratch2,
2582 norm32, scratch4, dividend,
2583 scratch6, scratch3, i43,
2584 /* scratch0 may be shared with i2p27. */
2585 scratch0, scratch1, scratch5,
2586 label, label, i2p27));
2587 }
2588 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2589 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2590 DONE;
2591 }")
2592
2593 (define_insn "divsi_inv20"
2594 [(set (match_operand:DI 0 "register_operand" "=&r")
2595 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2596 (match_operand:SI 2 "register_operand" "r")
2597 (match_operand:SI 3 "register_operand" "r")
2598 (match_operand:DI 4 "register_operand" "r")
2599 (match_operand:DI 5 "register_operand" "r")
2600 (match_operand:DI 6 "register_operand" "r")
2601 (match_operand:DI 12 "register_operand" "r")
2602 (match_operand 10 "target_operand" "b")
2603 (match_operand 11 "immediate_operand" "i")]
2604 UNSPEC_DIV_INV20))
2605 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2606 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2607 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2608 "TARGET_SHMEDIA
2609 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2610 "*
2611 {
2612 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2613 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2614 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2615 %10 label (tr), %11 label (imm)
2616
2617 muls.l inv1, norm32, scratch0 // s2.60
2618 muls.l inv1, dividend, result // s32.30
2619 xor i2p27, result_sign, round_scratch
2620 bge/u dividend_nsb, i43, tr.. (label)
2621 shari scratch0, 16, scratch0 // s-16.44
2622 muls.l sratch0_si, inv1, scratch0 // s-16.74
2623 sub result, round_scratch, result
2624 shari dividend, 14, scratch1 // s19.-14
2625 shari scratch0, 30, scratch0 // s-16.44
2626 muls.l scratch0, scratch1, round_scratch // s15.30
2627 label:
2628 sub result, round_scratch, result */
2629
2630 int likely = TARGET_DIVIDE_INV20L;
2631
2632 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2633 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2634 output_asm_insn (likely
2635 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2636 : \"bge/u\t%4, %6, %10\", operands);
2637 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2638 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2639 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2640 return (likely
2641 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2642 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2643 }")
2644
2645 (define_insn_and_split "divsi_inv_fp"
2646 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2647 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2648 (match_operand:SI 2 "register_operand" "rf")))
2649 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2650 (clobber (match_operand:SI 4 "register_operand" "=r"))
2651 (clobber (match_operand:SI 5 "register_operand" "=r"))
2652 (clobber (match_operand:DF 6 "register_operand" "=r"))
2653 (clobber (match_operand:DF 7 "register_operand" "=r"))
2654 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2655 "TARGET_SHMEDIA_FPU"
2656 "#"
2657 "&& (high_life_started || reload_completed)"
2658 [(set (match_dup 0) (match_dup 3))]
2659 ""
2660 [(set_attr "highpart" "must_split")])
2661
2662 ;; If a matching group of divide-by-inverse instructions is in the same
2663 ;; basic block after gcse & loop optimizations, we want to transform them
2664 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2665 (define_insn_and_split "*divsi_inv_fp_combine"
2666 [(set (match_operand:SI 0 "register_operand" "=f")
2667 (div:SI (match_operand:SI 1 "register_operand" "f")
2668 (match_operand:SI 2 "register_operand" "f")))
2669 (use (unspec:SI [(match_dup 1)
2670 (match_operand:SI 3 "" "")
2671 (unspec:SI [(match_operand:SI 4 "" "")
2672 (match_dup 3)
2673 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2674 (match_operand:DI 6 "" "")
2675 (const_int 0)
2676 (const_int 0)] UNSPEC_DIV_INV_M3))
2677 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2678 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2679 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2680 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2681 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2682 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2683 "#"
2684 "&& 1"
2685 [(set (match_dup 9) (float:DF (match_dup 1)))
2686 (set (match_dup 10) (float:DF (match_dup 2)))
2687 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2688 (set (match_dup 8)
2689 (fix:SI (match_dup 11)))
2690 (set (match_dup 0) (match_dup 8))]
2691 "
2692 {
2693 if (! fp_arith_reg_operand (operands[1], SImode))
2694 {
2695 emit_move_insn (operands[7], operands[1]);
2696 operands[1] = operands[7];
2697 }
2698 if (! fp_arith_reg_operand (operands[2], SImode))
2699 {
2700 emit_move_insn (operands[8], operands[2]);
2701 operands[2] = operands[8];
2702 }
2703 }"
2704 [(set_attr "highpart" "must_split")])
2705 \f
2706 ;; -------------------------------------------------------------------------
2707 ;; Multiplication instructions
2708 ;; -------------------------------------------------------------------------
2709
2710 (define_insn "umulhisi3_i"
2711 [(set (reg:SI MACL_REG)
2712 (mult:SI (zero_extend:SI
2713 (match_operand:HI 0 "arith_reg_operand" "r"))
2714 (zero_extend:SI
2715 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2716 "TARGET_SH1"
2717 "mulu.w %1,%0"
2718 [(set_attr "type" "smpy")])
2719
2720 (define_insn "mulhisi3_i"
2721 [(set (reg:SI MACL_REG)
2722 (mult:SI (sign_extend:SI
2723 (match_operand:HI 0 "arith_reg_operand" "r"))
2724 (sign_extend:SI
2725 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2726 "TARGET_SH1"
2727 "muls.w %1,%0"
2728 [(set_attr "type" "smpy")])
2729
2730 (define_expand "mulhisi3"
2731 [(set (reg:SI MACL_REG)
2732 (mult:SI (sign_extend:SI
2733 (match_operand:HI 1 "arith_reg_operand" ""))
2734 (sign_extend:SI
2735 (match_operand:HI 2 "arith_reg_operand" ""))))
2736 (set (match_operand:SI 0 "arith_reg_operand" "")
2737 (reg:SI MACL_REG))]
2738 "TARGET_SH1"
2739 "
2740 {
2741 rtx insn, macl;
2742
2743 macl = gen_rtx_REG (SImode, MACL_REG);
2744 start_sequence ();
2745 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2746 insn = get_insns ();
2747 end_sequence ();
2748 /* expand_binop can't find a suitable code in umul_widen_optab to
2749 make a REG_EQUAL note from, so make one here.
2750 See also smulsi3_highpart.
2751 ??? Alternatively, we could put this at the calling site of expand_binop,
2752 i.e. expand_expr. */
2753 /* Use emit_libcall_block for loop invariant code motion and to make
2754 a REG_EQUAL note. */
2755 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2756
2757 DONE;
2758 }")
2759
2760 (define_expand "umulhisi3"
2761 [(set (reg:SI MACL_REG)
2762 (mult:SI (zero_extend:SI
2763 (match_operand:HI 1 "arith_reg_operand" ""))
2764 (zero_extend:SI
2765 (match_operand:HI 2 "arith_reg_operand" ""))))
2766 (set (match_operand:SI 0 "arith_reg_operand" "")
2767 (reg:SI MACL_REG))]
2768 "TARGET_SH1"
2769 "
2770 {
2771 rtx insn, macl;
2772
2773 macl = gen_rtx_REG (SImode, MACL_REG);
2774 start_sequence ();
2775 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2776 insn = get_insns ();
2777 end_sequence ();
2778 /* expand_binop can't find a suitable code in umul_widen_optab to
2779 make a REG_EQUAL note from, so make one here.
2780 See also smulsi3_highpart.
2781 ??? Alternatively, we could put this at the calling site of expand_binop,
2782 i.e. expand_expr. */
2783 /* Use emit_libcall_block for loop invariant code motion and to make
2784 a REG_EQUAL note. */
2785 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2786
2787 DONE;
2788 }")
2789
2790 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2791 ;; a call to a routine which clobbers known registers.
2792
2793 (define_insn ""
2794 [(set (match_operand:SI 1 "register_operand" "=z")
2795 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2796 (clobber (reg:SI MACL_REG))
2797 (clobber (reg:SI T_REG))
2798 (clobber (reg:SI PR_REG))
2799 (clobber (reg:SI R3_REG))
2800 (clobber (reg:SI R2_REG))
2801 (clobber (reg:SI R1_REG))
2802 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2803 "TARGET_SH1"
2804 "jsr @%0%#"
2805 [(set_attr "type" "sfunc")
2806 (set_attr "needs_delay_slot" "yes")])
2807
2808 (define_expand "mulsi3_call"
2809 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2810 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2811 (parallel[(set (match_operand:SI 0 "register_operand" "")
2812 (mult:SI (reg:SI R4_REG)
2813 (reg:SI R5_REG)))
2814 (clobber (reg:SI MACL_REG))
2815 (clobber (reg:SI T_REG))
2816 (clobber (reg:SI PR_REG))
2817 (clobber (reg:SI R3_REG))
2818 (clobber (reg:SI R2_REG))
2819 (clobber (reg:SI R1_REG))
2820 (use (match_operand:SI 3 "register_operand" ""))])]
2821 "TARGET_SH1"
2822 "")
2823
2824 (define_insn "mul_r"
2825 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2826 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2827 (match_operand:SI 2 "arith_reg_operand" "z")))]
2828 "TARGET_SH2A"
2829 "mulr %2,%0"
2830 [(set_attr "type" "dmpy")])
2831
2832 (define_insn "mul_l"
2833 [(set (reg:SI MACL_REG)
2834 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2835 (match_operand:SI 1 "arith_reg_operand" "r")))]
2836 "TARGET_SH2"
2837 "mul.l %1,%0"
2838 [(set_attr "type" "dmpy")])
2839
2840 (define_expand "mulsi3"
2841 [(set (reg:SI MACL_REG)
2842 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2843 (match_operand:SI 2 "arith_reg_operand" "")))
2844 (set (match_operand:SI 0 "arith_reg_operand" "")
2845 (reg:SI MACL_REG))]
2846 "TARGET_SH1"
2847 "
2848 {
2849 if (!TARGET_SH2)
2850 {
2851 /* The address must be set outside the libcall,
2852 since it goes into a pseudo. */
2853 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854 rtx addr = force_reg (SImode, sym);
2855 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2856 operands[2], addr);
2857 emit_insn (insns);
2858 }
2859 else
2860 {
2861 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2862
2863 emit_insn (gen_mul_l (operands[1], operands[2]));
2864 /* consec_sets_giv can only recognize the first insn that sets a
2865 giv as the giv insn. So we must tag this also with a REG_EQUAL
2866 note. */
2867 emit_insn (gen_movsi_i ((operands[0]), macl));
2868 }
2869 DONE;
2870 }")
2871
2872 (define_insn "mulsidi3_i"
2873 [(set (reg:SI MACH_REG)
2874 (truncate:SI
2875 (lshiftrt:DI
2876 (mult:DI
2877 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2878 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2879 (const_int 32))))
2880 (set (reg:SI MACL_REG)
2881 (mult:SI (match_dup 0)
2882 (match_dup 1)))]
2883 "TARGET_SH2"
2884 "dmuls.l %1,%0"
2885 [(set_attr "type" "dmpy")])
2886
2887 (define_expand "mulsidi3"
2888 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2889 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2890 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2891 "TARGET_SH2 || TARGET_SHMEDIA"
2892 "
2893 {
2894 if (TARGET_SH2)
2895 {
2896 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2897 operands[2]));
2898 DONE;
2899 }
2900 }")
2901
2902 (define_insn "mulsidi3_media"
2903 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2904 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2905 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2906 "TARGET_SHMEDIA"
2907 "muls.l %1, %2, %0"
2908 [(set_attr "type" "dmpy_media")
2909 (set_attr "highpart" "ignore")])
2910
2911 (define_insn "mulsidi3_compact"
2912 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2913 (mult:DI
2914 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2915 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2916 (clobber (reg:SI MACH_REG))
2917 (clobber (reg:SI MACL_REG))]
2918 "TARGET_SH2"
2919 "#")
2920
2921 (define_split
2922 [(set (match_operand:DI 0 "arith_reg_dest" "")
2923 (mult:DI
2924 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2925 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2926 (clobber (reg:SI MACH_REG))
2927 (clobber (reg:SI MACL_REG))]
2928 "TARGET_SH2"
2929 [(const_int 0)]
2930 "
2931 {
2932 rtx low_dst = gen_lowpart (SImode, operands[0]);
2933 rtx high_dst = gen_highpart (SImode, operands[0]);
2934
2935 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2936
2937 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2938 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2939 /* We need something to tag the possible REG_EQUAL notes on to. */
2940 emit_move_insn (operands[0], operands[0]);
2941 DONE;
2942 }")
2943
2944 (define_insn "umulsidi3_i"
2945 [(set (reg:SI MACH_REG)
2946 (truncate:SI
2947 (lshiftrt:DI
2948 (mult:DI
2949 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2950 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2951 (const_int 32))))
2952 (set (reg:SI MACL_REG)
2953 (mult:SI (match_dup 0)
2954 (match_dup 1)))]
2955 "TARGET_SH2"
2956 "dmulu.l %1,%0"
2957 [(set_attr "type" "dmpy")])
2958
2959 (define_expand "umulsidi3"
2960 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2961 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2962 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2963 "TARGET_SH2 || TARGET_SHMEDIA"
2964 "
2965 {
2966 if (TARGET_SH2)
2967 {
2968 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2969 operands[2]));
2970 DONE;
2971 }
2972 }")
2973
2974 (define_insn "umulsidi3_media"
2975 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2976 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2977 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2978 "TARGET_SHMEDIA"
2979 "mulu.l %1, %2, %0"
2980 [(set_attr "type" "dmpy_media")
2981 (set_attr "highpart" "ignore")])
2982
2983 (define_insn "umulsidi3_compact"
2984 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2985 (mult:DI
2986 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2987 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2988 (clobber (reg:SI MACH_REG))
2989 (clobber (reg:SI MACL_REG))]
2990 "TARGET_SH2"
2991 "#")
2992
2993 (define_split
2994 [(set (match_operand:DI 0 "arith_reg_dest" "")
2995 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2996 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2997 (clobber (reg:SI MACH_REG))
2998 (clobber (reg:SI MACL_REG))]
2999 "TARGET_SH2"
3000 [(const_int 0)]
3001 "
3002 {
3003 rtx low_dst = gen_lowpart (SImode, operands[0]);
3004 rtx high_dst = gen_highpart (SImode, operands[0]);
3005
3006 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3007
3008 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3009 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3010 /* We need something to tag the possible REG_EQUAL notes on to. */
3011 emit_move_insn (operands[0], operands[0]);
3012 DONE;
3013 }")
3014
3015 (define_insn "smulsi3_highpart_i"
3016 [(set (reg:SI MACH_REG)
3017 (truncate:SI
3018 (lshiftrt:DI
3019 (mult:DI
3020 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3021 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3022 (const_int 32))))
3023 (clobber (reg:SI MACL_REG))]
3024 "TARGET_SH2"
3025 "dmuls.l %1,%0"
3026 [(set_attr "type" "dmpy")])
3027
3028 (define_expand "smulsi3_highpart"
3029 [(parallel
3030 [(set (reg:SI MACH_REG)
3031 (truncate:SI
3032 (lshiftrt:DI
3033 (mult:DI
3034 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3035 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3036 (const_int 32))))
3037 (clobber (reg:SI MACL_REG))])
3038 (set (match_operand:SI 0 "arith_reg_operand" "")
3039 (reg:SI MACH_REG))]
3040 "TARGET_SH2"
3041 "
3042 {
3043 rtx insn, mach;
3044
3045 mach = gen_rtx_REG (SImode, MACH_REG);
3046 start_sequence ();
3047 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3048 insn = get_insns ();
3049 end_sequence ();
3050 /* expand_binop can't find a suitable code in mul_highpart_optab to
3051 make a REG_EQUAL note from, so make one here.
3052 See also {,u}mulhisi.
3053 ??? Alternatively, we could put this at the calling site of expand_binop,
3054 i.e. expand_mult_highpart. */
3055 /* Use emit_libcall_block for loop invariant code motion and to make
3056 a REG_EQUAL note. */
3057 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3058
3059 DONE;
3060 }")
3061
3062 (define_insn "umulsi3_highpart_i"
3063 [(set (reg:SI MACH_REG)
3064 (truncate:SI
3065 (lshiftrt:DI
3066 (mult:DI
3067 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3068 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3069 (const_int 32))))
3070 (clobber (reg:SI MACL_REG))]
3071 "TARGET_SH2"
3072 "dmulu.l %1,%0"
3073 [(set_attr "type" "dmpy")])
3074
3075 (define_expand "umulsi3_highpart"
3076 [(parallel
3077 [(set (reg:SI MACH_REG)
3078 (truncate:SI
3079 (lshiftrt:DI
3080 (mult:DI
3081 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3082 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3083 (const_int 32))))
3084 (clobber (reg:SI MACL_REG))])
3085 (set (match_operand:SI 0 "arith_reg_operand" "")
3086 (reg:SI MACH_REG))]
3087 "TARGET_SH2"
3088 "
3089 {
3090 rtx insn, mach;
3091
3092 mach = gen_rtx_REG (SImode, MACH_REG);
3093 start_sequence ();
3094 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3095 insn = get_insns ();
3096 end_sequence ();
3097 /* Use emit_libcall_block for loop invariant code motion and to make
3098 a REG_EQUAL note. */
3099 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3100
3101 DONE;
3102 }")
3103
3104 (define_insn_and_split "muldi3"
3105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3106 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3107 (match_operand:DI 2 "arith_reg_operand" "r")))
3108 (clobber (match_scratch:DI 3 "=&r"))
3109 (clobber (match_scratch:DI 4 "=r"))]
3110 "TARGET_SHMEDIA"
3111 "#"
3112 "reload_completed"
3113 [(const_int 0)]
3114 "
3115 {
3116 rtx op3_v2si, op2_v2si;
3117
3118 op3_v2si = operands[3];
3119 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3120 {
3121 op3_v2si = XEXP (op3_v2si, 0);
3122 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3123 }
3124 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3125 op2_v2si = operands[2];
3126 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3127 {
3128 op2_v2si = XEXP (op2_v2si, 0);
3129 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3130 }
3131 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3132 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3133 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3134 emit_insn (gen_umulsidi3_media (operands[4],
3135 sh_gen_truncate (SImode, operands[1], 0),
3136 sh_gen_truncate (SImode, operands[2], 0)));
3137 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3138 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3139 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3140 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3141 DONE;
3142 }")
3143
3144 \f
3145 ;; -------------------------------------------------------------------------
3146 ;; Logical operations
3147 ;; -------------------------------------------------------------------------
3148
3149 (define_insn "*andsi3_compact"
3150 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3151 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3152 (match_operand:SI 2 "logical_operand" "r,K08")))]
3153 "TARGET_SH1"
3154 "and %2,%0"
3155 [(set_attr "type" "arith")])
3156
3157 (define_insn "*andsi3_media"
3158 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3159 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3160 (match_operand:SI 2 "logical_operand" "r,I10")))]
3161 "TARGET_SHMEDIA"
3162 "@
3163 and %1, %2, %0
3164 andi %1, %2, %0"
3165 [(set_attr "type" "arith_media")])
3166
3167 ;; If the constant is 255, then emit an extu.b instruction instead of an
3168 ;; and, since that will give better code.
3169
3170 (define_expand "andsi3"
3171 [(set (match_operand:SI 0 "arith_reg_operand" "")
3172 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3173 (match_operand:SI 2 "logical_operand" "")))]
3174 ""
3175 "
3176 {
3177 if (TARGET_SH1
3178 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3179 {
3180 emit_insn (gen_zero_extendqisi2 (operands[0],
3181 gen_lowpart (QImode, operands[1])));
3182 DONE;
3183 }
3184 }")
3185
3186 (define_insn_and_split "anddi3"
3187 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3188 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3189 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3190 "TARGET_SHMEDIA"
3191 "@
3192 and %1, %2, %0
3193 andi %1, %2, %0
3194 #"
3195 "reload_completed
3196 && ! logical_operand (operands[2], DImode)"
3197 [(const_int 0)]
3198 "
3199 {
3200 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3201 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3202 else
3203 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3204 DONE;
3205 }"
3206 [(set_attr "type" "arith_media")])
3207
3208 (define_insn "andcsi3"
3209 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3210 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3211 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3212 "TARGET_SHMEDIA"
3213 "andc %1,%2,%0"
3214 [(set_attr "type" "arith_media")])
3215
3216 (define_insn "andcdi3"
3217 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3218 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3219 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3220 "TARGET_SHMEDIA"
3221 "andc %1,%2,%0"
3222 [(set_attr "type" "arith_media")])
3223
3224 (define_expand "iorsi3"
3225 [(set (match_operand:SI 0 "arith_reg_operand" "")
3226 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3227 (match_operand:SI 2 "logical_operand" "")))]
3228 ""
3229 "")
3230
3231 (define_insn "*iorsi3_compact"
3232 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3233 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3234 (match_operand:SI 2 "logical_operand" "r,K08")))]
3235 "TARGET_SH1"
3236 "or %2,%0"
3237 [(set_attr "type" "arith")])
3238
3239 (define_insn "*iorsi3_media"
3240 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3241 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3242 (match_operand:SI 2 "logical_operand" "r,I10")))]
3243 "TARGET_SHMEDIA"
3244 "@
3245 or %1, %2, %0
3246 ori %1, %2, %0"
3247 [(set_attr "type" "arith_media")])
3248
3249 (define_insn "iordi3"
3250 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3251 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3252 (match_operand:DI 2 "logical_operand" "r,I10")))]
3253 "TARGET_SHMEDIA"
3254 "@
3255 or %1, %2, %0
3256 ori %1, %2, %0"
3257 [(set_attr "type" "arith_media")])
3258
3259 (define_insn_and_split "*logical_sidi3"
3260 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3261 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3262 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3263 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3264 "TARGET_SHMEDIA"
3265 "#"
3266 "&& reload_completed"
3267 [(set (match_dup 0) (match_dup 3))]
3268 "
3269 {
3270 operands[3]
3271 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3272 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3273 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3274 }")
3275
3276 (define_insn_and_split "*logical_sidisi3"
3277 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3278 (truncate:SI (sign_extend:DI
3279 (match_operator:SI 3 "logical_operator"
3280 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3281 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3282 "TARGET_SHMEDIA"
3283 "#"
3284 "&& 1"
3285 [(set (match_dup 0) (match_dup 3))])
3286
3287 (define_insn_and_split "*logical_sidi3_2"
3288 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3289 (sign_extend:DI (truncate:SI (sign_extend:DI
3290 (match_operator:SI 3 "logical_operator"
3291 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3292 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3293 "TARGET_SHMEDIA"
3294 "#"
3295 "&& 1"
3296 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3297
3298 (define_expand "xorsi3"
3299 [(set (match_operand:SI 0 "arith_reg_operand" "")
3300 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3301 (match_operand:SI 2 "xor_operand" "")))]
3302 ""
3303 "")
3304
3305 (define_insn "*xorsi3_compact"
3306 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3307 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3308 (match_operand:SI 2 "logical_operand" "K08,r")))]
3309 "TARGET_SH1"
3310 "xor %2,%0"
3311 [(set_attr "type" "arith")])
3312
3313 (define_insn "*xorsi3_media"
3314 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3315 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3316 (match_operand:SI 2 "xor_operand" "r,I06")))]
3317 "TARGET_SHMEDIA"
3318 "@
3319 xor %1, %2, %0
3320 xori %1, %2, %0"
3321 [(set_attr "type" "arith_media")])
3322
3323 (define_insn "xordi3"
3324 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3326 (match_operand:DI 2 "xor_operand" "r,I06")))]
3327 "TARGET_SHMEDIA"
3328 "@
3329 xor %1, %2, %0
3330 xori %1, %2, %0"
3331 [(set_attr "type" "arith_media")])
3332
3333 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3334 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3335 (define_split
3336 [(set (match_operand:DI 0 "arith_reg_dest" "")
3337 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3338 [(match_operand 1 "any_register_operand" "")
3339 (match_operand 2 "any_register_operand" "")])))]
3340 "TARGET_SHMEDIA"
3341 [(set (match_dup 5) (match_dup 4))
3342 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3343 "
3344 {
3345 enum machine_mode inmode = GET_MODE (operands[1]);
3346 int offset = 0;
3347
3348 if (GET_CODE (operands[0]) == SUBREG)
3349 {
3350 offset = SUBREG_BYTE (operands[0]);
3351 operands[0] = SUBREG_REG (operands[0]);
3352 }
3353 gcc_assert (GET_CODE (operands[0]) == REG);
3354 if (! TARGET_LITTLE_ENDIAN)
3355 offset += 8 - GET_MODE_SIZE (inmode);
3356 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3357 }")
3358 \f
3359 ;; -------------------------------------------------------------------------
3360 ;; Shifts and rotates
3361 ;; -------------------------------------------------------------------------
3362
3363 (define_expand "rotldi3"
3364 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3365 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3366 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3367 "TARGET_SHMEDIA"
3368 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3369
3370 (define_insn "rotldi3_mextr"
3371 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3372 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3373 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3374 "TARGET_SHMEDIA"
3375 "*
3376 {
3377 static char templ[16];
3378
3379 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3380 8 - (int) (INTVAL (operands[2]) >> 3));
3381 return templ;
3382 }"
3383 [(set_attr "type" "arith_media")])
3384
3385 (define_expand "rotrdi3"
3386 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3389 "TARGET_SHMEDIA"
3390 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3391
3392 (define_insn "rotrdi3_mextr"
3393 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3394 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3395 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3396 "TARGET_SHMEDIA"
3397 "*
3398 {
3399 static char templ[16];
3400
3401 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3402 return templ;
3403 }"
3404 [(set_attr "type" "arith_media")])
3405
3406 (define_split
3407 [(set (match_operand:DI 0 "arith_reg_dest" "")
3408 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3409 "ua_address_operand" "")))
3410 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3411 (const_int 8))))
3412 (clobber (match_operand:DI 3 "register_operand" ""))]
3413 "TARGET_SHMEDIA"
3414 [(match_dup 4) (match_dup 5)]
3415 "
3416 {
3417 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3418 (operands[3], operands[1]));
3419 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3420 GEN_INT (56), GEN_INT (8));
3421 }")
3422
3423 (define_insn "rotlsi3_1"
3424 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3425 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3426 (const_int 1)))
3427 (set (reg:SI T_REG)
3428 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3429 "TARGET_SH1"
3430 "rotl %0"
3431 [(set_attr "type" "arith")])
3432
3433 (define_insn "rotlsi3_31"
3434 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3436 (const_int 31)))
3437 (clobber (reg:SI T_REG))]
3438 "TARGET_SH1"
3439 "rotr %0"
3440 [(set_attr "type" "arith")])
3441
3442 (define_insn "rotlsi3_16"
3443 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3444 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3445 (const_int 16)))]
3446 "TARGET_SH1"
3447 "swap.w %1,%0"
3448 [(set_attr "type" "arith")])
3449
3450 (define_expand "rotlsi3"
3451 [(set (match_operand:SI 0 "arith_reg_dest" "")
3452 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3453 (match_operand:SI 2 "immediate_operand" "")))]
3454 "TARGET_SH1"
3455 "
3456 {
3457 static const char rot_tab[] = {
3458 000, 000, 000, 000, 000, 000, 010, 001,
3459 001, 001, 011, 013, 003, 003, 003, 003,
3460 003, 003, 003, 003, 003, 013, 012, 002,
3461 002, 002, 010, 000, 000, 000, 000, 000,
3462 };
3463
3464 int count, choice;
3465
3466 if (GET_CODE (operands[2]) != CONST_INT)
3467 FAIL;
3468 count = INTVAL (operands[2]);
3469 choice = rot_tab[count];
3470 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3471 FAIL;
3472 choice &= 7;
3473 switch (choice)
3474 {
3475 case 0:
3476 emit_move_insn (operands[0], operands[1]);
3477 count -= (count & 16) * 2;
3478 break;
3479 case 3:
3480 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3481 count -= 16;
3482 break;
3483 case 1:
3484 case 2:
3485 {
3486 rtx parts[2];
3487 parts[0] = gen_reg_rtx (SImode);
3488 parts[1] = gen_reg_rtx (SImode);
3489 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3490 emit_move_insn (parts[choice-1], operands[1]);
3491 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3492 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3493 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3494 count = (count & ~16) - 8;
3495 }
3496 }
3497
3498 for (; count > 0; count--)
3499 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3500 for (; count < 0; count++)
3501 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3502
3503 DONE;
3504 }")
3505
3506 (define_insn "*rotlhi3_8"
3507 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3508 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3509 (const_int 8)))]
3510 "TARGET_SH1"
3511 "swap.b %1,%0"
3512 [(set_attr "type" "arith")])
3513
3514 (define_expand "rotlhi3"
3515 [(set (match_operand:HI 0 "arith_reg_operand" "")
3516 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3517 (match_operand:HI 2 "immediate_operand" "")))]
3518 "TARGET_SH1"
3519 "
3520 {
3521 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3522 FAIL;
3523 }")
3524
3525 ;;
3526 ;; shift left
3527
3528 (define_insn "ashlsi3_sh2a"
3529 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531 (match_operand:SI 2 "arith_reg_operand" "r")))]
3532 "TARGET_SH2A"
3533 "shad %2,%0"
3534 [(set_attr "type" "arith")
3535 (set_attr "length" "4")])
3536
3537 ;; This pattern is used by init_expmed for computing the costs of shift
3538 ;; insns.
3539
3540 (define_insn_and_split "ashlsi3_std"
3541 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3542 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3543 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3544 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3545 "TARGET_SH3
3546 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3547 "@
3548 shld %2,%0
3549 add %0,%0
3550 shll%O2 %0
3551 #"
3552 "TARGET_SH3
3553 && reload_completed
3554 && GET_CODE (operands[2]) == CONST_INT
3555 && ! satisfies_constraint_P27 (operands[2])"
3556 [(set (match_dup 3) (match_dup 2))
3557 (parallel
3558 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3559 (clobber (match_dup 4))])]
3560 "operands[4] = gen_rtx_SCRATCH (SImode);"
3561 [(set_attr "length" "*,*,*,4")
3562 (set_attr "type" "dyn_shift,arith,arith,arith")])
3563
3564 (define_insn "ashlhi3_k"
3565 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3566 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3567 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3568 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3569 "@
3570 add %0,%0
3571 shll%O2 %0"
3572 [(set_attr "type" "arith")])
3573
3574 (define_insn "ashlsi3_n"
3575 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3576 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3577 (match_operand:SI 2 "const_int_operand" "n")))
3578 (clobber (reg:SI T_REG))]
3579 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3580 "#"
3581 [(set (attr "length")
3582 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3583 (const_string "2")
3584 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3585 (const_string "4")
3586 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3587 (const_string "6")]
3588 (const_string "8")))
3589 (set_attr "type" "arith")])
3590
3591 (define_split
3592 [(set (match_operand:SI 0 "arith_reg_dest" "")
3593 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3594 (match_operand:SI 2 "const_int_operand" "")))
3595 (clobber (reg:SI T_REG))]
3596 "TARGET_SH1 && reload_completed"
3597 [(use (reg:SI R0_REG))]
3598 "
3599 {
3600 gen_shifty_op (ASHIFT, operands);
3601 DONE;
3602 }")
3603
3604 (define_insn "ashlsi3_media"
3605 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3606 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3607 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3608 "TARGET_SHMEDIA"
3609 "@
3610 shlld.l %1, %2, %0
3611 shlli.l %1, %2, %0"
3612 [(set_attr "type" "arith_media")
3613 (set_attr "highpart" "ignore")])
3614
3615 (define_expand "ashlsi3"
3616 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3617 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3618 (match_operand:SI 2 "nonmemory_operand" "")))
3619 (clobber (reg:SI T_REG))])]
3620 ""
3621 "
3622 {
3623 if (TARGET_SHMEDIA)
3624 {
3625 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3626 DONE;
3627 }
3628 if (GET_CODE (operands[2]) == CONST_INT
3629 && sh_dynamicalize_shift_p (operands[2]))
3630 operands[2] = force_reg (SImode, operands[2]);
3631 if (TARGET_SH3)
3632 {
3633 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3634 DONE;
3635 }
3636 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3637 FAIL;
3638 }")
3639
3640 (define_insn "*ashlhi3_n"
3641 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3642 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3643 (match_operand:HI 2 "const_int_operand" "n")))
3644 (clobber (reg:SI T_REG))]
3645 "TARGET_SH1"
3646 "#"
3647 [(set (attr "length")
3648 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3649 (const_string "2")
3650 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3651 (const_string "4")]
3652 (const_string "6")))
3653 (set_attr "type" "arith")])
3654
3655 (define_expand "ashlhi3"
3656 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3657 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3658 (match_operand:SI 2 "nonmemory_operand" "")))
3659 (clobber (reg:SI T_REG))])]
3660 "TARGET_SH1"
3661 "
3662 {
3663 if (GET_CODE (operands[2]) != CONST_INT)
3664 FAIL;
3665 /* It may be possible to call gen_ashlhi3 directly with more generic
3666 operands. Make sure operands[1] is a HImode register here. */
3667 if (!arith_reg_operand (operands[1], HImode))
3668 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3669 }")
3670
3671 (define_split
3672 [(set (match_operand:HI 0 "arith_reg_dest" "")
3673 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3674 (match_operand:HI 2 "const_int_operand" "")))
3675 (clobber (reg:SI T_REG))]
3676 "TARGET_SH1 && reload_completed"
3677 [(use (reg:SI R0_REG))]
3678 "
3679 {
3680 gen_shifty_hi_op (ASHIFT, operands);
3681 DONE;
3682 }")
3683
3684 ;
3685 ; arithmetic shift right
3686 ;
3687
3688 (define_insn "ashrsi3_sh2a"
3689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3692 "TARGET_SH2A"
3693 "shad %2,%0"
3694 [(set_attr "type" "dyn_shift")
3695 (set_attr "length" "4")])
3696
3697 (define_insn "ashrsi3_k"
3698 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3699 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3700 (match_operand:SI 2 "const_int_operand" "M")))
3701 (clobber (reg:SI T_REG))]
3702 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3703 "shar %0"
3704 [(set_attr "type" "arith")])
3705
3706 ;; We can't do HImode right shifts correctly unless we start out with an
3707 ;; explicit zero / sign extension; doing that would result in worse overall
3708 ;; code, so just let the machine independent code widen the mode.
3709 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3710
3711
3712 ;; ??? This should be a define expand.
3713
3714 (define_insn "ashrsi2_16"
3715 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3716 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3717 (const_int 16)))]
3718 "TARGET_SH1"
3719 "#"
3720 [(set_attr "length" "4")])
3721
3722 (define_split
3723 [(set (match_operand:SI 0 "arith_reg_dest" "")
3724 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3725 (const_int 16)))]
3726 "TARGET_SH1"
3727 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3728 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3729 "operands[2] = gen_lowpart (HImode, operands[0]);")
3730
3731 ;; ??? This should be a define expand.
3732
3733 (define_insn "ashrsi2_31"
3734 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3735 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3736 (const_int 31)))
3737 (clobber (reg:SI T_REG))]
3738 "TARGET_SH1"
3739 "#"
3740 [(set_attr "length" "4")])
3741
3742 (define_split
3743 [(set (match_operand:SI 0 "arith_reg_dest" "")
3744 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3745 (const_int 31)))
3746 (clobber (reg:SI T_REG))]
3747 "TARGET_SH1"
3748 [(const_int 0)]
3749 "
3750 {
3751 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3752 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3753 DONE;
3754 }")
3755
3756 (define_peephole2
3757 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3758 (set (reg:SI T_REG)
3759 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3760 "TARGET_SH1
3761 && peep2_reg_dead_p (2, operands[0])
3762 && peep2_reg_dead_p (2, operands[1])"
3763 [(const_int 0)]
3764 "
3765 {
3766 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3767 DONE;
3768 }")
3769
3770 (define_insn "ashlsi_c"
3771 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3773 (set (reg:SI T_REG)
3774 (lt:SI (match_dup 1) (const_int 0)))]
3775 "TARGET_SH1"
3776 "shll %0"
3777 [(set_attr "type" "arith")])
3778
3779 (define_insn "*ashlsi_c_void"
3780 [(set (reg:SI T_REG)
3781 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3782 (clobber (match_scratch:SI 1 "=0"))]
3783 "TARGET_SH1 && cse_not_expected"
3784 "shll %0"
3785 [(set_attr "type" "arith")])
3786
3787 (define_insn "ashrsi3_d"
3788 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3789 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3790 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3791 "TARGET_SH3"
3792 "shad %2,%0"
3793 [(set_attr "type" "dyn_shift")])
3794
3795 (define_insn "ashrsi3_n"
3796 [(set (reg:SI R4_REG)
3797 (ashiftrt:SI (reg:SI R4_REG)
3798 (match_operand:SI 0 "const_int_operand" "i")))
3799 (clobber (reg:SI T_REG))
3800 (clobber (reg:SI PR_REG))
3801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3802 "TARGET_SH1"
3803 "jsr @%1%#"
3804 [(set_attr "type" "sfunc")
3805 (set_attr "needs_delay_slot" "yes")])
3806
3807 (define_insn "ashrsi3_media"
3808 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3809 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3810 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3811 "TARGET_SHMEDIA"
3812 "@
3813 shard.l %1, %2, %0
3814 shari.l %1, %2, %0"
3815 [(set_attr "type" "arith_media")
3816 (set_attr "highpart" "ignore")])
3817
3818 (define_expand "ashrsi3"
3819 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3820 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3821 (match_operand:SI 2 "nonmemory_operand" "")))
3822 (clobber (reg:SI T_REG))])]
3823 ""
3824 "
3825 {
3826 if (TARGET_SHMEDIA)
3827 {
3828 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3829 DONE;
3830 }
3831 if (expand_ashiftrt (operands))
3832 DONE;
3833 else
3834 FAIL;
3835 }")
3836
3837 ;; logical shift right
3838
3839 (define_insn "lshrsi3_sh2a"
3840 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3841 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3842 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3843 "TARGET_SH2A"
3844 "shld %2,%0"
3845 [(set_attr "type" "dyn_shift")
3846 (set_attr "length" "4")])
3847
3848 (define_insn "lshrsi3_d"
3849 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3850 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3851 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3852 "TARGET_SH3"
3853 "shld %2,%0"
3854 [(set_attr "type" "dyn_shift")])
3855
3856 ;; Only the single bit shift clobbers the T bit.
3857
3858 (define_insn "lshrsi3_m"
3859 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3860 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3861 (match_operand:SI 2 "const_int_operand" "M")))
3862 (clobber (reg:SI T_REG))]
3863 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3864 "shlr %0"
3865 [(set_attr "type" "arith")])
3866
3867 (define_insn "lshrsi3_k"
3868 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3869 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3870 (match_operand:SI 2 "const_int_operand" "P27")))]
3871 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3872 && ! satisfies_constraint_M (operands[2])"
3873 "shlr%O2 %0"
3874 [(set_attr "type" "arith")])
3875
3876 (define_insn "lshrsi3_n"
3877 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879 (match_operand:SI 2 "const_int_operand" "n")))
3880 (clobber (reg:SI T_REG))]
3881 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3882 "#"
3883 [(set (attr "length")
3884 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3885 (const_string "2")
3886 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3887 (const_string "4")
3888 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3889 (const_string "6")]
3890 (const_string "8")))
3891 (set_attr "type" "arith")])
3892
3893 (define_split
3894 [(set (match_operand:SI 0 "arith_reg_dest" "")
3895 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3896 (match_operand:SI 2 "const_int_operand" "")))
3897 (clobber (reg:SI T_REG))]
3898 "TARGET_SH1 && reload_completed"
3899 [(use (reg:SI R0_REG))]
3900 "
3901 {
3902 gen_shifty_op (LSHIFTRT, operands);
3903 DONE;
3904 }")
3905
3906 (define_insn "lshrsi3_media"
3907 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3908 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3909 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3910 "TARGET_SHMEDIA"
3911 "@
3912 shlrd.l %1, %2, %0
3913 shlri.l %1, %2, %0"
3914 [(set_attr "type" "arith_media")
3915 (set_attr "highpart" "ignore")])
3916
3917 (define_expand "lshrsi3"
3918 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3919 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3920 (match_operand:SI 2 "nonmemory_operand" "")))
3921 (clobber (reg:SI T_REG))])]
3922 ""
3923 "
3924 {
3925 if (TARGET_SHMEDIA)
3926 {
3927 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3928 DONE;
3929 }
3930 if (GET_CODE (operands[2]) == CONST_INT
3931 && sh_dynamicalize_shift_p (operands[2]))
3932 operands[2] = force_reg (SImode, operands[2]);
3933 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3934 {
3935 rtx count = copy_to_mode_reg (SImode, operands[2]);
3936 emit_insn (gen_negsi2 (count, count));
3937 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3938 DONE;
3939 }
3940 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3941 FAIL;
3942 }")
3943
3944 ;; ??? This should be a define expand.
3945
3946 (define_insn "ashldi3_k"
3947 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3948 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3949 (const_int 1)))
3950 (clobber (reg:SI T_REG))]
3951 "TARGET_SH1"
3952 "shll %R0\;rotcl %S0"
3953 [(set_attr "length" "4")
3954 (set_attr "type" "arith")])
3955
3956 (define_insn "ashldi3_media"
3957 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3958 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3959 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3960 "TARGET_SHMEDIA"
3961 "@
3962 shlld %1, %2, %0
3963 shlli %1, %2, %0"
3964 [(set_attr "type" "arith_media")])
3965
3966 (define_insn "*ashldisi3_media"
3967 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3968 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3969 (match_operand:DI 2 "const_int_operand" "n")))]
3970 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3971 "shlli.l %1, %2, %0"
3972 [(set_attr "type" "arith_media")
3973 (set_attr "highpart" "ignore")])
3974
3975 (define_expand "ashldi3"
3976 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3977 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3978 (match_operand:DI 2 "immediate_operand" "")))
3979 (clobber (reg:SI T_REG))])]
3980 ""
3981 "
3982 {
3983 if (TARGET_SHMEDIA)
3984 {
3985 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3986 DONE;
3987 }
3988 if (GET_CODE (operands[2]) != CONST_INT
3989 || INTVAL (operands[2]) != 1)
3990 FAIL;
3991 }")
3992
3993 ;; ??? This should be a define expand.
3994
3995 (define_insn "lshrdi3_k"
3996 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3997 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3998 (const_int 1)))
3999 (clobber (reg:SI T_REG))]
4000 "TARGET_SH1"
4001 "shlr %S0\;rotcr %R0"
4002 [(set_attr "length" "4")
4003 (set_attr "type" "arith")])
4004
4005 (define_insn "lshrdi3_media"
4006 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4007 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4008 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4009 "TARGET_SHMEDIA
4010 && (arith_reg_dest (operands[0], DImode)
4011 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4012 "@
4013 shlrd %1, %2, %0
4014 shlri %1, %2, %0"
4015 [(set_attr "type" "arith_media")])
4016
4017 (define_insn "*lshrdisi3_media"
4018 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4019 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4020 (match_operand:DI 2 "const_int_operand" "n")))]
4021 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4022 "shlri.l %1, %2, %0"
4023 [(set_attr "type" "arith_media")
4024 (set_attr "highpart" "ignore")])
4025
4026 (define_expand "lshrdi3"
4027 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4028 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4029 (match_operand:DI 2 "immediate_operand" "")))
4030 (clobber (reg:SI T_REG))])]
4031 ""
4032 "
4033 {
4034 if (TARGET_SHMEDIA)
4035 {
4036 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4037 DONE;
4038 }
4039 if (GET_CODE (operands[2]) != CONST_INT
4040 || INTVAL (operands[2]) != 1)
4041 FAIL;
4042 }")
4043
4044 ;; ??? This should be a define expand.
4045
4046 (define_insn "ashrdi3_k"
4047 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4048 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4049 (const_int 1)))
4050 (clobber (reg:SI T_REG))]
4051 "TARGET_SH1"
4052 "shar %S0\;rotcr %R0"
4053 [(set_attr "length" "4")
4054 (set_attr "type" "arith")])
4055
4056 (define_insn "ashrdi3_media"
4057 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4058 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4059 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4060 "TARGET_SHMEDIA
4061 && (arith_reg_dest (operands[0], DImode)
4062 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4063 "@
4064 shard %1, %2, %0
4065 shari %1, %2, %0"
4066 [(set_attr "type" "arith_media")])
4067
4068 (define_insn "*ashrdisi3_media"
4069 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4070 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4071 (match_operand:DI 2 "const_int_operand" "n")))]
4072 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4073 "shari.l %1, %2, %0"
4074 [(set_attr "type" "arith_media")
4075 (set_attr "highpart" "ignore")])
4076
4077 (define_insn "ashrdisi3_media_high"
4078 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4079 (truncate:SI
4080 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4081 (match_operand:DI 2 "const_int_operand" "n"))))]
4082 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4083 "shari %1, %2, %0"
4084 [(set_attr "type" "arith_media")])
4085
4086 (define_insn "ashrdisi3_media_opaque"
4087 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4088 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4089 (match_operand:DI 2 "const_int_operand" "n")]
4090 UNSPEC_ASHIFTRT))]
4091 "TARGET_SHMEDIA"
4092 "shari %1, %2, %0"
4093 [(set_attr "type" "arith_media")])
4094
4095 (define_expand "ashrdi3"
4096 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4097 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4098 (match_operand:DI 2 "immediate_operand" "")))
4099 (clobber (reg:SI T_REG))])]
4100 ""
4101 "
4102 {
4103 if (TARGET_SHMEDIA)
4104 {
4105 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4106 DONE;
4107 }
4108 if (GET_CODE (operands[2]) != CONST_INT
4109 || INTVAL (operands[2]) != 1)
4110 FAIL;
4111 }")
4112
4113 ;; combined left/right shift
4114
4115 (define_split
4116 [(set (match_operand:SI 0 "register_operand" "")
4117 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4118 (match_operand:SI 2 "const_int_operand" ""))
4119 (match_operand:SI 3 "const_int_operand" "")))]
4120 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4121 [(use (reg:SI R0_REG))]
4122 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4123 DONE;")
4124
4125 (define_split
4126 [(set (match_operand:SI 0 "register_operand" "")
4127 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4128 (match_operand:SI 2 "const_int_operand" ""))
4129 (match_operand:SI 3 "const_int_operand" "")))
4130 (clobber (reg:SI T_REG))]
4131 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4132 [(use (reg:SI R0_REG))]
4133 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4134 DONE;")
4135
4136 (define_insn ""
4137 [(set (match_operand:SI 0 "register_operand" "=r")
4138 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4139 (match_operand:SI 2 "const_int_operand" "n"))
4140 (match_operand:SI 3 "const_int_operand" "n")))
4141 (clobber (reg:SI T_REG))]
4142 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4143 "#"
4144 [(set (attr "length")
4145 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4146 (const_string "4")
4147 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4148 (const_string "6")
4149 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4150 (const_string "8")
4151 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4152 (const_string "10")
4153 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4154 (const_string "12")
4155 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4156 (const_string "14")
4157 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4158 (const_string "16")]
4159 (const_string "18")))
4160 (set_attr "type" "arith")])
4161
4162 (define_insn ""
4163 [(set (match_operand:SI 0 "register_operand" "=z")
4164 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4165 (match_operand:SI 2 "const_int_operand" "n"))
4166 (match_operand:SI 3 "const_int_operand" "n")))
4167 (clobber (reg:SI T_REG))]
4168 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4169 "#"
4170 [(set (attr "length")
4171 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4172 (const_string "4")
4173 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4174 (const_string "6")
4175 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4176 (const_string "8")]
4177 (const_string "10")))
4178 (set_attr "type" "arith")])
4179
4180 ;; shift left / and combination with a scratch register: The combine pass
4181 ;; does not accept the individual instructions, even though they are
4182 ;; cheap. But it needs a precise description so that it is usable after
4183 ;; reload.
4184 (define_insn "and_shl_scratch"
4185 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4186 (lshiftrt:SI
4187 (ashift:SI
4188 (and:SI
4189 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4190 (match_operand:SI 2 "const_int_operand" "N,n"))
4191 (match_operand:SI 3 "" "0,r"))
4192 (match_operand:SI 4 "const_int_operand" "n,n"))
4193 (match_operand:SI 5 "const_int_operand" "n,n")))
4194 (clobber (reg:SI T_REG))]
4195 "TARGET_SH1"
4196 "#"
4197 [(set (attr "length")
4198 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4199 (const_string "4")
4200 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4201 (const_string "6")
4202 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4203 (const_string "8")
4204 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4205 (const_string "10")]
4206 (const_string "12")))
4207 (set_attr "type" "arith")])
4208
4209 (define_split
4210 [(set (match_operand:SI 0 "register_operand" "")
4211 (lshiftrt:SI
4212 (ashift:SI
4213 (and:SI
4214 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4215 (match_operand:SI 2 "const_int_operand" ""))
4216 (match_operand:SI 3 "register_operand" ""))
4217 (match_operand:SI 4 "const_int_operand" ""))
4218 (match_operand:SI 5 "const_int_operand" "")))
4219 (clobber (reg:SI T_REG))]
4220 "TARGET_SH1"
4221 [(use (reg:SI R0_REG))]
4222 "
4223 {
4224 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4225
4226 if (INTVAL (operands[2]))
4227 {
4228 gen_shifty_op (LSHIFTRT, operands);
4229 }
4230 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4231 operands[2] = operands[4];
4232 gen_shifty_op (ASHIFT, operands);
4233 if (INTVAL (operands[5]))
4234 {
4235 operands[2] = operands[5];
4236 gen_shifty_op (LSHIFTRT, operands);
4237 }
4238 DONE;
4239 }")
4240
4241 ;; signed left/right shift combination.
4242 (define_split
4243 [(set (match_operand:SI 0 "register_operand" "")
4244 (sign_extract:SI
4245 (ashift:SI (match_operand:SI 1 "register_operand" "")
4246 (match_operand:SI 2 "const_int_operand" ""))
4247 (match_operand:SI 3 "const_int_operand" "")
4248 (const_int 0)))
4249 (clobber (reg:SI T_REG))]
4250 "TARGET_SH1"
4251 [(use (reg:SI R0_REG))]
4252 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4253 DONE;")
4254
4255 (define_insn "shl_sext_ext"
4256 [(set (match_operand:SI 0 "register_operand" "=r")
4257 (sign_extract:SI
4258 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4259 (match_operand:SI 2 "const_int_operand" "n"))
4260 (match_operand:SI 3 "const_int_operand" "n")
4261 (const_int 0)))
4262 (clobber (reg:SI T_REG))]
4263 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4264 "#"
4265 [(set (attr "length")
4266 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4267 (const_string "2")
4268 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4269 (const_string "4")
4270 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4271 (const_string "6")
4272 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4273 (const_string "8")
4274 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4275 (const_string "10")
4276 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4277 (const_string "12")
4278 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4279 (const_string "14")
4280 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4281 (const_string "16")]
4282 (const_string "18")))
4283 (set_attr "type" "arith")])
4284
4285 (define_insn "shl_sext_sub"
4286 [(set (match_operand:SI 0 "register_operand" "=z")
4287 (sign_extract:SI
4288 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4289 (match_operand:SI 2 "const_int_operand" "n"))
4290 (match_operand:SI 3 "const_int_operand" "n")
4291 (const_int 0)))
4292 (clobber (reg:SI T_REG))]
4293 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4294 "#"
4295 [(set (attr "length")
4296 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4297 (const_string "6")
4298 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4299 (const_string "8")
4300 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4301 (const_string "10")
4302 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4303 (const_string "12")]
4304 (const_string "14")))
4305 (set_attr "type" "arith")])
4306
4307 ;; These patterns are found in expansions of DImode shifts by 16, and
4308 ;; allow the xtrct instruction to be generated from C source.
4309
4310 (define_insn "xtrct_left"
4311 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4312 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4313 (const_int 16))
4314 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4315 (const_int 16))))]
4316 "TARGET_SH1"
4317 "xtrct %1,%0"
4318 [(set_attr "type" "arith")])
4319
4320 (define_insn "xtrct_right"
4321 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4322 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4323 (const_int 16))
4324 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4325 (const_int 16))))]
4326 "TARGET_SH1"
4327 "xtrct %2,%0"
4328 [(set_attr "type" "arith")])
4329
4330 ;; -------------------------------------------------------------------------
4331 ;; Unary arithmetic
4332 ;; -------------------------------------------------------------------------
4333
4334 (define_insn "negc"
4335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336 (neg:SI (plus:SI (reg:SI T_REG)
4337 (match_operand:SI 1 "arith_reg_operand" "r"))))
4338 (set (reg:SI T_REG)
4339 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4340 (const_int 0)))]
4341 "TARGET_SH1"
4342 "negc %1,%0"
4343 [(set_attr "type" "arith")])
4344
4345 (define_insn "*negdi_media"
4346 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4347 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4348 "TARGET_SHMEDIA"
4349 "sub r63, %1, %0"
4350 [(set_attr "type" "arith_media")])
4351
4352 (define_expand "negdi2"
4353 [(set (match_operand:DI 0 "arith_reg_operand" "")
4354 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4355 ""
4356 "
4357 {
4358 if (TARGET_SH1)
4359 {
4360 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4361 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4362
4363 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4364 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4365
4366 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4367 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4368
4369 emit_insn (gen_clrt ());
4370 emit_insn (gen_negc (low_dst, low_src));
4371 emit_insn (gen_negc (high_dst, high_src));
4372 DONE;
4373 }
4374 }")
4375
4376 (define_insn "negsi2"
4377 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4378 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4379 "TARGET_SH1"
4380 "neg %1,%0"
4381 [(set_attr "type" "arith")])
4382
4383 (define_insn "one_cmplsi2"
4384 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4385 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4386 "TARGET_SH1"
4387 "not %1,%0"
4388 [(set_attr "type" "arith")])
4389
4390 (define_expand "one_cmpldi2"
4391 [(set (match_operand:DI 0 "arith_reg_dest" "")
4392 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4393 (const_int -1)))]
4394 "TARGET_SHMEDIA" "")
4395
4396 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4397 This can be used as some kind of conditional execution, which is useful
4398 for abs. */
4399 (define_split
4400 [(set (match_operand:SI 0 "arith_reg_dest" "")
4401 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4402 (match_operand:SI 1 "arith_reg_operand" ""))
4403 (reg:SI T_REG)))]
4404 "TARGET_HARD_SH4"
4405 [(const_int 0)]
4406 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4407 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4408 DONE;")
4409
4410 (define_insn "cneg"
4411 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4412 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4413 (match_operand:SI 1 "arith_reg_operand" "0")
4414 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4415 "TARGET_HARD_SH4"
4416 "bf 0f\;neg %2,%0\\n0:"
4417 [(set_attr "type" "arith") ;; poor approximation
4418 (set_attr "length" "4")])
4419
4420 \f
4421 ;; -------------------------------------------------------------------------
4422 ;; Zero extension instructions
4423 ;; -------------------------------------------------------------------------
4424
4425 (define_insn "zero_extendsidi2"
4426 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4427 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4428 "TARGET_SHMEDIA"
4429 "addz.l %1, r63, %0"
4430 [(set_attr "type" "arith_media")
4431 (set_attr "highpart" "extend")])
4432
4433 (define_insn "zero_extendhidi2"
4434 [(set (match_operand:DI 0 "register_operand" "=r,r")
4435 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4436 "TARGET_SHMEDIA"
4437 "@
4438 #
4439 ld%M1.uw %m1, %0"
4440 [(set_attr "type" "*,load_media")
4441 (set (attr "highpart")
4442 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4443 (const_string "user")]
4444 (const_string "ignore")))])
4445
4446 (define_split
4447 [(set (match_operand:DI 0 "register_operand" "")
4448 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4449 "TARGET_SHMEDIA && reload_completed"
4450 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4451 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4452 "
4453 {
4454 if (GET_CODE (operands[1]) == TRUNCATE)
4455 operands[1] = XEXP (operands[1], 0);
4456 }")
4457
4458 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4459 ;; reload the entire truncate expression.
4460 (define_insn_and_split "*loaddi_trunc"
4461 [(set (match_operand 0 "any_register_operand" "=r")
4462 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4463 "TARGET_SHMEDIA && reload_completed"
4464 "#"
4465 "TARGET_SHMEDIA && reload_completed"
4466 [(set (match_dup 0) (match_dup 1))]
4467 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4468
4469 (define_insn "zero_extendqidi2"
4470 [(set (match_operand:DI 0 "register_operand" "=r,r")
4471 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4472 "TARGET_SHMEDIA"
4473 "@
4474 andi %1, 255, %0
4475 ld%M1.ub %m1, %0"
4476 [(set_attr "type" "arith_media,load_media")
4477 (set (attr "highpart")
4478 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4479 (const_string "user")]
4480 (const_string "ignore")))])
4481
4482 (define_expand "zero_extendhisi2"
4483 [(set (match_operand:SI 0 "arith_reg_operand" "")
4484 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4485 ""
4486 "
4487 {
4488 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4489 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4490 }")
4491
4492 (define_insn "*zero_extendhisi2_compact"
4493 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4494 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4495 "TARGET_SH1"
4496 "extu.w %1,%0"
4497 [(set_attr "type" "arith")])
4498
4499 (define_insn "*zero_extendhisi2_media"
4500 [(set (match_operand:SI 0 "register_operand" "=r,r")
4501 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4502 "TARGET_SHMEDIA"
4503 "@
4504 #
4505 ld%M1.uw %m1, %0"
4506 [(set_attr "type" "arith_media,load_media")
4507 (set (attr "highpart")
4508 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4509 (const_string "user")]
4510 (const_string "ignore")))])
4511
4512 (define_split
4513 [(set (match_operand:SI 0 "register_operand" "")
4514 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4515 "TARGET_SHMEDIA && reload_completed"
4516 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4517 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4518 "
4519 {
4520 rtx op1 = operands[1];
4521
4522 if (GET_CODE (op1) == TRUNCATE)
4523 op1 = XEXP (op1, 0);
4524 operands[2]
4525 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4526 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4527 }")
4528
4529 (define_expand "zero_extendqisi2"
4530 [(set (match_operand:SI 0 "arith_reg_operand" "")
4531 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4532 ""
4533 "
4534 {
4535 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4536 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4537 }")
4538
4539 (define_insn "*zero_extendqisi2_compact"
4540 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4541 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4542 "TARGET_SH1"
4543 "extu.b %1,%0"
4544 [(set_attr "type" "arith")])
4545
4546 (define_insn "*zero_extendqisi2_media"
4547 [(set (match_operand:SI 0 "register_operand" "=r,r")
4548 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4549 "TARGET_SHMEDIA"
4550 "@
4551 andi %1, 255, %0
4552 ld%M1.ub %m1, %0"
4553 [(set_attr "type" "arith_media,load_media")
4554 (set (attr "highpart")
4555 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4556 (const_string "user")]
4557 (const_string "ignore")))])
4558
4559 (define_insn "zero_extendqihi2"
4560 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4561 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4562 "TARGET_SH1"
4563 "extu.b %1,%0"
4564 [(set_attr "type" "arith")])
4565
4566 ;; -------------------------------------------------------------------------
4567 ;; Sign extension instructions
4568 ;; -------------------------------------------------------------------------
4569
4570 ;; ??? This should be a define expand.
4571 ;; ??? Or perhaps it should be dropped?
4572
4573 ;; convert_move generates good code for SH[1-4].
4574 (define_insn "extendsidi2"
4575 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4576 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4577 "TARGET_SHMEDIA"
4578 "@
4579 add.l %1, r63, %0
4580 ld%M1.l %m1, %0
4581 fmov.sl %1, %0"
4582 [(set_attr "type" "arith_media,load_media,fpconv_media")
4583 (set (attr "highpart")
4584 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4585 (const_string "user")]
4586 (const_string "extend")))])
4587
4588 (define_insn "extendhidi2"
4589 [(set (match_operand:DI 0 "register_operand" "=r,r")
4590 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4591 "TARGET_SHMEDIA"
4592 "@
4593 #
4594 ld%M1.w %m1, %0"
4595 [(set_attr "type" "*,load_media")
4596 (set (attr "highpart")
4597 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4598 (const_string "user")]
4599 (const_string "ignore")))])
4600
4601 (define_split
4602 [(set (match_operand:DI 0 "register_operand" "")
4603 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4604 "TARGET_SHMEDIA && reload_completed"
4605 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4606 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4607 "
4608 {
4609 if (GET_CODE (operands[1]) == TRUNCATE)
4610 operands[1] = XEXP (operands[1], 0);
4611 }")
4612
4613 (define_insn "extendqidi2"
4614 [(set (match_operand:DI 0 "register_operand" "=r,r")
4615 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4616 "TARGET_SHMEDIA"
4617 "@
4618 #
4619 ld%M1.b %m1, %0"
4620 [(set_attr "type" "*,load_media")
4621 (set (attr "highpart")
4622 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4623 (const_string "user")]
4624 (const_string "ignore")))])
4625
4626 (define_split
4627 [(set (match_operand:DI 0 "register_operand" "")
4628 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4629 "TARGET_SHMEDIA && reload_completed"
4630 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4631 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4632 "
4633 {
4634 if (GET_CODE (operands[1]) == TRUNCATE)
4635 operands[1] = XEXP (operands[1], 0);
4636 }")
4637
4638 (define_expand "extendhisi2"
4639 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4640 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4641 ""
4642 "")
4643
4644 (define_insn "*extendhisi2_compact"
4645 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4646 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4647 "TARGET_SH1"
4648 "@
4649 exts.w %1,%0
4650 mov.w %1,%0"
4651 [(set_attr "type" "arith,load")])
4652
4653 (define_insn "*extendhisi2_media"
4654 [(set (match_operand:SI 0 "register_operand" "=r,r")
4655 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4656 "TARGET_SHMEDIA"
4657 "@
4658 #
4659 ld%M1.w %m1, %0"
4660 [(set_attr "type" "arith_media,load_media")
4661 (set (attr "highpart")
4662 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4663 (const_string "user")]
4664 (const_string "ignore")))])
4665
4666 (define_split
4667 [(set (match_operand:SI 0 "register_operand" "")
4668 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4669 "TARGET_SHMEDIA && reload_completed"
4670 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4671 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4672 "
4673 {
4674 rtx op1 = operands[1];
4675 if (GET_CODE (op1) == TRUNCATE)
4676 op1 = XEXP (op1, 0);
4677 operands[2]
4678 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4679 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4680 }")
4681
4682 (define_expand "extendqisi2"
4683 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4684 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4685 ""
4686 "")
4687
4688 (define_insn "*extendqisi2_compact"
4689 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4690 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4691 "TARGET_SH1"
4692 "@
4693 exts.b %1,%0
4694 mov.b %1,%0"
4695 [(set_attr "type" "arith,load")])
4696
4697 (define_insn "*extendqisi2_media"
4698 [(set (match_operand:SI 0 "register_operand" "=r,r")
4699 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4700 "TARGET_SHMEDIA"
4701 "@
4702 #
4703 ld%M1.b %m1, %0"
4704 [(set_attr "type" "arith_media,load_media")
4705 (set (attr "highpart")
4706 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4707 (const_string "user")]
4708 (const_string "ignore")))])
4709
4710 (define_split
4711 [(set (match_operand:SI 0 "register_operand" "")
4712 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4713 "TARGET_SHMEDIA && reload_completed"
4714 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4715 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4716 "
4717 {
4718 rtx op1 = operands[1];
4719 if (GET_CODE (op1) == TRUNCATE)
4720 op1 = XEXP (op1, 0);
4721 operands[2]
4722 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4723 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4724 }")
4725
4726 (define_insn "extendqihi2"
4727 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4728 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4729 "TARGET_SH1"
4730 "@
4731 exts.b %1,%0
4732 mov.b %1,%0"
4733 [(set_attr "type" "arith,load")])
4734
4735 /* It would seem useful to combine the truncXi patterns into the movXi
4736 patterns, but unary operators are ignored when matching constraints,
4737 so we need separate patterns. */
4738 (define_insn "truncdisi2"
4739 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4740 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4741 "TARGET_SHMEDIA"
4742 "@
4743 add.l %1, r63, %0
4744 st%M0.l %m0, %1
4745 fst%M0.s %m0, %T1
4746 fmov.ls %1, %0
4747 fmov.sl %T1, %0
4748 fmov.s %T1, %0"
4749 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4750 (set (attr "highpart")
4751 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4752 (const_string "user")]
4753 (const_string "extend")))])
4754
4755 (define_insn "truncdihi2"
4756 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4757 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4758 "TARGET_SHMEDIA"
4759 "@
4760 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4761 st%M0.w %m0, %1"
4762 [(set_attr "type" "arith_media,store_media")
4763 (set_attr "length" "8,4")
4764 (set (attr "highpart")
4765 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4766 (const_string "user")]
4767 (const_string "extend")))])
4768
4769 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4770 ; Because we use zero extension, we can't provide signed QImode compares
4771 ; using a simple compare or conditional branch insn.
4772 (define_insn "truncdiqi2"
4773 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4774 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4775 "TARGET_SHMEDIA"
4776 "@
4777 andi %1, 255, %0
4778 st%M0.b %m0, %1"
4779 [(set_attr "type" "arith_media,store")
4780 (set (attr "highpart")
4781 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4782 (const_string "user")]
4783 (const_string "extend")))])
4784 ;; -------------------------------------------------------------------------
4785 ;; Move instructions
4786 ;; -------------------------------------------------------------------------
4787
4788 ;; define push and pop so it is easy for sh.c
4789 ;; We can't use push and pop on SHcompact because the stack must always
4790 ;; be 8-byte aligned.
4791
4792 (define_expand "push"
4793 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4794 (match_operand:SI 0 "register_operand" "r,l,x"))]
4795 "TARGET_SH1 && ! TARGET_SH5"
4796 "")
4797
4798 (define_expand "pop"
4799 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4800 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4801 "TARGET_SH1 && ! TARGET_SH5"
4802 "")
4803
4804 (define_expand "push_e"
4805 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4806 (match_operand:SF 0 "" ""))
4807 (use (reg:PSI FPSCR_REG))
4808 (clobber (scratch:SI))])]
4809 "TARGET_SH1 && ! TARGET_SH5"
4810 "")
4811
4812 (define_insn "push_fpul"
4813 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4814 "TARGET_SH2E && ! TARGET_SH5"
4815 "sts.l fpul,@-r15"
4816 [(set_attr "type" "fstore")
4817 (set_attr "late_fp_use" "yes")
4818 (set_attr "hit_stack" "yes")])
4819
4820 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4821 ;; so use that.
4822 (define_expand "push_4"
4823 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4824 (match_operand:DF 0 "" ""))
4825 (use (reg:PSI FPSCR_REG))
4826 (clobber (scratch:SI))])]
4827 "TARGET_SH1 && ! TARGET_SH5"
4828 "")
4829
4830 (define_expand "pop_e"
4831 [(parallel [(set (match_operand:SF 0 "" "")
4832 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4833 (use (reg:PSI FPSCR_REG))
4834 (clobber (scratch:SI))])]
4835 "TARGET_SH1 && ! TARGET_SH5"
4836 "")
4837
4838 (define_insn "pop_fpul"
4839 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4840 "TARGET_SH2E && ! TARGET_SH5"
4841 "lds.l @r15+,fpul"
4842 [(set_attr "type" "load")
4843 (set_attr "hit_stack" "yes")])
4844
4845 (define_expand "pop_4"
4846 [(parallel [(set (match_operand:DF 0 "" "")
4847 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4848 (use (reg:PSI FPSCR_REG))
4849 (clobber (scratch:SI))])]
4850 "TARGET_SH1 && ! TARGET_SH5"
4851 "")
4852
4853 (define_expand "push_fpscr"
4854 [(const_int 0)]
4855 "TARGET_SH2E"
4856 "
4857 {
4858 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4859 gen_rtx_PRE_DEC (Pmode,
4860 stack_pointer_rtx)),
4861 get_fpscr_rtx ()));
4862 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4863 DONE;
4864 }")
4865
4866 (define_expand "pop_fpscr"
4867 [(const_int 0)]
4868 "TARGET_SH2E"
4869 "
4870 {
4871 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4872 gen_frame_mem (PSImode,
4873 gen_rtx_POST_INC (Pmode,
4874 stack_pointer_rtx))));
4875 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4876 DONE;
4877 }")
4878
4879 ;; These two patterns can happen as the result of optimization, when
4880 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4881 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4882
4883 (define_insn "clrt"
4884 [(set (reg:SI T_REG) (const_int 0))]
4885 "TARGET_SH1"
4886 "clrt")
4887
4888 (define_insn "sett"
4889 [(set (reg:SI T_REG) (const_int 1))]
4890 "TARGET_SH1"
4891 "sett")
4892
4893 ;; t/r must come after r/r, lest reload will try to reload stuff like
4894 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4895 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4896 (define_insn "movsi_i"
4897 [(set (match_operand:SI 0 "general_movdst_operand"
4898 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4899 (match_operand:SI 1 "general_movsrc_operand"
4900 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4901 "TARGET_SH1
4902 && ! TARGET_SH2E
4903 && ! TARGET_SH2A
4904 && (register_operand (operands[0], SImode)
4905 || register_operand (operands[1], SImode))"
4906 "@
4907 mov.l %1,%0
4908 mov %1,%0
4909 mov %1,%0
4910 cmp/pl %1
4911 mov.l %1,%0
4912 sts %1,%0
4913 sts %1,%0
4914 movt %0
4915 mov.l %1,%0
4916 sts.l %1,%0
4917 sts.l %1,%0
4918 lds %1,%0
4919 lds %1,%0
4920 lds.l %1,%0
4921 lds.l %1,%0
4922 fake %1,%0"
4923 [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4924 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4925
4926 ;; t/r must come after r/r, lest reload will try to reload stuff like
4927 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4928 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4929 ;; will require a reload.
4930 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4931 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4932 (define_insn "movsi_ie"
4933 [(set (match_operand:SI 0 "general_movdst_operand"
4934 "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4935 (match_operand:SI 1 "general_movsrc_operand"
4936 "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4937 "(TARGET_SH2E || TARGET_SH2A)
4938 && (register_operand (operands[0], SImode)
4939 || register_operand (operands[1], SImode))"
4940 "@
4941 mov.l %1,%0
4942 mov %1,%0
4943 mov %1,%0
4944 movi20 %1,%0
4945 cmp/pl %1
4946 mov.l %1,%0
4947 sts %1,%0
4948 sts %1,%0
4949 movt %0
4950 mov.l %1,%0
4951 sts.l %1,%0
4952 sts.l %1,%0
4953 lds %1,%0
4954 lds %1,%0
4955 lds.l %1,%0
4956 lds.l %1,%0
4957 lds.l %1,%0
4958 sts.l %1,%0
4959 fake %1,%0
4960 lds %1,%0
4961 sts %1,%0
4962 fsts fpul,%0
4963 flds %1,fpul
4964 fmov %1,%0
4965 ! move optimized away"
4966 [(set_attr "type" "pcload_si,move,movi8,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4967 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4968 (set_attr_alternative "length"
4969 [(const_int 2)
4970 (const_int 2)
4971 (const_int 2)
4972 (const_int 4)
4973 (const_int 2)
4974 (if_then_else
4975 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4976 (const_int 4) (const_int 2))
4977 (const_int 2)
4978 (const_int 2)
4979 (const_int 2)
4980 (if_then_else
4981 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4982 (const_int 4) (const_int 2))
4983 (const_int 2)
4984 (const_int 2)
4985 (const_int 2)
4986 (const_int 2)
4987 (const_int 2)
4988 (const_int 2)
4989 (const_int 2)
4990 (const_int 2)
4991 (const_int 2)
4992 (const_int 2)
4993 (const_int 2)
4994 (const_int 2)
4995 (const_int 2)
4996 (const_int 2)
4997 (const_int 0)])])
4998
4999 (define_insn "movsi_i_lowpart"
5000 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5001 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5002 "TARGET_SH1
5003 && (register_operand (operands[0], SImode)
5004 || register_operand (operands[1], SImode))"
5005 "@
5006 mov.l %1,%0
5007 mov %1,%0
5008 mov %1,%0
5009 mov.l %1,%0
5010 sts %1,%0
5011 sts %1,%0
5012 movt %0
5013 mov.l %1,%0
5014 fake %1,%0"
5015 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5016
5017 (define_insn_and_split "load_ra"
5018 [(set (match_operand:SI 0 "general_movdst_operand" "")
5019 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5020 "TARGET_SH1"
5021 "#"
5022 "&& ! currently_expanding_to_rtl"
5023 [(set (match_dup 0) (match_dup 1))]
5024 "
5025 {
5026 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
5027 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5028 }")
5029
5030 ;; The '?'s in the following constraints may not reflect the time taken
5031 ;; to perform the move. They are there to discourage the use of floating-
5032 ;; point registers for storing integer values.
5033 (define_insn "*movsi_media"
5034 [(set (match_operand:SI 0 "general_movdst_operand"
5035 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5036 (match_operand:SI 1 "general_movsrc_operand"
5037 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5038 "TARGET_SHMEDIA_FPU
5039 && (register_operand (operands[0], SImode)
5040 || sh_register_operand (operands[1], SImode)
5041 || GET_CODE (operands[1]) == TRUNCATE)"
5042 "@
5043 add.l %1, r63, %0
5044 movi %1, %0
5045 #
5046 ld%M1.l %m1, %0
5047 st%M0.l %m0, %N1
5048 fld%M1.s %m1, %0
5049 fst%M0.s %m0, %1
5050 fmov.ls %N1, %0
5051 fmov.sl %1, %0
5052 fmov.s %1, %0
5053 ptabs %1, %0
5054 gettr %1, %0
5055 pt %1, %0"
5056 [(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")
5057 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5058 (set (attr "highpart")
5059 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5060 (const_string "user")]
5061 (const_string "ignore")))])
5062
5063 (define_insn "*movsi_media_nofpu"
5064 [(set (match_operand:SI 0 "general_movdst_operand"
5065 "=r,r,r,r,m,*b,r,*b")
5066 (match_operand:SI 1 "general_movsrc_operand"
5067 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5068 "TARGET_SHMEDIA
5069 && (register_operand (operands[0], SImode)
5070 || sh_register_operand (operands[1], SImode)
5071 || GET_CODE (operands[1]) == TRUNCATE)"
5072 "@
5073 add.l %1, r63, %0
5074 movi %1, %0
5075 #
5076 ld%M1.l %m1, %0
5077 st%M0.l %m0, %N1
5078 ptabs %1, %0
5079 gettr %1, %0
5080 pt %1, %0"
5081 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5082 (set_attr "length" "4,4,8,4,4,4,4,12")
5083 (set (attr "highpart")
5084 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5085 (const_string "user")]
5086 (const_string "ignore")))])
5087
5088 (define_expand "movsi_const"
5089 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5090 (const:SI (sign_extend:SI
5091 (truncate:HI
5092 (ashiftrt:SI
5093 (match_operand:DI 1 "immediate_operand" "s")
5094 (const_int 16))))))
5095 (set (match_dup 0)
5096 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5097 (const:SI
5098 (zero_extend:SI
5099 (truncate:HI (match_dup 1))))))]
5100 "TARGET_SHMEDIA && reload_completed
5101 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5102 "
5103 {
5104 if (GET_CODE (operands[1]) == LABEL_REF
5105 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5106 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5107 else if (GOTOFF_P (operands[1]))
5108 {
5109 rtx unspec = XEXP (operands[1], 0);
5110
5111 if (! UNSPEC_GOTOFF_P (unspec))
5112 {
5113 unspec = XEXP (unspec, 0);
5114 if (! UNSPEC_GOTOFF_P (unspec))
5115 abort ();
5116 }
5117 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5118 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5119 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5120 }
5121 }")
5122
5123 (define_expand "movsi_const_16bit"
5124 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5125 (const:SI (sign_extend:SI
5126 (truncate:HI
5127 (match_operand:DI 1 "immediate_operand" "s")))))]
5128 "TARGET_SHMEDIA && flag_pic && reload_completed
5129 && GET_CODE (operands[1]) == SYMBOL_REF"
5130 "")
5131
5132 (define_split
5133 [(set (match_operand:SI 0 "arith_reg_dest" "")
5134 (match_operand:SI 1 "immediate_operand" ""))]
5135 "TARGET_SHMEDIA && reload_completed
5136 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5137 [(const_int 0)]
5138 "
5139 {
5140 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5141
5142 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5143
5144 DONE;
5145 }")
5146
5147 (define_split
5148 [(set (match_operand:SI 0 "register_operand" "")
5149 (match_operand:SI 1 "immediate_operand" ""))]
5150 "TARGET_SHMEDIA && reload_completed
5151 && ((GET_CODE (operands[1]) == CONST_INT
5152 && ! satisfies_constraint_I16 (operands[1]))
5153 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5154 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5155
5156 (define_expand "movsi"
5157 [(set (match_operand:SI 0 "general_movdst_operand" "")
5158 (match_operand:SI 1 "general_movsrc_operand" ""))]
5159 ""
5160 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5161
5162 (define_expand "ic_invalidate_line"
5163 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5164 (match_dup 1)] UNSPEC_ICACHE)
5165 (clobber (scratch:SI))])]
5166 "TARGET_HARD_SH4 || TARGET_SH5"
5167 "
5168 {
5169 if (TARGET_SHMEDIA)
5170 {
5171 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5172 DONE;
5173 }
5174 else if (TARGET_SHCOMPACT)
5175 {
5176 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5177 operands[1] = force_reg (Pmode, operands[1]);
5178 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5179 DONE;
5180 }
5181 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5182 {
5183 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5184 DONE;
5185 }
5186 operands[0] = force_reg (Pmode, operands[0]);
5187 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5188 Pmode)));
5189 }")
5190
5191 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5192 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5193 ;; the requirement *1*00 for associative address writes. The alignment of
5194 ;; %0 implies that its least significant bit is cleared,
5195 ;; thus we clear the V bit of a matching entry if there is one.
5196 (define_insn "ic_invalidate_line_i"
5197 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5198 (match_operand:SI 1 "register_operand" "r")]
5199 UNSPEC_ICACHE)
5200 (clobber (match_scratch:SI 2 "=&r"))]
5201 "TARGET_HARD_SH4"
5202 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5203 [(set_attr "length" "8")
5204 (set_attr "type" "cwb")])
5205
5206 (define_insn "ic_invalidate_line_sh4a"
5207 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5208 UNSPEC_ICACHE)]
5209 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5210 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5211 [(set_attr "length" "16")
5212 (set_attr "type" "cwb")])
5213
5214 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5215 ;; an add in the code that calculates the address.
5216 (define_insn "ic_invalidate_line_media"
5217 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5218 UNSPEC_ICACHE)]
5219 "TARGET_SHMEDIA"
5220 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5221 [(set_attr "length" "16")
5222 (set_attr "type" "invalidate_line_media")])
5223
5224 (define_insn "ic_invalidate_line_compact"
5225 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5226 (match_operand:SI 1 "register_operand" "r")]
5227 UNSPEC_ICACHE)
5228 (clobber (reg:SI PR_REG))]
5229 "TARGET_SHCOMPACT"
5230 "jsr @%1%#"
5231 [(set_attr "type" "sfunc")
5232 (set_attr "needs_delay_slot" "yes")])
5233
5234 (define_expand "initialize_trampoline"
5235 [(match_operand:SI 0 "" "")
5236 (match_operand:SI 1 "" "")
5237 (match_operand:SI 2 "" "")]
5238 "TARGET_SHCOMPACT"
5239 "
5240 {
5241 rtx sfun, tramp;
5242
5243 tramp = force_reg (Pmode, operands[0]);
5244 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5245 SFUNC_STATIC));
5246 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5247 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5248
5249 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5250 DONE;
5251 }")
5252
5253 (define_insn "initialize_trampoline_compact"
5254 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5255 (match_operand:SI 1 "register_operand" "r")
5256 (reg:SI R2_REG) (reg:SI R3_REG)]
5257 UNSPEC_INIT_TRAMP)
5258
5259 (clobber (reg:SI PR_REG))]
5260 "TARGET_SHCOMPACT"
5261 "jsr @%1%#"
5262 [(set_attr "type" "sfunc")
5263 (set_attr "needs_delay_slot" "yes")])
5264
5265 (define_insn "movqi_i"
5266 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5267 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5268 "TARGET_SH1
5269 && (arith_reg_operand (operands[0], QImode)
5270 || arith_reg_operand (operands[1], QImode))"
5271 "@
5272 mov %1,%0
5273 mov %1,%0
5274 mov.b %1,%0
5275 mov.b %1,%0
5276 movt %0
5277 sts %1,%0
5278 lds %1,%0"
5279 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5280
5281 (define_insn "*movqi_media"
5282 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5283 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5284 "TARGET_SHMEDIA
5285 && (arith_reg_operand (operands[0], QImode)
5286 || extend_reg_or_0_operand (operands[1], QImode))"
5287 "@
5288 add.l %1, r63, %0
5289 movi %1, %0
5290 ld%M1.ub %m1, %0
5291 st%M0.b %m0, %N1"
5292 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5293 (set (attr "highpart")
5294 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5295 (const_string "user")]
5296 (const_string "ignore")))])
5297
5298 (define_expand "movqi"
5299 [(set (match_operand:QI 0 "general_operand" "")
5300 (match_operand:QI 1 "general_operand" ""))]
5301 ""
5302 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5303
5304 (define_expand "reload_inqi"
5305 [(set (match_operand:SI 2 "" "=&r")
5306 (match_operand:QI 1 "inqhi_operand" ""))
5307 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5308 (truncate:QI (match_dup 3)))]
5309 "TARGET_SHMEDIA"
5310 "
5311 {
5312 rtx inner = XEXP (operands[1], 0);
5313 int regno = REGNO (inner);
5314
5315 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5316 operands[1] = gen_rtx_REG (SImode, regno);
5317 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5318 }")
5319
5320 /* When storing r0, we have to avoid reg+reg addressing. */
5321 (define_insn "movhi_i"
5322 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5323 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5324 "TARGET_SH1
5325 && (arith_reg_operand (operands[0], HImode)
5326 || arith_reg_operand (operands[1], HImode))
5327 && (GET_CODE (operands[0]) != MEM
5328 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5329 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5330 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5331 "@
5332 mov.w %1,%0
5333 mov %1,%0
5334 mov.w %1,%0
5335 movt %0
5336 mov.w %1,%0
5337 sts %1,%0
5338 lds %1,%0
5339 fake %1,%0"
5340 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5341
5342 (define_insn "*movhi_media"
5343 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5344 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5345 "TARGET_SHMEDIA
5346 && (arith_reg_operand (operands[0], HImode)
5347 || arith_reg_or_0_operand (operands[1], HImode))"
5348 "@
5349 add.l %1, r63, %0
5350 movi %1, %0
5351 #
5352 ld%M1.w %m1, %0
5353 st%M0.w %m0, %N1"
5354 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5355 (set (attr "highpart")
5356 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5357 (const_string "user")]
5358 (const_string "ignore")))])
5359
5360 (define_split
5361 [(set (match_operand:HI 0 "register_operand" "")
5362 (match_operand:HI 1 "immediate_operand" ""))]
5363 "TARGET_SHMEDIA && reload_completed
5364 && ! satisfies_constraint_I16 (operands[1])"
5365 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5366
5367 (define_expand "movhi"
5368 [(set (match_operand:HI 0 "general_movdst_operand" "")
5369 (match_operand:HI 1 "general_movsrc_operand" ""))]
5370 ""
5371 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5372
5373 (define_expand "reload_inhi"
5374 [(set (match_operand:SI 2 "" "=&r")
5375 (match_operand:HI 1 "inqhi_operand" ""))
5376 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5377 (truncate:HI (match_dup 3)))]
5378 "TARGET_SHMEDIA"
5379 "
5380 {
5381 rtx inner = XEXP (operands[1], 0);
5382 int regno = REGNO (inner);
5383
5384 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5385 operands[1] = gen_rtx_REG (SImode, regno);
5386 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5387 }")
5388
5389 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5390 ;; compiled with -m2 -ml -O3 -funroll-loops
5391 (define_insn "*movdi_i"
5392 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5393 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5394 "TARGET_SH1
5395 && (arith_reg_operand (operands[0], DImode)
5396 || arith_reg_operand (operands[1], DImode))"
5397 "* return output_movedouble (insn, operands, DImode);"
5398 [(set_attr "length" "4")
5399 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5400
5401 ;; If the output is a register and the input is memory or a register, we have
5402 ;; to be careful and see which word needs to be loaded first.
5403
5404 (define_split
5405 [(set (match_operand:DI 0 "general_movdst_operand" "")
5406 (match_operand:DI 1 "general_movsrc_operand" ""))]
5407 "TARGET_SH1 && reload_completed"
5408 [(set (match_dup 2) (match_dup 3))
5409 (set (match_dup 4) (match_dup 5))]
5410 "
5411 {
5412 int regno;
5413
5414 if ((GET_CODE (operands[0]) == MEM
5415 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5416 || (GET_CODE (operands[1]) == MEM
5417 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5418 FAIL;
5419
5420 switch (GET_CODE (operands[0]))
5421 {
5422 case REG:
5423 regno = REGNO (operands[0]);
5424 break;
5425 case SUBREG:
5426 regno = subreg_regno (operands[0]);
5427 break;
5428 case MEM:
5429 regno = -1;
5430 break;
5431 default:
5432 gcc_unreachable ();
5433 }
5434
5435 if (regno == -1
5436 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5437 {
5438 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5439 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5440 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5441 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5442 }
5443 else
5444 {
5445 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5446 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5447 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5448 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5449 }
5450
5451 if (operands[2] == 0 || operands[3] == 0
5452 || operands[4] == 0 || operands[5] == 0)
5453 FAIL;
5454 }")
5455
5456 ;; The '?'s in the following constraints may not reflect the time taken
5457 ;; to perform the move. They are there to discourage the use of floating-
5458 ;; point registers for storing integer values.
5459 (define_insn "*movdi_media"
5460 [(set (match_operand:DI 0 "general_movdst_operand"
5461 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5462 (match_operand:DI 1 "general_movsrc_operand"
5463 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5464 "TARGET_SHMEDIA_FPU
5465 && (register_operand (operands[0], DImode)
5466 || sh_register_operand (operands[1], DImode))"
5467 "@
5468 add %1, r63, %0
5469 movi %1, %0
5470 #
5471 ld%M1.q %m1, %0
5472 st%M0.q %m0, %N1
5473 fld%M1.d %m1, %0
5474 fst%M0.d %m0, %1
5475 fmov.qd %N1, %0
5476 fmov.dq %1, %0
5477 fmov.d %1, %0
5478 ptabs %1, %0
5479 gettr %1, %0
5480 pt %1, %0"
5481 [(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")
5482 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5483
5484 (define_insn "*movdi_media_nofpu"
5485 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5486 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5487 "TARGET_SHMEDIA
5488 && (register_operand (operands[0], DImode)
5489 || sh_register_operand (operands[1], DImode))"
5490 "@
5491 add %1, r63, %0
5492 movi %1, %0
5493 #
5494 ld%M1.q %m1, %0
5495 st%M0.q %m0, %N1
5496 ptabs %1, %0
5497 gettr %1, %0
5498 pt %1, %0"
5499 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5500 (set_attr "length" "4,4,16,4,4,4,4,*")])
5501
5502 (define_insn "*movdi_media_I16"
5503 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5504 (match_operand:DI 1 "const_int_operand" "I16"))]
5505 "TARGET_SHMEDIA && reload_completed"
5506 "movi %1, %0"
5507 [(set_attr "type" "arith_media")
5508 (set_attr "length" "4")])
5509
5510 (define_split
5511 [(set (match_operand:DI 0 "arith_reg_dest" "")
5512 (match_operand:DI 1 "immediate_operand" ""))]
5513 "TARGET_SHMEDIA && reload_completed
5514 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5515 [(set (match_dup 0) (match_dup 1))]
5516 "
5517 {
5518 rtx insn;
5519
5520 if (TARGET_SHMEDIA64)
5521 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5522 else
5523 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5524
5525 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5526
5527 DONE;
5528 }")
5529
5530 (define_expand "movdi_const"
5531 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5532 (const:DI (sign_extend:DI
5533 (truncate:HI
5534 (ashiftrt:DI
5535 (match_operand:DI 1 "immediate_operand" "s")
5536 (const_int 48))))))
5537 (set (match_dup 0)
5538 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5539 (const:DI
5540 (zero_extend:DI
5541 (truncate:HI
5542 (ashiftrt:SI
5543 (match_dup 1)
5544 (const_int 32)))))))
5545 (set (match_dup 0)
5546 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5547 (const:DI
5548 (zero_extend:DI
5549 (truncate:HI
5550 (ashiftrt:SI
5551 (match_dup 1)
5552 (const_int 16)))))))
5553 (set (match_dup 0)
5554 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5555 (const:DI
5556 (zero_extend:DI
5557 (truncate:HI
5558 (match_dup 1))))))]
5559 "TARGET_SHMEDIA64 && reload_completed
5560 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5561 "
5562 {
5563 sh_mark_label (operands[1], 4);
5564 }")
5565
5566 (define_expand "movdi_const_32bit"
5567 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5568 (const:DI (sign_extend:DI
5569 (truncate:HI
5570 (ashiftrt:DI
5571 (match_operand:DI 1 "immediate_operand" "s")
5572 (const_int 16))))))
5573 (set (match_dup 0)
5574 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5575 (const:DI
5576 (zero_extend:DI
5577 (truncate:HI
5578 (match_dup 1))))))]
5579 "TARGET_SHMEDIA32 && reload_completed
5580 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5581 "
5582 {
5583 sh_mark_label (operands[1], 2);
5584 }")
5585
5586 (define_expand "movdi_const_16bit"
5587 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5588 (const:DI (sign_extend:DI
5589 (truncate:HI
5590 (match_operand:DI 1 "immediate_operand" "s")))))]
5591 "TARGET_SHMEDIA && flag_pic && reload_completed
5592 && GET_CODE (operands[1]) == SYMBOL_REF"
5593 "")
5594
5595 (define_split
5596 [(set (match_operand:DI 0 "ext_dest_operand" "")
5597 (match_operand:DI 1 "immediate_operand" ""))]
5598 "TARGET_SHMEDIA && reload_completed
5599 && GET_CODE (operands[1]) == CONST_INT
5600 && ! satisfies_constraint_I16 (operands[1])"
5601 [(set (match_dup 0) (match_dup 2))
5602 (match_dup 1)]
5603 "
5604 {
5605 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5606 unsigned HOST_WIDE_INT low = val;
5607 unsigned HOST_WIDE_INT high = val;
5608 unsigned HOST_WIDE_INT sign;
5609 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5610
5611 /* Zero-extend the 16 least-significant bits. */
5612 low &= 0xffff;
5613
5614 /* Arithmetic shift right the word by 16 bits. */
5615 high >>= 16;
5616 if (GET_CODE (operands[0]) == SUBREG
5617 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5618 {
5619 high &= 0xffff;
5620 high ^= 0x8000;
5621 high -= 0x8000;
5622 }
5623 else
5624 {
5625 sign = 1;
5626 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5627 high ^= sign;
5628 high -= sign;
5629 }
5630 do
5631 {
5632 /* If we can't generate the constant with a two-insn movi / shori
5633 sequence, try some other strategies. */
5634 if (! CONST_OK_FOR_I16 (high))
5635 {
5636 /* Try constant load / left shift. We know VAL != 0. */
5637 val2 = val ^ (val-1);
5638 if (val2 > 0x1ffff)
5639 {
5640 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5641
5642 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5643 || (! CONST_OK_FOR_I16 (high >> 16)
5644 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5645 {
5646 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5647 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5648 GEN_INT (trailing_zeroes));
5649 break;
5650 }
5651 }
5652 /* Try constant load / right shift. */
5653 val2 = (val >> 15) + 1;
5654 if (val2 == (val2 & -val2))
5655 {
5656 int shift = 49 - exact_log2 (val2);
5657
5658 val2 = trunc_int_for_mode (val << shift, DImode);
5659 if (CONST_OK_FOR_I16 (val2))
5660 {
5661 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5662 GEN_INT (shift));
5663 break;
5664 }
5665 }
5666 /* Try mperm.w . */
5667 val2 = val & 0xffff;
5668 if ((val >> 16 & 0xffff) == val2
5669 && (val >> 32 & 0xffff) == val2
5670 && (val >> 48 & 0xffff) == val2)
5671 {
5672 val2 = (HOST_WIDE_INT) val >> 48;
5673 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5674 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5675 break;
5676 }
5677 /* Try movi / mshflo.l */
5678 val2 = (HOST_WIDE_INT) val >> 32;
5679 if (val2 == ((unsigned HOST_WIDE_INT)
5680 trunc_int_for_mode (val, SImode)))
5681 {
5682 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5683 operands[0]);
5684 break;
5685 }
5686 /* Try movi / mshflo.l w/ r63. */
5687 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5688 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5689 {
5690 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5691 const0_rtx);
5692 break;
5693 }
5694 }
5695 val2 = high;
5696 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5697 }
5698 while (0);
5699 operands[2] = GEN_INT (val2);
5700 }")
5701
5702 (define_split
5703 [(set (match_operand:DI 0 "ext_dest_operand" "")
5704 (match_operand:DI 1 "immediate_operand" ""))]
5705 "TARGET_SHMEDIA && reload_completed
5706 && GET_CODE (operands[1]) == CONST_DOUBLE"
5707 [(set (match_dup 0) (match_dup 2))
5708 (set (match_dup 0)
5709 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5710 "
5711 {
5712 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5713 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5714 unsigned HOST_WIDE_INT val = low;
5715 unsigned HOST_WIDE_INT sign;
5716
5717 /* Zero-extend the 16 least-significant bits. */
5718 val &= 0xffff;
5719 operands[1] = GEN_INT (val);
5720
5721 /* Arithmetic shift right the double-word by 16 bits. */
5722 low >>= 16;
5723 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5724 high >>= 16;
5725 sign = 1;
5726 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5727 high ^= sign;
5728 high -= sign;
5729
5730 /* This will only be true if high is a sign-extension of low, i.e.,
5731 it must be either 0 or (unsigned)-1, and be zero iff the
5732 most-significant bit of low is set. */
5733 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5734 operands[2] = GEN_INT (low);
5735 else
5736 operands[2] = immed_double_const (low, high, DImode);
5737 }")
5738
5739 (define_insn "shori_media"
5740 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5741 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5742 (const_int 16))
5743 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5744 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5745 "@
5746 shori %u2, %0
5747 #"
5748 [(set_attr "type" "arith_media,*")])
5749
5750 (define_insn "*shori_media_si"
5751 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5752 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5753 (const_int 16))
5754 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5755 "TARGET_SHMEDIA"
5756 "shori %u2, %0")
5757
5758 (define_expand "movdi"
5759 [(set (match_operand:DI 0 "general_movdst_operand" "")
5760 (match_operand:DI 1 "general_movsrc_operand" ""))]
5761 ""
5762 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5763
5764 (define_insn "movdf_media"
5765 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5766 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5767 "TARGET_SHMEDIA_FPU
5768 && (register_operand (operands[0], DFmode)
5769 || sh_register_operand (operands[1], DFmode))"
5770 "@
5771 fmov.d %1, %0
5772 fmov.qd %N1, %0
5773 fmov.dq %1, %0
5774 add %1, r63, %0
5775 #
5776 fld%M1.d %m1, %0
5777 fst%M0.d %m0, %1
5778 ld%M1.q %m1, %0
5779 st%M0.q %m0, %N1"
5780 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5781
5782 (define_insn "movdf_media_nofpu"
5783 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5784 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5785 "TARGET_SHMEDIA
5786 && (register_operand (operands[0], DFmode)
5787 || sh_register_operand (operands[1], DFmode))"
5788 "@
5789 add %1, r63, %0
5790 #
5791 ld%M1.q %m1, %0
5792 st%M0.q %m0, %N1"
5793 [(set_attr "type" "arith_media,*,load_media,store_media")])
5794
5795 (define_split
5796 [(set (match_operand:DF 0 "arith_reg_dest" "")
5797 (match_operand:DF 1 "immediate_operand" ""))]
5798 "TARGET_SHMEDIA && reload_completed"
5799 [(set (match_dup 3) (match_dup 2))]
5800 "
5801 {
5802 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5803 long values[2];
5804 REAL_VALUE_TYPE value;
5805
5806 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5807 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5808
5809 if (HOST_BITS_PER_WIDE_INT >= 64)
5810 operands[2] = immed_double_const ((unsigned long) values[endian]
5811 | ((HOST_WIDE_INT) values[1 - endian]
5812 << 32), 0, DImode);
5813 else
5814 {
5815 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5816 operands[2] = immed_double_const (values[endian], values[1 - endian],
5817 DImode);
5818 }
5819
5820 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5821 }")
5822
5823 ;; ??? This should be a define expand.
5824
5825 (define_insn "movdf_k"
5826 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5827 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5828 "TARGET_SH1
5829 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5830 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5831 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5832 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5833 && (arith_reg_operand (operands[0], DFmode)
5834 || arith_reg_operand (operands[1], DFmode))"
5835 "* return output_movedouble (insn, operands, DFmode);"
5836 [(set_attr "length" "4")
5837 (set_attr "type" "move,pcload,load,store")])
5838
5839 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5840 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5841 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5842 ;; the d/m/c/X alternative, which is split later into single-precision
5843 ;; instructions. And when not optimizing, no splits are done before fixing
5844 ;; up pcloads, so we need usable length information for that.
5845 (define_insn "movdf_i4"
5846 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5847 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5848 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5849 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5850 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5851 && (arith_reg_operand (operands[0], DFmode)
5852 || arith_reg_operand (operands[1], DFmode))"
5853 "@
5854 fmov %1,%0
5855 #
5856 #
5857 fmov.d %1,%0
5858 fmov.d %1,%0
5859 #
5860 #
5861 #
5862 #
5863 #"
5864 [(set_attr_alternative "length"
5865 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5866 (const_int 4)
5867 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5868 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5869 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5870 (const_int 4)
5871 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5872 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5873 ;; increment or decrement r15 explicitly.
5874 (if_then_else
5875 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5876 (const_int 10) (const_int 8))
5877 (if_then_else
5878 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5879 (const_int 10) (const_int 8))])
5880 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5881 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5882 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5883 (const_string "double")
5884 (const_string "none")))])
5885
5886 ;; Moving DFmode between fp/general registers through memory
5887 ;; (the top of the stack) is faster than moving through fpul even for
5888 ;; little endian. Because the type of an instruction is important for its
5889 ;; scheduling, it is beneficial to split these operations, rather than
5890 ;; emitting them in one single chunk, even if this will expose a stack
5891 ;; use that will prevent scheduling of other stack accesses beyond this
5892 ;; instruction.
5893 (define_split
5894 [(set (match_operand:DF 0 "register_operand" "")
5895 (match_operand:DF 1 "register_operand" ""))
5896 (use (match_operand:PSI 2 "fpscr_operand" ""))
5897 (clobber (match_scratch:SI 3 "=X"))]
5898 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5899 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5900 [(const_int 0)]
5901 "
5902 {
5903 rtx insn, tos;
5904
5905 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5906 {
5907 emit_move_insn (stack_pointer_rtx,
5908 plus_constant (stack_pointer_rtx, -8));
5909 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5910 }
5911 else
5912 tos = gen_tmp_stack_mem (DFmode,
5913 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5914 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5915 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5916 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5917 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5918 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5919 else
5920 tos = gen_tmp_stack_mem (DFmode,
5921 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5922 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5923 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5924 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5925 else
5926 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5927 DONE;
5928 }")
5929
5930 ;; local-alloc sometimes allocates scratch registers even when not required,
5931 ;; so we must be prepared to handle these.
5932
5933 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5934 (define_split
5935 [(set (match_operand:DF 0 "general_movdst_operand" "")
5936 (match_operand:DF 1 "general_movsrc_operand" ""))
5937 (use (match_operand:PSI 2 "fpscr_operand" ""))
5938 (clobber (match_scratch:SI 3 ""))]
5939 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5940 && reload_completed
5941 && true_regnum (operands[0]) < 16
5942 && true_regnum (operands[1]) < 16"
5943 [(set (match_dup 0) (match_dup 1))]
5944 "
5945 {
5946 /* If this was a reg <-> mem operation with base + index reg addressing,
5947 we have to handle this in a special way. */
5948 rtx mem = operands[0];
5949 int store_p = 1;
5950 if (! memory_operand (mem, DFmode))
5951 {
5952 mem = operands[1];
5953 store_p = 0;
5954 }
5955 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5956 mem = SUBREG_REG (mem);
5957 if (GET_CODE (mem) == MEM)
5958 {
5959 rtx addr = XEXP (mem, 0);
5960 if (GET_CODE (addr) == PLUS
5961 && GET_CODE (XEXP (addr, 0)) == REG
5962 && GET_CODE (XEXP (addr, 1)) == REG)
5963 {
5964 int offset;
5965 rtx reg0 = gen_rtx_REG (Pmode, 0);
5966 rtx regop = operands[store_p], word0 ,word1;
5967
5968 if (GET_CODE (regop) == SUBREG)
5969 alter_subreg (&regop);
5970 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5971 offset = 2;
5972 else
5973 offset = 4;
5974 mem = copy_rtx (mem);
5975 PUT_MODE (mem, SImode);
5976 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5977 alter_subreg (&word0);
5978 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5979 alter_subreg (&word1);
5980 if (store_p || ! refers_to_regno_p (REGNO (word0),
5981 REGNO (word0) + 1, addr, 0))
5982 {
5983 emit_insn (store_p
5984 ? gen_movsi_ie (mem, word0)
5985 : gen_movsi_ie (word0, mem));
5986 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5987 mem = copy_rtx (mem);
5988 emit_insn (store_p
5989 ? gen_movsi_ie (mem, word1)
5990 : gen_movsi_ie (word1, mem));
5991 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5992 }
5993 else
5994 {
5995 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5996 emit_insn (gen_movsi_ie (word1, mem));
5997 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5998 mem = copy_rtx (mem);
5999 emit_insn (gen_movsi_ie (word0, mem));
6000 }
6001 DONE;
6002 }
6003 }
6004 }")
6005
6006 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6007 (define_split
6008 [(set (match_operand:DF 0 "register_operand" "")
6009 (match_operand:DF 1 "memory_operand" ""))
6010 (use (match_operand:PSI 2 "fpscr_operand" ""))
6011 (clobber (reg:SI R0_REG))]
6012 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6013 [(parallel [(set (match_dup 0) (match_dup 1))
6014 (use (match_dup 2))
6015 (clobber (scratch:SI))])]
6016 "")
6017
6018 (define_expand "reload_indf__frn"
6019 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6020 (match_operand:DF 1 "immediate_operand" "FQ"))
6021 (use (reg:PSI FPSCR_REG))
6022 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6023 "TARGET_SH1"
6024 "")
6025
6026 (define_expand "reload_outdf__RnFRm"
6027 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6028 (match_operand:DF 1 "register_operand" "af,r"))
6029 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6030 "TARGET_SH1"
6031 "")
6032
6033 ;; Simplify no-op moves.
6034 (define_split
6035 [(set (match_operand:SF 0 "register_operand" "")
6036 (match_operand:SF 1 "register_operand" ""))
6037 (use (match_operand:PSI 2 "fpscr_operand" ""))
6038 (clobber (match_scratch:SI 3 ""))]
6039 "TARGET_SH2E && reload_completed
6040 && true_regnum (operands[0]) == true_regnum (operands[1])"
6041 [(set (match_dup 0) (match_dup 0))]
6042 "")
6043
6044 ;; fmovd substitute post-reload splits
6045 (define_split
6046 [(set (match_operand:DF 0 "register_operand" "")
6047 (match_operand:DF 1 "register_operand" ""))
6048 (use (match_operand:PSI 2 "fpscr_operand" ""))
6049 (clobber (match_scratch:SI 3 ""))]
6050 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6051 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6052 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6053 [(const_int 0)]
6054 "
6055 {
6056 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6057 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6058 gen_rtx_REG (SFmode, src), operands[2]));
6059 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6060 gen_rtx_REG (SFmode, src + 1), operands[2]));
6061 DONE;
6062 }")
6063
6064 (define_split
6065 [(set (match_operand:DF 0 "register_operand" "")
6066 (mem:DF (match_operand:SI 1 "register_operand" "")))
6067 (use (match_operand:PSI 2 "fpscr_operand" ""))
6068 (clobber (match_scratch:SI 3 ""))]
6069 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6070 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6071 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6072 [(const_int 0)]
6073 "
6074 {
6075 int regno = true_regnum (operands[0]);
6076 rtx insn;
6077 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6078 rtx mem2
6079 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6080 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6081 regno + !! TARGET_LITTLE_ENDIAN),
6082 mem2, operands[2]));
6083 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6084 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6085 regno + ! TARGET_LITTLE_ENDIAN),
6086 change_address (mem, SFmode, NULL_RTX),
6087 operands[2]));
6088 DONE;
6089 }")
6090
6091 (define_split
6092 [(set (match_operand:DF 0 "register_operand" "")
6093 (match_operand:DF 1 "memory_operand" ""))
6094 (use (match_operand:PSI 2 "fpscr_operand" ""))
6095 (clobber (match_scratch:SI 3 ""))]
6096 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6097 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6098 [(const_int 0)]
6099 "
6100 {
6101 int regno = true_regnum (operands[0]);
6102 rtx addr, insn, adjust = NULL_RTX;
6103 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6104 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6105 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6106
6107 operands[1] = copy_rtx (mem2);
6108 addr = XEXP (mem2, 0);
6109 if (GET_CODE (addr) != POST_INC)
6110 {
6111 /* If we have to modify the stack pointer, the value that we have
6112 read with post-increment might be modified by an interrupt,
6113 so write it back. */
6114 if (REGNO (addr) == STACK_POINTER_REGNUM)
6115 adjust = gen_push_e (reg0);
6116 else
6117 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6118 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6119 }
6120 addr = XEXP (addr, 0);
6121 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6122 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6123 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6124 if (adjust)
6125 emit_insn (adjust);
6126 else
6127 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6128 DONE;
6129 }")
6130
6131 (define_split
6132 [(set (match_operand:DF 0 "memory_operand" "")
6133 (match_operand:DF 1 "register_operand" ""))
6134 (use (match_operand:PSI 2 "fpscr_operand" ""))
6135 (clobber (match_scratch:SI 3 ""))]
6136 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6137 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6138 [(const_int 0)]
6139 "
6140 {
6141 int regno = true_regnum (operands[1]);
6142 rtx insn, addr, adjust = NULL_RTX;
6143
6144 operands[0] = copy_rtx (operands[0]);
6145 PUT_MODE (operands[0], SFmode);
6146 insn = emit_insn (gen_movsf_ie (operands[0],
6147 gen_rtx_REG (SFmode,
6148 regno + ! TARGET_LITTLE_ENDIAN),
6149 operands[2]));
6150 operands[0] = copy_rtx (operands[0]);
6151 addr = XEXP (operands[0], 0);
6152 if (GET_CODE (addr) != PRE_DEC)
6153 {
6154 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6155 emit_insn_before (adjust, insn);
6156 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6157 }
6158 addr = XEXP (addr, 0);
6159 if (! adjust)
6160 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6161 insn = emit_insn (gen_movsf_ie (operands[0],
6162 gen_rtx_REG (SFmode,
6163 regno + !! TARGET_LITTLE_ENDIAN),
6164 operands[2]));
6165 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6166 DONE;
6167 }")
6168
6169 ;; If the output is a register and the input is memory or a register, we have
6170 ;; to be careful and see which word needs to be loaded first.
6171
6172 (define_split
6173 [(set (match_operand:DF 0 "general_movdst_operand" "")
6174 (match_operand:DF 1 "general_movsrc_operand" ""))]
6175 "TARGET_SH1 && reload_completed"
6176 [(set (match_dup 2) (match_dup 3))
6177 (set (match_dup 4) (match_dup 5))]
6178 "
6179 {
6180 int regno;
6181
6182 if ((GET_CODE (operands[0]) == MEM
6183 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6184 || (GET_CODE (operands[1]) == MEM
6185 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6186 FAIL;
6187
6188 switch (GET_CODE (operands[0]))
6189 {
6190 case REG:
6191 regno = REGNO (operands[0]);
6192 break;
6193 case SUBREG:
6194 regno = subreg_regno (operands[0]);
6195 break;
6196 case MEM:
6197 regno = -1;
6198 break;
6199 default:
6200 gcc_unreachable ();
6201 }
6202
6203 if (regno == -1
6204 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6205 {
6206 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6207 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6208 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6209 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6210 }
6211 else
6212 {
6213 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6214 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6215 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6216 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6217 }
6218
6219 if (operands[2] == 0 || operands[3] == 0
6220 || operands[4] == 0 || operands[5] == 0)
6221 FAIL;
6222 }")
6223
6224 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6225 ;; used only once, let combine add in the index again.
6226
6227 (define_split
6228 [(set (match_operand:SI 0 "register_operand" "")
6229 (match_operand:SI 1 "" ""))
6230 (clobber (match_operand 2 "register_operand" ""))]
6231 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6232 && ALLOW_INDEXED_ADDRESS"
6233 [(use (reg:SI R0_REG))]
6234 "
6235 {
6236 rtx addr, reg, const_int;
6237
6238 if (GET_CODE (operands[1]) != MEM)
6239 FAIL;
6240 addr = XEXP (operands[1], 0);
6241 if (GET_CODE (addr) != PLUS)
6242 FAIL;
6243 reg = XEXP (addr, 0);
6244 const_int = XEXP (addr, 1);
6245 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6246 && GET_CODE (const_int) == CONST_INT))
6247 FAIL;
6248 emit_move_insn (operands[2], const_int);
6249 emit_move_insn (operands[0],
6250 change_address (operands[1], VOIDmode,
6251 gen_rtx_PLUS (SImode, reg, operands[2])));
6252 DONE;
6253 }")
6254
6255 (define_split
6256 [(set (match_operand:SI 1 "" "")
6257 (match_operand:SI 0 "register_operand" ""))
6258 (clobber (match_operand 2 "register_operand" ""))]
6259 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6260 && ALLOW_INDEXED_ADDRESS"
6261 [(use (reg:SI R0_REG))]
6262 "
6263 {
6264 rtx addr, reg, const_int;
6265
6266 if (GET_CODE (operands[1]) != MEM)
6267 FAIL;
6268 addr = XEXP (operands[1], 0);
6269 if (GET_CODE (addr) != PLUS)
6270 FAIL;
6271 reg = XEXP (addr, 0);
6272 const_int = XEXP (addr, 1);
6273 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6274 && GET_CODE (const_int) == CONST_INT))
6275 FAIL;
6276 emit_move_insn (operands[2], const_int);
6277 emit_move_insn (change_address (operands[1], VOIDmode,
6278 gen_rtx_PLUS (SImode, reg, operands[2])),
6279 operands[0]);
6280 DONE;
6281 }")
6282
6283 (define_expand "movdf"
6284 [(set (match_operand:DF 0 "general_movdst_operand" "")
6285 (match_operand:DF 1 "general_movsrc_operand" ""))]
6286 ""
6287 "
6288 {
6289 if (prepare_move_operands (operands, DFmode)) DONE;
6290 if (TARGET_SHMEDIA)
6291 {
6292 if (TARGET_SHMEDIA_FPU)
6293 emit_insn (gen_movdf_media (operands[0], operands[1]));
6294 else
6295 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6296 DONE;
6297 }
6298 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6299 {
6300 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6301 DONE;
6302 }
6303 }")
6304
6305 ;;This is incompatible with the way gcc uses subregs.
6306 ;;(define_insn "movv2sf_i"
6307 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6308 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6309 ;; "TARGET_SHMEDIA_FPU
6310 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6311 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6312 ;; "@
6313 ;; #
6314 ;; fld%M1.p %m1, %0
6315 ;; fst%M0.p %m0, %1"
6316 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6317
6318 (define_insn_and_split "movv2sf_i"
6319 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6320 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6321 "TARGET_SHMEDIA_FPU"
6322 "#"
6323 "TARGET_SHMEDIA_FPU && reload_completed"
6324 [(set (match_dup 0) (match_dup 1))]
6325 "
6326 {
6327 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6328 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6329 }")
6330
6331 (define_expand "movv2sf"
6332 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6333 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6334 "TARGET_SHMEDIA_FPU"
6335 "
6336 {
6337 if (prepare_move_operands (operands, V2SFmode))
6338 DONE;
6339 }")
6340
6341 (define_expand "addv2sf3"
6342 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6343 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6344 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6345 "TARGET_SHMEDIA_FPU"
6346 "
6347 {
6348 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6349 DONE;
6350 }")
6351
6352 (define_expand "subv2sf3"
6353 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6354 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6355 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6356 "TARGET_SHMEDIA_FPU"
6357 "
6358 {
6359 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6360 DONE;
6361 }")
6362
6363 (define_expand "mulv2sf3"
6364 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6365 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6366 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6367 "TARGET_SHMEDIA_FPU"
6368 "
6369 {
6370 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6371 DONE;
6372 }")
6373
6374 (define_expand "divv2sf3"
6375 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6376 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6377 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6378 "TARGET_SHMEDIA_FPU"
6379 "
6380 {
6381 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6382 DONE;
6383 }")
6384
6385 (define_insn_and_split "*movv4sf_i"
6386 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6387 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6388 "TARGET_SHMEDIA_FPU"
6389 "#"
6390 "&& reload_completed"
6391 [(const_int 0)]
6392 "
6393 {
6394 int i;
6395
6396 for (i = 0; i < 4/2; i++)
6397 {
6398 rtx x, y;
6399
6400 if (GET_CODE (operands[0]) == MEM)
6401 x = adjust_address (operands[0], V2SFmode,
6402 i * GET_MODE_SIZE (V2SFmode));
6403 else
6404 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6405
6406 if (GET_CODE (operands[1]) == MEM)
6407 y = adjust_address (operands[1], V2SFmode,
6408 i * GET_MODE_SIZE (V2SFmode));
6409 else
6410 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6411
6412 emit_insn (gen_movv2sf_i (x, y));
6413 }
6414
6415 DONE;
6416 }"
6417 [(set_attr "length" "8")])
6418
6419 (define_expand "movv4sf"
6420 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6421 (match_operand:V4SF 1 "general_operand" ""))]
6422 "TARGET_SHMEDIA_FPU"
6423 "
6424 {
6425 if (prepare_move_operands (operands, V4SFmode))
6426 DONE;
6427 }")
6428
6429 (define_insn_and_split "*movv16sf_i"
6430 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6431 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6432 "TARGET_SHMEDIA_FPU"
6433 "#"
6434 "&& reload_completed"
6435 [(const_int 0)]
6436 "
6437 {
6438 int i;
6439
6440 for (i = 0; i < 16/2; i++)
6441 {
6442 rtx x,y;
6443
6444 if (GET_CODE (operands[0]) == MEM)
6445 x = adjust_address (operands[0], V2SFmode,
6446 i * GET_MODE_SIZE (V2SFmode));
6447 else
6448 {
6449 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6450 alter_subreg (&x);
6451 }
6452
6453 if (GET_CODE (operands[1]) == MEM)
6454 y = adjust_address (operands[1], V2SFmode,
6455 i * GET_MODE_SIZE (V2SFmode));
6456 else
6457 {
6458 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6459 alter_subreg (&y);
6460 }
6461
6462 emit_insn (gen_movv2sf_i (x, y));
6463 }
6464
6465 DONE;
6466 }"
6467 [(set_attr "length" "32")])
6468
6469 (define_expand "movv16sf"
6470 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6471 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6472 "TARGET_SHMEDIA_FPU"
6473 "
6474 {
6475 if (prepare_move_operands (operands, V16SFmode))
6476 DONE;
6477 }")
6478
6479 (define_insn "movsf_media"
6480 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6481 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6482 "TARGET_SHMEDIA_FPU
6483 && (register_operand (operands[0], SFmode)
6484 || sh_register_operand (operands[1], SFmode))"
6485 "@
6486 fmov.s %1, %0
6487 fmov.ls %N1, %0
6488 fmov.sl %1, %0
6489 add.l %1, r63, %0
6490 #
6491 fld%M1.s %m1, %0
6492 fst%M0.s %m0, %1
6493 ld%M1.l %m1, %0
6494 st%M0.l %m0, %N1"
6495 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6496 (set (attr "highpart")
6497 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6498 (const_string "user")]
6499 (const_string "ignore")))])
6500
6501 (define_insn "movsf_media_nofpu"
6502 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6503 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6504 "TARGET_SHMEDIA
6505 && (register_operand (operands[0], SFmode)
6506 || sh_register_operand (operands[1], SFmode))"
6507 "@
6508 add.l %1, r63, %0
6509 #
6510 ld%M1.l %m1, %0
6511 st%M0.l %m0, %N1"
6512 [(set_attr "type" "arith_media,*,load_media,store_media")
6513 (set (attr "highpart")
6514 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6515 (const_string "user")]
6516 (const_string "ignore")))])
6517
6518 (define_split
6519 [(set (match_operand:SF 0 "arith_reg_dest" "")
6520 (match_operand:SF 1 "immediate_operand" ""))]
6521 "TARGET_SHMEDIA && reload_completed
6522 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6523 [(set (match_dup 3) (match_dup 2))]
6524 "
6525 {
6526 long values;
6527 REAL_VALUE_TYPE value;
6528
6529 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6530 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6531 operands[2] = GEN_INT (values);
6532
6533 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6534 }")
6535
6536 (define_insn "movsf_i"
6537 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6538 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6539 "TARGET_SH1
6540 && (! TARGET_SH2E
6541 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6542 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6543 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6544 && (arith_reg_operand (operands[0], SFmode)
6545 || arith_reg_operand (operands[1], SFmode))"
6546 "@
6547 mov %1,%0
6548 mov #0,%0
6549 mov.l %1,%0
6550 mov.l %1,%0
6551 mov.l %1,%0
6552 lds %1,%0
6553 sts %1,%0"
6554 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6555
6556 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6557 ;; update_flow_info would not know where to put REG_EQUAL notes
6558 ;; when the destination changes mode.
6559 (define_insn "movsf_ie"
6560 [(set (match_operand:SF 0 "general_movdst_operand"
6561 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6562 (match_operand:SF 1 "general_movsrc_operand"
6563 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6564 (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"))
6565 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6566
6567 "TARGET_SH2E
6568 && (arith_reg_operand (operands[0], SFmode)
6569 || arith_reg_operand (operands[1], SFmode)
6570 || arith_reg_operand (operands[3], SImode)
6571 || (fpul_operand (operands[0], SFmode)
6572 && memory_operand (operands[1], SFmode)
6573 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6574 || (fpul_operand (operands[1], SFmode)
6575 && memory_operand (operands[0], SFmode)
6576 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6577 "@
6578 fmov %1,%0
6579 mov %1,%0
6580 fldi0 %0
6581 fldi1 %0
6582 #
6583 fmov.s %1,%0
6584 fmov.s %1,%0
6585 mov.l %1,%0
6586 mov.l %1,%0
6587 mov.l %1,%0
6588 fsts fpul,%0
6589 flds %1,fpul
6590 lds.l %1,%0
6591 #
6592 sts %1,%0
6593 lds %1,%0
6594 sts.l %1,%0
6595 lds.l %1,%0
6596 ! move optimized away"
6597 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6598 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6599 (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6600 (set_attr_alternative "length"
6601 [(const_int 2)
6602 (const_int 2)
6603 (const_int 2)
6604 (const_int 2)
6605 (const_int 4)
6606 (if_then_else
6607 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6608 (const_int 4) (const_int 2))
6609 (if_then_else
6610 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6611 (const_int 4) (const_int 2))
6612 (const_int 2)
6613 (const_int 2)
6614 (const_int 2)
6615 (const_int 2)
6616 (const_int 2)
6617 (const_int 2)
6618 (const_int 4)
6619 (const_int 2)
6620 (const_int 2)
6621 (const_int 2)
6622 (const_int 2)
6623 (const_int 0)])
6624 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6625 (const_string "single")
6626 (const_string "none")))])
6627
6628 (define_split
6629 [(set (match_operand:SF 0 "register_operand" "")
6630 (match_operand:SF 1 "register_operand" ""))
6631 (use (match_operand:PSI 2 "fpscr_operand" ""))
6632 (clobber (reg:SI FPUL_REG))]
6633 "TARGET_SH1"
6634 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6635 (use (match_dup 2))
6636 (clobber (scratch:SI))])
6637 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6638 (use (match_dup 2))
6639 (clobber (scratch:SI))])]
6640 "")
6641
6642 (define_expand "movsf"
6643 [(set (match_operand:SF 0 "general_movdst_operand" "")
6644 (match_operand:SF 1 "general_movsrc_operand" ""))]
6645 ""
6646 "
6647 {
6648 if (prepare_move_operands (operands, SFmode))
6649 DONE;
6650 if (TARGET_SHMEDIA)
6651 {
6652 if (TARGET_SHMEDIA_FPU)
6653 emit_insn (gen_movsf_media (operands[0], operands[1]));
6654 else
6655 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6656 DONE;
6657 }
6658 if (TARGET_SH2E)
6659 {
6660 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6661 DONE;
6662 }
6663 }")
6664
6665 (define_insn "mov_nop"
6666 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6667 "TARGET_SH2E"
6668 ""
6669 [(set_attr "length" "0")
6670 (set_attr "type" "nil")])
6671
6672 (define_expand "reload_insf__frn"
6673 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6674 (match_operand:SF 1 "immediate_operand" "FQ"))
6675 (use (reg:PSI FPSCR_REG))
6676 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6677 "TARGET_SH1"
6678 "")
6679
6680 (define_expand "reload_insi__i_fpul"
6681 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6682 (match_operand:SI 1 "immediate_operand" "i"))
6683 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6684 "TARGET_SH1"
6685 "")
6686
6687 (define_expand "ptabs"
6688 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6689 "TARGET_SHMEDIA"
6690 "
6691 {
6692 if (!TARGET_PT_FIXED)
6693 {
6694 rtx eq = operands[1];
6695
6696 /* ??? For canonical RTL we really should remove any CONST from EQ
6697 before wrapping it in the AND, and finally wrap the EQ into a
6698 const if is constant. However, for reload we must expose the
6699 input register or symbolic constant, and we can't have
6700 different insn structures outside of the operands for different
6701 alternatives of the same pattern. */
6702 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6703 GEN_INT (3));
6704 operands[1]
6705 = (gen_rtx_IF_THEN_ELSE
6706 (PDImode,
6707 eq,
6708 gen_rtx_MEM (PDImode, operands[1]),
6709 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6710 PDImode, operands[1])));
6711 }
6712 }")
6713
6714 ;; expanded by ptabs expander.
6715 (define_insn "*extendsipdi_media"
6716 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6717 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6718 "r,Csy")
6719 (const_int 3))
6720 (const_int 3))
6721 (mem:PDI (match_dup 1))
6722 (sign_extend:PDI (match_dup 1))))]
6723 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6724 "@
6725 ptabs %1, %0
6726 pt %1, %0"
6727 [(set_attr "type" "ptabs_media,pt_media")
6728 (set_attr "length" "4,*")])
6729
6730 (define_insn "*truncdipdi_media"
6731 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6732 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6733 "r,Csy")
6734 (const_int 3))
6735 (const_int 3))
6736 (mem:PDI (match_dup 1))
6737 (truncate:PDI (match_dup 1))))]
6738 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6739 "@
6740 ptabs %1, %0
6741 pt %1, %0"
6742 [(set_attr "type" "ptabs_media,pt_media")
6743 (set_attr "length" "4,*")])
6744
6745 (define_insn "*movsi_y"
6746 [(set (match_operand:SI 0 "register_operand" "=y,y")
6747 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6748 (clobber (match_scratch:SI 2 "=&z,r"))]
6749 "TARGET_SH2E
6750 && (reload_in_progress || reload_completed)"
6751 "#"
6752 [(set_attr "length" "4")
6753 (set_attr "type" "pcload,move")])
6754
6755 (define_split
6756 [(set (match_operand:SI 0 "register_operand" "")
6757 (match_operand:SI 1 "immediate_operand" ""))
6758 (clobber (match_operand:SI 2 "register_operand" ""))]
6759 "TARGET_SH1"
6760 [(set (match_dup 2) (match_dup 1))
6761 (set (match_dup 0) (match_dup 2))]
6762 "")
6763
6764 (define_split
6765 [(set (match_operand:SI 0 "register_operand" "")
6766 (match_operand:SI 1 "memory_operand" ""))
6767 (clobber (reg:SI R0_REG))]
6768 "TARGET_SH1"
6769 [(set (match_dup 0) (match_dup 1))]
6770 "")
6771 \f
6772 ;; ------------------------------------------------------------------------
6773 ;; Define the real conditional branch instructions.
6774 ;; ------------------------------------------------------------------------
6775
6776 (define_insn "branch_true"
6777 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6778 (label_ref (match_operand 0 "" ""))
6779 (pc)))]
6780 "TARGET_SH1"
6781 "* return output_branch (1, insn, operands);"
6782 [(set_attr "type" "cbranch")])
6783
6784 (define_insn "branch_false"
6785 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6786 (label_ref (match_operand 0 "" ""))
6787 (pc)))]
6788 "TARGET_SH1"
6789 "* return output_branch (0, insn, operands);"
6790 [(set_attr "type" "cbranch")])
6791
6792 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6793 ;; which destination is too far away.
6794 ;; The const_int_operand is distinct for each branch target; it avoids
6795 ;; unwanted matches with redundant_insn.
6796 (define_insn "block_branch_redirect"
6797 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6798 "TARGET_SH1"
6799 ""
6800 [(set_attr "length" "0")])
6801
6802 ;; This one has the additional purpose to record a possible scratch register
6803 ;; for the following branch.
6804 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6805 ;; because the insn then might be deemed dead and deleted. And we can't
6806 ;; make the use in the jump insn explicit because that would disable
6807 ;; delay slot scheduling from the target.
6808 (define_insn "indirect_jump_scratch"
6809 [(set (match_operand:SI 0 "register_operand" "=r")
6810 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6811 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6812 "TARGET_SH1"
6813 ""
6814 [(set_attr "length" "0")])
6815
6816 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6817 ;; being pulled into the delay slot of a condbranch that has been made to
6818 ;; jump around the unconditional jump because it was out of range.
6819 (define_insn "stuff_delay_slot"
6820 [(set (pc)
6821 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6822 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6823 "TARGET_SH1"
6824 ""
6825 [(set_attr "length" "0")
6826 (set_attr "cond_delay_slot" "yes")])
6827 \f
6828 ;; Conditional branch insns
6829
6830 (define_expand "beq_media"
6831 [(set (pc)
6832 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6833 (match_operand:DI 2 "arith_operand" "r,I06"))
6834 (match_operand 0 "" "")
6835 (pc)))]
6836 "TARGET_SHMEDIA"
6837 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6838
6839 (define_insn "*beq_media_i"
6840 [(set (pc)
6841 (if_then_else (match_operator 3 "equality_comparison_operator"
6842 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6843 (match_operand:DI 2 "arith_operand" "r,I06")])
6844 (match_operand 0 "target_operand" "b,b")
6845 (pc)))]
6846 "TARGET_SHMEDIA"
6847 "@
6848 b%o3%' %1, %2, %0%>
6849 b%o3i%' %1, %2, %0%>"
6850 [(set_attr "type" "cbranch_media")])
6851
6852 (define_insn "*beq_media_i32"
6853 [(set (pc)
6854 (if_then_else (match_operator 3 "equality_comparison_operator"
6855 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6856 (match_operand:SI 2 "arith_operand" "r,I06")])
6857 (match_operand 0 "target_operand" "b,b")
6858 (pc)))]
6859 "TARGET_SHMEDIA"
6860 "@
6861 b%o3%' %1, %2, %0%>
6862 b%o3i%' %1, %2, %0%>"
6863 [(set_attr "type" "cbranch_media")])
6864
6865 (define_expand "bne_media"
6866 [(set (pc)
6867 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6868 (match_operand:DI 2 "arith_operand" "r,I06"))
6869 (match_operand 0 "" "")
6870 (pc)))]
6871 "TARGET_SHMEDIA"
6872 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6873
6874 (define_expand "bgt_media"
6875 [(set (pc)
6876 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6877 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6878 (match_operand 0 "" "")
6879 (pc)))]
6880 "TARGET_SHMEDIA"
6881 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6882
6883 (define_expand "bge_media"
6884 [(set (pc)
6885 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6886 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6887 (match_operand 0 "" "")
6888 (pc)))]
6889 "TARGET_SHMEDIA"
6890 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6891
6892 (define_expand "bgtu_media"
6893 [(set (pc)
6894 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6895 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6896 (match_operand 0 "" "")
6897 (pc)))]
6898 "TARGET_SHMEDIA"
6899 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6900
6901 (define_expand "bgeu_media"
6902 [(set (pc)
6903 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6904 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6905 (match_operand 0 "" "")
6906 (pc)))]
6907 "TARGET_SHMEDIA"
6908 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6909
6910 (define_insn "*bgt_media_i"
6911 [(set (pc)
6912 (if_then_else (match_operator 3 "greater_comparison_operator"
6913 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6914 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6915 (match_operand 0 "target_operand" "b")
6916 (pc)))]
6917 "TARGET_SHMEDIA"
6918 "b%o3%' %N1, %N2, %0%>"
6919 [(set_attr "type" "cbranch_media")])
6920
6921 (define_insn "*bgt_media_i32"
6922 [(set (pc)
6923 (if_then_else (match_operator 3 "greater_comparison_operator"
6924 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6925 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6926 (match_operand 0 "target_operand" "b")
6927 (pc)))]
6928 "TARGET_SHMEDIA"
6929 "b%o3%' %N1, %N2, %0%>"
6930 [(set_attr "type" "cbranch_media")])
6931
6932 ;; These are only needed to make invert_jump() happy - otherwise, jump
6933 ;; optimization will be silently disabled.
6934 (define_insn "*blt_media_i"
6935 [(set (pc)
6936 (if_then_else (match_operator 3 "less_comparison_operator"
6937 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6938 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6939 (match_operand 0 "target_operand" "b")
6940 (pc)))]
6941 "TARGET_SHMEDIA"
6942 "b%o3%' %N2, %N1, %0%>"
6943 [(set_attr "type" "cbranch_media")])
6944
6945 (define_insn "*blt_media_i32"
6946 [(set (pc)
6947 (if_then_else (match_operator 3 "less_comparison_operator"
6948 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6949 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6950 (match_operand 0 "target_operand" "b")
6951 (pc)))]
6952 "TARGET_SHMEDIA"
6953 "b%o3%' %N2, %N1, %0%>"
6954 [(set_attr "type" "cbranch_media")])
6955
6956 (define_expand "beq"
6957 [(set (pc)
6958 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6959 (label_ref (match_operand 0 "" ""))
6960 (pc)))]
6961 ""
6962 "
6963 {
6964 if (TARGET_SHMEDIA)
6965 {
6966 enum machine_mode mode = GET_MODE (sh_compare_op0);
6967
6968 if (mode != DImode && mode != SImode)
6969 {
6970 rtx tmp = gen_reg_rtx (DImode);
6971
6972 emit_insn (gen_seq (tmp));
6973 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6974 DONE;
6975 }
6976
6977 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6978 if (CONSTANT_P (sh_compare_op1)
6979 && (! satisfies_constraint_I06 (sh_compare_op1)))
6980 sh_compare_op1 = force_reg (mode, sh_compare_op1);
6981 emit_jump_insn (gen_beq_media (operands[0],
6982 sh_compare_op0, sh_compare_op1));
6983 DONE;
6984 }
6985
6986 from_compare (operands, EQ);
6987 }")
6988
6989 (define_expand "bne"
6990 [(set (pc)
6991 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6992 (label_ref (match_operand 0 "" ""))
6993 (pc)))]
6994 ""
6995 "
6996 {
6997 if (TARGET_SHMEDIA)
6998 {
6999 enum machine_mode mode = GET_MODE (sh_compare_op0);
7000
7001 if (mode != DImode && mode != SImode)
7002 {
7003 rtx tmp = gen_reg_rtx (DImode);
7004
7005 emit_insn (gen_seq (tmp));
7006 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7007 DONE;
7008 }
7009
7010 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7011 if (CONSTANT_P (sh_compare_op1)
7012 && (! satisfies_constraint_I06 (sh_compare_op1)))
7013 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7014 emit_jump_insn (gen_bne_media (operands[0],
7015 sh_compare_op0, sh_compare_op1));
7016 DONE;
7017 }
7018
7019 from_compare (operands, EQ);
7020 }")
7021
7022 (define_expand "bgt"
7023 [(set (pc)
7024 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7025 (label_ref (match_operand 0 "" ""))
7026 (pc)))]
7027 ""
7028 "
7029 {
7030 if (TARGET_SHMEDIA)
7031 {
7032 enum machine_mode mode = GET_MODE (sh_compare_op0);
7033
7034 if (mode != DImode && mode != SImode)
7035 {
7036 rtx tmp = gen_reg_rtx (DImode);
7037
7038 emit_insn (gen_sgt (tmp));
7039 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7040 DONE;
7041 }
7042
7043 if (sh_compare_op0 != const0_rtx)
7044 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7045 if (sh_compare_op1 != const0_rtx)
7046 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7047 emit_jump_insn (gen_bgt_media (operands[0],
7048 sh_compare_op0, sh_compare_op1));
7049 DONE;
7050 }
7051
7052 from_compare (operands, GT);
7053 }")
7054
7055 (define_expand "blt"
7056 [(set (pc)
7057 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7058 (label_ref (match_operand 0 "" ""))
7059 (pc)))]
7060 ""
7061 "
7062 {
7063 if (TARGET_SHMEDIA)
7064 {
7065 enum machine_mode mode = GET_MODE (sh_compare_op0);
7066
7067 if (mode != DImode && mode != SImode)
7068 {
7069 rtx tmp = gen_reg_rtx (DImode);
7070
7071 emit_insn (gen_slt (tmp));
7072 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7073 DONE;
7074 }
7075
7076 if (sh_compare_op0 != const0_rtx)
7077 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7078 if (sh_compare_op1 != const0_rtx)
7079 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7080 emit_jump_insn (gen_bgt_media (operands[0],
7081 sh_compare_op1, sh_compare_op0));
7082 DONE;
7083 }
7084
7085 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7086 {
7087 rtx tmp = sh_compare_op0;
7088 sh_compare_op0 = sh_compare_op1;
7089 sh_compare_op1 = tmp;
7090 emit_insn (gen_bgt (operands[0]));
7091 DONE;
7092 }
7093 from_compare (operands, GE);
7094 }")
7095
7096 (define_expand "ble"
7097 [(set (pc)
7098 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7099 (label_ref (match_operand 0 "" ""))
7100 (pc)))]
7101 ""
7102 "
7103 {
7104 if (TARGET_SHMEDIA)
7105 {
7106 enum machine_mode mode = GET_MODE (sh_compare_op0);
7107
7108 if (mode != DImode && mode != SImode)
7109 {
7110 rtx tmp = gen_reg_rtx (DImode);
7111
7112 emit_insn (gen_sle (tmp));
7113 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7114 DONE;
7115 }
7116
7117 if (sh_compare_op0 != const0_rtx)
7118 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7119 if (sh_compare_op1 != const0_rtx)
7120 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7121 emit_jump_insn (gen_bge_media (operands[0],
7122 sh_compare_op1, sh_compare_op0));
7123 DONE;
7124 }
7125
7126 if (TARGET_SH2E
7127 && TARGET_IEEE
7128 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7129 {
7130 rtx tmp = sh_compare_op0;
7131 sh_compare_op0 = sh_compare_op1;
7132 sh_compare_op1 = tmp;
7133 emit_insn (gen_bge (operands[0]));
7134 DONE;
7135 }
7136 from_compare (operands, GT);
7137 }")
7138
7139 (define_expand "bge"
7140 [(set (pc)
7141 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7142 (label_ref (match_operand 0 "" ""))
7143 (pc)))]
7144 ""
7145 "
7146 {
7147 if (TARGET_SHMEDIA)
7148 {
7149 enum machine_mode mode = GET_MODE (sh_compare_op0);
7150
7151 if (mode != DImode && mode != SImode)
7152 {
7153 rtx tmp = gen_reg_rtx (DImode);
7154
7155 emit_insn (gen_sge (tmp));
7156 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7157 DONE;
7158 }
7159
7160 if (sh_compare_op0 != const0_rtx)
7161 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7162 if (sh_compare_op1 != const0_rtx)
7163 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7164 emit_jump_insn (gen_bge_media (operands[0],
7165 sh_compare_op0, sh_compare_op1));
7166 DONE;
7167 }
7168
7169 if (TARGET_SH2E
7170 && ! TARGET_IEEE
7171 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7172 {
7173 rtx tmp = sh_compare_op0;
7174 sh_compare_op0 = sh_compare_op1;
7175 sh_compare_op1 = tmp;
7176 emit_insn (gen_ble (operands[0]));
7177 DONE;
7178 }
7179 from_compare (operands, GE);
7180 }")
7181
7182 (define_expand "bgtu"
7183 [(set (pc)
7184 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7185 (label_ref (match_operand 0 "" ""))
7186 (pc)))]
7187 ""
7188 "
7189 {
7190 if (TARGET_SHMEDIA)
7191 {
7192 enum machine_mode mode = GET_MODE (sh_compare_op0);
7193
7194 if (sh_compare_op0 != const0_rtx)
7195 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7196 if (sh_compare_op1 != const0_rtx)
7197 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7198 emit_jump_insn (gen_bgtu_media (operands[0],
7199 sh_compare_op0, sh_compare_op1));
7200 DONE;
7201 }
7202
7203 from_compare (operands, GTU);
7204 }")
7205
7206 (define_expand "bltu"
7207 [(set (pc)
7208 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7209 (label_ref (match_operand 0 "" ""))
7210 (pc)))]
7211 ""
7212 "
7213 {
7214 if (TARGET_SHMEDIA)
7215 {
7216 enum machine_mode mode = GET_MODE (sh_compare_op0);
7217
7218 if (sh_compare_op0 != const0_rtx)
7219 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7220 if (sh_compare_op1 != const0_rtx)
7221 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7222 emit_jump_insn (gen_bgtu_media (operands[0],
7223 sh_compare_op1, sh_compare_op0));
7224 DONE;
7225 }
7226
7227 from_compare (operands, GEU);
7228 }")
7229
7230 (define_expand "bgeu"
7231 [(set (pc)
7232 (if_then_else (ne (reg:SI T_REG) (const_int 0))
7233 (label_ref (match_operand 0 "" ""))
7234 (pc)))]
7235 ""
7236 "
7237 {
7238 if (TARGET_SHMEDIA)
7239 {
7240 enum machine_mode mode = GET_MODE (sh_compare_op0);
7241
7242 if (sh_compare_op0 != const0_rtx)
7243 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7244 if (sh_compare_op1 != const0_rtx)
7245 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7246 emit_jump_insn (gen_bgeu_media (operands[0],
7247 sh_compare_op0, sh_compare_op1));
7248 DONE;
7249 }
7250
7251 from_compare (operands, GEU);
7252 }")
7253
7254 (define_expand "bleu"
7255 [(set (pc)
7256 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7257 (label_ref (match_operand 0 "" ""))
7258 (pc)))]
7259 ""
7260 "
7261 {
7262 if (TARGET_SHMEDIA)
7263 {
7264 enum machine_mode mode = GET_MODE (sh_compare_op0);
7265
7266 if (sh_compare_op0 != const0_rtx)
7267 sh_compare_op0 = force_reg (mode, sh_compare_op0);
7268 if (sh_compare_op1 != const0_rtx)
7269 sh_compare_op1 = force_reg (mode, sh_compare_op1);
7270 emit_jump_insn (gen_bgeu_media (operands[0],
7271 sh_compare_op1, sh_compare_op0));
7272 DONE;
7273 }
7274
7275 from_compare (operands, GTU);
7276 }")
7277
7278 (define_expand "bunordered"
7279 [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7280 (set (pc)
7281 (if_then_else (ne (match_dup 1) (const_int 0))
7282 (match_operand 0 "" "")
7283 (pc)))]
7284 "TARGET_SHMEDIA"
7285 "
7286 {
7287 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7288 operands[1] = gen_reg_rtx (SImode);
7289 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7290 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7291 }")
7292
7293 ;; combiner splitter for test-and-branch on single bit in register. This
7294 ;; is endian dependent because the non-paradoxical subreg looks different
7295 ;; on big endian.
7296 (define_split
7297 [(set (pc)
7298 (if_then_else
7299 (match_operator 3 "equality_comparison_operator"
7300 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7301 "extend_reg_operand" "")
7302 0)
7303 (const_int 1)
7304 (match_operand 2
7305 "const_int_operand" "")) 0)
7306 (const_int 0)])
7307 (match_operand 0 "target_operand" "")
7308 (pc)))
7309 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7310 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7311 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7312 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7313
7314 "
7315 {
7316 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7317 operands[6] = (GET_CODE (operands[3]) == EQ
7318 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7319 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7320 }")
7321
7322 ; operand 0 is the loop count pseudo register
7323 ; operand 1 is the number of loop iterations or 0 if it is unknown
7324 ; operand 2 is the maximum number of loop iterations
7325 ; operand 3 is the number of levels of enclosed loops
7326 ; operand 4 is the label to jump to at the top of the loop
7327
7328 (define_expand "doloop_end"
7329 [(parallel [(set (pc) (if_then_else
7330 (ne:SI (match_operand:SI 0 "" "")
7331 (const_int 1))
7332 (label_ref (match_operand 4 "" ""))
7333 (pc)))
7334 (set (match_dup 0)
7335 (plus:SI (match_dup 0) (const_int -1)))
7336 (clobber (reg:SI T_REG))])]
7337 "TARGET_SH2"
7338 "
7339 {
7340 if (GET_MODE (operands[0]) != SImode)
7341 FAIL;
7342 }
7343 ")
7344
7345 (define_insn_and_split "doloop_end_split"
7346 [(set (pc)
7347 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7348 (const_int 1))
7349 (label_ref (match_operand 1 "" ""))
7350 (pc)))
7351 (set (match_dup 0)
7352 (plus (match_dup 0) (const_int -1)))
7353 (clobber (reg:SI T_REG))]
7354 "TARGET_SH2"
7355 "#"
7356 ""
7357 [(parallel [(set (reg:SI T_REG)
7358 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7359 (const_int 1)))
7360 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7361 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7362 (label_ref (match_operand 1 "" ""))
7363 (pc)))]
7364 ""
7365 [(set_attr "type" "cbranch")])
7366
7367 \f
7368 ;; ------------------------------------------------------------------------
7369 ;; Jump and linkage insns
7370 ;; ------------------------------------------------------------------------
7371
7372 (define_insn "jump_compact"
7373 [(set (pc)
7374 (label_ref (match_operand 0 "" "")))]
7375 "TARGET_SH1"
7376 "*
7377 {
7378 /* The length is 16 if the delay slot is unfilled. */
7379 if (get_attr_length(insn) > 4)
7380 return output_far_jump(insn, operands[0]);
7381 else
7382 return \"bra %l0%#\";
7383 }"
7384 [(set_attr "type" "jump")
7385 (set_attr "needs_delay_slot" "yes")])
7386
7387 ;; ??? It would be much saner to explicitly use the scratch register
7388 ;; in the jump insn, and have indirect_jump_scratch only set it,
7389 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7390 ;; from the target then, as it uses simplejump_p.
7391 ;;(define_insn "jump_compact_far"
7392 ;; [(set (pc)
7393 ;; (label_ref (match_operand 0 "" "")))
7394 ;; (use (match_operand 1 "register_operand" "r")]
7395 ;; "TARGET_SH1"
7396 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7397 ;; [(set_attr "type" "jump")
7398 ;; (set_attr "needs_delay_slot" "yes")])
7399
7400 (define_insn "jump_media"
7401 [(set (pc)
7402 (match_operand 0 "target_operand" "b"))]
7403 "TARGET_SHMEDIA"
7404 "blink %0, r63%>"
7405 [(set_attr "type" "jump_media")])
7406
7407 (define_expand "jump"
7408 [(set (pc)
7409 (label_ref (match_operand 0 "" "")))]
7410 ""
7411 "
7412 {
7413 if (TARGET_SH1)
7414 emit_jump_insn (gen_jump_compact (operands[0]));
7415 else if (TARGET_SHMEDIA)
7416 {
7417 if (reload_in_progress || reload_completed)
7418 FAIL;
7419 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7420 operands[0])));
7421 }
7422 DONE;
7423 }")
7424
7425 (define_insn "force_mode_for_call"
7426 [(use (reg:PSI FPSCR_REG))]
7427 "TARGET_SHCOMPACT"
7428 ""
7429 [(set_attr "length" "0")
7430 (set (attr "fp_mode")
7431 (if_then_else (eq_attr "fpu_single" "yes")
7432 (const_string "single") (const_string "double")))])
7433
7434 (define_insn "calli"
7435 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7436 (match_operand 1 "" ""))
7437 (use (reg:PSI FPSCR_REG))
7438 (clobber (reg:SI PR_REG))]
7439 "TARGET_SH1"
7440 "jsr @%0%#"
7441 [(set_attr "type" "call")
7442 (set (attr "fp_mode")
7443 (if_then_else (eq_attr "fpu_single" "yes")
7444 (const_string "single") (const_string "double")))
7445 (set_attr "needs_delay_slot" "yes")
7446 (set_attr "fp_set" "unknown")])
7447
7448 ;; This is a pc-rel call, using bsrf, for use with PIC.
7449
7450 (define_insn "calli_pcrel"
7451 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7452 (match_operand 1 "" ""))
7453 (use (reg:PSI FPSCR_REG))
7454 (use (reg:SI PIC_REG))
7455 (use (match_operand 2 "" ""))
7456 (clobber (reg:SI PR_REG))]
7457 "TARGET_SH2"
7458 "bsrf %0\\n%O2:%#"
7459 [(set_attr "type" "call")
7460 (set (attr "fp_mode")
7461 (if_then_else (eq_attr "fpu_single" "yes")
7462 (const_string "single") (const_string "double")))
7463 (set_attr "needs_delay_slot" "yes")
7464 (set_attr "fp_set" "unknown")])
7465
7466 (define_insn_and_split "call_pcrel"
7467 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7468 (match_operand 1 "" ""))
7469 (use (reg:PSI FPSCR_REG))
7470 (use (reg:SI PIC_REG))
7471 (clobber (reg:SI PR_REG))
7472 (clobber (match_scratch:SI 2 "=r"))]
7473 "TARGET_SH2"
7474 "#"
7475 "reload_completed"
7476 [(const_int 0)]
7477 "
7478 {
7479 rtx lab = PATTERN (gen_call_site ());
7480
7481 if (SYMBOL_REF_LOCAL_P (operands[0]))
7482 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7483 else
7484 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7485 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7486 DONE;
7487 }"
7488 [(set_attr "type" "call")
7489 (set (attr "fp_mode")
7490 (if_then_else (eq_attr "fpu_single" "yes")
7491 (const_string "single") (const_string "double")))
7492 (set_attr "needs_delay_slot" "yes")
7493 (set_attr "fp_set" "unknown")])
7494
7495 (define_insn "call_compact"
7496 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7497 (match_operand 1 "" ""))
7498 (match_operand 2 "immediate_operand" "n")
7499 (use (reg:SI R0_REG))
7500 (use (reg:SI R1_REG))
7501 (use (reg:PSI FPSCR_REG))
7502 (clobber (reg:SI PR_REG))]
7503 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7504 "jsr @%0%#"
7505 [(set_attr "type" "call")
7506 (set (attr "fp_mode")
7507 (if_then_else (eq_attr "fpu_single" "yes")
7508 (const_string "single") (const_string "double")))
7509 (set_attr "needs_delay_slot" "yes")])
7510
7511 (define_insn "call_compact_rettramp"
7512 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7513 (match_operand 1 "" ""))
7514 (match_operand 2 "immediate_operand" "n")
7515 (use (reg:SI R0_REG))
7516 (use (reg:SI R1_REG))
7517 (use (reg:PSI FPSCR_REG))
7518 (clobber (reg:SI R10_REG))
7519 (clobber (reg:SI PR_REG))]
7520 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521 "jsr @%0%#"
7522 [(set_attr "type" "call")
7523 (set (attr "fp_mode")
7524 (if_then_else (eq_attr "fpu_single" "yes")
7525 (const_string "single") (const_string "double")))
7526 (set_attr "needs_delay_slot" "yes")])
7527
7528 (define_insn "call_media"
7529 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7530 (match_operand 1 "" ""))
7531 (clobber (reg:DI PR_MEDIA_REG))]
7532 "TARGET_SHMEDIA"
7533 "blink %0, r18"
7534 [(set_attr "type" "jump_media")])
7535
7536 (define_insn "call_valuei"
7537 [(set (match_operand 0 "" "=rf")
7538 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7539 (match_operand 2 "" "")))
7540 (use (reg:PSI FPSCR_REG))
7541 (clobber (reg:SI PR_REG))]
7542 "TARGET_SH1"
7543 "jsr @%1%#"
7544 [(set_attr "type" "call")
7545 (set (attr "fp_mode")
7546 (if_then_else (eq_attr "fpu_single" "yes")
7547 (const_string "single") (const_string "double")))
7548 (set_attr "needs_delay_slot" "yes")
7549 (set_attr "fp_set" "unknown")])
7550
7551 (define_insn "call_valuei_pcrel"
7552 [(set (match_operand 0 "" "=rf")
7553 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7554 (match_operand 2 "" "")))
7555 (use (reg:PSI FPSCR_REG))
7556 (use (reg:SI PIC_REG))
7557 (use (match_operand 3 "" ""))
7558 (clobber (reg:SI PR_REG))]
7559 "TARGET_SH2"
7560 "bsrf %1\\n%O3:%#"
7561 [(set_attr "type" "call")
7562 (set (attr "fp_mode")
7563 (if_then_else (eq_attr "fpu_single" "yes")
7564 (const_string "single") (const_string "double")))
7565 (set_attr "needs_delay_slot" "yes")
7566 (set_attr "fp_set" "unknown")])
7567
7568 (define_insn_and_split "call_value_pcrel"
7569 [(set (match_operand 0 "" "=rf")
7570 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7571 (match_operand 2 "" "")))
7572 (use (reg:PSI FPSCR_REG))
7573 (use (reg:SI PIC_REG))
7574 (clobber (reg:SI PR_REG))
7575 (clobber (match_scratch:SI 3 "=r"))]
7576 "TARGET_SH2"
7577 "#"
7578 "reload_completed"
7579 [(const_int 0)]
7580 "
7581 {
7582 rtx lab = PATTERN (gen_call_site ());
7583
7584 if (SYMBOL_REF_LOCAL_P (operands[1]))
7585 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7586 else
7587 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7588 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7589 operands[2], copy_rtx (lab)));
7590 DONE;
7591 }"
7592 [(set_attr "type" "call")
7593 (set (attr "fp_mode")
7594 (if_then_else (eq_attr "fpu_single" "yes")
7595 (const_string "single") (const_string "double")))
7596 (set_attr "needs_delay_slot" "yes")
7597 (set_attr "fp_set" "unknown")])
7598
7599 (define_insn "call_value_compact"
7600 [(set (match_operand 0 "" "=rf")
7601 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7602 (match_operand 2 "" "")))
7603 (match_operand 3 "immediate_operand" "n")
7604 (use (reg:SI R0_REG))
7605 (use (reg:SI R1_REG))
7606 (use (reg:PSI FPSCR_REG))
7607 (clobber (reg:SI PR_REG))]
7608 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7609 "jsr @%1%#"
7610 [(set_attr "type" "call")
7611 (set (attr "fp_mode")
7612 (if_then_else (eq_attr "fpu_single" "yes")
7613 (const_string "single") (const_string "double")))
7614 (set_attr "needs_delay_slot" "yes")])
7615
7616 (define_insn "call_value_compact_rettramp"
7617 [(set (match_operand 0 "" "=rf")
7618 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7619 (match_operand 2 "" "")))
7620 (match_operand 3 "immediate_operand" "n")
7621 (use (reg:SI R0_REG))
7622 (use (reg:SI R1_REG))
7623 (use (reg:PSI FPSCR_REG))
7624 (clobber (reg:SI R10_REG))
7625 (clobber (reg:SI PR_REG))]
7626 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7627 "jsr @%1%#"
7628 [(set_attr "type" "call")
7629 (set (attr "fp_mode")
7630 (if_then_else (eq_attr "fpu_single" "yes")
7631 (const_string "single") (const_string "double")))
7632 (set_attr "needs_delay_slot" "yes")])
7633
7634 (define_insn "call_value_media"
7635 [(set (match_operand 0 "" "=rf")
7636 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7637 (match_operand 2 "" "")))
7638 (clobber (reg:DI PR_MEDIA_REG))]
7639 "TARGET_SHMEDIA"
7640 "blink %1, r18"
7641 [(set_attr "type" "jump_media")])
7642
7643 (define_expand "call"
7644 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7645 (match_operand 1 "" ""))
7646 (match_operand 2 "" "")
7647 (use (reg:PSI FPSCR_REG))
7648 (clobber (reg:SI PR_REG))])]
7649 ""
7650 "
7651 {
7652 if (TARGET_SHMEDIA)
7653 {
7654 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7655 emit_call_insn (gen_call_media (operands[0], operands[1]));
7656 DONE;
7657 }
7658 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7659 {
7660 rtx cookie_rtx = operands[2];
7661 long cookie = INTVAL (cookie_rtx);
7662 rtx func = XEXP (operands[0], 0);
7663 rtx r0, r1;
7664
7665 if (flag_pic)
7666 {
7667 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7668 {
7669 rtx reg = gen_reg_rtx (Pmode);
7670
7671 emit_insn (gen_symGOTPLT2reg (reg, func));
7672 func = reg;
7673 }
7674 else
7675 func = legitimize_pic_address (func, Pmode, 0);
7676 }
7677
7678 r0 = gen_rtx_REG (SImode, R0_REG);
7679 r1 = gen_rtx_REG (SImode, R1_REG);
7680
7681 /* Since such a call function may use all call-clobbered
7682 registers, we force a mode switch earlier, so that we don't
7683 run out of registers when adjusting fpscr for the call. */
7684 emit_insn (gen_force_mode_for_call ());
7685
7686 operands[0]
7687 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7688 SFUNC_GOT);
7689 operands[0] = force_reg (SImode, operands[0]);
7690
7691 emit_move_insn (r0, func);
7692 emit_move_insn (r1, cookie_rtx);
7693
7694 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7695 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7696 operands[2]));
7697 else
7698 emit_call_insn (gen_call_compact (operands[0], operands[1],
7699 operands[2]));
7700
7701 DONE;
7702 }
7703 else if (TARGET_SHCOMPACT && flag_pic
7704 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7705 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7706 {
7707 rtx reg = gen_reg_rtx (Pmode);
7708
7709 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7710 XEXP (operands[0], 0) = reg;
7711 }
7712 if (flag_pic && TARGET_SH2
7713 && GET_CODE (operands[0]) == MEM
7714 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7715 {
7716 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7717 DONE;
7718 }
7719 else
7720 {
7721 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7722 operands[1] = operands[2];
7723 }
7724
7725 emit_call_insn (gen_calli (operands[0], operands[1]));
7726 DONE;
7727 }")
7728
7729 (define_insn "call_pop_compact"
7730 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7731 (match_operand 1 "" ""))
7732 (match_operand 2 "immediate_operand" "n")
7733 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7734 (match_operand 3 "immediate_operand" "n")))
7735 (use (reg:SI R0_REG))
7736 (use (reg:SI R1_REG))
7737 (use (reg:PSI FPSCR_REG))
7738 (clobber (reg:SI PR_REG))]
7739 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7740 "jsr @%0%#"
7741 [(set_attr "type" "call")
7742 (set (attr "fp_mode")
7743 (if_then_else (eq_attr "fpu_single" "yes")
7744 (const_string "single") (const_string "double")))
7745 (set_attr "needs_delay_slot" "yes")])
7746
7747 (define_insn "call_pop_compact_rettramp"
7748 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7749 (match_operand 1 "" ""))
7750 (match_operand 2 "immediate_operand" "n")
7751 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7752 (match_operand 3 "immediate_operand" "n")))
7753 (use (reg:SI R0_REG))
7754 (use (reg:SI R1_REG))
7755 (use (reg:PSI FPSCR_REG))
7756 (clobber (reg:SI R10_REG))
7757 (clobber (reg:SI PR_REG))]
7758 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7759 "jsr @%0%#"
7760 [(set_attr "type" "call")
7761 (set (attr "fp_mode")
7762 (if_then_else (eq_attr "fpu_single" "yes")
7763 (const_string "single") (const_string "double")))
7764 (set_attr "needs_delay_slot" "yes")])
7765
7766 (define_expand "call_pop"
7767 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7768 (match_operand 1 "" ""))
7769 (match_operand 2 "" "")
7770 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7771 (match_operand 3 "" "")))])]
7772 "TARGET_SHCOMPACT"
7773 "
7774 {
7775 rtx cookie_rtx;
7776 long cookie;
7777 rtx func;
7778 rtx r0, r1;
7779
7780 gcc_assert (operands[2] && INTVAL (operands[2]));
7781 cookie_rtx = operands[2];
7782 cookie = INTVAL (cookie_rtx);
7783 func = XEXP (operands[0], 0);
7784
7785 if (flag_pic)
7786 {
7787 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7788 {
7789 rtx reg = gen_reg_rtx (Pmode);
7790 emit_insn (gen_symGOTPLT2reg (reg, func));
7791 func = reg;
7792 }
7793 else
7794 func = legitimize_pic_address (func, Pmode, 0);
7795 }
7796
7797 r0 = gen_rtx_REG (SImode, R0_REG);
7798 r1 = gen_rtx_REG (SImode, R1_REG);
7799
7800 /* Since such a call function may use all call-clobbered
7801 registers, we force a mode switch earlier, so that we don't
7802 run out of registers when adjusting fpscr for the call. */
7803 emit_insn (gen_force_mode_for_call ());
7804
7805 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7806 SFUNC_GOT);
7807 operands[0] = force_reg (SImode, operands[0]);
7808
7809 emit_move_insn (r0, func);
7810 emit_move_insn (r1, cookie_rtx);
7811
7812 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7813 emit_call_insn (gen_call_pop_compact_rettramp
7814 (operands[0], operands[1], operands[2], operands[3]));
7815 else
7816 emit_call_insn (gen_call_pop_compact
7817 (operands[0], operands[1], operands[2], operands[3]));
7818
7819 DONE;
7820 }")
7821
7822 (define_expand "call_value"
7823 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7824 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7825 (match_operand 2 "" "")))
7826 (match_operand 3 "" "")
7827 (use (reg:PSI FPSCR_REG))
7828 (clobber (reg:SI PR_REG))])]
7829 ""
7830 "
7831 {
7832 if (TARGET_SHMEDIA)
7833 {
7834 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7835 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7836 operands[2]));
7837 DONE;
7838 }
7839 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7840 {
7841 rtx cookie_rtx = operands[3];
7842 long cookie = INTVAL (cookie_rtx);
7843 rtx func = XEXP (operands[1], 0);
7844 rtx r0, r1;
7845
7846 if (flag_pic)
7847 {
7848 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7849 {
7850 rtx reg = gen_reg_rtx (Pmode);
7851
7852 emit_insn (gen_symGOTPLT2reg (reg, func));
7853 func = reg;
7854 }
7855 else
7856 func = legitimize_pic_address (func, Pmode, 0);
7857 }
7858
7859 r0 = gen_rtx_REG (SImode, R0_REG);
7860 r1 = gen_rtx_REG (SImode, R1_REG);
7861
7862 /* Since such a call function may use all call-clobbered
7863 registers, we force a mode switch earlier, so that we don't
7864 run out of registers when adjusting fpscr for the call. */
7865 emit_insn (gen_force_mode_for_call ());
7866
7867 operands[1]
7868 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7869 SFUNC_GOT);
7870 operands[1] = force_reg (SImode, operands[1]);
7871
7872 emit_move_insn (r0, func);
7873 emit_move_insn (r1, cookie_rtx);
7874
7875 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7876 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7877 operands[1],
7878 operands[2],
7879 operands[3]));
7880 else
7881 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7882 operands[2], operands[3]));
7883
7884 DONE;
7885 }
7886 else if (TARGET_SHCOMPACT && flag_pic
7887 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7888 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7889 {
7890 rtx reg = gen_reg_rtx (Pmode);
7891
7892 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7893 XEXP (operands[1], 0) = reg;
7894 }
7895 if (flag_pic && TARGET_SH2
7896 && GET_CODE (operands[1]) == MEM
7897 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7898 {
7899 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7900 operands[2]));
7901 DONE;
7902 }
7903 else
7904 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7905
7906 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7907 DONE;
7908 }")
7909
7910 (define_insn "sibcalli"
7911 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7912 (match_operand 1 "" ""))
7913 (use (reg:PSI FPSCR_REG))
7914 (return)]
7915 "TARGET_SH1"
7916 "jmp @%0%#"
7917 [(set_attr "needs_delay_slot" "yes")
7918 (set (attr "fp_mode")
7919 (if_then_else (eq_attr "fpu_single" "yes")
7920 (const_string "single") (const_string "double")))
7921 (set_attr "type" "jump_ind")])
7922
7923 (define_insn "sibcalli_pcrel"
7924 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7925 (match_operand 1 "" ""))
7926 (use (match_operand 2 "" ""))
7927 (use (reg:PSI FPSCR_REG))
7928 (return)]
7929 "TARGET_SH2"
7930 "braf %0\\n%O2:%#"
7931 [(set_attr "needs_delay_slot" "yes")
7932 (set (attr "fp_mode")
7933 (if_then_else (eq_attr "fpu_single" "yes")
7934 (const_string "single") (const_string "double")))
7935 (set_attr "type" "jump_ind")])
7936
7937 ;; This uses an unspec to describe that the symbol_ref is very close.
7938 (define_insn "sibcalli_thunk"
7939 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7940 UNSPEC_THUNK))
7941 (match_operand 1 "" ""))
7942 (use (reg:PSI FPSCR_REG))
7943 (return)]
7944 "TARGET_SH1"
7945 "bra %O0"
7946 [(set_attr "needs_delay_slot" "yes")
7947 (set (attr "fp_mode")
7948 (if_then_else (eq_attr "fpu_single" "yes")
7949 (const_string "single") (const_string "double")))
7950 (set_attr "type" "jump")
7951 (set_attr "length" "2")])
7952
7953 (define_insn_and_split "sibcall_pcrel"
7954 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7955 (match_operand 1 "" ""))
7956 (use (reg:PSI FPSCR_REG))
7957 (clobber (match_scratch:SI 2 "=k"))
7958 (return)]
7959 "TARGET_SH2"
7960 "#"
7961 "reload_completed"
7962 [(const_int 0)]
7963 "
7964 {
7965 rtx lab = PATTERN (gen_call_site ());
7966 rtx call_insn;
7967
7968 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7969 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7970 copy_rtx (lab)));
7971 SIBLING_CALL_P (call_insn) = 1;
7972 DONE;
7973 }"
7974 [(set_attr "needs_delay_slot" "yes")
7975 (set (attr "fp_mode")
7976 (if_then_else (eq_attr "fpu_single" "yes")
7977 (const_string "single") (const_string "double")))
7978 (set_attr "type" "jump_ind")])
7979
7980 (define_insn "sibcall_compact"
7981 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7982 (match_operand 1 "" ""))
7983 (return)
7984 (use (match_operand:SI 2 "register_operand" "z,x"))
7985 (use (reg:SI R1_REG))
7986 (use (reg:PSI FPSCR_REG))
7987 ;; We want to make sure the `x' above will only match MACH_REG
7988 ;; because sibcall_epilogue may clobber MACL_REG.
7989 (clobber (reg:SI MACL_REG))]
7990 "TARGET_SHCOMPACT"
7991 "@
7992 jmp @%0%#
7993 jmp @%0\\n sts %2, r0"
7994 [(set_attr "needs_delay_slot" "yes,no")
7995 (set_attr "length" "2,4")
7996 (set (attr "fp_mode") (const_string "single"))
7997 (set_attr "type" "jump_ind")])
7998
7999 (define_insn "sibcall_media"
8000 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8001 (match_operand 1 "" ""))
8002 (use (reg:SI PR_MEDIA_REG))
8003 (return)]
8004 "TARGET_SHMEDIA"
8005 "blink %0, r63"
8006 [(set_attr "type" "jump_media")])
8007
8008 (define_expand "sibcall"
8009 [(parallel
8010 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8011 (match_operand 1 "" ""))
8012 (match_operand 2 "" "")
8013 (use (reg:PSI FPSCR_REG))
8014 (return)])]
8015 ""
8016 "
8017 {
8018 if (TARGET_SHMEDIA)
8019 {
8020 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8021 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8022 DONE;
8023 }
8024 else if (TARGET_SHCOMPACT && operands[2]
8025 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8026 {
8027 rtx cookie_rtx = operands[2];
8028 long cookie = INTVAL (cookie_rtx);
8029 rtx func = XEXP (operands[0], 0);
8030 rtx mach, r1;
8031
8032 if (flag_pic)
8033 {
8034 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8035 {
8036 rtx reg = gen_reg_rtx (Pmode);
8037
8038 emit_insn (gen_symGOT2reg (reg, func));
8039 func = reg;
8040 }
8041 else
8042 func = legitimize_pic_address (func, Pmode, 0);
8043 }
8044
8045 /* FIXME: if we could tell whether all argument registers are
8046 already taken, we could decide whether to force the use of
8047 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8048 simple way to tell. We could use the CALL_COOKIE, but we
8049 can't currently tell a register used for regular argument
8050 passing from one that is unused. If we leave it up to reload
8051 to decide which register to use, it seems to always choose
8052 R0_REG, which leaves no available registers in SIBCALL_REGS
8053 to hold the address of the trampoline. */
8054 mach = gen_rtx_REG (SImode, MACH_REG);
8055 r1 = gen_rtx_REG (SImode, R1_REG);
8056
8057 /* Since such a call function may use all call-clobbered
8058 registers, we force a mode switch earlier, so that we don't
8059 run out of registers when adjusting fpscr for the call. */
8060 emit_insn (gen_force_mode_for_call ());
8061
8062 operands[0]
8063 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8064 SFUNC_GOT);
8065 operands[0] = force_reg (SImode, operands[0]);
8066
8067 /* We don't need a return trampoline, since the callee will
8068 return directly to the upper caller. */
8069 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8070 {
8071 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8072 cookie_rtx = GEN_INT (cookie);
8073 }
8074
8075 emit_move_insn (mach, func);
8076 emit_move_insn (r1, cookie_rtx);
8077
8078 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8079 DONE;
8080 }
8081 else if (TARGET_SHCOMPACT && flag_pic
8082 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8083 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8084 {
8085 rtx reg = gen_reg_rtx (Pmode);
8086
8087 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8088 XEXP (operands[0], 0) = reg;
8089 }
8090 if (flag_pic && TARGET_SH2
8091 && GET_CODE (operands[0]) == MEM
8092 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8093 /* The PLT needs the PIC register, but the epilogue would have
8094 to restore it, so we can only use PC-relative PIC calls for
8095 static functions. */
8096 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8097 {
8098 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8099 DONE;
8100 }
8101 else
8102 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8103
8104 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8105 DONE;
8106 }")
8107
8108 (define_insn "sibcall_valuei"
8109 [(set (match_operand 0 "" "=rf")
8110 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8111 (match_operand 2 "" "")))
8112 (use (reg:PSI FPSCR_REG))
8113 (return)]
8114 "TARGET_SH1"
8115 "jmp @%1%#"
8116 [(set_attr "needs_delay_slot" "yes")
8117 (set (attr "fp_mode")
8118 (if_then_else (eq_attr "fpu_single" "yes")
8119 (const_string "single") (const_string "double")))
8120 (set_attr "type" "jump_ind")])
8121
8122 (define_insn "sibcall_valuei_pcrel"
8123 [(set (match_operand 0 "" "=rf")
8124 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8125 (match_operand 2 "" "")))
8126 (use (match_operand 3 "" ""))
8127 (use (reg:PSI FPSCR_REG))
8128 (return)]
8129 "TARGET_SH2"
8130 "braf %1\\n%O3:%#"
8131 [(set_attr "needs_delay_slot" "yes")
8132 (set (attr "fp_mode")
8133 (if_then_else (eq_attr "fpu_single" "yes")
8134 (const_string "single") (const_string "double")))
8135 (set_attr "type" "jump_ind")])
8136
8137 (define_insn_and_split "sibcall_value_pcrel"
8138 [(set (match_operand 0 "" "=rf")
8139 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8140 (match_operand 2 "" "")))
8141 (use (reg:PSI FPSCR_REG))
8142 (clobber (match_scratch:SI 3 "=k"))
8143 (return)]
8144 "TARGET_SH2"
8145 "#"
8146 "reload_completed"
8147 [(const_int 0)]
8148 "
8149 {
8150 rtx lab = PATTERN (gen_call_site ());
8151 rtx call_insn;
8152
8153 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8154 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8155 operands[3],
8156 operands[2],
8157 copy_rtx (lab)));
8158 SIBLING_CALL_P (call_insn) = 1;
8159 DONE;
8160 }"
8161 [(set_attr "needs_delay_slot" "yes")
8162 (set (attr "fp_mode")
8163 (if_then_else (eq_attr "fpu_single" "yes")
8164 (const_string "single") (const_string "double")))
8165 (set_attr "type" "jump_ind")])
8166
8167 (define_insn "sibcall_value_compact"
8168 [(set (match_operand 0 "" "=rf,rf")
8169 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8170 (match_operand 2 "" "")))
8171 (return)
8172 (use (match_operand:SI 3 "register_operand" "z,x"))
8173 (use (reg:SI R1_REG))
8174 (use (reg:PSI FPSCR_REG))
8175 ;; We want to make sure the `x' above will only match MACH_REG
8176 ;; because sibcall_epilogue may clobber MACL_REG.
8177 (clobber (reg:SI MACL_REG))]
8178 "TARGET_SHCOMPACT"
8179 "@
8180 jmp @%1%#
8181 jmp @%1\\n sts %3, r0"
8182 [(set_attr "needs_delay_slot" "yes,no")
8183 (set_attr "length" "2,4")
8184 (set (attr "fp_mode") (const_string "single"))
8185 (set_attr "type" "jump_ind")])
8186
8187 (define_insn "sibcall_value_media"
8188 [(set (match_operand 0 "" "=rf")
8189 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8190 (match_operand 2 "" "")))
8191 (use (reg:SI PR_MEDIA_REG))
8192 (return)]
8193 "TARGET_SHMEDIA"
8194 "blink %1, r63"
8195 [(set_attr "type" "jump_media")])
8196
8197 (define_expand "sibcall_value"
8198 [(parallel
8199 [(set (match_operand 0 "arith_reg_operand" "")
8200 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8201 (match_operand 2 "" "")))
8202 (match_operand 3 "" "")
8203 (use (reg:PSI FPSCR_REG))
8204 (return)])]
8205 ""
8206 "
8207 {
8208 if (TARGET_SHMEDIA)
8209 {
8210 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8211 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8212 operands[2]));
8213 DONE;
8214 }
8215 else if (TARGET_SHCOMPACT && operands[3]
8216 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8217 {
8218 rtx cookie_rtx = operands[3];
8219 long cookie = INTVAL (cookie_rtx);
8220 rtx func = XEXP (operands[1], 0);
8221 rtx mach, r1;
8222
8223 if (flag_pic)
8224 {
8225 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8226 {
8227 rtx reg = gen_reg_rtx (Pmode);
8228
8229 emit_insn (gen_symGOT2reg (reg, func));
8230 func = reg;
8231 }
8232 else
8233 func = legitimize_pic_address (func, Pmode, 0);
8234 }
8235
8236 /* FIXME: if we could tell whether all argument registers are
8237 already taken, we could decide whether to force the use of
8238 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8239 simple way to tell. We could use the CALL_COOKIE, but we
8240 can't currently tell a register used for regular argument
8241 passing from one that is unused. If we leave it up to reload
8242 to decide which register to use, it seems to always choose
8243 R0_REG, which leaves no available registers in SIBCALL_REGS
8244 to hold the address of the trampoline. */
8245 mach = gen_rtx_REG (SImode, MACH_REG);
8246 r1 = gen_rtx_REG (SImode, R1_REG);
8247
8248 /* Since such a call function may use all call-clobbered
8249 registers, we force a mode switch earlier, so that we don't
8250 run out of registers when adjusting fpscr for the call. */
8251 emit_insn (gen_force_mode_for_call ());
8252
8253 operands[1]
8254 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8255 SFUNC_GOT);
8256 operands[1] = force_reg (SImode, operands[1]);
8257
8258 /* We don't need a return trampoline, since the callee will
8259 return directly to the upper caller. */
8260 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8261 {
8262 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8263 cookie_rtx = GEN_INT (cookie);
8264 }
8265
8266 emit_move_insn (mach, func);
8267 emit_move_insn (r1, cookie_rtx);
8268
8269 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8270 operands[2], mach));
8271 DONE;
8272 }
8273 else if (TARGET_SHCOMPACT && flag_pic
8274 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8275 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8276 {
8277 rtx reg = gen_reg_rtx (Pmode);
8278
8279 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8280 XEXP (operands[1], 0) = reg;
8281 }
8282 if (flag_pic && TARGET_SH2
8283 && GET_CODE (operands[1]) == MEM
8284 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8285 /* The PLT needs the PIC register, but the epilogue would have
8286 to restore it, so we can only use PC-relative PIC calls for
8287 static functions. */
8288 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8289 {
8290 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8291 XEXP (operands[1], 0),
8292 operands[2]));
8293 DONE;
8294 }
8295 else
8296 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8297
8298 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8299 DONE;
8300 }")
8301
8302 (define_insn "call_value_pop_compact"
8303 [(set (match_operand 0 "" "=rf")
8304 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8305 (match_operand 2 "" "")))
8306 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8307 (match_operand 4 "immediate_operand" "n")))
8308 (match_operand 3 "immediate_operand" "n")
8309 (use (reg:SI R0_REG))
8310 (use (reg:SI R1_REG))
8311 (use (reg:PSI FPSCR_REG))
8312 (clobber (reg:SI PR_REG))]
8313 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8314 "jsr @%1%#"
8315 [(set_attr "type" "call")
8316 (set (attr "fp_mode")
8317 (if_then_else (eq_attr "fpu_single" "yes")
8318 (const_string "single") (const_string "double")))
8319 (set_attr "needs_delay_slot" "yes")])
8320
8321 (define_insn "call_value_pop_compact_rettramp"
8322 [(set (match_operand 0 "" "=rf")
8323 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8324 (match_operand 2 "" "")))
8325 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8326 (match_operand 4 "immediate_operand" "n")))
8327 (match_operand 3 "immediate_operand" "n")
8328 (use (reg:SI R0_REG))
8329 (use (reg:SI R1_REG))
8330 (use (reg:PSI FPSCR_REG))
8331 (clobber (reg:SI R10_REG))
8332 (clobber (reg:SI PR_REG))]
8333 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8334 "jsr @%1%#"
8335 [(set_attr "type" "call")
8336 (set (attr "fp_mode")
8337 (if_then_else (eq_attr "fpu_single" "yes")
8338 (const_string "single") (const_string "double")))
8339 (set_attr "needs_delay_slot" "yes")])
8340
8341 (define_expand "call_value_pop"
8342 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8343 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8344 (match_operand 2 "" "")))
8345 (match_operand 3 "" "")
8346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8347 (match_operand 4 "" "")))])]
8348 "TARGET_SHCOMPACT"
8349 "
8350 {
8351 rtx cookie_rtx;
8352 long cookie;
8353 rtx func;
8354 rtx r0, r1;
8355
8356 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8357 cookie_rtx = operands[3];
8358 cookie = INTVAL (cookie_rtx);
8359 func = XEXP (operands[1], 0);
8360
8361 if (flag_pic)
8362 {
8363 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8364 {
8365 rtx reg = gen_reg_rtx (Pmode);
8366
8367 emit_insn (gen_symGOTPLT2reg (reg, func));
8368 func = reg;
8369 }
8370 else
8371 func = legitimize_pic_address (func, Pmode, 0);
8372 }
8373
8374 r0 = gen_rtx_REG (SImode, R0_REG);
8375 r1 = gen_rtx_REG (SImode, R1_REG);
8376
8377 /* Since such a call function may use all call-clobbered
8378 registers, we force a mode switch earlier, so that we don't
8379 run out of registers when adjusting fpscr for the call. */
8380 emit_insn (gen_force_mode_for_call ());
8381
8382 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8383 SFUNC_GOT);
8384 operands[1] = force_reg (SImode, operands[1]);
8385
8386 emit_move_insn (r0, func);
8387 emit_move_insn (r1, cookie_rtx);
8388
8389 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8390 emit_call_insn (gen_call_value_pop_compact_rettramp
8391 (operands[0], operands[1], operands[2],
8392 operands[3], operands[4]));
8393 else
8394 emit_call_insn (gen_call_value_pop_compact
8395 (operands[0], operands[1], operands[2],
8396 operands[3], operands[4]));
8397
8398 DONE;
8399 }")
8400
8401 (define_expand "sibcall_epilogue"
8402 [(return)]
8403 ""
8404 "
8405 {
8406 sh_expand_epilogue (1);
8407 if (TARGET_SHCOMPACT)
8408 {
8409 rtx insn, set;
8410
8411 /* If epilogue clobbers r0, preserve it in macl. */
8412 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8413 if ((set = single_set (insn))
8414 && GET_CODE (SET_DEST (set)) == REG
8415 && REGNO (SET_DEST (set)) == R0_REG)
8416 {
8417 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8418 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8419
8420 /* We can't tell at this point whether the sibcall is a
8421 sibcall_compact and, if it is, whether it uses r0 or
8422 mach as operand 2, so let the instructions that
8423 preserve r0 be optimized away if r0 turns out to be
8424 dead. */
8425 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8426 emit_move_insn (r0, tmp);
8427 break;
8428 }
8429 }
8430 DONE;
8431 }")
8432
8433 (define_insn "indirect_jump_compact"
8434 [(set (pc)
8435 (match_operand:SI 0 "arith_reg_operand" "r"))]
8436 "TARGET_SH1"
8437 "jmp @%0%#"
8438 [(set_attr "needs_delay_slot" "yes")
8439 (set_attr "type" "jump_ind")])
8440
8441 (define_expand "indirect_jump"
8442 [(set (pc)
8443 (match_operand 0 "register_operand" ""))]
8444 ""
8445 "
8446 {
8447 if (GET_MODE (operands[0]) != Pmode)
8448 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8449 }")
8450
8451 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8452 ;; which can be present in structured code from indirect jumps which can not
8453 ;; be present in structured code. This allows -fprofile-arcs to work.
8454
8455 ;; For SH1 processors.
8456 (define_insn "casesi_jump_1"
8457 [(set (pc)
8458 (match_operand:SI 0 "register_operand" "r"))
8459 (use (label_ref (match_operand 1 "" "")))]
8460 "TARGET_SH1"
8461 "jmp @%0%#"
8462 [(set_attr "needs_delay_slot" "yes")
8463 (set_attr "type" "jump_ind")])
8464
8465 ;; For all later processors.
8466 (define_insn "casesi_jump_2"
8467 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8468 (label_ref (match_operand 1 "" ""))))
8469 (use (label_ref (match_operand 2 "" "")))]
8470 "TARGET_SH2
8471 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8472 "braf %0%#"
8473 [(set_attr "needs_delay_slot" "yes")
8474 (set_attr "type" "jump_ind")])
8475
8476 (define_insn "casesi_jump_media"
8477 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8478 (use (label_ref (match_operand 1 "" "")))]
8479 "TARGET_SHMEDIA"
8480 "blink %0, r63"
8481 [(set_attr "type" "jump_media")])
8482
8483 ;; Call subroutine returning any type.
8484 ;; ??? This probably doesn't work.
8485
8486 (define_expand "untyped_call"
8487 [(parallel [(call (match_operand 0 "" "")
8488 (const_int 0))
8489 (match_operand 1 "" "")
8490 (match_operand 2 "" "")])]
8491 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8492 "
8493 {
8494 int i;
8495
8496 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8497
8498 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8499 {
8500 rtx set = XVECEXP (operands[2], 0, i);
8501 emit_move_insn (SET_DEST (set), SET_SRC (set));
8502 }
8503
8504 /* The optimizer does not know that the call sets the function value
8505 registers we stored in the result block. We avoid problems by
8506 claiming that all hard registers are used and clobbered at this
8507 point. */
8508 emit_insn (gen_blockage ());
8509
8510 DONE;
8511 }")
8512 \f
8513 ;; ------------------------------------------------------------------------
8514 ;; Misc insns
8515 ;; ------------------------------------------------------------------------
8516
8517 (define_insn "dect"
8518 [(set (reg:SI T_REG)
8519 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8520 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8521 "TARGET_SH2"
8522 "dt %0"
8523 [(set_attr "type" "arith")])
8524
8525 (define_insn "nop"
8526 [(const_int 0)]
8527 ""
8528 "nop")
8529
8530 ;; Load address of a label. This is only generated by the casesi expand,
8531 ;; and by machine_dependent_reorg (fixing up fp moves).
8532 ;; This must use unspec, because this only works for labels that are
8533 ;; within range,
8534
8535 (define_insn "mova"
8536 [(set (reg:SI R0_REG)
8537 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8538 "TARGET_SH1"
8539 "mova %O0,r0"
8540 [(set_attr "in_delay_slot" "no")
8541 (set_attr "type" "arith")])
8542
8543 ;; machine_dependent_reorg will make this a `mova'.
8544 (define_insn "mova_const"
8545 [(set (reg:SI R0_REG)
8546 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8547 "TARGET_SH1"
8548 "#"
8549 [(set_attr "in_delay_slot" "no")
8550 (set_attr "type" "arith")])
8551
8552 (define_expand "GOTaddr2picreg"
8553 [(set (reg:SI R0_REG)
8554 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8555 UNSPEC_MOVA))
8556 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8557 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8558 "" "
8559 {
8560 if (TARGET_VXWORKS_RTP)
8561 {
8562 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8563 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8564 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8565 DONE;
8566 }
8567
8568 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8569 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8570
8571 if (TARGET_SHMEDIA)
8572 {
8573 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8574 rtx pic = operands[0];
8575 rtx lab = PATTERN (gen_call_site ());
8576 rtx insn, equiv;
8577
8578 equiv = operands[1];
8579 operands[1] = gen_rtx_MINUS (Pmode,
8580 operands[1],
8581 gen_rtx_CONST
8582 (Pmode,
8583 gen_rtx_MINUS (Pmode,
8584 gen_rtx_CONST (Pmode,
8585 lab),
8586 pc_rtx)));
8587 operands[1] = gen_sym2PIC (operands[1]);
8588 PUT_MODE (operands[1], Pmode);
8589
8590 if (Pmode == SImode)
8591 {
8592 emit_insn (gen_movsi_const (pic, operands[1]));
8593 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8594 }
8595 else
8596 {
8597 emit_insn (gen_movdi_const (pic, operands[1]));
8598 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8599 }
8600
8601 insn = emit_move_insn (operands[0], tr);
8602
8603 set_unique_reg_note (insn, REG_EQUAL, equiv);
8604
8605 DONE;
8606 }
8607 }
8608 ")
8609
8610 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8611 ;; PIC register.
8612
8613 (define_expand "vxworks_picreg"
8614 [(set (reg:SI PIC_REG)
8615 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8616 (set (reg:SI R0_REG)
8617 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8618 (set (reg:SI PIC_REG)
8619 (mem:SI (reg:SI PIC_REG)))
8620 (set (reg:SI PIC_REG)
8621 (mem:SI (plus:SI (reg:SI PIC_REG)
8622 (reg:SI R0_REG))))]
8623 "TARGET_VXWORKS_RTP")
8624
8625 (define_insn "*ptb"
8626 [(set (match_operand 0 "target_reg_operand" "=b")
8627 (const (unspec [(match_operand 1 "" "Csy")]
8628 UNSPEC_DATALABEL)))]
8629 "TARGET_SHMEDIA && flag_pic
8630 && satisfies_constraint_Csy (operands[1])"
8631 "ptb/u datalabel %1, %0"
8632 [(set_attr "type" "ptabs_media")
8633 (set_attr "length" "*")])
8634
8635 (define_insn "ptrel_si"
8636 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8637 (plus:SI (match_operand:SI 1 "register_operand" "r")
8638 (pc)))
8639 (match_operand:SI 2 "" "")]
8640 "TARGET_SHMEDIA"
8641 "%O2: ptrel/u %1, %0"
8642 [(set_attr "type" "ptabs_media")])
8643
8644 (define_insn "ptrel_di"
8645 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8646 (plus:DI (match_operand:DI 1 "register_operand" "r")
8647 (pc)))
8648 (match_operand:DI 2 "" "")]
8649 "TARGET_SHMEDIA"
8650 "%O2: ptrel/u %1, %0"
8651 [(set_attr "type" "ptabs_media")])
8652
8653 (define_expand "builtin_setjmp_receiver"
8654 [(match_operand 0 "" "")]
8655 "flag_pic"
8656 "
8657 {
8658 emit_insn (gen_GOTaddr2picreg ());
8659 DONE;
8660 }")
8661
8662 (define_expand "call_site"
8663 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8664 "TARGET_SH1"
8665 "
8666 {
8667 static HOST_WIDE_INT i = 0;
8668 operands[0] = GEN_INT (i);
8669 i++;
8670 }")
8671
8672 (define_expand "sym_label2reg"
8673 [(set (match_operand:SI 0 "" "")
8674 (const:SI (minus:SI
8675 (const:SI
8676 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8677 (const:SI
8678 (plus:SI
8679 (match_operand:SI 2 "" "")
8680 (const_int 2))))))]
8681 "TARGET_SH1" "")
8682
8683 (define_expand "symGOT_load"
8684 [(set (match_dup 2) (match_operand 1 "" ""))
8685 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8686 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8687 ""
8688 "
8689 {
8690 rtx insn, mem;
8691
8692 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8693 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8694
8695 if (TARGET_SHMEDIA)
8696 {
8697 rtx reg = operands[2];
8698
8699 if (Pmode == DImode)
8700 {
8701 if (flag_pic > 1)
8702 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8703 else
8704 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8705 }
8706 else
8707 {
8708 if (flag_pic > 1)
8709 emit_insn (gen_movsi_const (reg, operands[1]));
8710 else
8711 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8712 }
8713 }
8714 else
8715 emit_move_insn (operands[2], operands[1]);
8716
8717 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8718 operands[2],
8719 gen_rtx_REG (Pmode, PIC_REG)));
8720
8721 /* When stack protector inserts codes after the result is set to
8722 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8723 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8724 when rX is a GOT address for the guard symbol. Ugly but doesn't
8725 matter because this is a rare situation. */
8726 if (!TARGET_SHMEDIA
8727 && flag_stack_protect
8728 && GET_CODE (operands[1]) == CONST
8729 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8730 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8731 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8732 \"__stack_chk_guard\") == 0)
8733 emit_insn (gen_blockage ());
8734
8735 /* N.B. This is not constant for a GOTPLT relocation. */
8736 mem = gen_rtx_MEM (Pmode, operands[3]);
8737 MEM_NOTRAP_P (mem) = 1;
8738 /* ??? Should we have a special alias set for the GOT? */
8739 insn = emit_move_insn (operands[0], mem);
8740
8741 set_unique_reg_note (insn, REG_EQUAL,
8742 XVECEXP (XEXP (operands[1], 0), 0, 0));
8743
8744 DONE;
8745 }")
8746
8747 (define_expand "sym2GOT"
8748 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8749 ""
8750 "")
8751
8752 (define_expand "symGOT2reg"
8753 [(match_operand 0 "" "") (match_operand 1 "" "")]
8754 ""
8755 "
8756 {
8757 rtx gotsym, insn;
8758
8759 gotsym = gen_sym2GOT (operands[1]);
8760 PUT_MODE (gotsym, Pmode);
8761 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8762
8763 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8764
8765 DONE;
8766 }")
8767
8768 (define_expand "symGOTPLT2reg"
8769 [(match_operand 0 "" "") (match_operand 1 "" "")]
8770 ""
8771 "
8772 {
8773 rtx pltsym = gen_rtx_CONST (Pmode,
8774 gen_rtx_UNSPEC (Pmode,
8775 gen_rtvec (1, operands[1]),
8776 UNSPEC_GOTPLT));
8777 emit_insn (gen_symGOT_load (operands[0], pltsym));
8778 DONE;
8779 }")
8780
8781 (define_expand "sym2GOTOFF"
8782 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8783 ""
8784 "")
8785
8786 (define_expand "symGOTOFF2reg"
8787 [(match_operand 0 "" "") (match_operand 1 "" "")]
8788 ""
8789 "
8790 {
8791 rtx gotoffsym, insn;
8792 rtx t = (!can_create_pseudo_p ()
8793 ? operands[0]
8794 : gen_reg_rtx (GET_MODE (operands[0])));
8795
8796 gotoffsym = gen_sym2GOTOFF (operands[1]);
8797 PUT_MODE (gotoffsym, Pmode);
8798 emit_move_insn (t, gotoffsym);
8799 insn = emit_move_insn (operands[0],
8800 gen_rtx_PLUS (Pmode, t,
8801 gen_rtx_REG (Pmode, PIC_REG)));
8802
8803 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8804
8805 DONE;
8806 }")
8807
8808 (define_expand "symPLT_label2reg"
8809 [(set (match_operand:SI 0 "" "")
8810 (const:SI (minus:SI
8811 (const:SI
8812 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8813 (const:SI
8814 (minus:SI
8815 (const:SI (plus:SI
8816 (match_operand:SI 2 "" "")
8817 (const_int 2)))
8818 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8819 ;; Even though the PIC register is not really used by the call
8820 ;; sequence in which this is expanded, the PLT code assumes the PIC
8821 ;; register is set, so we must not skip its initialization. Since
8822 ;; we only use this expand as part of calling sequences, and never
8823 ;; to take the address of a function, this is the best point to
8824 ;; insert the (use). Using the PLT to take the address of a
8825 ;; function would be wrong, not only because the PLT entry could
8826 ;; then be called from a function that doesn't initialize the PIC
8827 ;; register to the proper GOT, but also because pointers to the
8828 ;; same function might not compare equal, should they be set by
8829 ;; different shared libraries.
8830 (use (reg:SI PIC_REG))]
8831 "TARGET_SH1"
8832 "")
8833
8834 (define_expand "sym2PIC"
8835 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8836 ""
8837 "")
8838
8839 ;; TLS code generation.
8840 ;; ??? this should be a define_insn_and_split
8841 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8842 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8843 ;; for details.
8844
8845 (define_insn "tls_global_dynamic"
8846 [(set (match_operand:SI 0 "register_operand" "=&z")
8847 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8848 UNSPEC_TLSGD))
8849 (const_int 0)))
8850 (use (reg:PSI FPSCR_REG))
8851 (use (reg:SI PIC_REG))
8852 (clobber (reg:SI PR_REG))
8853 (clobber (scratch:SI))]
8854 "TARGET_SH1"
8855 "*
8856 {
8857 return \"\\
8858 mov.l\\t1f,r4\\n\\
8859 \\tmova\\t2f,r0\\n\\
8860 \\tmov.l\\t2f,r1\\n\\
8861 \\tadd\\tr0,r1\\n\\
8862 \\tjsr\\t@r1\\n\\
8863 \\tadd\\tr12,r4\\n\\
8864 \\tbra\\t3f\\n\\
8865 \\tnop\\n\\
8866 \\t.align\\t2\\n\\
8867 1:\\t.long\\t%a1@TLSGD\\n\\
8868 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8869 3:\";
8870 }"
8871 [(set_attr "type" "tls_load")
8872 (set_attr "length" "26")])
8873
8874 (define_insn "tls_local_dynamic"
8875 [(set (match_operand:SI 0 "register_operand" "=&z")
8876 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8877 UNSPEC_TLSLDM))
8878 (const_int 0)))
8879 (use (reg:PSI FPSCR_REG))
8880 (use (reg:SI PIC_REG))
8881 (clobber (reg:SI PR_REG))
8882 (clobber (scratch:SI))]
8883 "TARGET_SH1"
8884 "*
8885 {
8886 return \"\\
8887 mov.l\\t1f,r4\\n\\
8888 \\tmova\\t2f,r0\\n\\
8889 \\tmov.l\\t2f,r1\\n\\
8890 \\tadd\\tr0,r1\\n\\
8891 \\tjsr\\t@r1\\n\\
8892 \\tadd\\tr12,r4\\n\\
8893 \\tbra\\t3f\\n\\
8894 \\tnop\\n\\
8895 \\t.align\\t2\\n\\
8896 1:\\t.long\\t%a1@TLSLDM\\n\\
8897 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8898 3:\";
8899 }"
8900 [(set_attr "type" "tls_load")
8901 (set_attr "length" "26")])
8902
8903 (define_expand "sym2DTPOFF"
8904 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8905 ""
8906 "")
8907
8908 (define_expand "symDTPOFF2reg"
8909 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8910 ""
8911 "
8912 {
8913 rtx dtpoffsym, insn;
8914 rtx t = (!can_create_pseudo_p ()
8915 ? operands[0]
8916 : gen_reg_rtx (GET_MODE (operands[0])));
8917
8918 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8919 PUT_MODE (dtpoffsym, Pmode);
8920 emit_move_insn (t, dtpoffsym);
8921 insn = emit_move_insn (operands[0],
8922 gen_rtx_PLUS (Pmode, t, operands[2]));
8923 DONE;
8924 }")
8925
8926 (define_expand "sym2GOTTPOFF"
8927 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8928 ""
8929 "")
8930
8931 (define_insn "tls_initial_exec"
8932 [(set (match_operand:SI 0 "register_operand" "=&r")
8933 (unspec:SI [(match_operand:SI 1 "" "")]
8934 UNSPEC_TLSIE))
8935 (use (reg:SI GBR_REG))
8936 (use (reg:SI PIC_REG))
8937 (clobber (reg:SI R0_REG))]
8938 ""
8939 "*
8940 {
8941 return \"\\
8942 mov.l\\t1f,r0\\n\\
8943 \\tstc\\tgbr,%0\\n\\
8944 \\tmov.l\\t@(r0,r12),r0\\n\\
8945 \\tbra\\t2f\\n\\
8946 \\tadd\\tr0,%0\\n\\
8947 \\t.align\\t2\\n\\
8948 1:\\t.long\\t%a1\\n\\
8949 2:\";
8950 }"
8951 [(set_attr "type" "tls_load")
8952 (set_attr "length" "16")])
8953
8954 (define_expand "sym2TPOFF"
8955 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8956 ""
8957 "")
8958
8959 (define_expand "symTPOFF2reg"
8960 [(match_operand 0 "" "") (match_operand 1 "" "")]
8961 ""
8962 "
8963 {
8964 rtx tpoffsym, insn;
8965
8966 tpoffsym = gen_sym2TPOFF (operands[1]);
8967 PUT_MODE (tpoffsym, Pmode);
8968 insn = emit_move_insn (operands[0], tpoffsym);
8969 DONE;
8970 }")
8971
8972 (define_insn "load_gbr"
8973 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8974 (use (reg:SI GBR_REG))]
8975 ""
8976 "stc gbr,%0"
8977 [(set_attr "type" "tls_load")])
8978
8979 ;; case instruction for switch statements.
8980
8981 ;; Operand 0 is index
8982 ;; operand 1 is the minimum bound
8983 ;; operand 2 is the maximum bound - minimum bound + 1
8984 ;; operand 3 is CODE_LABEL for the table;
8985 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8986
8987 (define_expand "casesi"
8988 [(match_operand:SI 0 "arith_reg_operand" "")
8989 (match_operand:SI 1 "arith_reg_operand" "")
8990 (match_operand:SI 2 "arith_reg_operand" "")
8991 (match_operand 3 "" "") (match_operand 4 "" "")]
8992 ""
8993 "
8994 {
8995 rtx reg = gen_reg_rtx (SImode);
8996 rtx reg2 = gen_reg_rtx (SImode);
8997 if (TARGET_SHMEDIA)
8998 {
8999 rtx reg = gen_reg_rtx (DImode);
9000 rtx reg2 = gen_reg_rtx (DImode);
9001 rtx reg3 = gen_reg_rtx (Pmode);
9002 rtx reg4 = gen_reg_rtx (Pmode);
9003 rtx reg5 = gen_reg_rtx (Pmode);
9004 rtx load;
9005
9006 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9007 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9008 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9009
9010 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9011 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9012 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9013 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9014 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9015 (Pmode, operands[3])));
9016 /* Messy: can we subreg to clean this up? */
9017 if (Pmode == DImode)
9018 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9019 else
9020 load = gen_casesi_load_media (reg4,
9021 gen_rtx_SUBREG (DImode, reg3, 0),
9022 reg2, operands[3]);
9023 PUT_MODE (SET_SRC (load), Pmode);
9024 emit_insn (load);
9025 /* ??? The following add could be eliminated if we used ptrel. */
9026 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9027 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9028 emit_barrier ();
9029 DONE;
9030 }
9031 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9032 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9033 /* If optimizing, casesi_worker depends on the mode of the instruction
9034 before label it 'uses' - operands[3]. */
9035 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9036 reg));
9037 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9038 if (TARGET_SH2)
9039 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9040 else
9041 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9042 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9043 operands[3], but to lab. We will fix this up in
9044 machine_dependent_reorg. */
9045 emit_barrier ();
9046 DONE;
9047 }")
9048
9049 (define_expand "casesi_0"
9050 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9051 (set (match_dup 4) (minus:SI (match_dup 4)
9052 (match_operand:SI 1 "arith_operand" "")))
9053 (set (reg:SI T_REG)
9054 (gtu:SI (match_dup 4)
9055 (match_operand:SI 2 "arith_reg_operand" "")))
9056 (set (pc)
9057 (if_then_else (ne (reg:SI T_REG)
9058 (const_int 0))
9059 (label_ref (match_operand 3 "" ""))
9060 (pc)))]
9061 "TARGET_SH1"
9062 "")
9063
9064 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9065 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9066 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9067
9068 (define_insn "casesi_worker_0"
9069 [(set (match_operand:SI 0 "register_operand" "=r,r")
9070 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9071 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9072 (clobber (match_scratch:SI 3 "=X,1"))
9073 (clobber (match_scratch:SI 4 "=&z,z"))]
9074 "TARGET_SH1"
9075 "#")
9076
9077 (define_split
9078 [(set (match_operand:SI 0 "register_operand" "")
9079 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9080 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9081 (clobber (match_scratch:SI 3 ""))
9082 (clobber (match_scratch:SI 4 ""))]
9083 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9084 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9085 (parallel [(set (match_dup 0)
9086 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9087 (label_ref (match_dup 2))] UNSPEC_CASESI))
9088 (clobber (match_dup 3))])
9089 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9090 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9091
9092 (define_split
9093 [(set (match_operand:SI 0 "register_operand" "")
9094 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9095 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9096 (clobber (match_scratch:SI 3 ""))
9097 (clobber (match_scratch:SI 4 ""))]
9098 "TARGET_SH2 && reload_completed"
9099 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9100 (parallel [(set (match_dup 0)
9101 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9102 (label_ref (match_dup 2))] UNSPEC_CASESI))
9103 (clobber (match_dup 3))])]
9104 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9105
9106 (define_insn "casesi_worker_1"
9107 [(set (match_operand:SI 0 "register_operand" "=r,r")
9108 (unspec:SI [(reg:SI R0_REG)
9109 (match_operand:SI 1 "register_operand" "0,r")
9110 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9111 (clobber (match_scratch:SI 3 "=X,1"))]
9112 "TARGET_SH1"
9113 "*
9114 {
9115 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9116
9117 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9118
9119 switch (GET_MODE (diff_vec))
9120 {
9121 case SImode:
9122 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9123 case HImode:
9124 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9125 case QImode:
9126 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9127 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9128 return \"mov.b @(r0,%1),%0\";
9129 default:
9130 gcc_unreachable ();
9131 }
9132 }"
9133 [(set_attr "length" "4")])
9134
9135 (define_insn "casesi_worker_2"
9136 [(set (match_operand:SI 0 "register_operand" "=r,r")
9137 (unspec:SI [(reg:SI R0_REG)
9138 (match_operand:SI 1 "register_operand" "0,r")
9139 (label_ref (match_operand 2 "" ""))
9140 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9141 (clobber (match_operand:SI 4 "" "=X,1"))]
9142 "TARGET_SH2 && reload_completed && flag_pic"
9143 "*
9144 {
9145 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9146 const char *load;
9147
9148 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9149
9150 switch (GET_MODE (diff_vec))
9151 {
9152 case SImode:
9153 output_asm_insn (\"shll2 %1\", operands);
9154 load = \"mov.l @(r0,%1),%0\"; break;
9155 case HImode:
9156 output_asm_insn (\"add %1,%1\", operands);
9157 load = \"mov.w @(r0,%1),%0\"; break;
9158 case QImode:
9159 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9160 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9161 else
9162 load = \"mov.b @(r0,%1),%0\";
9163 break;
9164 default:
9165 gcc_unreachable ();
9166 }
9167 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9168 return load;
9169 }"
9170 [(set_attr "length" "8")])
9171
9172 (define_insn "casesi_shift_media"
9173 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9174 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9175 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9176 UNSPEC_CASESI)))]
9177 "TARGET_SHMEDIA"
9178 "*
9179 {
9180 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9181
9182 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9183
9184 switch (GET_MODE (diff_vec))
9185 {
9186 case SImode:
9187 return \"shlli %1, 2, %0\";
9188 case HImode:
9189 return \"shlli %1, 1, %0\";
9190 case QImode:
9191 if (rtx_equal_p (operands[0], operands[1]))
9192 return \"\";
9193 return \"add %1, r63, %0\";
9194 default:
9195 gcc_unreachable ();
9196 }
9197 }"
9198 [(set_attr "type" "arith_media")])
9199
9200 (define_insn "casesi_load_media"
9201 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9202 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9203 (match_operand:DI 2 "arith_reg_operand" "r")
9204 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9205 "TARGET_SHMEDIA"
9206 "*
9207 {
9208 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9209
9210 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9211
9212 switch (GET_MODE (diff_vec))
9213 {
9214 case SImode:
9215 return \"ldx.l %1, %2, %0\";
9216 case HImode:
9217 #if 0
9218 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9219 return \"ldx.uw %1, %2, %0\";
9220 #endif
9221 return \"ldx.w %1, %2, %0\";
9222 case QImode:
9223 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9224 return \"ldx.ub %1, %2, %0\";
9225 return \"ldx.b %1, %2, %0\";
9226 default:
9227 gcc_unreachable ();
9228 }
9229 }"
9230 [(set_attr "type" "load_media")])
9231
9232 (define_expand "return"
9233 [(return)]
9234 "reload_completed && ! sh_need_epilogue ()"
9235 "
9236 {
9237 if (TARGET_SHMEDIA)
9238 {
9239 emit_jump_insn (gen_return_media ());
9240 DONE;
9241 }
9242
9243 if (TARGET_SHCOMPACT
9244 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9245 {
9246 emit_jump_insn (gen_shcompact_return_tramp ());
9247 DONE;
9248 }
9249 }")
9250
9251 (define_insn "*return_i"
9252 [(return)]
9253 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9254 && (current_function_args_info.call_cookie
9255 & CALL_COOKIE_RET_TRAMP (1)))
9256 && reload_completed
9257 && lookup_attribute (\"trap_exit\",
9258 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9259 "%@ %#"
9260 [(set_attr "type" "return")
9261 (set_attr "needs_delay_slot" "yes")])
9262
9263 ;; trapa has no delay slot.
9264 (define_insn "*return_trapa"
9265 [(return)]
9266 "TARGET_SH1 && !TARGET_SHCOMPACT
9267 && reload_completed"
9268 "%@"
9269 [(set_attr "type" "return")])
9270
9271 (define_expand "shcompact_return_tramp"
9272 [(return)]
9273 "TARGET_SHCOMPACT
9274 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9275 "
9276 {
9277 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9278
9279 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9280 emit_jump_insn (gen_shcompact_return_tramp_i ());
9281 DONE;
9282 }")
9283
9284 (define_insn "shcompact_return_tramp_i"
9285 [(parallel [(return) (use (reg:SI R0_REG))])]
9286 "TARGET_SHCOMPACT
9287 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9288 "jmp @r0%#"
9289 [(set_attr "type" "jump_ind")
9290 (set_attr "needs_delay_slot" "yes")])
9291
9292 (define_insn "return_media_i"
9293 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9294 "TARGET_SHMEDIA && reload_completed"
9295 "blink %0, r63"
9296 [(set_attr "type" "jump_media")])
9297
9298 (define_insn "return_media_rte"
9299 [(return)]
9300 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9301 "rte"
9302 [(set_attr "type" "jump_media")])
9303
9304 (define_expand "return_media"
9305 [(return)]
9306 "TARGET_SHMEDIA && reload_completed"
9307 "
9308 {
9309 int tr_regno = sh_media_register_for_return ();
9310 rtx tr;
9311
9312 if (current_function_interrupt)
9313 {
9314 emit_jump_insn (gen_return_media_rte ());
9315 DONE;
9316 }
9317 if (tr_regno < 0)
9318 {
9319 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9320
9321 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9322 tr_regno = TR0_REG;
9323 tr = gen_rtx_REG (Pmode, tr_regno);
9324 emit_move_insn (tr, r18);
9325 }
9326 else
9327 tr = gen_rtx_REG (Pmode, tr_regno);
9328
9329 emit_jump_insn (gen_return_media_i (tr));
9330 DONE;
9331 }")
9332
9333 (define_insn "shcompact_preserve_incoming_args"
9334 [(set (match_operand:SI 0 "register_operand" "+r")
9335 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9336 "TARGET_SHCOMPACT"
9337 ""
9338 [(set_attr "length" "0")])
9339
9340 (define_insn "shcompact_incoming_args"
9341 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9342 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9343 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9344 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9345 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9346 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9347 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9348 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9349 (set (mem:BLK (reg:SI MACL_REG))
9350 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9351 (use (reg:SI R0_REG))
9352 (clobber (reg:SI R0_REG))
9353 (clobber (reg:SI MACL_REG))
9354 (clobber (reg:SI MACH_REG))
9355 (clobber (reg:SI PR_REG))]
9356 "TARGET_SHCOMPACT"
9357 "jsr @r0%#"
9358 [(set_attr "needs_delay_slot" "yes")])
9359
9360 (define_insn "shmedia_save_restore_regs_compact"
9361 [(set (reg:SI SP_REG)
9362 (plus:SI (reg:SI SP_REG)
9363 (match_operand:SI 0 "immediate_operand" "i")))
9364 (use (reg:SI R0_REG))
9365 (clobber (reg:SI PR_REG))]
9366 "TARGET_SHCOMPACT
9367 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9368 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9369 "jsr @r0%#"
9370 [(set_attr "needs_delay_slot" "yes")])
9371
9372 (define_expand "prologue"
9373 [(const_int 0)]
9374 ""
9375 "sh_expand_prologue (); DONE;")
9376
9377 (define_expand "epilogue"
9378 [(return)]
9379 ""
9380 "
9381 {
9382 sh_expand_epilogue (0);
9383 emit_jump_insn (gen_return ());
9384 DONE;
9385 }")
9386
9387 (define_expand "eh_return"
9388 [(use (match_operand 0 "register_operand" ""))]
9389 ""
9390 {
9391 rtx ra = operands[0];
9392
9393 if (TARGET_SHMEDIA64)
9394 emit_insn (gen_eh_set_ra_di (ra));
9395 else
9396 emit_insn (gen_eh_set_ra_si (ra));
9397
9398 DONE;
9399 })
9400
9401 ;; Clobber the return address on the stack. We can't expand this
9402 ;; until we know where it will be put in the stack frame.
9403
9404 (define_insn "eh_set_ra_si"
9405 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9406 UNSPECV_EH_RETURN)
9407 (clobber (match_scratch:SI 1 "=&r"))]
9408 "! TARGET_SHMEDIA64"
9409 "#")
9410
9411 (define_insn "eh_set_ra_di"
9412 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9413 UNSPECV_EH_RETURN)
9414 (clobber (match_scratch:DI 1 "=&r"))]
9415 "TARGET_SHMEDIA64"
9416 "#")
9417
9418 (define_split
9419 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9420 UNSPECV_EH_RETURN)
9421 (clobber (match_scratch 1 ""))]
9422 "reload_completed"
9423 [(const_int 0)]
9424 "
9425 {
9426 sh_set_return_address (operands[0], operands[1]);
9427 DONE;
9428 }")
9429
9430 (define_insn "blockage"
9431 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9432 ""
9433 ""
9434 [(set_attr "length" "0")])
9435 \f
9436 ;; ------------------------------------------------------------------------
9437 ;; Scc instructions
9438 ;; ------------------------------------------------------------------------
9439
9440 (define_insn "movt"
9441 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9442 (eq:SI (reg:SI T_REG) (const_int 1)))]
9443 "TARGET_SH1"
9444 "movt %0"
9445 [(set_attr "type" "arith")])
9446
9447 (define_expand "seq"
9448 [(set (match_operand:SI 0 "arith_reg_dest" "")
9449 (match_dup 1))]
9450 ""
9451 "
9452 {
9453 if (TARGET_SHMEDIA)
9454 {
9455 rtx reg;
9456
9457 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9458 if (sh_compare_op1 != const0_rtx)
9459 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9460 ? GET_MODE (sh_compare_op0)
9461 : GET_MODE (sh_compare_op1),
9462 sh_compare_op1);
9463 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9464 {
9465 if (GET_MODE (operands[0]) != SImode)
9466 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9467
9468 switch (GET_MODE (sh_compare_op0))
9469 {
9470 case SImode:
9471 emit_insn (gen_cmpeqsi_media (operands[0],
9472 sh_compare_op0, sh_compare_op1));
9473 break;
9474
9475 case DImode:
9476 emit_insn (gen_cmpeqdi_media (operands[0],
9477 sh_compare_op0, sh_compare_op1));
9478 break;
9479
9480 case SFmode:
9481 if (! TARGET_SHMEDIA_FPU)
9482 FAIL;
9483 emit_insn (gen_cmpeqsf_media (operands[0],
9484 sh_compare_op0, sh_compare_op1));
9485 break;
9486
9487 case DFmode:
9488 if (! TARGET_SHMEDIA_FPU)
9489 FAIL;
9490 emit_insn (gen_cmpeqdf_media (operands[0],
9491 sh_compare_op0, sh_compare_op1));
9492 break;
9493
9494 default:
9495 FAIL;
9496 }
9497 DONE;
9498 }
9499
9500 reg = operands[0];
9501 if (GET_MODE (operands[0]) != SImode)
9502 reg = (!can_create_pseudo_p ()
9503 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9504 : gen_reg_rtx (SImode));
9505
9506 switch (GET_MODE (sh_compare_op0))
9507 {
9508 case SImode:
9509 emit_insn (gen_cmpeqsi_media (reg,
9510 sh_compare_op0, sh_compare_op1));
9511 break;
9512
9513 case DImode:
9514 emit_insn (gen_cmpeqdi_media (reg,
9515 sh_compare_op0, sh_compare_op1));
9516 break;
9517
9518 case SFmode:
9519 if (! TARGET_SHMEDIA_FPU)
9520 FAIL;
9521 emit_insn (gen_cmpeqsf_media (reg,
9522 sh_compare_op0, sh_compare_op1));
9523 break;
9524
9525 case DFmode:
9526 if (! TARGET_SHMEDIA_FPU)
9527 FAIL;
9528 emit_insn (gen_cmpeqdf_media (reg,
9529 sh_compare_op0, sh_compare_op1));
9530 break;
9531
9532 default:
9533 FAIL;
9534 }
9535
9536 if (GET_MODE (operands[0]) == DImode)
9537 emit_insn (gen_extendsidi2 (operands[0], reg));
9538
9539 DONE;
9540 }
9541 if (sh_expand_t_scc (EQ, operands[0]))
9542 DONE;
9543 if (! currently_expanding_to_rtl)
9544 FAIL;
9545 operands[1] = prepare_scc_operands (EQ);
9546 }")
9547
9548 (define_expand "slt"
9549 [(set (match_operand:SI 0 "arith_reg_operand" "")
9550 (match_dup 1))]
9551 ""
9552 "
9553 {
9554 if (TARGET_SHMEDIA)
9555 {
9556 rtx reg;
9557
9558 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9559 if (sh_compare_op1 != const0_rtx)
9560 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9561 ? GET_MODE (sh_compare_op0)
9562 : GET_MODE (sh_compare_op1),
9563 sh_compare_op1);
9564
9565 reg = operands[0];
9566 if (GET_MODE (operands[0]) != SImode)
9567 reg = (!can_create_pseudo_p ()
9568 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9569 : gen_reg_rtx (SImode));
9570
9571 switch (GET_MODE (sh_compare_op0))
9572 {
9573 case SImode:
9574 emit_insn (gen_cmpgtsi_media (reg,
9575 sh_compare_op1, sh_compare_op0));
9576 break;
9577
9578 case DImode:
9579 emit_insn (gen_cmpgtdi_media (reg,
9580 sh_compare_op1, sh_compare_op0));
9581 break;
9582
9583 case SFmode:
9584 if (! TARGET_SHMEDIA_FPU)
9585 FAIL;
9586 emit_insn (gen_cmpgtsf_media (reg,
9587 sh_compare_op1, sh_compare_op0));
9588 break;
9589
9590 case DFmode:
9591 if (! TARGET_SHMEDIA_FPU)
9592 FAIL;
9593 emit_insn (gen_cmpgtdf_media (reg,
9594 sh_compare_op1, sh_compare_op0));
9595 break;
9596
9597 default:
9598 FAIL;
9599 }
9600
9601 if (GET_MODE (operands[0]) == DImode)
9602 emit_insn (gen_extendsidi2 (operands[0], reg));
9603
9604 DONE;
9605 }
9606 if (! currently_expanding_to_rtl)
9607 FAIL;
9608 operands[1] = prepare_scc_operands (LT);
9609 }")
9610
9611 (define_expand "sle"
9612 [(match_operand:SI 0 "arith_reg_operand" "")]
9613 ""
9614 "
9615 {
9616 rtx tmp = sh_compare_op0;
9617
9618 if (TARGET_SHMEDIA)
9619 {
9620 rtx reg;
9621
9622 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9623 if (sh_compare_op1 != const0_rtx)
9624 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9625 ? GET_MODE (sh_compare_op0)
9626 : GET_MODE (sh_compare_op1),
9627 sh_compare_op1);
9628
9629 reg = operands[0];
9630 if (GET_MODE (operands[0]) != SImode)
9631 reg = (!can_create_pseudo_p ()
9632 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9633 : gen_reg_rtx (SImode));
9634
9635 switch (GET_MODE (sh_compare_op0))
9636 {
9637 case SImode:
9638 {
9639 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9640
9641 emit_insn (gen_cmpgtsi_media (tmp,
9642 sh_compare_op0, sh_compare_op1));
9643 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9644 break;
9645 }
9646
9647 case DImode:
9648 {
9649 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9650
9651 emit_insn (gen_cmpgtdi_media (tmp,
9652 sh_compare_op0, sh_compare_op1));
9653 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9654 break;
9655 }
9656
9657 case SFmode:
9658 if (! TARGET_SHMEDIA_FPU)
9659 FAIL;
9660 emit_insn (gen_cmpgesf_media (reg,
9661 sh_compare_op1, sh_compare_op0));
9662 break;
9663
9664 case DFmode:
9665 if (! TARGET_SHMEDIA_FPU)
9666 FAIL;
9667 emit_insn (gen_cmpgedf_media (reg,
9668 sh_compare_op1, sh_compare_op0));
9669 break;
9670
9671 default:
9672 FAIL;
9673 }
9674
9675 if (GET_MODE (operands[0]) == DImode)
9676 emit_insn (gen_extendsidi2 (operands[0], reg));
9677
9678 DONE;
9679 }
9680
9681 sh_compare_op0 = sh_compare_op1;
9682 sh_compare_op1 = tmp;
9683 emit_insn (gen_sge (operands[0]));
9684 DONE;
9685 }")
9686
9687 (define_expand "sgt"
9688 [(set (match_operand:SI 0 "arith_reg_operand" "")
9689 (match_dup 1))]
9690 ""
9691 "
9692 {
9693 if (TARGET_SHMEDIA)
9694 {
9695 rtx reg;
9696
9697 reg = operands[0];
9698 if (GET_MODE (operands[0]) != SImode)
9699 reg = (!can_create_pseudo_p () ?
9700 gen_rtx_SUBREG (SImode, operands[0], 0)
9701 : gen_reg_rtx (SImode));
9702 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9703 if (sh_compare_op1 != const0_rtx)
9704 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9705 ? GET_MODE (sh_compare_op0)
9706 : GET_MODE (sh_compare_op1),
9707 sh_compare_op1);
9708
9709 switch (GET_MODE (sh_compare_op0))
9710 {
9711 case SImode:
9712 emit_insn (gen_cmpgtsi_media (reg,
9713 sh_compare_op0, sh_compare_op1));
9714 break;
9715
9716 case DImode:
9717 emit_insn (gen_cmpgtdi_media (reg,
9718 sh_compare_op0, sh_compare_op1));
9719 break;
9720
9721 case SFmode:
9722 if (! TARGET_SHMEDIA_FPU)
9723 FAIL;
9724 emit_insn (gen_cmpgtsf_media (reg,
9725 sh_compare_op0, sh_compare_op1));
9726 break;
9727
9728 case DFmode:
9729 if (! TARGET_SHMEDIA_FPU)
9730 FAIL;
9731 emit_insn (gen_cmpgtdf_media (reg,
9732 sh_compare_op0, sh_compare_op1));
9733 break;
9734
9735 default:
9736 FAIL;
9737 }
9738
9739 if (GET_MODE (operands[0]) == DImode)
9740 emit_insn (gen_extendsidi2 (operands[0], reg));
9741
9742 DONE;
9743 }
9744 if (! currently_expanding_to_rtl)
9745 FAIL;
9746 operands[1] = prepare_scc_operands (GT);
9747 }")
9748
9749 (define_expand "sge"
9750 [(set (match_operand:SI 0 "arith_reg_operand" "")
9751 (match_dup 1))]
9752 ""
9753 "
9754 {
9755 if (TARGET_SHMEDIA)
9756 {
9757 rtx reg;
9758 enum machine_mode mode = GET_MODE (sh_compare_op0);
9759
9760 if ((mode) == VOIDmode)
9761 mode = GET_MODE (sh_compare_op1);
9762 reg = operands[0];
9763 if (GET_MODE (operands[0]) != SImode)
9764 reg = (!can_create_pseudo_p ()
9765 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9766 : gen_reg_rtx (SImode));
9767 sh_compare_op0 = force_reg (mode, sh_compare_op0);
9768 if (sh_compare_op1 != const0_rtx)
9769 sh_compare_op1 = force_reg (mode, sh_compare_op1);
9770
9771 switch (mode)
9772 {
9773 case SImode:
9774 {
9775 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9776
9777 emit_insn (gen_cmpgtsi_media (tmp,
9778 sh_compare_op1, sh_compare_op0));
9779 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9780 break;
9781 }
9782
9783 case DImode:
9784 {
9785 rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9786
9787 emit_insn (gen_cmpgtdi_media (tmp,
9788 sh_compare_op1, sh_compare_op0));
9789 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9790 break;
9791 }
9792
9793 case SFmode:
9794 if (! TARGET_SHMEDIA_FPU)
9795 FAIL;
9796 emit_insn (gen_cmpgesf_media (reg,
9797 sh_compare_op0, sh_compare_op1));
9798 break;
9799
9800 case DFmode:
9801 if (! TARGET_SHMEDIA_FPU)
9802 FAIL;
9803 emit_insn (gen_cmpgedf_media (reg,
9804 sh_compare_op0, sh_compare_op1));
9805 break;
9806
9807 default:
9808 FAIL;
9809 }
9810
9811 if (GET_MODE (operands[0]) == DImode)
9812 emit_insn (gen_extendsidi2 (operands[0], reg));
9813
9814 DONE;
9815 }
9816
9817 if (! currently_expanding_to_rtl)
9818 FAIL;
9819 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9820 {
9821 if (TARGET_IEEE)
9822 {
9823 rtx lab = gen_label_rtx ();
9824 prepare_scc_operands (EQ);
9825 emit_jump_insn (gen_branch_true (lab));
9826 prepare_scc_operands (GT);
9827 emit_label (lab);
9828 emit_insn (gen_movt (operands[0]));
9829 }
9830 else
9831 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9832 DONE;
9833 }
9834 operands[1] = prepare_scc_operands (GE);
9835 }")
9836
9837 (define_expand "sgtu"
9838 [(set (match_operand:SI 0 "arith_reg_operand" "")
9839 (match_dup 1))]
9840 ""
9841 "
9842 {
9843 if (TARGET_SHMEDIA)
9844 {
9845 rtx reg;
9846
9847 reg = operands[0];
9848 if (GET_MODE (operands[0]) == DImode)
9849 reg = (!can_create_pseudo_p ()
9850 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9851 : gen_reg_rtx (SImode));
9852 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9853 if (sh_compare_op1 != const0_rtx)
9854 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9855 ? GET_MODE (sh_compare_op0)
9856 : GET_MODE (sh_compare_op1),
9857 sh_compare_op1);
9858
9859 emit_insn (gen_cmpgtudi_media (reg,
9860 sh_compare_op0, sh_compare_op1));
9861 if (GET_MODE (operands[0]) == DImode)
9862 emit_insn (gen_extendsidi2 (operands[0], reg));
9863
9864 DONE;
9865 }
9866 if (! currently_expanding_to_rtl)
9867 FAIL;
9868 operands[1] = prepare_scc_operands (GTU);
9869 }")
9870
9871 (define_expand "sltu"
9872 [(set (match_operand:SI 0 "arith_reg_operand" "")
9873 (match_dup 1))]
9874 ""
9875 "
9876 {
9877 if (TARGET_SHMEDIA)
9878 {
9879 rtx reg;
9880
9881 reg = operands[0];
9882 if (GET_MODE (operands[0]) == DImode)
9883 reg = (!can_create_pseudo_p ()
9884 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9885 : gen_reg_rtx (SImode));
9886 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9887 if (sh_compare_op1 != const0_rtx)
9888 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9889 ? GET_MODE (sh_compare_op0)
9890 : GET_MODE (sh_compare_op1),
9891 sh_compare_op1);
9892
9893 emit_insn (gen_cmpgtudi_media (reg,
9894 sh_compare_op1, sh_compare_op0));
9895 if (GET_MODE (operands[0]) == DImode)
9896 emit_insn (gen_extendsidi2 (operands[0], reg));
9897
9898 DONE;
9899 }
9900 if (! currently_expanding_to_rtl)
9901 FAIL;
9902 operands[1] = prepare_scc_operands (LTU);
9903 }")
9904
9905 (define_expand "sleu"
9906 [(set (match_operand:SI 0 "arith_reg_operand" "")
9907 (match_dup 1))]
9908 ""
9909 "
9910 {
9911 if (TARGET_SHMEDIA)
9912 {
9913 rtx tmp, reg;
9914
9915 reg = operands[0];
9916 if (GET_MODE (operands[0]) != SImode)
9917 reg = (!can_create_pseudo_p ()
9918 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9919 : gen_reg_rtx (SImode));
9920 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9921 if (sh_compare_op1 != const0_rtx)
9922 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9923 ? GET_MODE (sh_compare_op0)
9924 : GET_MODE (sh_compare_op1),
9925 sh_compare_op1);
9926
9927 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9928
9929 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9930 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9931 if (GET_MODE (operands[0]) == DImode)
9932 emit_insn (gen_extendsidi2 (operands[0], reg));
9933
9934 DONE;
9935 }
9936 if (! currently_expanding_to_rtl)
9937 FAIL;
9938 operands[1] = prepare_scc_operands (LEU);
9939 }")
9940
9941 (define_expand "sgeu"
9942 [(set (match_operand:SI 0 "arith_reg_operand" "")
9943 (match_dup 1))]
9944 ""
9945 "
9946 {
9947 if (TARGET_SHMEDIA)
9948 {
9949 rtx tmp, reg;
9950
9951 reg = operands[0];
9952 if (GET_MODE (operands[0]) != SImode)
9953 reg = (!can_create_pseudo_p ()
9954 ? gen_rtx_SUBREG (SImode, operands[0], 0)
9955 : gen_reg_rtx (SImode));
9956 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9957 if (sh_compare_op1 != const0_rtx)
9958 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9959 ? GET_MODE (sh_compare_op0)
9960 : GET_MODE (sh_compare_op1),
9961 sh_compare_op1);
9962
9963 tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
9964
9965 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9966 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9967 if (GET_MODE (operands[0]) == DImode)
9968 emit_insn (gen_extendsidi2 (operands[0], reg));
9969
9970 DONE;
9971 }
9972
9973 if (! currently_expanding_to_rtl)
9974 FAIL;
9975 operands[1] = prepare_scc_operands (GEU);
9976 }")
9977
9978 ;; sne moves the complement of the T reg to DEST like this:
9979 ;; cmp/eq ...
9980 ;; mov #-1,temp
9981 ;; negc temp,dest
9982 ;; This is better than xoring compare result with 1 because it does
9983 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9984 ;; loop.
9985
9986 (define_expand "sne"
9987 [(set (match_dup 2) (const_int -1))
9988 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9989 (neg:SI (plus:SI (match_dup 1)
9990 (match_dup 2))))
9991 (set (reg:SI T_REG)
9992 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9993 (const_int 0)))])]
9994 ""
9995 "
9996 {
9997 if (TARGET_SHMEDIA)
9998 {
9999 rtx tmp, reg;
10000
10001 reg = operands[0];
10002 if (GET_MODE (operands[0]) != SImode)
10003 reg = (!can_create_pseudo_p ()
10004 ? gen_rtx_SUBREG (SImode, operands[0], 0)
10005 : gen_reg_rtx (SImode));
10006 if (! TARGET_SHMEDIA_FPU
10007 && GET_MODE (sh_compare_op0) != DImode
10008 && GET_MODE (sh_compare_op0) != SImode)
10009 FAIL;
10010
10011 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10012 if (sh_compare_op1 != const0_rtx)
10013 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10014 ? GET_MODE (sh_compare_op0)
10015 : GET_MODE (sh_compare_op1),
10016 sh_compare_op1);
10017
10018 tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10019
10020 emit_insn (gen_seq (tmp));
10021 emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10022 if (GET_MODE (operands[0]) == DImode)
10023 emit_insn (gen_extendsidi2 (operands[0], reg));
10024
10025 DONE;
10026 }
10027
10028 if (sh_expand_t_scc (NE, operands[0]))
10029 DONE;
10030 if (! currently_expanding_to_rtl)
10031 FAIL;
10032 operands[1] = prepare_scc_operands (EQ);
10033 operands[2] = gen_reg_rtx (SImode);
10034 }")
10035
10036 (define_expand "sunordered"
10037 [(set (match_operand:SI 0 "arith_reg_operand" "")
10038 (unordered:SI (match_dup 1) (match_dup 2)))]
10039 "TARGET_SHMEDIA_FPU"
10040 "
10041 {
10042 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10043 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10044 }")
10045
10046 ;; Use the same trick for FP sle / sge
10047
10048 ;; Apart from the constant use and the T setting, this is like movt,
10049 ;; except that it uses the logically negated value of T, i.e.
10050 ;; operand[0] := T ? 0 : 1.
10051 (define_expand "movnegt"
10052 [(set (match_dup 2) (const_int -1))
10053 (parallel [(set (match_operand 0 "" "")
10054 (neg:SI (plus:SI (match_dup 1)
10055 (match_dup 2))))
10056 (set (reg:SI T_REG)
10057 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10058 (const_int 0)))])]
10059 "TARGET_SH1"
10060 "operands[2] = gen_reg_rtx (SImode);")
10061
10062 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10063 ;; This prevents a regression that occurred when we switched from xor to
10064 ;; mov/neg for sne.
10065
10066 (define_split
10067 [(set (match_operand:SI 0 "arith_reg_dest" "")
10068 (plus:SI (reg:SI T_REG)
10069 (const_int -1)))]
10070 "TARGET_SH1"
10071 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10072 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10073 "")
10074
10075 ;; -------------------------------------------------------------------------
10076 ;; Instructions to cope with inline literal tables
10077 ;; -------------------------------------------------------------------------
10078
10079 ; 2 byte integer in line
10080
10081 (define_insn "consttable_2"
10082 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10083 (match_operand 1 "" "")]
10084 UNSPECV_CONST2)]
10085 ""
10086 "*
10087 {
10088 if (operands[1] != const0_rtx)
10089 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10090 return \"\";
10091 }"
10092 [(set_attr "length" "2")
10093 (set_attr "in_delay_slot" "no")])
10094
10095 ; 4 byte integer in line
10096
10097 (define_insn "consttable_4"
10098 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10099 (match_operand 1 "" "")]
10100 UNSPECV_CONST4)]
10101 ""
10102 "*
10103 {
10104 if (operands[1] != const0_rtx)
10105 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10106 return \"\";
10107 }"
10108 [(set_attr "length" "4")
10109 (set_attr "in_delay_slot" "no")])
10110
10111 ; 8 byte integer in line
10112
10113 (define_insn "consttable_8"
10114 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10115 (match_operand 1 "" "")]
10116 UNSPECV_CONST8)]
10117 ""
10118 "*
10119 {
10120 if (operands[1] != const0_rtx)
10121 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10122 return \"\";
10123 }"
10124 [(set_attr "length" "8")
10125 (set_attr "in_delay_slot" "no")])
10126
10127 ; 4 byte floating point
10128
10129 (define_insn "consttable_sf"
10130 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10131 (match_operand 1 "" "")]
10132 UNSPECV_CONST4)]
10133 ""
10134 "*
10135 {
10136 if (operands[1] != const0_rtx)
10137 {
10138 REAL_VALUE_TYPE d;
10139 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10140 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10141 }
10142 return \"\";
10143 }"
10144 [(set_attr "length" "4")
10145 (set_attr "in_delay_slot" "no")])
10146
10147 ; 8 byte floating point
10148
10149 (define_insn "consttable_df"
10150 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10151 (match_operand 1 "" "")]
10152 UNSPECV_CONST8)]
10153 ""
10154 "*
10155 {
10156 if (operands[1] != const0_rtx)
10157 {
10158 REAL_VALUE_TYPE d;
10159 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10160 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10161 }
10162 return \"\";
10163 }"
10164 [(set_attr "length" "8")
10165 (set_attr "in_delay_slot" "no")])
10166
10167 ;; Alignment is needed for some constant tables; it may also be added for
10168 ;; Instructions at the start of loops, or after unconditional branches.
10169 ;; ??? We would get more accurate lengths if we did instruction
10170 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10171 ;; here is too conservative.
10172
10173 ; align to a two byte boundary
10174
10175 (define_expand "align_2"
10176 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10177 ""
10178 "")
10179
10180 ; align to a four byte boundary
10181 ;; align_4 and align_log are instructions for the starts of loops, or
10182 ;; after unconditional branches, which may take up extra room.
10183
10184 (define_expand "align_4"
10185 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10186 ""
10187 "")
10188
10189 ; align to a cache line boundary
10190
10191 (define_insn "align_log"
10192 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10193 ""
10194 ""
10195 [(set_attr "length" "0")
10196 (set_attr "in_delay_slot" "no")])
10197
10198 ; emitted at the end of the literal table, used to emit the
10199 ; 32bit branch labels if needed.
10200
10201 (define_insn "consttable_end"
10202 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10203 ""
10204 "* return output_jump_label_table ();"
10205 [(set_attr "in_delay_slot" "no")])
10206
10207 ; emitted at the end of the window in the literal table.
10208
10209 (define_insn "consttable_window_end"
10210 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10211 ""
10212 ""
10213 [(set_attr "length" "0")
10214 (set_attr "in_delay_slot" "no")])
10215
10216 ;; -------------------------------------------------------------------------
10217 ;; Misc
10218 ;; -------------------------------------------------------------------------
10219
10220 ;; String/block move insn.
10221
10222 (define_expand "movmemsi"
10223 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10224 (mem:BLK (match_operand:BLK 1 "" "")))
10225 (use (match_operand:SI 2 "nonmemory_operand" ""))
10226 (use (match_operand:SI 3 "immediate_operand" ""))
10227 (clobber (reg:SI PR_REG))
10228 (clobber (reg:SI R4_REG))
10229 (clobber (reg:SI R5_REG))
10230 (clobber (reg:SI R0_REG))])]
10231 "TARGET_SH1 && ! TARGET_SH5"
10232 "
10233 {
10234 if(expand_block_move (operands))
10235 DONE;
10236 else FAIL;
10237 }")
10238
10239 (define_insn "block_move_real"
10240 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10241 (mem:BLK (reg:SI R5_REG)))
10242 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10243 (clobber (reg:SI PR_REG))
10244 (clobber (reg:SI R0_REG))])]
10245 "TARGET_SH1 && ! TARGET_HARD_SH4"
10246 "jsr @%0%#"
10247 [(set_attr "type" "sfunc")
10248 (set_attr "needs_delay_slot" "yes")])
10249
10250 (define_insn "block_lump_real"
10251 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10252 (mem:BLK (reg:SI R5_REG)))
10253 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10254 (use (reg:SI R6_REG))
10255 (clobber (reg:SI PR_REG))
10256 (clobber (reg:SI T_REG))
10257 (clobber (reg:SI R4_REG))
10258 (clobber (reg:SI R5_REG))
10259 (clobber (reg:SI R6_REG))
10260 (clobber (reg:SI R0_REG))])]
10261 "TARGET_SH1 && ! TARGET_HARD_SH4"
10262 "jsr @%0%#"
10263 [(set_attr "type" "sfunc")
10264 (set_attr "needs_delay_slot" "yes")])
10265
10266 (define_insn "block_move_real_i4"
10267 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10268 (mem:BLK (reg:SI R5_REG)))
10269 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10270 (clobber (reg:SI PR_REG))
10271 (clobber (reg:SI R0_REG))
10272 (clobber (reg:SI R1_REG))
10273 (clobber (reg:SI R2_REG))])]
10274 "TARGET_HARD_SH4"
10275 "jsr @%0%#"
10276 [(set_attr "type" "sfunc")
10277 (set_attr "needs_delay_slot" "yes")])
10278
10279 (define_insn "block_lump_real_i4"
10280 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10281 (mem:BLK (reg:SI R5_REG)))
10282 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10283 (use (reg:SI R6_REG))
10284 (clobber (reg:SI PR_REG))
10285 (clobber (reg:SI T_REG))
10286 (clobber (reg:SI R4_REG))
10287 (clobber (reg:SI R5_REG))
10288 (clobber (reg:SI R6_REG))
10289 (clobber (reg:SI R0_REG))
10290 (clobber (reg:SI R1_REG))
10291 (clobber (reg:SI R2_REG))
10292 (clobber (reg:SI R3_REG))])]
10293 "TARGET_HARD_SH4"
10294 "jsr @%0%#"
10295 [(set_attr "type" "sfunc")
10296 (set_attr "needs_delay_slot" "yes")])
10297 \f
10298 ;; -------------------------------------------------------------------------
10299 ;; Floating point instructions.
10300 ;; -------------------------------------------------------------------------
10301
10302 ;; ??? All patterns should have a type attribute.
10303
10304 (define_expand "movpsi"
10305 [(set (match_operand:PSI 0 "register_operand" "")
10306 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10307 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10308 "")
10309
10310 ;; The c / m alternative is a fake to guide reload to load directly into
10311 ;; fpscr, since reload doesn't know how to use post-increment.
10312 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10313 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10314 ;; predicate after reload.
10315 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10316 ;; like a mac -> gpr move.
10317 (define_insn "fpu_switch"
10318 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10319 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10320 "TARGET_SH2E
10321 && (! reload_completed
10322 || true_regnum (operands[0]) != FPSCR_REG
10323 || GET_CODE (operands[1]) != MEM
10324 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10325 "@
10326 ! precision stays the same
10327 lds.l %1,fpscr
10328 mov.l %1,%0
10329 #
10330 lds %1,fpscr
10331 mov %1,%0
10332 mov.l %1,%0
10333 sts fpscr,%0
10334 sts.l fpscr,%0"
10335 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10336 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10337
10338 (define_peephole2
10339 [(set (reg:PSI FPSCR_REG)
10340 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10341 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10342 [(const_int 0)]
10343 {
10344 rtx fpscr, mem, new_insn;
10345
10346 fpscr = SET_DEST (PATTERN (curr_insn));
10347 mem = SET_SRC (PATTERN (curr_insn));
10348 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10349
10350 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10351 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10352 DONE;
10353 })
10354
10355 (define_split
10356 [(set (reg:PSI FPSCR_REG)
10357 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10358 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10359 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10360 [(const_int 0)]
10361 {
10362 rtx fpscr, mem, new_insn;
10363
10364 fpscr = SET_DEST (PATTERN (curr_insn));
10365 mem = SET_SRC (PATTERN (curr_insn));
10366 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10367
10368 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10369 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10370
10371 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10372 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10373 DONE;
10374 })
10375
10376 ;; ??? This uses the fp unit, but has no type indicating that.
10377 ;; If we did that, this would either give a bogus latency or introduce
10378 ;; a bogus FIFO constraint.
10379 ;; Since this insn is currently only used for prologues/epilogues,
10380 ;; it is probably best to claim no function unit, which matches the
10381 ;; current setting.
10382 (define_insn "toggle_sz"
10383 [(set (reg:PSI FPSCR_REG)
10384 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10385 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10386 "fschg"
10387 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10388
10389 ;; There's no way we can use it today, since optimize mode switching
10390 ;; doesn't enable us to know from which mode we're switching to the
10391 ;; mode it requests, to tell whether we can use a relative mode switch
10392 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10393 ;; memory).
10394 (define_insn "toggle_pr"
10395 [(set (reg:PSI FPSCR_REG)
10396 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10397 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10398 "fpchg"
10399 [(set_attr "type" "fpscr_toggle")])
10400
10401 (define_expand "addsf3"
10402 [(set (match_operand:SF 0 "arith_reg_operand" "")
10403 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10404 (match_operand:SF 2 "arith_reg_operand" "")))]
10405 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10406 "
10407 {
10408 if (TARGET_SH2E)
10409 {
10410 expand_sf_binop (&gen_addsf3_i, operands);
10411 DONE;
10412 }
10413 }")
10414
10415 (define_insn "*addsf3_media"
10416 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10417 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10418 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10419 "TARGET_SHMEDIA_FPU"
10420 "fadd.s %1, %2, %0"
10421 [(set_attr "type" "fparith_media")])
10422
10423 (define_insn_and_split "unary_sf_op"
10424 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10425 (vec_select:V2SF
10426 (vec_concat:V2SF
10427 (vec_select:SF
10428 (match_dup 0)
10429 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10430 (match_operator:SF 2 "unary_float_operator"
10431 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10432 (parallel [(match_operand 4
10433 "const_int_operand" "n")]))]))
10434 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10435 "TARGET_SHMEDIA_FPU"
10436 "#"
10437 "TARGET_SHMEDIA_FPU && reload_completed"
10438 [(set (match_dup 5) (match_dup 6))]
10439 "
10440 {
10441 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10442 rtx op1 = gen_rtx_REG (SFmode,
10443 (true_regnum (operands[1])
10444 + (INTVAL (operands[4]) ^ endian)));
10445
10446 operands[7] = gen_rtx_REG (SFmode,
10447 (true_regnum (operands[0])
10448 + (INTVAL (operands[3]) ^ endian)));
10449 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10450 }"
10451 [(set_attr "type" "fparith_media")])
10452
10453 (define_insn_and_split "binary_sf_op"
10454 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10455 (vec_select:V2SF
10456 (vec_concat:V2SF
10457 (vec_select:SF
10458 (match_dup 0)
10459 (parallel [(match_operand 7 "const_int_operand" "n")]))
10460 (match_operator:SF 3 "binary_float_operator"
10461 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10462 (parallel [(match_operand 5
10463 "const_int_operand" "n")]))
10464 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10465 (parallel [(match_operand 6
10466 "const_int_operand" "n")]))]))
10467 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10468 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10469 "#"
10470 "&& reload_completed"
10471 [(set (match_dup 8) (match_dup 9))]
10472 "
10473 {
10474 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10475 rtx op1 = gen_rtx_REG (SFmode,
10476 (true_regnum (operands[1])
10477 + (INTVAL (operands[5]) ^ endian)));
10478 rtx op2 = gen_rtx_REG (SFmode,
10479 (true_regnum (operands[2])
10480 + (INTVAL (operands[6]) ^ endian)));
10481
10482 operands[8] = gen_rtx_REG (SFmode,
10483 (true_regnum (operands[0])
10484 + (INTVAL (operands[4]) ^ endian)));
10485 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10486 }"
10487 [(set_attr "type" "fparith_media")])
10488
10489 (define_insn "addsf3_i"
10490 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10491 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10492 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10493 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10494 "TARGET_SH2E"
10495 "fadd %2,%0"
10496 [(set_attr "type" "fp")
10497 (set_attr "fp_mode" "single")])
10498
10499 (define_expand "subsf3"
10500 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10501 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10502 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10503 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10504 "
10505 {
10506 if (TARGET_SH2E)
10507 {
10508 expand_sf_binop (&gen_subsf3_i, operands);
10509 DONE;
10510 }
10511 }")
10512
10513 (define_insn "*subsf3_media"
10514 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10515 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10516 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10517 "TARGET_SHMEDIA_FPU"
10518 "fsub.s %1, %2, %0"
10519 [(set_attr "type" "fparith_media")])
10520
10521 (define_insn "subsf3_i"
10522 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10523 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10524 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10525 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10526 "TARGET_SH2E"
10527 "fsub %2,%0"
10528 [(set_attr "type" "fp")
10529 (set_attr "fp_mode" "single")])
10530
10531 (define_expand "mulsf3"
10532 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10533 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10534 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10535 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10536 "")
10537
10538 (define_insn "*mulsf3_media"
10539 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10540 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10541 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10542 "TARGET_SHMEDIA_FPU"
10543 "fmul.s %1, %2, %0"
10544 [(set_attr "type" "fparith_media")])
10545
10546 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10547 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10548 ;; we start out with a mulsf pattern that does not depend on fpscr.
10549 ;; This is split after combine to introduce the dependency, in order to
10550 ;; get mode switching and scheduling right.
10551 (define_insn_and_split "mulsf3_ie"
10552 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10553 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10554 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10555 "TARGET_SH2E"
10556 "fmul %2,%0"
10557 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10558 [(const_int 0)]
10559 "
10560 {
10561 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10562 get_fpscr_rtx ()));
10563 DONE;
10564 }"
10565 [(set_attr "type" "fp")])
10566
10567 (define_insn "mulsf3_i4"
10568 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10569 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10570 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10571 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10572 "TARGET_SH2E"
10573 "fmul %2,%0"
10574 [(set_attr "type" "fp")
10575 (set_attr "fp_mode" "single")])
10576
10577 (define_insn "mac_media"
10578 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10579 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10580 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10581 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10582 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10583 "fmac.s %1, %2, %0"
10584 [(set_attr "type" "fparith_media")])
10585
10586 (define_insn "*macsf3"
10587 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10588 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10589 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10590 (match_operand:SF 3 "arith_reg_operand" "0")))
10591 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10592 "TARGET_SH2E && TARGET_FMAC"
10593 "fmac fr0,%2,%0"
10594 [(set_attr "type" "fp")
10595 (set_attr "fp_mode" "single")])
10596
10597 (define_expand "divsf3"
10598 [(set (match_operand:SF 0 "arith_reg_operand" "")
10599 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10600 (match_operand:SF 2 "arith_reg_operand" "")))]
10601 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10602 "
10603 {
10604 if (TARGET_SH2E)
10605 {
10606 expand_sf_binop (&gen_divsf3_i, operands);
10607 DONE;
10608 }
10609 }")
10610
10611 (define_insn "*divsf3_media"
10612 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10613 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10614 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10615 "TARGET_SHMEDIA_FPU"
10616 "fdiv.s %1, %2, %0"
10617 [(set_attr "type" "fdiv_media")])
10618
10619 (define_insn "divsf3_i"
10620 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10621 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10622 (match_operand:SF 2 "arith_reg_operand" "f")))
10623 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10624 "TARGET_SH2E"
10625 "fdiv %2,%0"
10626 [(set_attr "type" "fdiv")
10627 (set_attr "fp_mode" "single")])
10628
10629 (define_insn "floatdisf2"
10630 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10631 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10632 "TARGET_SHMEDIA_FPU"
10633 "float.qs %1, %0"
10634 [(set_attr "type" "fpconv_media")])
10635
10636 (define_expand "floatsisf2"
10637 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10638 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10639 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10640 "
10641 {
10642 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10643 {
10644 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10645 DONE;
10646 }
10647 }")
10648
10649 (define_insn "*floatsisf2_media"
10650 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10651 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10652 "TARGET_SHMEDIA_FPU"
10653 "float.ls %1, %0"
10654 [(set_attr "type" "fpconv_media")])
10655
10656 (define_insn "floatsisf2_i4"
10657 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10658 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10659 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10660 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10661 "float %1,%0"
10662 [(set_attr "type" "fp")
10663 (set_attr "fp_mode" "single")])
10664
10665 (define_insn "*floatsisf2_ie"
10666 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10667 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10668 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10669 "float %1,%0"
10670 [(set_attr "type" "fp")])
10671
10672 (define_insn "fix_truncsfdi2"
10673 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10674 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10675 "TARGET_SHMEDIA_FPU"
10676 "ftrc.sq %1, %0"
10677 [(set_attr "type" "fpconv_media")])
10678
10679 (define_expand "fix_truncsfsi2"
10680 [(set (match_operand:SI 0 "fpul_operand" "=y")
10681 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10682 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10683 "
10684 {
10685 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10686 {
10687 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10688 DONE;
10689 }
10690 }")
10691
10692 (define_insn "*fix_truncsfsi2_media"
10693 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10694 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10695 "TARGET_SHMEDIA_FPU"
10696 "ftrc.sl %1, %0"
10697 [(set_attr "type" "fpconv_media")])
10698
10699 (define_insn "fix_truncsfsi2_i4"
10700 [(set (match_operand:SI 0 "fpul_operand" "=y")
10701 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10702 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10703 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10704 "ftrc %1,%0"
10705 [(set_attr "type" "ftrc_s")
10706 (set_attr "fp_mode" "single")])
10707
10708 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10709 ;; fix_truncsfsi2_i4.
10710 ;; (define_insn "fix_truncsfsi2_i4_2"
10711 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10712 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10713 ;; (use (reg:PSI FPSCR_REG))
10714 ;; (clobber (reg:SI FPUL_REG))]
10715 ;; "TARGET_SH4"
10716 ;; "#"
10717 ;; [(set_attr "length" "4")
10718 ;; (set_attr "fp_mode" "single")])
10719
10720 ;;(define_split
10721 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10722 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10723 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10724 ;; (clobber (reg:SI FPUL_REG))]
10725 ;; "TARGET_SH4"
10726 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10727 ;; (use (match_dup 2))])
10728 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10729
10730 (define_insn "*fixsfsi"
10731 [(set (match_operand:SI 0 "fpul_operand" "=y")
10732 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10733 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10734 "ftrc %1,%0"
10735 [(set_attr "type" "fp")])
10736
10737 (define_insn "cmpgtsf_t"
10738 [(set (reg:SI T_REG)
10739 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10740 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10741 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10742 "fcmp/gt %1,%0"
10743 [(set_attr "type" "fp_cmp")
10744 (set_attr "fp_mode" "single")])
10745
10746 (define_insn "cmpeqsf_t"
10747 [(set (reg:SI T_REG)
10748 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10749 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10750 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10751 "fcmp/eq %1,%0"
10752 [(set_attr "type" "fp_cmp")
10753 (set_attr "fp_mode" "single")])
10754
10755 (define_insn "ieee_ccmpeqsf_t"
10756 [(set (reg:SI T_REG)
10757 (ior:SI (reg:SI T_REG)
10758 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10759 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10760 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10761 "* return output_ieee_ccmpeq (insn, operands);"
10762 [(set_attr "length" "4")])
10763
10764
10765 (define_insn "cmpgtsf_t_i4"
10766 [(set (reg:SI T_REG)
10767 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10768 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10769 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10770 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10771 "fcmp/gt %1,%0"
10772 [(set_attr "type" "fp_cmp")
10773 (set_attr "fp_mode" "single")])
10774
10775 (define_insn "cmpeqsf_t_i4"
10776 [(set (reg:SI T_REG)
10777 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10778 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10779 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10780 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10781 "fcmp/eq %1,%0"
10782 [(set_attr "type" "fp_cmp")
10783 (set_attr "fp_mode" "single")])
10784
10785 (define_insn "*ieee_ccmpeqsf_t_4"
10786 [(set (reg:SI T_REG)
10787 (ior:SI (reg:SI T_REG)
10788 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10789 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10790 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10791 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10792 "* return output_ieee_ccmpeq (insn, operands);"
10793 [(set_attr "length" "4")
10794 (set_attr "fp_mode" "single")])
10795
10796 (define_insn "cmpeqsf_media"
10797 [(set (match_operand:SI 0 "register_operand" "=r")
10798 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10799 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10800 "TARGET_SHMEDIA_FPU"
10801 "fcmpeq.s %1, %2, %0"
10802 [(set_attr "type" "fcmp_media")])
10803
10804 (define_insn "cmpgtsf_media"
10805 [(set (match_operand:SI 0 "register_operand" "=r")
10806 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10807 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10808 "TARGET_SHMEDIA_FPU"
10809 "fcmpgt.s %1, %2, %0"
10810 [(set_attr "type" "fcmp_media")])
10811
10812 (define_insn "cmpgesf_media"
10813 [(set (match_operand:SI 0 "register_operand" "=r")
10814 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10815 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10816 "TARGET_SHMEDIA_FPU"
10817 "fcmpge.s %1, %2, %0"
10818 [(set_attr "type" "fcmp_media")])
10819
10820 (define_insn "cmpunsf_media"
10821 [(set (match_operand:SI 0 "register_operand" "=r")
10822 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10823 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10824 "TARGET_SHMEDIA_FPU"
10825 "fcmpun.s %1, %2, %0"
10826 [(set_attr "type" "fcmp_media")])
10827
10828 (define_expand "cmpsf"
10829 [(set (reg:SI T_REG)
10830 (compare (match_operand:SF 0 "arith_operand" "")
10831 (match_operand:SF 1 "arith_operand" "")))]
10832 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10833 "
10834 {
10835 sh_compare_op0 = operands[0];
10836 sh_compare_op1 = operands[1];
10837 DONE;
10838 }")
10839
10840 (define_expand "negsf2"
10841 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10842 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10843 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10844 "
10845 {
10846 if (TARGET_SH2E)
10847 {
10848 expand_sf_unop (&gen_negsf2_i, operands);
10849 DONE;
10850 }
10851 }")
10852
10853 (define_insn "*negsf2_media"
10854 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10855 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10856 "TARGET_SHMEDIA_FPU"
10857 "fneg.s %1, %0"
10858 [(set_attr "type" "fmove_media")])
10859
10860 (define_insn "negsf2_i"
10861 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10862 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10863 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10864 "TARGET_SH2E"
10865 "fneg %0"
10866 [(set_attr "type" "fmove")
10867 (set_attr "fp_mode" "single")])
10868
10869 (define_expand "sqrtsf2"
10870 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10871 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10872 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10873 "
10874 {
10875 if (TARGET_SH3E)
10876 {
10877 expand_sf_unop (&gen_sqrtsf2_i, operands);
10878 DONE;
10879 }
10880 }")
10881
10882 (define_insn "*sqrtsf2_media"
10883 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10884 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10885 "TARGET_SHMEDIA_FPU"
10886 "fsqrt.s %1, %0"
10887 [(set_attr "type" "fdiv_media")])
10888
10889 (define_insn "sqrtsf2_i"
10890 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10891 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10892 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10893 "TARGET_SH3E"
10894 "fsqrt %0"
10895 [(set_attr "type" "fdiv")
10896 (set_attr "fp_mode" "single")])
10897
10898 (define_insn "rsqrtsf2"
10899 [(set (match_operand:SF 0 "register_operand" "=f")
10900 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10901 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10902 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10903 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10904 && operands[1] == CONST1_RTX (SFmode)"
10905 "fsrra %0"
10906 [(set_attr "type" "fsrra")
10907 (set_attr "fp_mode" "single")])
10908
10909 (define_insn "fsca"
10910 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10911 (vec_concat:V2SF
10912 (unspec:SF [(mult:SF
10913 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10914 (match_operand:SF 2 "immediate_operand" "i"))
10915 ] UNSPEC_FSINA)
10916 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10917 ] UNSPEC_FCOSA)))
10918 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10919 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10920 && operands[2] == sh_fsca_int2sf ()"
10921 "fsca fpul,%d0"
10922 [(set_attr "type" "fsca")
10923 (set_attr "fp_mode" "single")])
10924
10925 (define_expand "sinsf2"
10926 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10927 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10928 UNSPEC_FSINA))]
10929 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10930 "
10931 {
10932 rtx scaled = gen_reg_rtx (SFmode);
10933 rtx truncated = gen_reg_rtx (SImode);
10934 rtx fsca = gen_reg_rtx (V2SFmode);
10935 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10936
10937 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10938 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10939 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10940 get_fpscr_rtx ()));
10941 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10942 DONE;
10943 }")
10944
10945 (define_expand "cossf2"
10946 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10947 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10948 UNSPEC_FCOSA))]
10949 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10950 "
10951 {
10952 rtx scaled = gen_reg_rtx (SFmode);
10953 rtx truncated = gen_reg_rtx (SImode);
10954 rtx fsca = gen_reg_rtx (V2SFmode);
10955 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10956
10957 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10958 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10959 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10960 get_fpscr_rtx ()));
10961 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10962 DONE;
10963 }")
10964
10965 (define_expand "sindf2"
10966 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10967 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10968 UNSPEC_FSINA))]
10969 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10970 "
10971 {
10972 rtx scaled = gen_reg_rtx (DFmode);
10973 rtx truncated = gen_reg_rtx (SImode);
10974 rtx fsca = gen_reg_rtx (V2SFmode);
10975 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10976 rtx sfresult = gen_reg_rtx (SFmode);
10977
10978 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10979 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10980 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10981 get_fpscr_rtx ()));
10982 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10983 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10984 DONE;
10985 }")
10986
10987 (define_expand "cosdf2"
10988 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10989 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10990 UNSPEC_FCOSA))]
10991 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10992 "
10993 {
10994 rtx scaled = gen_reg_rtx (DFmode);
10995 rtx truncated = gen_reg_rtx (SImode);
10996 rtx fsca = gen_reg_rtx (V2SFmode);
10997 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10998 rtx sfresult = gen_reg_rtx (SFmode);
10999
11000 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11001 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11002 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11003 get_fpscr_rtx ()));
11004 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11005 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11006 DONE;
11007 }")
11008
11009 (define_expand "abssf2"
11010 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11011 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11012 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11013 "
11014 {
11015 if (TARGET_SH2E)
11016 {
11017 expand_sf_unop (&gen_abssf2_i, operands);
11018 DONE;
11019 }
11020 }")
11021
11022 (define_insn "*abssf2_media"
11023 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11024 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11025 "TARGET_SHMEDIA_FPU"
11026 "fabs.s %1, %0"
11027 [(set_attr "type" "fmove_media")])
11028
11029 (define_insn "abssf2_i"
11030 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11031 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11032 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11033 "TARGET_SH2E"
11034 "fabs %0"
11035 [(set_attr "type" "fmove")
11036 (set_attr "fp_mode" "single")])
11037
11038 (define_expand "adddf3"
11039 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11040 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11041 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11042 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11043 "
11044 {
11045 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11046 {
11047 expand_df_binop (&gen_adddf3_i, operands);
11048 DONE;
11049 }
11050 }")
11051
11052 (define_insn "*adddf3_media"
11053 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11054 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11055 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11056 "TARGET_SHMEDIA_FPU"
11057 "fadd.d %1, %2, %0"
11058 [(set_attr "type" "dfparith_media")])
11059
11060 (define_insn "adddf3_i"
11061 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11062 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11063 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11064 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11065 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11066 "fadd %2,%0"
11067 [(set_attr "type" "dfp_arith")
11068 (set_attr "fp_mode" "double")])
11069
11070 (define_expand "subdf3"
11071 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11072 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11073 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11074 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11075 "
11076 {
11077 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11078 {
11079 expand_df_binop (&gen_subdf3_i, operands);
11080 DONE;
11081 }
11082 }")
11083
11084 (define_insn "*subdf3_media"
11085 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11086 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11087 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11088 "TARGET_SHMEDIA_FPU"
11089 "fsub.d %1, %2, %0"
11090 [(set_attr "type" "dfparith_media")])
11091
11092 (define_insn "subdf3_i"
11093 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11094 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11095 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11096 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11097 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11098 "fsub %2,%0"
11099 [(set_attr "type" "dfp_arith")
11100 (set_attr "fp_mode" "double")])
11101
11102 (define_expand "muldf3"
11103 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11104 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11105 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11106 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11107 "
11108 {
11109 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11110 {
11111 expand_df_binop (&gen_muldf3_i, operands);
11112 DONE;
11113 }
11114 }")
11115
11116 (define_insn "*muldf3_media"
11117 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11118 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11119 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11120 "TARGET_SHMEDIA_FPU"
11121 "fmul.d %1, %2, %0"
11122 [(set_attr "type" "dfmul_media")])
11123
11124 (define_insn "muldf3_i"
11125 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11126 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11127 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11128 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11129 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11130 "fmul %2,%0"
11131 [(set_attr "type" "dfp_mul")
11132 (set_attr "fp_mode" "double")])
11133
11134 (define_expand "divdf3"
11135 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11136 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11137 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11138 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11139 "
11140 {
11141 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11142 {
11143 expand_df_binop (&gen_divdf3_i, operands);
11144 DONE;
11145 }
11146 }")
11147
11148 (define_insn "*divdf3_media"
11149 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11150 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11151 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11152 "TARGET_SHMEDIA_FPU"
11153 "fdiv.d %1, %2, %0"
11154 [(set_attr "type" "dfdiv_media")])
11155
11156 (define_insn "divdf3_i"
11157 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11158 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11159 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11160 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11161 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11162 "fdiv %2,%0"
11163 [(set_attr "type" "dfdiv")
11164 (set_attr "fp_mode" "double")])
11165
11166 (define_insn "floatdidf2"
11167 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11168 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11169 "TARGET_SHMEDIA_FPU"
11170 "float.qd %1, %0"
11171 [(set_attr "type" "dfpconv_media")])
11172
11173 (define_expand "floatsidf2"
11174 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11175 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11176 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11177 "
11178 {
11179 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11180 {
11181 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11182 get_fpscr_rtx ()));
11183 DONE;
11184 }
11185 }")
11186
11187 (define_insn "*floatsidf2_media"
11188 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11189 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11190 "TARGET_SHMEDIA_FPU"
11191 "float.ld %1, %0"
11192 [(set_attr "type" "dfpconv_media")])
11193
11194 (define_insn "floatsidf2_i"
11195 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11196 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11197 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11198 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11199 "float %1,%0"
11200 [(set_attr "type" "dfp_conv")
11201 (set_attr "fp_mode" "double")])
11202
11203 (define_insn "fix_truncdfdi2"
11204 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11205 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11206 "TARGET_SHMEDIA_FPU"
11207 "ftrc.dq %1, %0"
11208 [(set_attr "type" "dfpconv_media")])
11209
11210 (define_expand "fix_truncdfsi2"
11211 [(set (match_operand:SI 0 "fpul_operand" "")
11212 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11213 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11214 "
11215 {
11216 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11217 {
11218 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11219 get_fpscr_rtx ()));
11220 DONE;
11221 }
11222 }")
11223
11224 (define_insn "*fix_truncdfsi2_media"
11225 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11226 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11227 "TARGET_SHMEDIA_FPU"
11228 "ftrc.dl %1, %0"
11229 [(set_attr "type" "dfpconv_media")])
11230
11231 (define_insn "fix_truncdfsi2_i"
11232 [(set (match_operand:SI 0 "fpul_operand" "=y")
11233 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11234 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11235 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11236 "ftrc %1,%0"
11237 [(set_attr "type" "dfp_conv")
11238 (set_attr "dfp_comp" "no")
11239 (set_attr "fp_mode" "double")])
11240
11241 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11242 ;; fix_truncdfsi2_i.
11243 ;; (define_insn "fix_truncdfsi2_i4"
11244 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11245 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11246 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11247 ;; (clobber (reg:SI FPUL_REG))]
11248 ;; "TARGET_SH4"
11249 ;; "#"
11250 ;; [(set_attr "length" "4")
11251 ;; (set_attr "fp_mode" "double")])
11252 ;;
11253 ;; (define_split
11254 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11255 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11256 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11257 ;; (clobber (reg:SI FPUL_REG))]
11258 ;; "TARGET_SH4"
11259 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11260 ;; (use (match_dup 2))])
11261 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11262
11263 (define_insn "cmpgtdf_t"
11264 [(set (reg:SI T_REG)
11265 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11266 (match_operand:DF 1 "arith_reg_operand" "f")))
11267 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11268 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11269 "fcmp/gt %1,%0"
11270 [(set_attr "type" "dfp_cmp")
11271 (set_attr "fp_mode" "double")])
11272
11273 (define_insn "cmpeqdf_t"
11274 [(set (reg:SI T_REG)
11275 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11276 (match_operand:DF 1 "arith_reg_operand" "f")))
11277 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11278 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11279 "fcmp/eq %1,%0"
11280 [(set_attr "type" "dfp_cmp")
11281 (set_attr "fp_mode" "double")])
11282
11283 (define_insn "*ieee_ccmpeqdf_t"
11284 [(set (reg:SI T_REG)
11285 (ior:SI (reg:SI T_REG)
11286 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11287 (match_operand:DF 1 "arith_reg_operand" "f"))))
11288 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11289 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11290 "* return output_ieee_ccmpeq (insn, operands);"
11291 [(set_attr "length" "4")
11292 (set_attr "fp_mode" "double")])
11293
11294 (define_insn "cmpeqdf_media"
11295 [(set (match_operand:SI 0 "register_operand" "=r")
11296 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11297 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11298 "TARGET_SHMEDIA_FPU"
11299 "fcmpeq.d %1,%2,%0"
11300 [(set_attr "type" "fcmp_media")])
11301
11302 (define_insn "cmpgtdf_media"
11303 [(set (match_operand:SI 0 "register_operand" "=r")
11304 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11305 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11306 "TARGET_SHMEDIA_FPU"
11307 "fcmpgt.d %1,%2,%0"
11308 [(set_attr "type" "fcmp_media")])
11309
11310 (define_insn "cmpgedf_media"
11311 [(set (match_operand:SI 0 "register_operand" "=r")
11312 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11313 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11314 "TARGET_SHMEDIA_FPU"
11315 "fcmpge.d %1,%2,%0"
11316 [(set_attr "type" "fcmp_media")])
11317
11318 (define_insn "cmpundf_media"
11319 [(set (match_operand:SI 0 "register_operand" "=r")
11320 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11321 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11322 "TARGET_SHMEDIA_FPU"
11323 "fcmpun.d %1,%2,%0"
11324 [(set_attr "type" "fcmp_media")])
11325
11326 (define_expand "cmpdf"
11327 [(set (reg:SI T_REG)
11328 (compare (match_operand:DF 0 "arith_operand" "")
11329 (match_operand:DF 1 "arith_operand" "")))]
11330 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11331 "
11332 {
11333 sh_compare_op0 = operands[0];
11334 sh_compare_op1 = operands[1];
11335 DONE;
11336 }")
11337
11338 (define_expand "negdf2"
11339 [(set (match_operand:DF 0 "arith_reg_operand" "")
11340 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11341 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11342 "
11343 {
11344 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11345 {
11346 expand_df_unop (&gen_negdf2_i, operands);
11347 DONE;
11348 }
11349 }")
11350
11351 (define_insn "*negdf2_media"
11352 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11353 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11354 "TARGET_SHMEDIA_FPU"
11355 "fneg.d %1, %0"
11356 [(set_attr "type" "fmove_media")])
11357
11358 (define_insn "negdf2_i"
11359 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11360 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11361 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11362 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11363 "fneg %0"
11364 [(set_attr "type" "fmove")
11365 (set_attr "fp_mode" "double")])
11366
11367 (define_expand "sqrtdf2"
11368 [(set (match_operand:DF 0 "arith_reg_operand" "")
11369 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11370 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11371 "
11372 {
11373 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11374 {
11375 expand_df_unop (&gen_sqrtdf2_i, operands);
11376 DONE;
11377 }
11378 }")
11379
11380 (define_insn "*sqrtdf2_media"
11381 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11382 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11383 "TARGET_SHMEDIA_FPU"
11384 "fsqrt.d %1, %0"
11385 [(set_attr "type" "dfdiv_media")])
11386
11387 (define_insn "sqrtdf2_i"
11388 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11389 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11390 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11391 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11392 "fsqrt %0"
11393 [(set_attr "type" "dfdiv")
11394 (set_attr "fp_mode" "double")])
11395
11396 (define_expand "absdf2"
11397 [(set (match_operand:DF 0 "arith_reg_operand" "")
11398 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11399 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11400 "
11401 {
11402 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11403 {
11404 expand_df_unop (&gen_absdf2_i, operands);
11405 DONE;
11406 }
11407 }")
11408
11409 (define_insn "*absdf2_media"
11410 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11411 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11412 "TARGET_SHMEDIA_FPU"
11413 "fabs.d %1, %0"
11414 [(set_attr "type" "fmove_media")])
11415
11416 (define_insn "absdf2_i"
11417 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11418 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11419 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11420 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11421 "fabs %0"
11422 [(set_attr "type" "fmove")
11423 (set_attr "fp_mode" "double")])
11424
11425 (define_expand "extendsfdf2"
11426 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11427 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11428 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11429 "
11430 {
11431 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11432 {
11433 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11434 get_fpscr_rtx ()));
11435 DONE;
11436 }
11437 }")
11438
11439 (define_insn "*extendsfdf2_media"
11440 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11441 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11442 "TARGET_SHMEDIA_FPU"
11443 "fcnv.sd %1, %0"
11444 [(set_attr "type" "dfpconv_media")])
11445
11446 (define_insn "extendsfdf2_i4"
11447 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11448 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11449 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11450 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11451 "fcnvsd %1,%0"
11452 [(set_attr "type" "fp")
11453 (set_attr "fp_mode" "double")])
11454
11455 (define_expand "truncdfsf2"
11456 [(set (match_operand:SF 0 "fpul_operand" "")
11457 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11458 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11459 "
11460 {
11461 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11462 {
11463 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11464 get_fpscr_rtx ()));
11465 DONE;
11466 }
11467 }")
11468
11469 (define_insn "*truncdfsf2_media"
11470 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11471 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11472 "TARGET_SHMEDIA_FPU"
11473 "fcnv.ds %1, %0"
11474 [(set_attr "type" "dfpconv_media")])
11475
11476 (define_insn "truncdfsf2_i4"
11477 [(set (match_operand:SF 0 "fpul_operand" "=y")
11478 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11479 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11480 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11481 "fcnvds %1,%0"
11482 [(set_attr "type" "fp")
11483 (set_attr "fp_mode" "double")])
11484 \f
11485 ;; Bit field extract patterns. These give better code for packed bitfields,
11486 ;; because they allow auto-increment addresses to be generated.
11487
11488 (define_expand "insv"
11489 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11490 (match_operand:SI 1 "immediate_operand" "")
11491 (match_operand:SI 2 "immediate_operand" ""))
11492 (match_operand:SI 3 "general_operand" ""))]
11493 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11494 "
11495 {
11496 rtx addr_target, orig_address, shift_reg, qi_val;
11497 HOST_WIDE_INT bitsize, size, v = 0;
11498 rtx x = operands[3];
11499
11500 /* ??? expmed doesn't care for non-register predicates. */
11501 if (! memory_operand (operands[0], VOIDmode)
11502 || ! immediate_operand (operands[1], VOIDmode)
11503 || ! immediate_operand (operands[2], VOIDmode)
11504 || ! general_operand (x, VOIDmode))
11505 FAIL;
11506 /* If this isn't a 16 / 24 / 32 bit field, or if
11507 it doesn't start on a byte boundary, then fail. */
11508 bitsize = INTVAL (operands[1]);
11509 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11510 || (INTVAL (operands[2]) % 8) != 0)
11511 FAIL;
11512
11513 size = bitsize / 8;
11514 orig_address = XEXP (operands[0], 0);
11515 shift_reg = gen_reg_rtx (SImode);
11516 if (GET_CODE (x) == CONST_INT)
11517 {
11518 v = INTVAL (x);
11519 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11520 }
11521 else
11522 {
11523 emit_insn (gen_movsi (shift_reg, operands[3]));
11524 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11525 }
11526 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11527
11528 operands[0] = replace_equiv_address (operands[0], addr_target);
11529 emit_insn (gen_movqi (operands[0], qi_val));
11530
11531 while (size -= 1)
11532 {
11533 if (GET_CODE (x) == CONST_INT)
11534 qi_val
11535 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11536 else
11537 {
11538 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11539 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11540 }
11541 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11542 emit_insn (gen_movqi (operands[0], qi_val));
11543 }
11544
11545 DONE;
11546 }")
11547
11548 (define_insn "movua"
11549 [(set (match_operand:SI 0 "register_operand" "=z")
11550 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11551 UNSPEC_MOVUA))]
11552 "TARGET_SH4A_ARCH"
11553 "movua.l %1,%0"
11554 [(set_attr "type" "movua")])
11555
11556 ;; We shouldn't need this, but cse replaces increments with references
11557 ;; to other regs before flow has a chance to create post_inc
11558 ;; addressing modes, and only postreload's cse_move2add brings the
11559 ;; increments back to a usable form.
11560 (define_peephole2
11561 [(set (match_operand:SI 0 "register_operand" "")
11562 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11563 (const_int 32) (const_int 0)))
11564 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11565 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11566 [(set (match_operand:SI 0 "register_operand" "")
11567 (sign_extract:SI (mem:SI (post_inc:SI
11568 (match_operand:SI 1 "register_operand" "")))
11569 (const_int 32) (const_int 0)))]
11570 "")
11571
11572 (define_expand "extv"
11573 [(set (match_operand:SI 0 "register_operand" "")
11574 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11575 (match_operand 2 "const_int_operand" "")
11576 (match_operand 3 "const_int_operand" "")))]
11577 "TARGET_SH4A_ARCH"
11578 {
11579 if (TARGET_SH4A_ARCH
11580 && INTVAL (operands[2]) == 32
11581 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11582 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11583 {
11584 rtx src = adjust_address (operands[1], BLKmode, 0);
11585 set_mem_size (src, GEN_INT (4));
11586 emit_insn (gen_movua (operands[0], src));
11587 DONE;
11588 }
11589
11590 FAIL;
11591 })
11592
11593 (define_expand "extzv"
11594 [(set (match_operand:SI 0 "register_operand" "")
11595 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11596 (match_operand 2 "const_int_operand" "")
11597 (match_operand 3 "const_int_operand" "")))]
11598 "TARGET_SH4A_ARCH"
11599 {
11600 if (TARGET_SH4A_ARCH
11601 && INTVAL (operands[2]) == 32
11602 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11603 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11604 {
11605 rtx src = adjust_address (operands[1], BLKmode, 0);
11606 set_mem_size (src, GEN_INT (4));
11607 emit_insn (gen_movua (operands[0], src));
11608 DONE;
11609 }
11610
11611 FAIL;
11612 })
11613
11614 \f
11615 ;; -------------------------------------------------------------------------
11616 ;; Peepholes
11617 ;; -------------------------------------------------------------------------
11618
11619 ;; This matches cases where a stack pointer increment at the start of the
11620 ;; epilogue combines with a stack slot read loading the return value.
11621
11622 (define_peephole
11623 [(set (match_operand:SI 0 "arith_reg_operand" "")
11624 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11625 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11626 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11627 "mov.l @%1+,%0")
11628
11629 ;; See the comment on the dt combiner pattern above.
11630
11631 (define_peephole
11632 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11633 (plus:SI (match_dup 0)
11634 (const_int -1)))
11635 (set (reg:SI T_REG)
11636 (eq:SI (match_dup 0)
11637 (const_int 0)))]
11638 "TARGET_SH2"
11639 "dt %0")
11640
11641 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11642 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11643 ;; reload when the constant is too large for a reg+offset address.
11644
11645 ;; ??? We would get much better code if this was done in reload. This would
11646 ;; require modifying find_reloads_address to recognize that if the constant
11647 ;; is out-of-range for an immediate add, then we get better code by reloading
11648 ;; the constant into a register than by reloading the sum into a register,
11649 ;; since the former is one instruction shorter if the address does not need
11650 ;; to be offsettable. Unfortunately this does not work, because there is
11651 ;; only one register, r0, that can be used as an index register. This register
11652 ;; is also the function return value register. So, if we try to force reload
11653 ;; to use double-reg addresses, then we end up with some instructions that
11654 ;; need to use r0 twice. The only way to fix this is to change the calling
11655 ;; convention so that r0 is not used to return values.
11656
11657 (define_peephole
11658 [(set (match_operand:SI 0 "register_operand" "=r")
11659 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11660 (set (mem:SI (match_dup 0))
11661 (match_operand:SI 2 "general_movsrc_operand" ""))]
11662 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11663 "mov.l %2,@(%0,%1)")
11664
11665 (define_peephole
11666 [(set (match_operand:SI 0 "register_operand" "=r")
11667 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11668 (set (match_operand:SI 2 "general_movdst_operand" "")
11669 (mem:SI (match_dup 0)))]
11670 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11671 "mov.l @(%0,%1),%2")
11672
11673 (define_peephole
11674 [(set (match_operand:SI 0 "register_operand" "=r")
11675 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11676 (set (mem:HI (match_dup 0))
11677 (match_operand:HI 2 "general_movsrc_operand" ""))]
11678 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11679 "mov.w %2,@(%0,%1)")
11680
11681 (define_peephole
11682 [(set (match_operand:SI 0 "register_operand" "=r")
11683 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11684 (set (match_operand:HI 2 "general_movdst_operand" "")
11685 (mem:HI (match_dup 0)))]
11686 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11687 "mov.w @(%0,%1),%2")
11688
11689 (define_peephole
11690 [(set (match_operand:SI 0 "register_operand" "=r")
11691 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11692 (set (mem:QI (match_dup 0))
11693 (match_operand:QI 2 "general_movsrc_operand" ""))]
11694 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11695 "mov.b %2,@(%0,%1)")
11696
11697 (define_peephole
11698 [(set (match_operand:SI 0 "register_operand" "=r")
11699 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11700 (set (match_operand:QI 2 "general_movdst_operand" "")
11701 (mem:QI (match_dup 0)))]
11702 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11703 "mov.b @(%0,%1),%2")
11704
11705 (define_peephole
11706 [(set (match_operand:SI 0 "register_operand" "=r")
11707 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11708 (set (mem:SF (match_dup 0))
11709 (match_operand:SF 2 "general_movsrc_operand" ""))]
11710 "TARGET_SH1 && REGNO (operands[0]) == 0
11711 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11712 || (GET_CODE (operands[2]) == SUBREG
11713 && REGNO (SUBREG_REG (operands[2])) < 16))
11714 && reg_unused_after (operands[0], insn)"
11715 "mov.l %2,@(%0,%1)")
11716
11717 (define_peephole
11718 [(set (match_operand:SI 0 "register_operand" "=r")
11719 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11720 (set (match_operand:SF 2 "general_movdst_operand" "")
11721
11722 (mem:SF (match_dup 0)))]
11723 "TARGET_SH1 && REGNO (operands[0]) == 0
11724 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11725 || (GET_CODE (operands[2]) == SUBREG
11726 && REGNO (SUBREG_REG (operands[2])) < 16))
11727 && reg_unused_after (operands[0], insn)"
11728 "mov.l @(%0,%1),%2")
11729
11730 (define_peephole
11731 [(set (match_operand:SI 0 "register_operand" "=r")
11732 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11733 (set (mem:SF (match_dup 0))
11734 (match_operand:SF 2 "general_movsrc_operand" ""))]
11735 "TARGET_SH2E && REGNO (operands[0]) == 0
11736 && ((GET_CODE (operands[2]) == REG
11737 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11738 || (GET_CODE (operands[2]) == SUBREG
11739 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11740 && reg_unused_after (operands[0], insn)"
11741 "fmov{.s|} %2,@(%0,%1)")
11742
11743 (define_peephole
11744 [(set (match_operand:SI 0 "register_operand" "=r")
11745 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11746 (set (match_operand:SF 2 "general_movdst_operand" "")
11747
11748 (mem:SF (match_dup 0)))]
11749 "TARGET_SH2E && REGNO (operands[0]) == 0
11750 && ((GET_CODE (operands[2]) == REG
11751 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11752 || (GET_CODE (operands[2]) == SUBREG
11753 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11754 && reg_unused_after (operands[0], insn)"
11755 "fmov{.s|} @(%0,%1),%2")
11756
11757 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11758 (define_insn "sp_switch_1"
11759 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11760 "TARGET_SH1"
11761 "*
11762 {
11763 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11764 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11765 return \"mov r0,r15\";
11766 }"
11767 [(set_attr "length" "10")])
11768
11769 ;; Switch back to the original stack for interrupt functions with the
11770 ;; sp_switch attribute. */
11771 (define_insn "sp_switch_2"
11772 [(const_int 2)]
11773 "TARGET_SH1"
11774 "mov.l @r15+,r15\;mov.l @r15+,r0"
11775 [(set_attr "length" "4")])
11776
11777 ;; Integer vector moves
11778
11779 (define_expand "movv8qi"
11780 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11781 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11782 "TARGET_SHMEDIA"
11783 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11784
11785 (define_insn "movv8qi_i"
11786 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11787 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11788 "TARGET_SHMEDIA
11789 && (register_operand (operands[0], V8QImode)
11790 || sh_register_operand (operands[1], V8QImode))"
11791 "@
11792 add %1, r63, %0
11793 movi %1, %0
11794 #
11795 ld%M1.q %m1, %0
11796 st%M0.q %m0, %N1"
11797 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11798 (set_attr "length" "4,4,16,4,4")])
11799
11800 (define_split
11801 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11802 (subreg:V8QI (const_int 0) 0))]
11803 "TARGET_SHMEDIA"
11804 [(set (match_dup 0)
11805 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11806 (const_int 0) (const_int 0) (const_int 0)
11807 (const_int 0) (const_int 0)]))])
11808
11809 (define_split
11810 [(set (match_operand 0 "arith_reg_dest" "")
11811 (match_operand 1 "sh_rep_vec" ""))]
11812 "TARGET_SHMEDIA && reload_completed
11813 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11814 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11815 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11816 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11817 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11818 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11819 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11820 [(set (match_dup 0) (match_dup 1))
11821 (match_dup 2)]
11822 "
11823 {
11824 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11825 rtx elt1 = XVECEXP (operands[1], 0, 1);
11826
11827 if (unit_size > 2)
11828 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11829 else
11830 {
11831 if (unit_size < 2)
11832 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11833 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11834 }
11835 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11836 operands[1] = XVECEXP (operands[1], 0, 0);
11837 if (unit_size < 2)
11838 {
11839 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11840 operands[1]
11841 = GEN_INT (TARGET_LITTLE_ENDIAN
11842 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11843 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11844 else
11845 {
11846 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11847 operands[1]
11848 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11849 }
11850 }
11851 }")
11852
11853 (define_split
11854 [(set (match_operand 0 "arith_reg_dest" "")
11855 (match_operand 1 "sh_const_vec" ""))]
11856 "TARGET_SHMEDIA && reload_completed
11857 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11858 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11859 [(set (match_dup 0) (match_dup 1))]
11860 "
11861 {
11862 rtx v = operands[1];
11863 enum machine_mode new_mode
11864 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11865
11866 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11867 operands[1]
11868 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11869 }")
11870
11871 (define_expand "movv2hi"
11872 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11873 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11874 "TARGET_SHMEDIA"
11875 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11876
11877 (define_insn "movv2hi_i"
11878 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11879 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11880 "TARGET_SHMEDIA
11881 && (register_operand (operands[0], V2HImode)
11882 || sh_register_operand (operands[1], V2HImode))"
11883 "@
11884 add.l %1, r63, %0
11885 movi %1, %0
11886 #
11887 ld%M1.l %m1, %0
11888 st%M0.l %m0, %N1"
11889 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11890 (set_attr "length" "4,4,16,4,4")
11891 (set (attr "highpart")
11892 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11893 (const_string "user")]
11894 (const_string "ignore")))])
11895
11896 (define_expand "movv4hi"
11897 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11898 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11899 "TARGET_SHMEDIA"
11900 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11901
11902 (define_insn "movv4hi_i"
11903 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11904 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11905 "TARGET_SHMEDIA
11906 && (register_operand (operands[0], V4HImode)
11907 || sh_register_operand (operands[1], V4HImode))"
11908 "@
11909 add %1, r63, %0
11910 movi %1, %0
11911 #
11912 ld%M1.q %m1, %0
11913 st%M0.q %m0, %N1"
11914 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11915 (set_attr "length" "4,4,16,4,4")
11916 (set_attr "highpart" "depend")])
11917
11918 (define_expand "movv2si"
11919 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11920 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11921 "TARGET_SHMEDIA"
11922 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11923
11924 (define_insn "movv2si_i"
11925 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11926 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11927 "TARGET_SHMEDIA
11928 && (register_operand (operands[0], V2SImode)
11929 || sh_register_operand (operands[1], V2SImode))"
11930 "@
11931 add %1, r63, %0
11932 #
11933 #
11934 ld%M1.q %m1, %0
11935 st%M0.q %m0, %N1"
11936 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11937 (set_attr "length" "4,4,16,4,4")
11938 (set_attr "highpart" "depend")])
11939
11940 ;; Multimedia Intrinsics
11941
11942 (define_insn "absv2si2"
11943 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11944 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11945 "TARGET_SHMEDIA"
11946 "mabs.l %1, %0"
11947 [(set_attr "type" "mcmp_media")
11948 (set_attr "highpart" "depend")])
11949
11950 (define_insn "absv4hi2"
11951 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11952 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11953 "TARGET_SHMEDIA"
11954 "mabs.w %1, %0"
11955 [(set_attr "type" "mcmp_media")
11956 (set_attr "highpart" "depend")])
11957
11958 (define_insn "addv2si3"
11959 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11960 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11961 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11962 "TARGET_SHMEDIA"
11963 "madd.l %1, %2, %0"
11964 [(set_attr "type" "arith_media")
11965 (set_attr "highpart" "depend")])
11966
11967 (define_insn "addv4hi3"
11968 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11969 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11970 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11971 "TARGET_SHMEDIA"
11972 "madd.w %1, %2, %0"
11973 [(set_attr "type" "arith_media")
11974 (set_attr "highpart" "depend")])
11975
11976 (define_insn_and_split "addv2hi3"
11977 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11978 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11979 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11980 "TARGET_SHMEDIA"
11981 "#"
11982 "TARGET_SHMEDIA"
11983 [(const_int 0)]
11984 "
11985 {
11986 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11987 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11988 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11989 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11990 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11991
11992 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11993 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11994 DONE;
11995 }"
11996 [(set_attr "highpart" "must_split")])
11997
11998 (define_insn "ssaddv2si3"
11999 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12000 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12001 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12002 "TARGET_SHMEDIA"
12003 "madds.l %1, %2, %0"
12004 [(set_attr "type" "mcmp_media")
12005 (set_attr "highpart" "depend")])
12006
12007 (define_insn "usaddv8qi3"
12008 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12009 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12010 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12011 "TARGET_SHMEDIA"
12012 "madds.ub %1, %2, %0"
12013 [(set_attr "type" "mcmp_media")
12014 (set_attr "highpart" "depend")])
12015
12016 (define_insn "ssaddv4hi3"
12017 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12018 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12019 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12020 "TARGET_SHMEDIA"
12021 "madds.w %1, %2, %0"
12022 [(set_attr "type" "mcmp_media")
12023 (set_attr "highpart" "depend")])
12024
12025 (define_insn "negcmpeqv8qi"
12026 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12027 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12028 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12029 "TARGET_SHMEDIA"
12030 "mcmpeq.b %N1, %N2, %0"
12031 [(set_attr "type" "mcmp_media")
12032 (set_attr "highpart" "depend")])
12033
12034 (define_insn "negcmpeqv2si"
12035 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12036 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12037 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12038 "TARGET_SHMEDIA"
12039 "mcmpeq.l %N1, %N2, %0"
12040 [(set_attr "type" "mcmp_media")
12041 (set_attr "highpart" "depend")])
12042
12043 (define_insn "negcmpeqv4hi"
12044 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12045 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12046 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12047 "TARGET_SHMEDIA"
12048 "mcmpeq.w %N1, %N2, %0"
12049 [(set_attr "type" "mcmp_media")
12050 (set_attr "highpart" "depend")])
12051
12052 (define_insn "negcmpgtuv8qi"
12053 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12054 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12055 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12056 "TARGET_SHMEDIA"
12057 "mcmpgt.ub %N1, %N2, %0"
12058 [(set_attr "type" "mcmp_media")
12059 (set_attr "highpart" "depend")])
12060
12061 (define_insn "negcmpgtv2si"
12062 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12063 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12064 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12065 "TARGET_SHMEDIA"
12066 "mcmpgt.l %N1, %N2, %0"
12067 [(set_attr "type" "mcmp_media")
12068 (set_attr "highpart" "depend")])
12069
12070 (define_insn "negcmpgtv4hi"
12071 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12072 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12073 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12074 "TARGET_SHMEDIA"
12075 "mcmpgt.w %N1, %N2, %0"
12076 [(set_attr "type" "mcmp_media")
12077 (set_attr "highpart" "depend")])
12078
12079 (define_insn "mcmv"
12080 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12081 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12082 (match_operand:DI 2 "arith_reg_operand" "r"))
12083 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12084 (not:DI (match_dup 2)))))]
12085 "TARGET_SHMEDIA"
12086 "mcmv %N1, %2, %0"
12087 [(set_attr "type" "arith_media")
12088 (set_attr "highpart" "depend")])
12089
12090 (define_insn "mcnvs_lw"
12091 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12092 (vec_concat:V4HI
12093 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12094 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12095 "TARGET_SHMEDIA"
12096 "mcnvs.lw %N1, %N2, %0"
12097 [(set_attr "type" "mcmp_media")])
12098
12099 (define_insn "mcnvs_wb"
12100 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12101 (vec_concat:V8QI
12102 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12103 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12104 "TARGET_SHMEDIA"
12105 "mcnvs.wb %N1, %N2, %0"
12106 [(set_attr "type" "mcmp_media")])
12107
12108 (define_insn "mcnvs_wub"
12109 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12110 (vec_concat:V8QI
12111 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12112 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12113 "TARGET_SHMEDIA"
12114 "mcnvs.wub %N1, %N2, %0"
12115 [(set_attr "type" "mcmp_media")])
12116
12117 (define_insn "mextr_rl"
12118 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12119 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12120 (match_operand:HI 3 "mextr_bit_offset" "i"))
12121 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12122 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12123 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12124 "*
12125 {
12126 static char templ[21];
12127
12128 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12129 (int) INTVAL (operands[3]) >> 3);
12130 return templ;
12131 }"
12132 [(set_attr "type" "arith_media")])
12133
12134 (define_insn "*mextr_lr"
12135 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12136 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12137 (match_operand:HI 3 "mextr_bit_offset" "i"))
12138 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12139 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12140 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12141 "*
12142 {
12143 static char templ[21];
12144
12145 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12146 (int) INTVAL (operands[4]) >> 3);
12147 return templ;
12148 }"
12149 [(set_attr "type" "arith_media")])
12150
12151 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12152 ; vector then varies depending on endianness.
12153 (define_expand "mextr1"
12154 [(match_operand:DI 0 "arith_reg_dest" "")
12155 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12156 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12157 "TARGET_SHMEDIA"
12158 "
12159 {
12160 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12161 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12162 DONE;
12163 }")
12164
12165 (define_expand "mextr2"
12166 [(match_operand:DI 0 "arith_reg_dest" "")
12167 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12168 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12169 "TARGET_SHMEDIA"
12170 "
12171 {
12172 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12173 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12174 DONE;
12175 }")
12176
12177 (define_expand "mextr3"
12178 [(match_operand:DI 0 "arith_reg_dest" "")
12179 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12180 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12181 "TARGET_SHMEDIA"
12182 "
12183 {
12184 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12185 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12186 DONE;
12187 }")
12188
12189 (define_expand "mextr4"
12190 [(match_operand:DI 0 "arith_reg_dest" "")
12191 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12192 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12193 "TARGET_SHMEDIA"
12194 "
12195 {
12196 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12197 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12198 DONE;
12199 }")
12200
12201 (define_expand "mextr5"
12202 [(match_operand:DI 0 "arith_reg_dest" "")
12203 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12204 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12205 "TARGET_SHMEDIA"
12206 "
12207 {
12208 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12209 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12210 DONE;
12211 }")
12212
12213 (define_expand "mextr6"
12214 [(match_operand:DI 0 "arith_reg_dest" "")
12215 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12216 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12217 "TARGET_SHMEDIA"
12218 "
12219 {
12220 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12221 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12222 DONE;
12223 }")
12224
12225 (define_expand "mextr7"
12226 [(match_operand:DI 0 "arith_reg_dest" "")
12227 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12228 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12229 "TARGET_SHMEDIA"
12230 "
12231 {
12232 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12233 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12234 DONE;
12235 }")
12236
12237 (define_expand "mmacfx_wl"
12238 [(match_operand:V2SI 0 "arith_reg_dest" "")
12239 (match_operand:V2HI 1 "extend_reg_operand" "")
12240 (match_operand:V2HI 2 "extend_reg_operand" "")
12241 (match_operand:V2SI 3 "arith_reg_operand" "")]
12242 "TARGET_SHMEDIA"
12243 "
12244 {
12245 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12246 operands[1], operands[2]));
12247 DONE;
12248 }")
12249
12250 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12251 ;; is depend
12252 (define_insn "mmacfx_wl_i"
12253 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12254 (ss_plus:V2SI
12255 (match_operand:V2SI 1 "arith_reg_operand" "0")
12256 (ss_truncate:V2SI
12257 (ashift:V2DI
12258 (sign_extend:V2DI
12259 (mult:V2SI
12260 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12261 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12262 (const_int 1)))))]
12263 "TARGET_SHMEDIA"
12264 "mmacfx.wl %2, %3, %0"
12265 [(set_attr "type" "mac_media")
12266 (set_attr "highpart" "depend")])
12267
12268 (define_expand "mmacnfx_wl"
12269 [(match_operand:V2SI 0 "arith_reg_dest" "")
12270 (match_operand:V2HI 1 "extend_reg_operand" "")
12271 (match_operand:V2HI 2 "extend_reg_operand" "")
12272 (match_operand:V2SI 3 "arith_reg_operand" "")]
12273 "TARGET_SHMEDIA"
12274 "
12275 {
12276 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12277 operands[1], operands[2]));
12278 DONE;
12279 }")
12280
12281 (define_insn "mmacnfx_wl_i"
12282 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12283 (ss_minus:V2SI
12284 (match_operand:V2SI 1 "arith_reg_operand" "0")
12285 (ss_truncate:V2SI
12286 (ashift:V2DI
12287 (sign_extend:V2DI
12288 (mult:V2SI
12289 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12290 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12291 (const_int 1)))))]
12292 "TARGET_SHMEDIA"
12293 "mmacnfx.wl %2, %3, %0"
12294 [(set_attr "type" "mac_media")
12295 (set_attr "highpart" "depend")])
12296
12297 (define_insn "mulv2si3"
12298 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12299 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12300 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12301 "TARGET_SHMEDIA"
12302 "mmul.l %1, %2, %0"
12303 [(set_attr "type" "d2mpy_media")
12304 (set_attr "highpart" "depend")])
12305
12306 (define_insn "mulv4hi3"
12307 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12308 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12309 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12310 "TARGET_SHMEDIA"
12311 "mmul.w %1, %2, %0"
12312 [(set_attr "type" "dmpy_media")
12313 (set_attr "highpart" "depend")])
12314
12315 (define_insn "mmulfx_l"
12316 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12317 (ss_truncate:V2SI
12318 (ashiftrt:V2DI
12319 (mult:V2DI
12320 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12321 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12322 (const_int 31))))]
12323 "TARGET_SHMEDIA"
12324 "mmulfx.l %1, %2, %0"
12325 [(set_attr "type" "d2mpy_media")
12326 (set_attr "highpart" "depend")])
12327
12328 (define_insn "mmulfx_w"
12329 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12330 (ss_truncate:V4HI
12331 (ashiftrt:V4SI
12332 (mult:V4SI
12333 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12334 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12335 (const_int 15))))]
12336 "TARGET_SHMEDIA"
12337 "mmulfx.w %1, %2, %0"
12338 [(set_attr "type" "dmpy_media")
12339 (set_attr "highpart" "depend")])
12340
12341 (define_insn "mmulfxrp_w"
12342 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12343 (ss_truncate:V4HI
12344 (ashiftrt:V4SI
12345 (plus:V4SI
12346 (mult:V4SI
12347 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12348 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12349 (const_int 16384))
12350 (const_int 15))))]
12351 "TARGET_SHMEDIA"
12352 "mmulfxrp.w %1, %2, %0"
12353 [(set_attr "type" "dmpy_media")
12354 (set_attr "highpart" "depend")])
12355
12356
12357 (define_expand "mmulhi_wl"
12358 [(match_operand:V2SI 0 "arith_reg_dest" "")
12359 (match_operand:V4HI 1 "arith_reg_operand" "")
12360 (match_operand:V4HI 2 "arith_reg_operand" "")]
12361 "TARGET_SHMEDIA"
12362 "
12363 {
12364 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12365 (operands[0], operands[1], operands[2]));
12366 DONE;
12367 }")
12368
12369 (define_expand "mmullo_wl"
12370 [(match_operand:V2SI 0 "arith_reg_dest" "")
12371 (match_operand:V4HI 1 "arith_reg_operand" "")
12372 (match_operand:V4HI 2 "arith_reg_operand" "")]
12373 "TARGET_SHMEDIA"
12374 "
12375 {
12376 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12377 (operands[0], operands[1], operands[2]));
12378 DONE;
12379 }")
12380
12381 (define_insn "mmul23_wl"
12382 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12383 (vec_select:V2SI
12384 (mult:V4SI
12385 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12386 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12387 (parallel [(const_int 2) (const_int 3)])))]
12388 "TARGET_SHMEDIA"
12389 "* return (TARGET_LITTLE_ENDIAN
12390 ? \"mmulhi.wl %1, %2, %0\"
12391 : \"mmullo.wl %1, %2, %0\");"
12392 [(set_attr "type" "dmpy_media")
12393 (set (attr "highpart")
12394 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12395 (const_string "user")))])
12396
12397 (define_insn "mmul01_wl"
12398 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12399 (vec_select:V2SI
12400 (mult:V4SI
12401 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12402 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12403 (parallel [(const_int 0) (const_int 1)])))]
12404 "TARGET_SHMEDIA"
12405 "* return (TARGET_LITTLE_ENDIAN
12406 ? \"mmullo.wl %1, %2, %0\"
12407 : \"mmulhi.wl %1, %2, %0\");"
12408 [(set_attr "type" "dmpy_media")
12409 (set (attr "highpart")
12410 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12411 (const_string "user")))])
12412
12413
12414 (define_expand "mmulsum_wq"
12415 [(match_operand:DI 0 "arith_reg_dest" "")
12416 (match_operand:V4HI 1 "arith_reg_operand" "")
12417 (match_operand:V4HI 2 "arith_reg_operand" "")
12418 (match_operand:DI 3 "arith_reg_operand" "")]
12419 "TARGET_SHMEDIA"
12420 "
12421 {
12422 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12423 operands[1], operands[2]));
12424 DONE;
12425 }")
12426
12427 (define_insn "mmulsum_wq_i"
12428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12429 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12430 (plus:DI
12431 (plus:DI
12432 (vec_select:DI
12433 (mult:V4DI
12434 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12435 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12436 (parallel [(const_int 0)]))
12437 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12438 (sign_extend:V4DI (match_dup 3)))
12439 (parallel [(const_int 1)])))
12440 (plus:DI
12441 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12442 (sign_extend:V4DI (match_dup 3)))
12443 (parallel [(const_int 2)]))
12444 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12445 (sign_extend:V4DI (match_dup 3)))
12446 (parallel [(const_int 3)]))))))]
12447 "TARGET_SHMEDIA"
12448 "mmulsum.wq %2, %3, %0"
12449 [(set_attr "type" "mac_media")])
12450
12451 (define_expand "mperm_w"
12452 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12453 (match_operand:V4HI 1 "arith_reg_operand" "r")
12454 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12455 "TARGET_SHMEDIA"
12456 "
12457 {
12458 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12459 (operands[0], operands[1], operands[2]));
12460 DONE;
12461 }")
12462
12463 ; This use of vec_select isn't exactly correct according to rtl.texi
12464 ; (because not constant), but it seems a straightforward extension.
12465 (define_insn "mperm_w_little"
12466 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12467 (vec_select:V4HI
12468 (match_operand:V4HI 1 "arith_reg_operand" "r")
12469 (parallel
12470 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12471 (const_int 2) (const_int 0))
12472 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12473 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12474 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12475 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12476 "mperm.w %1, %N2, %0"
12477 [(set_attr "type" "arith_media")])
12478
12479 (define_insn "mperm_w_big"
12480 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12481 (vec_select:V4HI
12482 (match_operand:V4HI 1 "arith_reg_operand" "r")
12483 (parallel
12484 [(zero_extract:QI (not:QI (match_operand:QI 2
12485 "extend_reg_or_0_operand" "rZ"))
12486 (const_int 2) (const_int 0))
12487 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12488 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12489 (zero_extract:QI (not:QI (match_dup 2))
12490 (const_int 2) (const_int 6))])))]
12491 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12492 "mperm.w %1, %N2, %0"
12493 [(set_attr "type" "arith_media")])
12494
12495 (define_insn "mperm_w0"
12496 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12497 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12498 "trunc_hi_operand" "r"))))]
12499 "TARGET_SHMEDIA"
12500 "mperm.w %1, r63, %0"
12501 [(set_attr "type" "arith_media")
12502 (set_attr "highpart" "ignore")])
12503
12504 (define_expand "msad_ubq"
12505 [(match_operand:DI 0 "arith_reg_dest" "")
12506 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12507 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12508 (match_operand:DI 3 "arith_reg_operand" "")]
12509 "TARGET_SHMEDIA"
12510 "
12511 {
12512 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12513 operands[1], operands[2]));
12514 DONE;
12515 }")
12516
12517 (define_insn "msad_ubq_i"
12518 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12519 (plus:DI
12520 (plus:DI
12521 (plus:DI
12522 (plus:DI
12523 (match_operand:DI 1 "arith_reg_operand" "0")
12524 (abs:DI (vec_select:DI
12525 (minus:V8DI
12526 (zero_extend:V8DI
12527 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12528 (zero_extend:V8DI
12529 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12530 (parallel [(const_int 0)]))))
12531 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12532 (zero_extend:V8DI (match_dup 3)))
12533 (parallel [(const_int 1)]))))
12534 (plus:DI
12535 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12536 (zero_extend:V8DI (match_dup 3)))
12537 (parallel [(const_int 2)])))
12538 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12539 (zero_extend:V8DI (match_dup 3)))
12540 (parallel [(const_int 3)])))))
12541 (plus:DI
12542 (plus:DI
12543 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12544 (zero_extend:V8DI (match_dup 3)))
12545 (parallel [(const_int 4)])))
12546 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12547 (zero_extend:V8DI (match_dup 3)))
12548 (parallel [(const_int 5)]))))
12549 (plus:DI
12550 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12551 (zero_extend:V8DI (match_dup 3)))
12552 (parallel [(const_int 6)])))
12553 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12554 (zero_extend:V8DI (match_dup 3)))
12555 (parallel [(const_int 7)])))))))]
12556 "TARGET_SHMEDIA"
12557 "msad.ubq %N2, %N3, %0"
12558 [(set_attr "type" "mac_media")])
12559
12560 (define_insn "mshalds_l"
12561 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12562 (ss_truncate:V2SI
12563 (ashift:V2DI
12564 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12565 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12566 (const_int 31)))))]
12567 "TARGET_SHMEDIA"
12568 "mshalds.l %1, %2, %0"
12569 [(set_attr "type" "mcmp_media")
12570 (set_attr "highpart" "depend")])
12571
12572 (define_insn "mshalds_w"
12573 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12574 (ss_truncate:V4HI
12575 (ashift:V4SI
12576 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12577 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12578 (const_int 15)))))]
12579 "TARGET_SHMEDIA"
12580 "mshalds.w %1, %2, %0"
12581 [(set_attr "type" "mcmp_media")
12582 (set_attr "highpart" "depend")])
12583
12584 (define_insn "ashrv2si3"
12585 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12586 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12587 (match_operand:DI 2 "arith_reg_operand" "r")))]
12588 "TARGET_SHMEDIA"
12589 "mshard.l %1, %2, %0"
12590 [(set_attr "type" "arith_media")
12591 (set_attr "highpart" "depend")])
12592
12593 (define_insn "ashrv4hi3"
12594 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12595 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12596 (match_operand:DI 2 "arith_reg_operand" "r")))]
12597 "TARGET_SHMEDIA"
12598 "mshard.w %1, %2, %0"
12599 [(set_attr "type" "arith_media")
12600 (set_attr "highpart" "depend")])
12601
12602 (define_insn "mshards_q"
12603 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12604 (ss_truncate:HI
12605 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12606 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12607 "TARGET_SHMEDIA"
12608 "mshards.q %1, %N2, %0"
12609 [(set_attr "type" "mcmp_media")])
12610
12611 (define_expand "mshfhi_b"
12612 [(match_operand:V8QI 0 "arith_reg_dest" "")
12613 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12614 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12615 "TARGET_SHMEDIA"
12616 "
12617 {
12618 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12619 (operands[0], operands[1], operands[2]));
12620 DONE;
12621 }")
12622
12623 (define_expand "mshflo_b"
12624 [(match_operand:V8QI 0 "arith_reg_dest" "")
12625 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12626 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12627 "TARGET_SHMEDIA"
12628 "
12629 {
12630 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12631 (operands[0], operands[1], operands[2]));
12632 DONE;
12633 }")
12634
12635 (define_insn "mshf4_b"
12636 [(set
12637 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12638 (vec_select:V8QI
12639 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12640 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12641 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12642 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12643 "TARGET_SHMEDIA"
12644 "* return (TARGET_LITTLE_ENDIAN
12645 ? \"mshfhi.b %N1, %N2, %0\"
12646 : \"mshflo.b %N1, %N2, %0\");"
12647 [(set_attr "type" "arith_media")
12648 (set (attr "highpart")
12649 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12650 (const_string "user")))])
12651
12652 (define_insn "mshf0_b"
12653 [(set
12654 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12655 (vec_select:V8QI
12656 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12657 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12658 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12659 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12660 "TARGET_SHMEDIA"
12661 "* return (TARGET_LITTLE_ENDIAN
12662 ? \"mshflo.b %N1, %N2, %0\"
12663 : \"mshfhi.b %N1, %N2, %0\");"
12664 [(set_attr "type" "arith_media")
12665 (set (attr "highpart")
12666 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12667 (const_string "user")))])
12668
12669 (define_expand "mshfhi_l"
12670 [(match_operand:V2SI 0 "arith_reg_dest" "")
12671 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12672 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12673 "TARGET_SHMEDIA"
12674 "
12675 {
12676 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12677 (operands[0], operands[1], operands[2]));
12678 DONE;
12679 }")
12680
12681 (define_expand "mshflo_l"
12682 [(match_operand:V2SI 0 "arith_reg_dest" "")
12683 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12684 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12685 "TARGET_SHMEDIA"
12686 "
12687 {
12688 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12689 (operands[0], operands[1], operands[2]));
12690 DONE;
12691 }")
12692
12693 (define_insn "mshf4_l"
12694 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12695 (vec_select:V2SI
12696 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12697 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12698 (parallel [(const_int 1) (const_int 3)])))]
12699 "TARGET_SHMEDIA"
12700 "* return (TARGET_LITTLE_ENDIAN
12701 ? \"mshfhi.l %N1, %N2, %0\"
12702 : \"mshflo.l %N1, %N2, %0\");"
12703 [(set_attr "type" "arith_media")
12704 (set (attr "highpart")
12705 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12706 (const_string "user")))])
12707
12708 (define_insn "mshf0_l"
12709 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12710 (vec_select:V2SI
12711 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12712 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12713 (parallel [(const_int 0) (const_int 2)])))]
12714 "TARGET_SHMEDIA"
12715 "* return (TARGET_LITTLE_ENDIAN
12716 ? \"mshflo.l %N1, %N2, %0\"
12717 : \"mshfhi.l %N1, %N2, %0\");"
12718 [(set_attr "type" "arith_media")
12719 (set (attr "highpart")
12720 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12721 (const_string "user")))])
12722
12723 (define_expand "mshfhi_w"
12724 [(match_operand:V4HI 0 "arith_reg_dest" "")
12725 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12726 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12727 "TARGET_SHMEDIA"
12728 "
12729 {
12730 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12731 (operands[0], operands[1], operands[2]));
12732 DONE;
12733 }")
12734
12735 (define_expand "mshflo_w"
12736 [(match_operand:V4HI 0 "arith_reg_dest" "")
12737 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12738 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12739 "TARGET_SHMEDIA"
12740 "
12741 {
12742 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12743 (operands[0], operands[1], operands[2]));
12744 DONE;
12745 }")
12746
12747 (define_insn "mshf4_w"
12748 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12749 (vec_select:V4HI
12750 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12751 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12752 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12753 "TARGET_SHMEDIA"
12754 "* return (TARGET_LITTLE_ENDIAN
12755 ? \"mshfhi.w %N1, %N2, %0\"
12756 : \"mshflo.w %N1, %N2, %0\");"
12757 [(set_attr "type" "arith_media")
12758 (set (attr "highpart")
12759 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12760 (const_string "user")))])
12761
12762 (define_insn "mshf0_w"
12763 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12764 (vec_select:V4HI
12765 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12766 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12767 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12768 "TARGET_SHMEDIA"
12769 "* return (TARGET_LITTLE_ENDIAN
12770 ? \"mshflo.w %N1, %N2, %0\"
12771 : \"mshfhi.w %N1, %N2, %0\");"
12772 [(set_attr "type" "arith_media")
12773 (set (attr "highpart")
12774 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12775 (const_string "user")))])
12776
12777 (define_insn "mshflo_w_x"
12778 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12779 (vec_select:V4HI
12780 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12781 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12782 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12783 "TARGET_SHMEDIA"
12784 "mshflo.w %N1, %N2, %0"
12785 [(set_attr "type" "arith_media")
12786 (set_attr "highpart" "ignore")])
12787
12788 /* These are useful to expand ANDs and as combiner patterns. */
12789 (define_insn_and_split "mshfhi_l_di"
12790 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12791 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12792 (const_int 32))
12793 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12794 (const_int -4294967296))))]
12795 "TARGET_SHMEDIA"
12796 "@
12797 mshfhi.l %N1, %N2, %0
12798 #"
12799 "TARGET_SHMEDIA && reload_completed
12800 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12801 [(set (match_dup 3) (match_dup 4))
12802 (set (match_dup 5) (match_dup 6))]
12803 "
12804 {
12805 operands[3] = gen_lowpart (SImode, operands[0]);
12806 operands[4] = gen_highpart (SImode, operands[1]);
12807 operands[5] = gen_highpart (SImode, operands[0]);
12808 operands[6] = gen_highpart (SImode, operands[2]);
12809 }"
12810 [(set_attr "type" "arith_media")])
12811
12812 (define_insn "*mshfhi_l_di_rev"
12813 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12814 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12815 (const_int -4294967296))
12816 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12817 (const_int 32))))]
12818 "TARGET_SHMEDIA"
12819 "mshfhi.l %N2, %N1, %0"
12820 [(set_attr "type" "arith_media")])
12821
12822 (define_split
12823 [(set (match_operand:DI 0 "arith_reg_dest" "")
12824 (ior:DI (zero_extend:DI (match_operand:SI 1
12825 "extend_reg_or_0_operand" ""))
12826 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12827 (const_int -4294967296))))
12828 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12829 "TARGET_SHMEDIA"
12830 [(const_int 0)]
12831 "
12832 {
12833 emit_insn (gen_ashldi3_media (operands[3],
12834 simplify_gen_subreg (DImode, operands[1],
12835 SImode, 0),
12836 GEN_INT (32)));
12837 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12838 DONE;
12839 }")
12840
12841 (define_insn "mshflo_l_di"
12842 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12843 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12844 (const_int 4294967295))
12845 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12846 (const_int 32))))]
12847
12848 "TARGET_SHMEDIA"
12849 "mshflo.l %N1, %N2, %0"
12850 [(set_attr "type" "arith_media")
12851 (set_attr "highpart" "ignore")])
12852
12853 (define_insn "*mshflo_l_di_rev"
12854 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12855 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12856 (const_int 32))
12857 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12858 (const_int 4294967295))))]
12859
12860 "TARGET_SHMEDIA"
12861 "mshflo.l %N2, %N1, %0"
12862 [(set_attr "type" "arith_media")
12863 (set_attr "highpart" "ignore")])
12864
12865 ;; Combiner pattern for trampoline initialization.
12866 (define_insn_and_split "*double_shori"
12867 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12868 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12869 (const_int 32))
12870 (match_operand:DI 2 "const_int_operand" "n")))]
12871 "TARGET_SHMEDIA
12872 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12873 "#"
12874 "rtx_equal_p (operands[0], operands[1])"
12875 [(const_int 0)]
12876 "
12877 {
12878 HOST_WIDE_INT v = INTVAL (operands[2]);
12879
12880 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12881 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12882 DONE;
12883 }"
12884 [(set_attr "highpart" "ignore")])
12885
12886
12887 (define_insn "*mshflo_l_di_x"
12888 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12889 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12890 "rZ"))
12891 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12892 (const_int 32))))]
12893
12894 "TARGET_SHMEDIA"
12895 "mshflo.l %N1, %N2, %0"
12896 [(set_attr "type" "arith_media")
12897 (set_attr "highpart" "ignore")])
12898
12899 (define_insn_and_split "concat_v2sf"
12900 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12901 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12902 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12903 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12904
12905 "TARGET_SHMEDIA"
12906 "@
12907 mshflo.l %N1, %N2, %0
12908 #
12909 #"
12910 "TARGET_SHMEDIA && reload_completed
12911 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12912 [(set (match_dup 3) (match_dup 1))
12913 (set (match_dup 4) (match_dup 2))]
12914 "
12915 {
12916 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12917 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12918 }"
12919 [(set_attr "type" "arith_media")
12920 (set_attr "highpart" "ignore")])
12921
12922 (define_insn "*mshflo_l_di_x_rev"
12923 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12924 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12925 (const_int 32))
12926 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12927
12928 "TARGET_SHMEDIA"
12929 "mshflo.l %N2, %N1, %0"
12930 [(set_attr "type" "arith_media")
12931 (set_attr "highpart" "ignore")])
12932
12933 (define_insn "ashlv2si3"
12934 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12935 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12936 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12937 "TARGET_SHMEDIA"
12938 "mshlld.l %1, %2, %0"
12939 [(set_attr "type" "arith_media")
12940 (set_attr "highpart" "depend")])
12941
12942 (define_split
12943 [(set (match_operand 0 "any_register_operand" "")
12944 (match_operator 3 "shift_operator"
12945 [(match_operand 1 "any_register_operand" "")
12946 (match_operand 2 "shift_count_reg_operand" "")]))]
12947 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12948 [(set (match_dup 0) (match_dup 3))]
12949 "
12950 {
12951 rtx count = operands[2];
12952 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12953
12954 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12955 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12956 || GET_CODE (count) == TRUNCATE)
12957 count = XEXP (count, 0);
12958 inner_mode = GET_MODE (count);
12959 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12960 subreg_lowpart_offset (outer_mode, inner_mode));
12961 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12962 operands[1], count);
12963 }")
12964
12965 (define_insn "ashlv4hi3"
12966 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12967 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12968 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12969 "TARGET_SHMEDIA"
12970 "mshlld.w %1, %2, %0"
12971 [(set_attr "type" "arith_media")
12972 (set_attr "highpart" "depend")])
12973
12974 (define_insn "lshrv2si3"
12975 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12976 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12977 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12978 "TARGET_SHMEDIA"
12979 "mshlrd.l %1, %2, %0"
12980 [(set_attr "type" "arith_media")
12981 (set_attr "highpart" "depend")])
12982
12983 (define_insn "lshrv4hi3"
12984 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12985 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12986 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12987 "TARGET_SHMEDIA"
12988 "mshlrd.w %1, %2, %0"
12989 [(set_attr "type" "arith_media")
12990 (set_attr "highpart" "depend")])
12991
12992 (define_insn "subv2si3"
12993 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12994 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12995 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12996 "TARGET_SHMEDIA"
12997 "msub.l %N1, %2, %0"
12998 [(set_attr "type" "arith_media")
12999 (set_attr "highpart" "depend")])
13000
13001 (define_insn "subv4hi3"
13002 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13003 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13004 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13005 "TARGET_SHMEDIA"
13006 "msub.w %N1, %2, %0"
13007 [(set_attr "type" "arith_media")
13008 (set_attr "highpart" "depend")])
13009
13010 (define_insn_and_split "subv2hi3"
13011 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13012 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13013 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13014 "TARGET_SHMEDIA"
13015 "#"
13016 "TARGET_SHMEDIA"
13017 [(const_int 0)]
13018 "
13019 {
13020 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13021 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13022 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13023 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13024 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13025
13026 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13027 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13028 DONE;
13029 }"
13030 [(set_attr "highpart" "must_split")])
13031
13032 (define_insn "sssubv2si3"
13033 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13034 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13035 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13036 "TARGET_SHMEDIA"
13037 "msubs.l %N1, %2, %0"
13038 [(set_attr "type" "mcmp_media")
13039 (set_attr "highpart" "depend")])
13040
13041 (define_insn "ussubv8qi3"
13042 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13043 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13044 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13045 "TARGET_SHMEDIA"
13046 "msubs.ub %N1, %2, %0"
13047 [(set_attr "type" "mcmp_media")
13048 (set_attr "highpart" "depend")])
13049
13050 (define_insn "sssubv4hi3"
13051 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13052 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13053 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13054 "TARGET_SHMEDIA"
13055 "msubs.w %N1, %2, %0"
13056 [(set_attr "type" "mcmp_media")
13057 (set_attr "highpart" "depend")])
13058
13059 ;; Floating Point Intrinsics
13060
13061 (define_insn "fcosa_s"
13062 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13063 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13064 UNSPEC_FCOSA))]
13065 "TARGET_SHMEDIA"
13066 "fcosa.s %1, %0"
13067 [(set_attr "type" "atrans_media")])
13068
13069 (define_insn "fsina_s"
13070 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13071 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13072 UNSPEC_FSINA))]
13073 "TARGET_SHMEDIA"
13074 "fsina.s %1, %0"
13075 [(set_attr "type" "atrans_media")])
13076
13077 (define_insn "fipr"
13078 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13079 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13080 "fp_arith_reg_operand" "f")
13081 (match_operand:V4SF 2
13082 "fp_arith_reg_operand" "f"))
13083 (parallel [(const_int 0)]))
13084 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13085 (parallel [(const_int 1)])))
13086 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13087 (parallel [(const_int 2)]))
13088 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13089 (parallel [(const_int 3)])))))]
13090 "TARGET_SHMEDIA"
13091 "fipr.s %1, %2, %0"
13092 [(set_attr "type" "fparith_media")])
13093
13094 (define_insn "fsrra_s"
13095 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13096 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13097 UNSPEC_FSRRA))]
13098 "TARGET_SHMEDIA"
13099 "fsrra.s %1, %0"
13100 [(set_attr "type" "atrans_media")])
13101
13102 (define_insn "ftrv"
13103 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13104 (plus:V4SF
13105 (plus:V4SF
13106 (mult:V4SF
13107 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13108 (parallel [(const_int 0) (const_int 5)
13109 (const_int 10) (const_int 15)]))
13110 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13111 (mult:V4SF
13112 (vec_select:V4SF (match_dup 1)
13113 (parallel [(const_int 4) (const_int 9)
13114 (const_int 14) (const_int 3)]))
13115 (vec_select:V4SF (match_dup 2)
13116 (parallel [(const_int 1) (const_int 2)
13117 (const_int 3) (const_int 0)]))))
13118 (plus:V4SF
13119 (mult:V4SF
13120 (vec_select:V4SF (match_dup 1)
13121 (parallel [(const_int 8) (const_int 13)
13122 (const_int 2) (const_int 7)]))
13123 (vec_select:V4SF (match_dup 2)
13124 (parallel [(const_int 2) (const_int 3)
13125 (const_int 0) (const_int 1)])))
13126 (mult:V4SF
13127 (vec_select:V4SF (match_dup 1)
13128 (parallel [(const_int 12) (const_int 1)
13129 (const_int 6) (const_int 11)]))
13130 (vec_select:V4SF (match_dup 2)
13131 (parallel [(const_int 3) (const_int 0)
13132 (const_int 1) (const_int 2)]))))))]
13133 "TARGET_SHMEDIA"
13134 "ftrv.s %1, %2, %0"
13135 [(set_attr "type" "fparith_media")])
13136
13137 (define_insn "ldhi_l"
13138 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13139 (zero_extract:SI
13140 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13141 (const_int 3))
13142 (const_int -3)))
13143 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13144 (const_int 0)))]
13145 "TARGET_SHMEDIA32"
13146 "ldhi.l %U1, %0"
13147 [(set_attr "type" "load_media")])
13148
13149 (define_insn "ldhi_q"
13150 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13151 (zero_extract:DI
13152 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13153 (const_int 7))
13154 (const_int -7)))
13155 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13156 (const_int 0)))]
13157 "TARGET_SHMEDIA32"
13158 "ldhi.q %U1, %0"
13159 [(set_attr "type" "load_media")])
13160
13161 (define_insn_and_split "*ldhi_q_comb0"
13162 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13163 (zero_extract:DI
13164 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13165 "register_operand" "r")
13166 (match_operand:SI 2
13167 "ua_offset" "I06"))
13168 (const_int 7))
13169 (const_int -7)))
13170 (plus:SI (and:SI (match_dup 1) (const_int 7))
13171 (const_int 1))
13172 (const_int 0)))]
13173 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13174 "#"
13175 ""
13176 [(pc)]
13177 "emit_insn (gen_ldhi_q (operands[0],
13178 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13179 DONE;")
13180
13181
13182 (define_insn_and_split "*ldhi_q_comb1"
13183 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13184 (zero_extract:DI
13185 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13186 "register_operand" "r")
13187 (match_operand:SI 2
13188 "ua_offset" "I06"))
13189 (const_int 7))
13190 (const_int -7)))
13191 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13192 "ua_offset" "I06"))
13193 (const_int 7))
13194 (const_int 1))
13195 (const_int 0)))]
13196 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13197 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13198 "#"
13199 ""
13200 [(pc)]
13201 "emit_insn (gen_ldhi_q (operands[0],
13202 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13203 DONE;")
13204
13205
13206 (define_insn "ldlo_l"
13207 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13208 (zero_extract:SI
13209 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13210 (const_int -4)))
13211 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13212 (and:SI (match_dup 1) (const_int 3))))]
13213 "TARGET_SHMEDIA32"
13214 "ldlo.l %U1, %0"
13215 [(set_attr "type" "load_media")])
13216
13217 (define_insn "ldlo_q"
13218 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13219 (zero_extract:DI
13220 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13221 (const_int -8)))
13222 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13223 (and:SI (match_dup 1) (const_int 7))))]
13224 "TARGET_SHMEDIA32"
13225 "ldlo.q %U1, %0"
13226 [(set_attr "type" "load_media")])
13227
13228 (define_insn_and_split "*ldlo_q_comb0"
13229 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13230 (zero_extract:DI
13231 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13232 (match_operand:SI 2 "ua_offset" "I06"))
13233 (const_int -8)))
13234 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13235 (and:SI (match_dup 1) (const_int 7))))]
13236 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13237 "#"
13238 ""
13239 [(pc)]
13240 "emit_insn (gen_ldlo_q (operands[0],
13241 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13242 DONE;")
13243
13244 (define_insn_and_split "*ldlo_q_comb1"
13245 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13246 (zero_extract:DI
13247 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13248 (match_operand:SI 2 "ua_offset" "I06"))
13249 (const_int -8)))
13250 (minus:SI (const_int 8)
13251 (and:SI (plus:SI (match_dup 1)
13252 (match_operand:SI 3 "ua_offset" "I06"))
13253 (const_int 7)))
13254 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13255 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13256 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13257 "#"
13258 ""
13259 [(pc)]
13260 "emit_insn (gen_ldlo_q (operands[0],
13261 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13262 DONE;")
13263
13264 (define_insn "sthi_l"
13265 [(set (zero_extract:SI
13266 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13267 (const_int 3))
13268 (const_int -3)))
13269 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13270 (const_int 0))
13271 (match_operand:SI 1 "arith_reg_operand" "r"))]
13272 "TARGET_SHMEDIA32"
13273 "sthi.l %U0, %1"
13274 [(set_attr "type" "ustore_media")])
13275
13276 ;; All unaligned stores are considered to be 'narrow' because they typically
13277 ;; operate on less that a quadword, and when they operate on a full quadword,
13278 ;; the vanilla store high / store low sequence will cause a stall if not
13279 ;; scheduled apart.
13280 (define_insn "sthi_q"
13281 [(set (zero_extract:DI
13282 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13283 (const_int 7))
13284 (const_int -7)))
13285 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13286 (const_int 0))
13287 (match_operand:DI 1 "arith_reg_operand" "r"))]
13288 "TARGET_SHMEDIA32"
13289 "sthi.q %U0, %1"
13290 [(set_attr "type" "ustore_media")])
13291
13292 (define_insn_and_split "*sthi_q_comb0"
13293 [(set (zero_extract:DI
13294 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13295 "register_operand" "r")
13296 (match_operand:SI 1 "ua_offset"
13297 "I06"))
13298 (const_int 7))
13299 (const_int -7)))
13300 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13301 (const_int 0))
13302 (match_operand:DI 2 "arith_reg_operand" "r"))]
13303 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13304 "#"
13305 ""
13306 [(pc)]
13307 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13308 operands[2]));
13309 DONE;")
13310
13311 (define_insn_and_split "*sthi_q_comb1"
13312 [(set (zero_extract:DI
13313 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13314 "register_operand" "r")
13315 (match_operand:SI 1 "ua_offset"
13316 "I06"))
13317 (const_int 7))
13318 (const_int -7)))
13319 (plus:SI (and:SI (plus:SI (match_dup 0)
13320 (match_operand:SI 2 "ua_offset" "I06"))
13321 (const_int 7))
13322 (const_int 1))
13323 (const_int 0))
13324 (match_operand:DI 3 "arith_reg_operand" "r"))]
13325 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13326 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13327 "#"
13328 ""
13329 [(pc)]
13330 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13331 operands[3]));
13332 DONE;")
13333
13334 ;; This is highpart user because the address is used as full 64 bit.
13335 (define_insn "stlo_l"
13336 [(set (zero_extract:SI
13337 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13338 (const_int -4)))
13339 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13340 (and:SI (match_dup 0) (const_int 3)))
13341 (match_operand:SI 1 "arith_reg_operand" "r"))]
13342 "TARGET_SHMEDIA32"
13343 "stlo.l %U0, %1"
13344 [(set_attr "type" "ustore_media")])
13345
13346 (define_insn "stlo_q"
13347 [(set (zero_extract:DI
13348 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13349 (const_int -8)))
13350 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13351 (and:SI (match_dup 0) (const_int 7)))
13352 (match_operand:DI 1 "arith_reg_operand" "r"))]
13353 "TARGET_SHMEDIA32"
13354 "stlo.q %U0, %1"
13355 [(set_attr "type" "ustore_media")])
13356
13357 (define_insn_and_split "*stlo_q_comb0"
13358 [(set (zero_extract:DI
13359 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13360 (match_operand:SI 1 "ua_offset" "I06"))
13361 (const_int -8)))
13362 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13363 (and:SI (match_dup 0) (const_int 7)))
13364 (match_operand:DI 2 "arith_reg_operand" "r"))]
13365 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13366 "#"
13367 ""
13368 [(pc)]
13369 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13370 operands[2]));
13371 DONE;")
13372
13373 (define_insn_and_split "*stlo_q_comb1"
13374 [(set (zero_extract:DI
13375 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13376 (match_operand:SI 1 "ua_offset" "I06"))
13377 (const_int -8)))
13378 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13379 (match_operand:SI 2
13380 "ua_offset" "I06"))
13381 (const_int 7)))
13382 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13383 (match_operand:DI 3 "arith_reg_operand" "r"))]
13384 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13385 "#"
13386 ""
13387 [(pc)]
13388 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13389 operands[3]));
13390 DONE;")
13391
13392 (define_insn "ldhi_l64"
13393 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13394 (zero_extract:SI
13395 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13396 (const_int 3))
13397 (const_int -3)))
13398 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13399 (const_int 0)))]
13400 "TARGET_SHMEDIA64"
13401 "ldhi.l %U1, %0"
13402 [(set_attr "type" "load_media")])
13403
13404 (define_insn "ldhi_q64"
13405 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13406 (zero_extract:DI
13407 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13408 (const_int 7))
13409 (const_int -7)))
13410 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13411 (const_int 0)))]
13412 "TARGET_SHMEDIA64"
13413 "ldhi.q %U1, %0"
13414 [(set_attr "type" "load_media")])
13415
13416 (define_insn "ldlo_l64"
13417 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13418 (zero_extract:SI
13419 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13420 (const_int -4)))
13421 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13422 (and:DI (match_dup 1) (const_int 3))))]
13423 "TARGET_SHMEDIA64"
13424 "ldlo.l %U1, %0"
13425 [(set_attr "type" "load_media")])
13426
13427 (define_insn "ldlo_q64"
13428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13429 (zero_extract:DI
13430 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13431 (const_int -8)))
13432 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13433 (and:DI (match_dup 1) (const_int 7))))]
13434 "TARGET_SHMEDIA64"
13435 "ldlo.q %U1, %0"
13436 [(set_attr "type" "load_media")])
13437
13438 (define_insn "sthi_l64"
13439 [(set (zero_extract:SI
13440 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13441 (const_int 3))
13442 (const_int -3)))
13443 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13444 (const_int 0))
13445 (match_operand:SI 1 "arith_reg_operand" "r"))]
13446 "TARGET_SHMEDIA64"
13447 "sthi.l %U0, %1"
13448 [(set_attr "type" "ustore_media")])
13449
13450 (define_insn "sthi_q64"
13451 [(set (zero_extract:DI
13452 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13453 (const_int 7))
13454 (const_int -7)))
13455 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13456 (const_int 0))
13457 (match_operand:DI 1 "arith_reg_operand" "r"))]
13458 "TARGET_SHMEDIA64"
13459 "sthi.q %U0, %1"
13460 [(set_attr "type" "ustore_media")])
13461
13462 (define_insn "stlo_l64"
13463 [(set (zero_extract:SI
13464 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13465 (const_int -4)))
13466 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13467 (and:DI (match_dup 0) (const_int 3)))
13468 (match_operand:SI 1 "arith_reg_operand" "r"))]
13469 "TARGET_SHMEDIA64"
13470 "stlo.l %U0, %1"
13471 [(set_attr "type" "ustore_media")])
13472
13473 (define_insn "stlo_q64"
13474 [(set (zero_extract:DI
13475 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13476 (const_int -8)))
13477 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13478 (and:DI (match_dup 0) (const_int 7)))
13479 (match_operand:DI 1 "arith_reg_operand" "r"))]
13480 "TARGET_SHMEDIA64"
13481 "stlo.q %U0, %1"
13482 [(set_attr "type" "ustore_media")])
13483
13484 (define_insn "nsb"
13485 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13486 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13487 UNSPEC_NSB))]
13488 "TARGET_SHMEDIA"
13489 "nsb %1, %0"
13490 [(set_attr "type" "arith_media")])
13491
13492 (define_insn "nsbsi"
13493 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13494 (zero_extend:SI
13495 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13496 UNSPEC_NSB)))]
13497 "TARGET_SHMEDIA"
13498 "nsb %1, %0"
13499 [(set_attr "type" "arith_media")])
13500
13501 (define_insn "nsbdi"
13502 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13503 (zero_extend:DI
13504 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13505 UNSPEC_NSB)))]
13506 "TARGET_SHMEDIA"
13507 "nsb %1, %0"
13508 [(set_attr "type" "arith_media")])
13509
13510 (define_expand "ffsdi2"
13511 [(set (match_operand:DI 0 "arith_reg_dest" "")
13512 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13513 "TARGET_SHMEDIA"
13514 "
13515 {
13516 rtx scratch = gen_reg_rtx (DImode);
13517 rtx last;
13518
13519 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13520 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13521 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13522 emit_insn (gen_nsbdi (scratch, scratch));
13523 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13524 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13525 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13526 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13527
13528 DONE;
13529 }")
13530
13531 (define_expand "ffssi2"
13532 [(set (match_operand:SI 0 "arith_reg_dest" "")
13533 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13534 "TARGET_SHMEDIA"
13535 "
13536 {
13537 rtx scratch = gen_reg_rtx (SImode);
13538 rtx discratch = gen_reg_rtx (DImode);
13539 rtx last;
13540
13541 emit_insn (gen_adddi3 (discratch,
13542 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13543 constm1_rtx));
13544 emit_insn (gen_andcdi3 (discratch,
13545 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13546 discratch));
13547 emit_insn (gen_nsbsi (scratch, discratch));
13548 last = emit_insn (gen_subsi3 (operands[0],
13549 force_reg (SImode, GEN_INT (63)), scratch));
13550 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13551
13552 DONE;
13553 }")
13554
13555 (define_insn "byterev"
13556 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13557 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13558 (parallel [(const_int 7) (const_int 6) (const_int 5)
13559 (const_int 4) (const_int 3) (const_int 2)
13560 (const_int 1) (const_int 0)])))]
13561 "TARGET_SHMEDIA"
13562 "byterev %1, %0"
13563 [(set_attr "type" "arith_media")])
13564
13565 (define_insn "*prefetch_media"
13566 [(prefetch (match_operand:QI 0 "address_operand" "p")
13567 (match_operand:SI 1 "const_int_operand" "n")
13568 (match_operand:SI 2 "const_int_operand" "n"))]
13569 "TARGET_SHMEDIA"
13570 "*
13571 {
13572 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13573 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13574 return \"\";
13575 }"
13576 [(set_attr "type" "other")])
13577
13578 (define_insn "*prefetch_i4"
13579 [(prefetch (match_operand:SI 0 "register_operand" "r")
13580 (match_operand:SI 1 "const_int_operand" "n")
13581 (match_operand:SI 2 "const_int_operand" "n"))]
13582 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13583 "*
13584 {
13585 return \"pref @%0\";
13586 }"
13587 [(set_attr "type" "other")])
13588
13589 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13590 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13591 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13592 (define_expand "prefetch"
13593 [(prefetch (match_operand 0 "address_operand" "p")
13594 (match_operand:SI 1 "const_int_operand" "n")
13595 (match_operand:SI 2 "const_int_operand" "n"))]
13596 "(TARGET_HARD_SH4 || TARGET_SH5) && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP)"
13597 "
13598 {
13599 if (GET_MODE (operands[0]) != Pmode
13600 || GET_CODE (operands[1]) != CONST_INT
13601 || GET_CODE (operands[2]) != CONST_INT)
13602 FAIL;
13603 if (! TARGET_SHMEDIA)
13604 operands[0] = force_reg (Pmode, operands[0]);
13605 }")
13606
13607 (define_insn "alloco_i"
13608 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13609 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13610 "TARGET_SHMEDIA32"
13611 "*
13612 {
13613 rtx xops[2];
13614
13615 if (GET_CODE (operands[0]) == PLUS)
13616 {
13617 xops[0] = XEXP (operands[0], 0);
13618 xops[1] = XEXP (operands[0], 1);
13619 }
13620 else
13621 {
13622 xops[0] = operands[0];
13623 xops[1] = const0_rtx;
13624 }
13625 output_asm_insn (\"alloco %0, %1\", xops);
13626 return \"\";
13627 }"
13628 [(set_attr "type" "other")])
13629
13630 (define_split
13631 [(set (match_operand 0 "any_register_operand" "")
13632 (match_operand 1 "" ""))]
13633 "TARGET_SHMEDIA && reload_completed"
13634 [(set (match_dup 0) (match_dup 1))]
13635 "
13636 {
13637 int n_changes = 0;
13638
13639 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13640 if (!n_changes)
13641 FAIL;
13642 }")
13643
13644 ; Stack Protector Patterns
13645
13646 (define_expand "stack_protect_set"
13647 [(set (match_operand 0 "memory_operand" "")
13648 (match_operand 1 "memory_operand" ""))]
13649 ""
13650 {
13651 if (TARGET_SHMEDIA)
13652 {
13653 if (TARGET_SHMEDIA64)
13654 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13655 else
13656 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13657 }
13658 else
13659 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13660
13661 DONE;
13662 })
13663
13664 (define_insn "stack_protect_set_si"
13665 [(set (match_operand:SI 0 "memory_operand" "=m")
13666 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13667 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13668 "!TARGET_SHMEDIA"
13669 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13670 [(set_attr "type" "other")
13671 (set_attr "length" "6")])
13672
13673 (define_insn "stack_protect_set_si_media"
13674 [(set (match_operand:SI 0 "memory_operand" "=m")
13675 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13676 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13677 "TARGET_SHMEDIA"
13678 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13679 [(set_attr "type" "other")
13680 (set_attr "length" "12")])
13681
13682 (define_insn "stack_protect_set_di_media"
13683 [(set (match_operand:DI 0 "memory_operand" "=m")
13684 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13685 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13686 "TARGET_SHMEDIA64"
13687 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13688 [(set_attr "type" "other")
13689 (set_attr "length" "12")])
13690
13691 (define_expand "stack_protect_test"
13692 [(match_operand 0 "memory_operand" "")
13693 (match_operand 1 "memory_operand" "")
13694 (match_operand 2 "" "")]
13695 ""
13696 {
13697 if (TARGET_SHMEDIA)
13698 {
13699 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13700
13701 if (TARGET_SHMEDIA64)
13702 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13703 operands[1]));
13704 else
13705 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13706 operands[1]));
13707
13708 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13709 }
13710 else
13711 {
13712 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13713 emit_jump_insn (gen_branch_true (operands[2]));
13714 }
13715
13716 DONE;
13717 })
13718
13719 (define_insn "stack_protect_test_si"
13720 [(set (reg:SI T_REG)
13721 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13722 (match_operand:SI 1 "memory_operand" "m")]
13723 UNSPEC_SP_TEST))
13724 (set (match_scratch:SI 2 "=&r") (const_int 0))
13725 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13726 "!TARGET_SHMEDIA"
13727 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13728 [(set_attr "type" "other")
13729 (set_attr "length" "10")])
13730
13731 (define_insn "stack_protect_test_si_media"
13732 [(set (match_operand:SI 0 "register_operand" "=&r")
13733 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13734 (match_operand:SI 2 "memory_operand" "m")]
13735 UNSPEC_SP_TEST))
13736 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13737 "TARGET_SHMEDIA"
13738 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13739 [(set_attr "type" "other")
13740 (set_attr "length" "16")])
13741
13742 (define_insn "stack_protect_test_di_media"
13743 [(set (match_operand:DI 0 "register_operand" "=&r")
13744 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13745 (match_operand:DI 2 "memory_operand" "m")]
13746 UNSPEC_SP_TEST))
13747 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13748 "TARGET_SHMEDIA64"
13749 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13750 [(set_attr "type" "other")
13751 (set_attr "length" "16")])