re PR target/41029 (ICE RTL check: expected code 'reg', have 'post_inc' in rhs_regno...
[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, 2008, 2009 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 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
157 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
158 (UNSPEC_EXTRACT_S16 43)
159 (UNSPEC_EXTRACT_U16 44)
160
161 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
162 (UNSPEC_SYMOFF 45)
163
164 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
165 (UNSPEC_PCREL_SYMOFF 46)
166
167 ;; These are used with unspec_volatile.
168 (UNSPECV_BLOCKAGE 0)
169 (UNSPECV_ALIGN 1)
170 (UNSPECV_CONST2 2)
171 (UNSPECV_CONST4 4)
172 (UNSPECV_CONST8 6)
173 (UNSPECV_WINDOW_END 10)
174 (UNSPECV_CONST_END 11)
175 (UNSPECV_EH_RETURN 12)
176 ])
177
178 ;; -------------------------------------------------------------------------
179 ;; Attributes
180 ;; -------------------------------------------------------------------------
181
182 ;; Target CPU.
183
184 (define_attr "cpu"
185 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
186 (const (symbol_ref "sh_cpu_attr")))
187
188 (define_attr "endian" "big,little"
189 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
190 (const_string "little") (const_string "big"))))
191
192 ;; Indicate if the default fpu mode is single precision.
193 (define_attr "fpu_single" "yes,no"
194 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
195 (const_string "yes") (const_string "no"))))
196
197 (define_attr "fmovd" "yes,no"
198 (const (if_then_else (symbol_ref "TARGET_FMOVD")
199 (const_string "yes") (const_string "no"))))
200 ;; pipeline model
201 (define_attr "pipe_model" "sh1,sh4,sh5media"
202 (const
203 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
204 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
205 (const_string "sh1"))))
206
207 ;; cbranch conditional branch instructions
208 ;; jump unconditional jumps
209 ;; arith ordinary arithmetic
210 ;; arith3 a compound insn that behaves similarly to a sequence of
211 ;; three insns of type arith
212 ;; arith3b like above, but might end with a redirected branch
213 ;; load from memory
214 ;; load_si Likewise, SImode variant for general register.
215 ;; fload Likewise, but load to fp register.
216 ;; store to memory
217 ;; fstore floating point register to memory
218 ;; move general purpose register to register
219 ;; movi8 8-bit immediate to general purpose register
220 ;; mt_group other sh4 mt instructions
221 ;; fmove register to register, floating point
222 ;; smpy word precision integer multiply
223 ;; dmpy longword or doublelongword precision integer multiply
224 ;; return rts
225 ;; pload load of pr reg, which can't be put into delay slot of rts
226 ;; prset copy register to pr reg, ditto
227 ;; pstore store of pr reg, which can't be put into delay slot of jsr
228 ;; prget copy pr to register, ditto
229 ;; pcload pc relative load of constant value
230 ;; pcfload Likewise, but load to fp register.
231 ;; pcload_si Likewise, SImode variant for general register.
232 ;; rte return from exception
233 ;; sfunc special function call with known used registers
234 ;; call function call
235 ;; fp floating point
236 ;; fpscr_toggle toggle a bit in the fpscr
237 ;; fdiv floating point divide (or square root)
238 ;; gp_fpul move from general purpose register to fpul
239 ;; fpul_gp move from fpul to general purpose register
240 ;; mac_gp move from mac[lh] to general purpose register
241 ;; gp_mac move from general purpose register to mac[lh]
242 ;; mac_mem move from mac[lh] to memory
243 ;; mem_mac move from memory to mac[lh]
244 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
245 ;; ftrc_s fix_truncsfsi2_i4
246 ;; dfdiv double precision floating point divide (or square root)
247 ;; cwb ic_invalidate_line_i
248 ;; movua SH4a unaligned load
249 ;; fsrra square root reciprocal approximate
250 ;; fsca sine and cosine approximate
251 ;; tls_load load TLS related address
252 ;; arith_media SHmedia arithmetic, logical, and shift instructions
253 ;; cbranch_media SHmedia conditional branch instructions
254 ;; cmp_media SHmedia compare instructions
255 ;; dfdiv_media SHmedia double precision divide and square root
256 ;; dfmul_media SHmedia double precision multiply instruction
257 ;; dfparith_media SHmedia double precision floating point arithmetic
258 ;; dfpconv_media SHmedia double precision floating point conversions
259 ;; dmpy_media SHmedia longword multiply
260 ;; fcmp_media SHmedia floating point compare instructions
261 ;; fdiv_media SHmedia single precision divide and square root
262 ;; fload_media SHmedia floating point register load instructions
263 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
264 ;; fparith_media SHmedia single precision floating point arithmetic
265 ;; fpconv_media SHmedia single precision floating point conversions
266 ;; fstore_media SHmedia floating point register store instructions
267 ;; gettr_media SHmedia gettr instruction
268 ;; invalidate_line_media SHmedia invalidate_line sequence
269 ;; jump_media SHmedia unconditional branch instructions
270 ;; load_media SHmedia general register load instructions
271 ;; pt_media SHmedia pt instruction (expanded by assembler)
272 ;; ptabs_media SHmedia ptabs instruction
273 ;; store_media SHmedia general register store instructions
274 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
275 ;; mac_media SHmedia mac-style fixed point operations
276 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
277 ;; atrans_media SHmedia approximate transcendental functions
278 ;; ustore_media SHmedia unaligned stores
279 ;; nil no-op move, will be deleted.
280
281 (define_attr "type"
282 "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"
283 (const_string "other"))
284
285 ;; We define a new attribute namely "insn_class".We use
286 ;; this for the DFA based pipeline description.
287 ;;
288 ;; mt_group SH4 "mt" group instructions.
289 ;;
290 ;; ex_group SH4 "ex" group instructions.
291 ;;
292 ;; ls_group SH4 "ls" group instructions.
293 ;;
294
295 (define_attr "insn_class"
296 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
297 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
298 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
299 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
300 (eq_attr "type" "cbranch,jump") (const_string "br_group")
301 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
302 (const_string "fe_group")
303 (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")]
304 (const_string "none")))
305 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
306 ;; so these do not belong in an insn group, although they are modeled
307 ;; with their own define_insn_reservations.
308
309 ;; Indicate what precision must be selected in fpscr for this insn, if any.
310
311 (define_attr "fp_mode" "single,double,none" (const_string "none"))
312
313 ;; Indicate if the fpu mode is set by this instruction
314 ;; "unknown" must have the value as "none" in fp_mode, and means
315 ;; that the instruction/abi has left the processor in an unknown
316 ;; state.
317 ;; "none" means that nothing has changed and no mode is set.
318 ;; This attribute is only used for the Renesas ABI.
319 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
320
321 ; If a conditional branch destination is within -252..258 bytes away
322 ; from the instruction it can be 2 bytes long. Something in the
323 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
324 ; branches are initially assumed to be 16 bytes long.
325 ; In machine_dependent_reorg, we split all branches that are longer than
326 ; 2 bytes.
327
328 ;; The maximum range used for SImode constant pool entries is 1018. A final
329 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
330 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
331 ;; instruction around the pool table, 2 bytes of alignment before the table,
332 ;; and 30 bytes of alignment after the table. That gives a maximum total
333 ;; pool size of 1058 bytes.
334 ;; Worst case code/pool content size ratio is 1:2 (using asms).
335 ;; Thus, in the worst case, there is one instruction in front of a maximum
336 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
337 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
338 ;; If we have a forward branch, the initial table will be put after the
339 ;; unconditional branch.
340 ;;
341 ;; ??? We could do much better by keeping track of the actual pcloads within
342 ;; the branch range and in the pcload range in front of the branch range.
343
344 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
345 ;; inside an le.
346 (define_attr "short_cbranch_p" "no,yes"
347 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348 (const_string "no")
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
350 (const_string "yes")
351 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
352 (const_string "no")
353 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
354 (const_string "yes")
355 ] (const_string "no")))
356
357 (define_attr "med_branch_p" "no,yes"
358 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
359 (const_int 1988))
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 4092))
364 (const_int 8186))
365 (const_string "yes")
366 ] (const_string "no")))
367
368 (define_attr "med_cbranch_p" "no,yes"
369 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
370 (const_int 1986))
371 (const_string "yes")
372 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
373 (const_string "no")
374 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
375 (const_int 8184))
376 (const_string "yes")
377 ] (const_string "no")))
378
379 (define_attr "braf_branch_p" "no,yes"
380 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
381 (const_string "no")
382 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
383 (const_int 20660))
384 (const_string "yes")
385 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
386 (const_string "no")
387 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
388 (const_int 65530))
389 (const_string "yes")
390 ] (const_string "no")))
391
392 (define_attr "braf_cbranch_p" "no,yes"
393 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
394 (const_string "no")
395 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
396 (const_int 20658))
397 (const_string "yes")
398 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
399 (const_string "no")
400 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
401 (const_int 65528))
402 (const_string "yes")
403 ] (const_string "no")))
404
405 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
406 ; For wider ranges, we need a combination of a code and a data part.
407 ; If we can get a scratch register for a long range jump, the code
408 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
409 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
410 ; long; otherwise, it must be 6 bytes long.
411
412 ; All other instructions are two bytes long by default.
413
414 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
415 ;; but getattrtab doesn't understand this.
416 (define_attr "length" ""
417 (cond [(eq_attr "type" "cbranch")
418 (cond [(eq_attr "short_cbranch_p" "yes")
419 (const_int 2)
420 (eq_attr "med_cbranch_p" "yes")
421 (const_int 6)
422 (eq_attr "braf_cbranch_p" "yes")
423 (const_int 12)
424 ;; ??? using pc is not computed transitively.
425 (ne (match_dup 0) (match_dup 0))
426 (const_int 14)
427 (ne (symbol_ref ("flag_pic")) (const_int 0))
428 (const_int 24)
429 ] (const_int 16))
430 (eq_attr "type" "jump")
431 (cond [(eq_attr "med_branch_p" "yes")
432 (const_int 2)
433 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
434 (const_int 0))
435 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
436 (symbol_ref "INSN"))
437 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
438 (symbol_ref "code_for_indirect_jump_scratch"))))
439 (cond [(eq_attr "braf_branch_p" "yes")
440 (const_int 6)
441 (eq (symbol_ref "flag_pic") (const_int 0))
442 (const_int 10)
443 (ne (symbol_ref "TARGET_SH2") (const_int 0))
444 (const_int 10)] (const_int 18))
445 (eq_attr "braf_branch_p" "yes")
446 (const_int 10)
447 ;; ??? using pc is not computed transitively.
448 (ne (match_dup 0) (match_dup 0))
449 (const_int 12)
450 (ne (symbol_ref ("flag_pic")) (const_int 0))
451 (const_int 22)
452 ] (const_int 14))
453 (eq_attr "type" "pt_media")
454 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
455 (const_int 20) (const_int 12))
456 (and (eq_attr "type" "jump_media")
457 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
458 (const_int 8)
459 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
460 (const_int 4)
461 (const_int 2))))
462
463 ;; DFA descriptions for the pipelines
464
465 (include "sh1.md")
466 (include "shmedia.md")
467 (include "sh4.md")
468
469 (include "predicates.md")
470 (include "constraints.md")
471
472 ;; Definitions for filling delay slots
473
474 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475
476 (define_attr "banked" "yes,no"
477 (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
478 (const_int 1))
479 (const_string "yes")]
480 (const_string "no")))
481
482 ;; ??? This should be (nil) instead of (const_int 0)
483 (define_attr "hit_stack" "yes,no"
484 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
485 (const_int 0))
486 (const_string "no")]
487 (const_string "yes")))
488
489 (define_attr "interrupt_function" "no,yes"
490 (const (symbol_ref "current_function_interrupt")))
491
492 (define_attr "in_delay_slot" "yes,no"
493 (cond [(eq_attr "type" "cbranch") (const_string "no")
494 (eq_attr "type" "pcload,pcload_si") (const_string "no")
495 (eq_attr "needs_delay_slot" "yes") (const_string "no")
496 (eq_attr "length" "2") (const_string "yes")
497 ] (const_string "no")))
498
499 (define_attr "cond_delay_slot" "yes,no"
500 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
501 ] (const_string "no")))
502
503 (define_attr "is_sfunc" ""
504 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
505
506 (define_attr "is_mac_media" ""
507 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
508
509 (define_attr "branch_zero" "yes,no"
510 (cond [(eq_attr "type" "!cbranch") (const_string "no")
511 (ne (symbol_ref "(next_active_insn (insn)\
512 == (prev_active_insn\
513 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
514 && get_attr_length (next_active_insn (insn)) == 2")
515 (const_int 0))
516 (const_string "yes")]
517 (const_string "no")))
518
519 ;; SH4 Double-precision computation with double-precision result -
520 ;; the two halves are ready at different times.
521 (define_attr "dfp_comp" "yes,no"
522 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
523 (const_string "no")))
524
525 ;; Insns for which the latency of a preceding fp insn is decreased by one.
526 (define_attr "late_fp_use" "yes,no" (const_string "no"))
527 ;; And feeding insns for which this relevant.
528 (define_attr "any_fp_comp" "yes,no"
529 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
530 (const_string "yes")]
531 (const_string "no")))
532
533 (define_attr "any_int_load" "yes,no"
534 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
535 (const_string "yes")]
536 (const_string "no")))
537
538 (define_attr "highpart" "user, ignore, extend, depend, must_split"
539 (const_string "user"))
540
541 (define_delay
542 (eq_attr "needs_delay_slot" "yes")
543 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
544
545 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
546 ;; and thus we can't put a pop instruction in its delay slot.
547 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
548 ;; instruction can go in the delay slot.
549
550 ;; Since a normal return (rts) implicitly uses the PR register,
551 ;; we can't allow PR register loads in an rts delay slot.
552
553 (define_delay
554 (eq_attr "type" "return")
555 [(and (eq_attr "in_delay_slot" "yes")
556 (ior (and (eq_attr "interrupt_function" "no")
557 (eq_attr "type" "!pload,prset"))
558 (and (eq_attr "interrupt_function" "yes")
559 (ior
560 (eq (symbol_ref "TARGET_SH3") (const_int 0))
561 (eq_attr "hit_stack" "no")
562 (eq_attr "banked" "no"))))) (nil) (nil)])
563
564 ;; Since a call implicitly uses the PR register, we can't allow
565 ;; a PR register store in a jsr delay slot.
566
567 (define_delay
568 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
569 [(and (eq_attr "in_delay_slot" "yes")
570 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
571
572 ;; Say that we have annulled true branches, since this gives smaller and
573 ;; faster code when branches are predicted as not taken.
574
575 ;; ??? The non-annulled condition should really be "in_delay_slot",
576 ;; but insns that can be filled in non-annulled get priority over insns
577 ;; that can only be filled in anulled.
578
579 (define_delay
580 (and (eq_attr "type" "cbranch")
581 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
582 ;; SH2e has a hardware bug that pretty much prohibits the use of
583 ;; annuled delay slots.
584 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
585 (not (eq_attr "cpu" "sh2e"))) (nil)])
586 \f
587 ;; -------------------------------------------------------------------------
588 ;; SImode signed integer comparisons
589 ;; -------------------------------------------------------------------------
590
591 (define_insn ""
592 [(set (reg:SI T_REG)
593 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
594 (match_operand:SI 1 "arith_operand" "K08,r"))
595 (const_int 0)))]
596 "TARGET_SH1"
597 "tst %1,%0"
598 [(set_attr "type" "mt_group")])
599
600 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
601 ;; That would still allow reload to create cmpi instructions, but would
602 ;; perhaps allow forcing the constant into a register when that is better.
603 ;; Probably should use r0 for mem/imm compares, but force constant into a
604 ;; register for pseudo/imm compares.
605
606 (define_insn "cmpeqsi_t"
607 [(set (reg:SI T_REG)
608 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
609 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
610 "TARGET_SH1"
611 "@
612 tst %0,%0
613 cmp/eq %1,%0
614 cmp/eq %1,%0"
615 [(set_attr "type" "mt_group")])
616
617 (define_insn "cmpgtsi_t"
618 [(set (reg:SI T_REG)
619 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
621 "TARGET_SH1"
622 "@
623 cmp/gt %1,%0
624 cmp/pl %0"
625 [(set_attr "type" "mt_group")])
626
627 (define_insn "cmpgesi_t"
628 [(set (reg:SI T_REG)
629 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
630 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
631 "TARGET_SH1"
632 "@
633 cmp/ge %1,%0
634 cmp/pz %0"
635 [(set_attr "type" "mt_group")])
636
637 ;; -------------------------------------------------------------------------
638 ;; SImode compare and branch
639 ;; -------------------------------------------------------------------------
640
641 (define_expand "cbranchsi4"
642 [(set (pc)
643 (if_then_else (match_operator 0 "comparison_operator"
644 [(match_operand:SI 1 "arith_operand" "")
645 (match_operand:SI 2 "arith_operand" "")])
646 (label_ref (match_operand 3 "" ""))
647 (pc)))
648 (clobber (reg:SI T_REG))]
649 ""
650 "if (TARGET_SHMEDIA)
651 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
652 operands[2], operands[3]));
653 else if (TARGET_CBRANCHDI4)
654 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
655 else
656 sh_emit_compare_and_branch (operands, SImode);
657 DONE;")
658
659 ;; -------------------------------------------------------------------------
660 ;; SImode unsigned integer comparisons
661 ;; -------------------------------------------------------------------------
662
663 (define_insn_and_split "cmpgeusi_t"
664 [(set (reg:SI T_REG)
665 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
666 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
667 "TARGET_SH1"
668 "cmp/hs %1,%0"
669 "&& operands[1] == CONST0_RTX (SImode)"
670 [(pc)]
671 "
672 {
673 emit_insn (gen_sett ());
674 DONE;
675 }"
676 [(set_attr "type" "mt_group")])
677
678 (define_insn "cmpgtusi_t"
679 [(set (reg:SI T_REG)
680 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
681 (match_operand:SI 1 "arith_reg_operand" "r")))]
682 "TARGET_SH1"
683 "cmp/hi %1,%0"
684 [(set_attr "type" "mt_group")])
685
686 \f
687 ;; -------------------------------------------------------------------------
688 ;; DImode compare and branch
689 ;; -------------------------------------------------------------------------
690
691
692 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
693 ;; Therefore, we aim to have a set of three branches that go straight to the
694 ;; destination, i.e. only one of them is taken at any one time.
695 ;; This mechanism should also be slightly better for the sh4-200.
696
697 (define_expand "cbranchdi4"
698 [(set (pc)
699 (if_then_else (match_operator 0 "comparison_operator"
700 [(match_operand:DI 1 "arith_operand" "")
701 (match_operand:DI 2 "arith_operand" "")])
702 (label_ref (match_operand 3 "" ""))
703 (pc)))
704 (clobber (match_dup 4))
705 (clobber (reg:SI T_REG))]
706 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
707 "
708 {
709 enum rtx_code comparison;
710
711 if (TARGET_SHMEDIA)
712 {
713 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
714 operands[2], operands[3]));
715 DONE;
716 }
717
718 else if (!TARGET_CBRANCHDI4)
719 {
720 sh_emit_compare_and_branch (operands, DImode);
721 DONE;
722 }
723
724 else
725 {
726 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
727 DONE;
728
729 comparison = prepare_cbranch_operands (operands, DImode,
730 LAST_AND_UNUSED_RTX_CODE);
731 if (comparison != GET_CODE (operands[0]))
732 operands[0]
733 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
734 operands[4] = gen_rtx_SCRATCH (SImode);
735 }
736 }")
737
738 (define_insn_and_split "cbranchdi4_i"
739 [(set (pc)
740 (if_then_else (match_operator 0 "comparison_operator"
741 [(match_operand:DI 1 "arith_operand" "r,r")
742 (match_operand:DI 2 "arith_operand" "rN,I08")])
743 (label_ref (match_operand 3 "" ""))
744 (pc)))
745 (clobber (match_scratch:SI 4 "=X,&r"))
746 (clobber (reg:SI T_REG))]
747 "TARGET_CBRANCHDI4"
748 "#"
749 "&& reload_completed"
750 [(pc)]
751 "
752 {
753 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
754 FAIL;
755 DONE;
756 }")
757
758 ;; -------------------------------------------------------------------------
759 ;; DImode signed integer comparisons
760 ;; -------------------------------------------------------------------------
761
762 (define_insn ""
763 [(set (reg:SI T_REG)
764 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
765 (match_operand:DI 1 "arith_operand" "r"))
766 (const_int 0)))]
767 "TARGET_SH1"
768 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
769 insn, operands);"
770 [(set_attr "length" "6")
771 (set_attr "type" "arith3b")])
772
773 (define_insn "cmpeqdi_t"
774 [(set (reg:SI T_REG)
775 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
776 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
777 "TARGET_SH1"
778 "@
779 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
780 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
781 [(set_attr "length" "6")
782 (set_attr "type" "arith3b")])
783
784 (define_split
785 [(set (reg:SI T_REG)
786 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
787 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
788 ;; If we applied this split when not optimizing, it would only be
789 ;; applied during the machine-dependent reorg, when no new basic blocks
790 ;; may be created.
791 "TARGET_SH1 && reload_completed && optimize"
792 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
793 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
794 (label_ref (match_dup 6))
795 (pc)))
796 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
797 (match_dup 6)]
798 "
799 {
800 operands[2]
801 = gen_rtx_REG (SImode,
802 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
803 operands[3]
804 = (operands[1] == const0_rtx
805 ? const0_rtx
806 : gen_rtx_REG (SImode,
807 true_regnum (operands[1])
808 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
809 operands[4] = gen_lowpart (SImode, operands[0]);
810 operands[5] = gen_lowpart (SImode, operands[1]);
811 operands[6] = gen_label_rtx ();
812 }")
813
814 (define_insn "cmpgtdi_t"
815 [(set (reg:SI T_REG)
816 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
817 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
818 "TARGET_SH2"
819 "@
820 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
821 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
822 [(set_attr "length" "8")
823 (set_attr "type" "arith3")])
824
825 (define_insn "cmpgedi_t"
826 [(set (reg:SI T_REG)
827 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
828 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
829 "TARGET_SH2"
830 "@
831 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
832 cmp/pz\\t%S0"
833 [(set_attr "length" "8,2")
834 (set_attr "type" "arith3,mt_group")])
835 \f
836 ;; -------------------------------------------------------------------------
837 ;; DImode unsigned integer comparisons
838 ;; -------------------------------------------------------------------------
839
840 (define_insn "cmpgeudi_t"
841 [(set (reg:SI T_REG)
842 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
843 (match_operand:DI 1 "arith_reg_operand" "r")))]
844 "TARGET_SH2"
845 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
846 [(set_attr "length" "8")
847 (set_attr "type" "arith3")])
848
849 (define_insn "cmpgtudi_t"
850 [(set (reg:SI T_REG)
851 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
852 (match_operand:DI 1 "arith_reg_operand" "r")))]
853 "TARGET_SH2"
854 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
855 [(set_attr "length" "8")
856 (set_attr "type" "arith3")])
857
858 (define_insn "cmpeqsi_media"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
861 (match_operand:SI 2 "cmp_operand" "Nr")))]
862 "TARGET_SHMEDIA"
863 "cmpeq %1, %N2, %0"
864 [(set_attr "type" "cmp_media")])
865
866 (define_insn "cmpeqdi_media"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (eq:SI (match_operand:DI 1 "register_operand" "%r")
869 (match_operand:DI 2 "cmp_operand" "Nr")))]
870 "TARGET_SHMEDIA"
871 "cmpeq %1, %N2, %0"
872 [(set_attr "type" "cmp_media")])
873
874 (define_insn "cmpgtsi_media"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
877 (match_operand:SI 2 "cmp_operand" "rN")))]
878 "TARGET_SHMEDIA"
879 "cmpgt %N1, %N2, %0"
880 [(set_attr "type" "cmp_media")])
881
882 (define_insn "cmpgtdi_media"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (gt: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 "cmpgt %N1, %N2, %0"
888 [(set_attr "type" "cmp_media")])
889
890 (define_insn "cmpgtusi_media"
891 [(set (match_operand:SI 0 "register_operand" "=r")
892 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
893 (match_operand:SI 2 "cmp_operand" "rN")))]
894 "TARGET_SHMEDIA"
895 "cmpgtu %N1, %N2, %0"
896 [(set_attr "type" "cmp_media")])
897
898 (define_insn "cmpgtudi_media"
899 [(set (match_operand:SI 0 "register_operand" "=r")
900 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
901 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
902 "TARGET_SHMEDIA"
903 "cmpgtu %N1, %N2, %0"
904 [(set_attr "type" "cmp_media")])
905
906 ; These two patterns are for combine.
907 (define_insn "*cmpne0sisi_media"
908 [(set (match_operand:SI 0 "register_operand" "=r")
909 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
910 "TARGET_SHMEDIA"
911 "cmpgtu %1,r63,%0"
912 [(set_attr "type" "cmp_media")])
913
914 ;; -------------------------------------------------------------------------
915 ;; Conditional move instructions
916 ;; -------------------------------------------------------------------------
917
918 ;; The insn names may seem reversed, but note that cmveq performs the move
919 ;; if op1 == 0, and cmvne does it if op1 != 0.
920
921 (define_insn "movdicc_false"
922 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
923 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
924 (const_int 0))
925 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
926 (match_operand:DI 3 "arith_reg_operand" "0")))]
927 "TARGET_SHMEDIA"
928 "cmveq %1, %N2, %0"
929 [(set_attr "type" "arith_media")])
930
931 (define_insn "movdicc_true"
932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
933 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
934 (const_int 0))
935 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
936 (match_operand:DI 3 "arith_reg_operand" "0")))]
937 "TARGET_SHMEDIA"
938 "cmvne %1, %N2, %0"
939 [(set_attr "type" "arith_media")])
940
941 (define_peephole2
942 [(set (match_operand:DI 0 "arith_reg_dest" "")
943 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
944 [(match_operand:DI 1 "arith_reg_operand" "")
945 (const_int 0)])
946 (match_operand:DI 2 "arith_reg_dest" "")
947 (match_dup 0)))
948 (set (match_dup 2) (match_dup 0))]
949 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
950 [(set (match_dup 2)
951 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
952 "
953 {
954 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
955 VOIDmode, operands[1], CONST0_RTX (DImode));
956 }")
957
958 (define_peephole2
959 [(set (match_operand:DI 0 "general_movdst_operand" "")
960 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
961 (set (match_operand:DI 2 "arith_reg_dest" "")
962 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
963 [(match_operand:DI 3 "arith_reg_operand" "")
964 (const_int 0)])
965 (match_dup 0)
966 (match_dup 2)))]
967 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
968 [(set (match_dup 2)
969 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
970 "")
971
972 (define_expand "movdicc"
973 [(set (match_operand:DI 0 "register_operand" "")
974 (if_then_else:DI (match_operand 1 "comparison_operator" "")
975 (match_operand:DI 2 "register_operand" "")
976 (match_operand:DI 3 "register_operand" "")))]
977 "TARGET_SHMEDIA"
978 "
979 {
980 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
981 && GET_MODE (XEXP (operands[1], 0)) == DImode
982 && XEXP (operands[1], 1) == const0_rtx)
983 ;
984 else
985 {
986 if (!can_create_pseudo_p ())
987 FAIL;
988
989 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
990 GET_CODE (operands[1]),
991 XEXP (operands[1], 0),
992 XEXP (operands[1], 1));
993 if (!operands[1])
994 FAIL;
995 }
996 }")
997
998 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
999 ;; SImode to DImode.
1000 (define_insn "movsicc_false"
1001 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1002 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1003 (const_int 0))
1004 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1005 (match_operand:SI 3 "arith_reg_operand" "0")))]
1006 "TARGET_SHMEDIA"
1007 "cmveq %1, %N2, %0"
1008 [(set_attr "type" "arith_media")])
1009
1010 (define_insn "movsicc_true"
1011 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1012 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1013 (const_int 0))
1014 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1015 (match_operand:SI 3 "arith_reg_operand" "0")))]
1016 "TARGET_SHMEDIA"
1017 "cmvne %1, %N2, %0"
1018 [(set_attr "type" "arith_media")])
1019
1020 (define_peephole2
1021 [(set (match_operand:SI 0 "arith_reg_dest" "")
1022 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1023 [(match_operand:SI 1 "arith_reg_operand" "")
1024 (const_int 0)])
1025 (match_operand:SI 2 "arith_reg_dest" "")
1026 (match_dup 0)))
1027 (set (match_dup 2) (match_dup 0))]
1028 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1029 [(set (match_dup 2)
1030 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1031 "
1032 {
1033 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1034 VOIDmode, operands[1], CONST0_RTX (SImode));
1035 }")
1036
1037 (define_peephole2
1038 [(set (match_operand:SI 0 "general_movdst_operand" "")
1039 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1040 (set (match_operand:SI 2 "arith_reg_dest" "")
1041 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1042 [(match_operand:SI 3 "arith_reg_operand" "")
1043 (const_int 0)])
1044 (match_dup 0)
1045 (match_dup 2)))]
1046 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1047 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1048 [(set (match_dup 2)
1049 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1050 "
1051 {
1052 replace_rtx (operands[4], operands[0], operands[1]);
1053 }")
1054
1055 (define_peephole2
1056 [(set (match_operand 0 "any_register_operand" "")
1057 (match_operand 1 "any_register_operand" ""))
1058 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1059 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1060 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1061 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1062 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1063 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1064 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1065 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1066 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1067 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1068 && (REGNO_REG_CLASS (REGNO (operands[0]))
1069 == REGNO_REG_CLASS (REGNO (operands[2])))
1070 && (REGNO_REG_CLASS (REGNO (operands[1]))
1071 == REGNO_REG_CLASS (REGNO (operands[0])))"
1072 [(set (match_dup 0) (match_dup 3))
1073 (set (match_dup 4) (match_dup 5))]
1074 "
1075 {
1076 rtx set1, set2, insn2;
1077 rtx replacements[4];
1078
1079 /* We want to replace occurrences of operands[0] with operands[1] and
1080 operands[2] with operands[0] in operands[4]/operands[5].
1081 Doing just two replace_rtx calls naively would result in the second
1082 replacement undoing all that the first did if operands[1] and operands[2]
1083 are identical, so we must do this simultaneously. */
1084 replacements[0] = operands[0];
1085 replacements[1] = operands[1];
1086 replacements[2] = operands[2];
1087 replacements[3] = operands[0];
1088 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1089 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1090 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1091 FAIL;
1092
1093 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1094 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1095 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1096 /* The operands array is aliased to recog_data.operand, which gets
1097 clobbered by extract_insn, so finish with it now. */
1098 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1099 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1100 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1101 always uses emit_insn. */
1102 /* Check that we don't violate matching constraints or earlyclobbers. */
1103 extract_insn (emit_insn (set1));
1104 if (! constrain_operands (1))
1105 goto failure;
1106 insn2 = emit (set2);
1107 if (GET_CODE (insn2) == BARRIER)
1108 goto failure;
1109 extract_insn (insn2);
1110 if (! constrain_operands (1))
1111 {
1112 rtx tmp;
1113 failure:
1114 tmp = replacements[0];
1115 replacements[0] = replacements[1];
1116 replacements[1] = tmp;
1117 tmp = replacements[2];
1118 replacements[2] = replacements[3];
1119 replacements[3] = tmp;
1120 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1121 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1122 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1123 FAIL;
1124 }
1125 DONE;
1126 }")
1127
1128 ;; The register allocator is rather clumsy in handling multi-way conditional
1129 ;; moves, so allow the combiner to make them, and we split them up after
1130 ;; reload. */
1131 (define_insn_and_split "*movsicc_umin"
1132 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1133 (umin:SI (if_then_else:SI
1134 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1135 (const_int 0))
1136 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1137 (match_operand:SI 3 "register_operand" "0"))
1138 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1139 (clobber (match_scratch:SI 5 "=&r"))]
1140 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1141 "#"
1142 "TARGET_SHMEDIA && reload_completed"
1143 [(pc)]
1144 "
1145 {
1146 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1147 operands[3]));
1148 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1149 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1150 operands[0]));
1151 DONE;
1152 }")
1153
1154 (define_insn "*movsicc_t_false"
1155 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1156 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1157 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1158 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1159 "TARGET_PRETEND_CMOVE
1160 && (arith_reg_operand (operands[1], SImode)
1161 || (immediate_operand (operands[1], SImode)
1162 && satisfies_constraint_I08 (operands[1])))"
1163 "bt 0f\;mov %1,%0\\n0:"
1164 [(set_attr "type" "mt_group,arith") ;; poor approximation
1165 (set_attr "length" "4")])
1166
1167 (define_insn "*movsicc_t_true"
1168 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1169 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1170 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1171 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1172 "TARGET_PRETEND_CMOVE
1173 && (arith_reg_operand (operands[1], SImode)
1174 || (immediate_operand (operands[1], SImode)
1175 && satisfies_constraint_I08 (operands[1])))"
1176 "bf 0f\;mov %1,%0\\n0:"
1177 [(set_attr "type" "mt_group,arith") ;; poor approximation
1178 (set_attr "length" "4")])
1179
1180 (define_expand "movsicc"
1181 [(set (match_operand:SI 0 "arith_reg_dest" "")
1182 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1183 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1184 (match_operand:SI 3 "arith_reg_operand" "")))]
1185 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1186 "
1187 {
1188 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1189 && GET_MODE (XEXP (operands[1], 0)) == SImode
1190 && (TARGET_SHMEDIA
1191 || (REG_P (XEXP (operands[1], 0))
1192 && REGNO (XEXP (operands[1], 0)) == T_REG))
1193 && XEXP (operands[1], 1) == const0_rtx)
1194 ;
1195
1196 else if (TARGET_PRETEND_CMOVE)
1197 {
1198 enum rtx_code code = GET_CODE (operands[1]);
1199 enum rtx_code new_code = code;
1200 rtx op0 = XEXP (operands[1], 0);
1201 rtx op1 = XEXP (operands[1], 1);
1202
1203 if (! currently_expanding_to_rtl)
1204 FAIL;
1205 switch (code)
1206 {
1207 case LT: case LE: case LEU: case LTU:
1208 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1209 break;
1210 case NE:
1211 new_code = reverse_condition (code);
1212 break;
1213 case EQ: case GT: case GE: case GEU: case GTU:
1214 break;
1215 default:
1216 FAIL;
1217 }
1218 sh_emit_scc_to_t (new_code, op0, op1);
1219 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1220 gen_rtx_REG (SImode, T_REG), const0_rtx);
1221 }
1222 else
1223 {
1224 if (!can_create_pseudo_p ())
1225 FAIL;
1226
1227 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1228 GET_CODE (operands[1]),
1229 XEXP (operands[1], 0),
1230 XEXP (operands[1], 1));
1231 if (!operands[1])
1232 FAIL;
1233 }
1234 }")
1235
1236 (define_expand "movqicc"
1237 [(set (match_operand:QI 0 "register_operand" "")
1238 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1239 (match_operand:QI 2 "register_operand" "")
1240 (match_operand:QI 3 "register_operand" "")))]
1241 "TARGET_SHMEDIA"
1242 "
1243 {
1244 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1245 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1246 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1247 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1248 DONE;
1249 }")
1250 \f
1251 ;; -------------------------------------------------------------------------
1252 ;; Addition instructions
1253 ;; -------------------------------------------------------------------------
1254
1255 (define_expand "adddi3"
1256 [(set (match_operand:DI 0 "arith_reg_operand" "")
1257 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1258 (match_operand:DI 2 "arith_operand" "")))]
1259 ""
1260 "
1261 {
1262 if (TARGET_SH1)
1263 {
1264 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1265 FAIL;
1266 operands[2] = force_reg (DImode, operands[2]);
1267 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1268 DONE;
1269 }
1270 }")
1271
1272 (define_insn "*adddi3_media"
1273 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1274 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1275 (match_operand:DI 2 "arith_operand" "r,I10")))]
1276 "TARGET_SHMEDIA"
1277 "@
1278 add %1, %2, %0
1279 addi %1, %2, %0"
1280 [(set_attr "type" "arith_media")])
1281
1282 (define_insn "*adddisi3_media"
1283 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1284 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1285 (match_operand:DI 2 "arith_operand" "r,I10")))]
1286 "TARGET_SHMEDIA"
1287 "@
1288 add.l %1, %2, %0
1289 addi.l %1, %2, %0"
1290 [(set_attr "type" "arith_media")
1291 (set_attr "highpart" "ignore")])
1292
1293 (define_insn "adddi3z_media"
1294 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1295 (zero_extend:DI
1296 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1297 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1298 "TARGET_SHMEDIA"
1299 "addz.l %1, %N2, %0"
1300 [(set_attr "type" "arith_media")
1301 (set_attr "highpart" "ignore")])
1302
1303 (define_insn "adddi3_compact"
1304 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1305 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1306 (match_operand:DI 2 "arith_reg_operand" "r")))
1307 (clobber (reg:SI T_REG))]
1308 "TARGET_SH1"
1309 "#"
1310 [(set_attr "length" "6")])
1311
1312 (define_split
1313 [(set (match_operand:DI 0 "arith_reg_dest" "")
1314 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1315 (match_operand:DI 2 "arith_reg_operand" "")))
1316 (clobber (reg:SI T_REG))]
1317 "TARGET_SH1 && reload_completed"
1318 [(const_int 0)]
1319 "
1320 {
1321 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1322 high0 = gen_rtx_REG (SImode,
1323 true_regnum (operands[0])
1324 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1325 high2 = gen_rtx_REG (SImode,
1326 true_regnum (operands[2])
1327 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1328 emit_insn (gen_clrt ());
1329 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1330 emit_insn (gen_addc1 (high0, high0, high2));
1331 DONE;
1332 }")
1333
1334 (define_insn "addc"
1335 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1336 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1337 (match_operand:SI 2 "arith_reg_operand" "r"))
1338 (reg:SI T_REG)))
1339 (set (reg:SI T_REG)
1340 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1341 "TARGET_SH1"
1342 "addc %2,%0"
1343 [(set_attr "type" "arith")])
1344
1345 (define_insn "addc1"
1346 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1347 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348 (match_operand:SI 2 "arith_reg_operand" "r"))
1349 (reg:SI T_REG)))
1350 (clobber (reg:SI T_REG))]
1351 "TARGET_SH1"
1352 "addc %2,%0"
1353 [(set_attr "type" "arith")])
1354
1355 (define_expand "addsi3"
1356 [(set (match_operand:SI 0 "arith_reg_operand" "")
1357 (plus:SI (match_operand:SI 1 "arith_operand" "")
1358 (match_operand:SI 2 "arith_operand" "")))]
1359 ""
1360 "
1361 {
1362 if (TARGET_SHMEDIA)
1363 operands[1] = force_reg (SImode, operands[1]);
1364 }")
1365
1366 (define_insn "addsi3_media"
1367 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1368 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1369 (match_operand:SI 2 "arith_operand" "r,I10")))]
1370 "TARGET_SHMEDIA"
1371 "@
1372 add.l %1, %2, %0
1373 addi.l %1, %2, %0"
1374 [(set_attr "type" "arith_media")
1375 (set_attr "highpart" "ignore")])
1376
1377 (define_insn "addsidi3_media"
1378 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1379 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1380 "%r,r")
1381 (match_operand:SI 2 "arith_operand"
1382 "r,I10"))))]
1383 "TARGET_SHMEDIA"
1384 "@
1385 add.l %1, %2, %0
1386 addi.l %1, %2, %0"
1387 [(set_attr "type" "arith_media")
1388 (set_attr "highpart" "ignore")])
1389
1390 (define_insn "*addsi3_compact"
1391 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1393 (match_operand:SI 2 "arith_operand" "rI08")))]
1394 "TARGET_SH1"
1395 "add %2,%0"
1396 [(set_attr "type" "arith")])
1397
1398 ;; -------------------------------------------------------------------------
1399 ;; Subtraction instructions
1400 ;; -------------------------------------------------------------------------
1401
1402 (define_expand "subdi3"
1403 [(set (match_operand:DI 0 "arith_reg_operand" "")
1404 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1405 (match_operand:DI 2 "arith_reg_operand" "")))]
1406 ""
1407 "
1408 {
1409 if (TARGET_SH1)
1410 {
1411 operands[1] = force_reg (DImode, operands[1]);
1412 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1413 DONE;
1414 }
1415 }")
1416
1417 (define_insn "*subdi3_media"
1418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1419 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1420 (match_operand:DI 2 "arith_reg_operand" "r")))]
1421 "TARGET_SHMEDIA"
1422 "sub %N1, %2, %0"
1423 [(set_attr "type" "arith_media")])
1424
1425 (define_insn "subdisi3_media"
1426 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1427 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1428 (match_operand:DI 2 "arith_reg_operand" "r")))]
1429 "TARGET_SHMEDIA"
1430 "sub.l %N1, %2, %0"
1431 [(set_attr "type" "arith_media")
1432 (set_attr "highpart" "ignore")])
1433
1434 (define_insn "subdi3_compact"
1435 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1436 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1437 (match_operand:DI 2 "arith_reg_operand" "r")))
1438 (clobber (reg:SI T_REG))]
1439 "TARGET_SH1"
1440 "#"
1441 [(set_attr "length" "6")])
1442
1443 (define_split
1444 [(set (match_operand:DI 0 "arith_reg_dest" "")
1445 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1446 (match_operand:DI 2 "arith_reg_operand" "")))
1447 (clobber (reg:SI T_REG))]
1448 "TARGET_SH1 && reload_completed"
1449 [(const_int 0)]
1450 "
1451 {
1452 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1453 high0 = gen_rtx_REG (SImode,
1454 true_regnum (operands[0])
1455 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1456 high2 = gen_rtx_REG (SImode,
1457 true_regnum (operands[2])
1458 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1459 emit_insn (gen_clrt ());
1460 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1461 emit_insn (gen_subc1 (high0, high0, high2));
1462 DONE;
1463 }")
1464
1465 (define_insn "subc"
1466 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1467 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1468 (match_operand:SI 2 "arith_reg_operand" "r"))
1469 (reg:SI T_REG)))
1470 (set (reg:SI T_REG)
1471 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1472 (reg:SI T_REG))
1473 (match_dup 1)))]
1474 "TARGET_SH1"
1475 "subc %2,%0"
1476 [(set_attr "type" "arith")])
1477
1478 (define_insn "subc1"
1479 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1481 (match_operand:SI 2 "arith_reg_operand" "r"))
1482 (reg:SI T_REG)))
1483 (clobber (reg:SI T_REG))]
1484 "TARGET_SH1"
1485 "subc %2,%0"
1486 [(set_attr "type" "arith")])
1487
1488 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1489 ;; pattern for this case. This helps multimedia applications that compute
1490 ;; the sum of absolute differences.
1491 (define_insn "mov_neg_si_t"
1492 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1493 "TARGET_SH1"
1494 "subc %0,%0"
1495 [(set_attr "type" "arith")])
1496
1497 (define_insn "*subsi3_internal"
1498 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1499 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1500 (match_operand:SI 2 "arith_reg_operand" "r")))]
1501 "TARGET_SH1"
1502 "sub %2,%0"
1503 [(set_attr "type" "arith")])
1504
1505 (define_insn_and_split "*subsi3_media"
1506 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1507 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1508 (match_operand:SI 2 "extend_reg_operand" "r")))]
1509 "TARGET_SHMEDIA
1510 && (operands[1] != constm1_rtx
1511 || (GET_CODE (operands[2]) != TRUNCATE
1512 && GET_CODE (operands[2]) != SUBREG))"
1513 "sub.l %N1, %2, %0"
1514 "operands[1] == constm1_rtx"
1515 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1516 ""
1517 [(set_attr "type" "arith_media")
1518 (set_attr "highpart" "ignore")])
1519
1520 (define_split
1521 [(set (match_operand:SI 0 "arith_reg_dest" "")
1522 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1523 "general_extend_operand"
1524 "") 0)) 0)))]
1525 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1526 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1527 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1528 "")
1529
1530 (define_split
1531 [(set (match_operand:SI 0 "arith_reg_dest" "")
1532 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1533 "general_extend_operand"
1534 "") 0)) 3)))]
1535 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1536 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1537 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1538 "")
1539 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1540 ;; will sometimes save one instruction. Otherwise we might get
1541 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1542 ;; are the same.
1543
1544 (define_expand "subsi3"
1545 [(set (match_operand:SI 0 "arith_reg_operand" "")
1546 (minus:SI (match_operand:SI 1 "arith_operand" "")
1547 (match_operand:SI 2 "arith_reg_operand" "")))]
1548 ""
1549 "
1550 {
1551 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1552 {
1553 emit_insn (gen_negsi2 (operands[0], operands[2]));
1554 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1555 DONE;
1556 }
1557 if (TARGET_SHMEDIA)
1558 {
1559 if (!can_create_pseudo_p ()
1560 && ! arith_reg_or_0_operand (operands[1], SImode))
1561 FAIL;
1562 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1563 operands[1] = force_reg (SImode, operands[1]);
1564 }
1565 }")
1566 \f
1567 ;; -------------------------------------------------------------------------
1568 ;; Division instructions
1569 ;; -------------------------------------------------------------------------
1570
1571 ;; We take advantage of the library routines which don't clobber as many
1572 ;; registers as a normal function call would.
1573
1574 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1575 ;; also has an effect on the register that holds the address of the sfunc.
1576 ;; To make this work, we have an extra dummy insn that shows the use
1577 ;; of this register for reorg.
1578
1579 (define_insn "use_sfunc_addr"
1580 [(set (reg:SI PR_REG)
1581 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1582 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1583 ""
1584 [(set_attr "length" "0")])
1585
1586 (define_insn "udivsi3_sh2a"
1587 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1588 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1589 (match_operand:SI 2 "arith_reg_operand" "z")))]
1590 "TARGET_SH2A"
1591 "divu %2,%1"
1592 [(set_attr "type" "arith")
1593 (set_attr "in_delay_slot" "no")])
1594
1595 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1596 ;; hard register 0. If we used hard register 0, then the next instruction
1597 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1598 ;; gets allocated to a stack slot that needs its address reloaded, then
1599 ;; there is nothing to prevent reload from using r0 to reload the address.
1600 ;; This reload would clobber the value in r0 we are trying to store.
1601 ;; If we let reload allocate r0, then this problem can never happen.
1602
1603 (define_insn "udivsi3_i1"
1604 [(set (match_operand:SI 0 "register_operand" "=z")
1605 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1606 (clobber (reg:SI T_REG))
1607 (clobber (reg:SI PR_REG))
1608 (clobber (reg:SI R4_REG))
1609 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1610 "TARGET_SH1 && ! TARGET_SH4"
1611 "jsr @%1%#"
1612 [(set_attr "type" "sfunc")
1613 (set_attr "needs_delay_slot" "yes")])
1614
1615 ; Since shmedia-nofpu code could be linked against shcompact code, and
1616 ; the udivsi3 libcall has the same name, we must consider all registers
1617 ; clobbered that are in the union of the registers clobbered by the
1618 ; shmedia and the shcompact implementation. Note, if the shcompact
1619 ; implementation actually used shcompact code, we'd need to clobber
1620 ; also r23 and fr23.
1621 (define_insn "udivsi3_i1_media"
1622 [(set (match_operand:SI 0 "register_operand" "=z")
1623 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1624 (clobber (reg:SI T_MEDIA_REG))
1625 (clobber (reg:SI PR_MEDIA_REG))
1626 (clobber (reg:SI R20_REG))
1627 (clobber (reg:SI R21_REG))
1628 (clobber (reg:SI R22_REG))
1629 (clobber (reg:DI TR0_REG))
1630 (clobber (reg:DI TR1_REG))
1631 (clobber (reg:DI TR2_REG))
1632 (use (match_operand 1 "target_reg_operand" "b"))]
1633 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1634 "blink %1, r18"
1635 [(set_attr "type" "sfunc")
1636 (set_attr "needs_delay_slot" "yes")])
1637
1638 (define_expand "udivsi3_i4_media"
1639 [(set (match_dup 3)
1640 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1641 (set (match_dup 4)
1642 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1643 (set (match_dup 5) (float:DF (match_dup 3)))
1644 (set (match_dup 6) (float:DF (match_dup 4)))
1645 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1646 (set (match_dup 8) (fix:DI (match_dup 7)))
1647 (set (match_operand:SI 0 "register_operand" "")
1648 (truncate:SI (match_dup 8)))]
1649 "TARGET_SHMEDIA_FPU"
1650 "
1651 {
1652 operands[3] = gen_reg_rtx (DImode);
1653 operands[4] = gen_reg_rtx (DImode);
1654 operands[5] = gen_reg_rtx (DFmode);
1655 operands[6] = gen_reg_rtx (DFmode);
1656 operands[7] = gen_reg_rtx (DFmode);
1657 operands[8] = gen_reg_rtx (DImode);
1658 }")
1659
1660 (define_insn "udivsi3_i4"
1661 [(set (match_operand:SI 0 "register_operand" "=y")
1662 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1663 (clobber (reg:SI T_REG))
1664 (clobber (reg:SI PR_REG))
1665 (clobber (reg:DF DR0_REG))
1666 (clobber (reg:DF DR2_REG))
1667 (clobber (reg:DF DR4_REG))
1668 (clobber (reg:SI R0_REG))
1669 (clobber (reg:SI R1_REG))
1670 (clobber (reg:SI R4_REG))
1671 (clobber (reg:SI R5_REG))
1672 (use (reg:PSI FPSCR_REG))
1673 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1674 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1675 "jsr @%1%#"
1676 [(set_attr "type" "sfunc")
1677 (set_attr "fp_mode" "double")
1678 (set_attr "needs_delay_slot" "yes")])
1679
1680 (define_insn "udivsi3_i4_single"
1681 [(set (match_operand:SI 0 "register_operand" "=y")
1682 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1683 (clobber (reg:SI T_REG))
1684 (clobber (reg:SI PR_REG))
1685 (clobber (reg:DF DR0_REG))
1686 (clobber (reg:DF DR2_REG))
1687 (clobber (reg:DF DR4_REG))
1688 (clobber (reg:SI R0_REG))
1689 (clobber (reg:SI R1_REG))
1690 (clobber (reg:SI R4_REG))
1691 (clobber (reg:SI R5_REG))
1692 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1693 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1694 "jsr @%1%#"
1695 [(set_attr "type" "sfunc")
1696 (set_attr "needs_delay_slot" "yes")])
1697
1698 (define_insn "udivsi3_i4_int"
1699 [(set (match_operand:SI 0 "register_operand" "=z")
1700 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1701 (clobber (reg:SI T_REG))
1702 (clobber (reg:SI R1_REG))
1703 (clobber (reg:SI PR_REG))
1704 (clobber (reg:SI MACH_REG))
1705 (clobber (reg:SI MACL_REG))
1706 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1707 "TARGET_SH1"
1708 "jsr @%1%#"
1709 [(set_attr "type" "sfunc")
1710 (set_attr "needs_delay_slot" "yes")])
1711
1712
1713 (define_expand "udivsi3"
1714 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1715 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1716 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1717 (parallel [(set (match_operand:SI 0 "register_operand" "")
1718 (udiv:SI (reg:SI R4_REG)
1719 (reg:SI R5_REG)))
1720 (clobber (reg:SI T_REG))
1721 (clobber (reg:SI PR_REG))
1722 (clobber (reg:SI R4_REG))
1723 (use (match_dup 3))])]
1724 ""
1725 "
1726 {
1727 rtx last;
1728
1729 operands[3] = gen_reg_rtx (Pmode);
1730 /* Emit the move of the address to a pseudo outside of the libcall. */
1731 if (TARGET_DIVIDE_CALL_TABLE)
1732 {
1733 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1734 that causes problems when the divide code is supposed to come from a
1735 separate library. Division by zero is undefined, so dividing 1 can be
1736 implemented by comparing with the divisor. */
1737 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1738 {
1739 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1740 emit_insn (gen_cstoresi4 (operands[0], test,
1741 operands[1], operands[2]));
1742 DONE;
1743 }
1744 else if (operands[2] == const0_rtx)
1745 {
1746 emit_move_insn (operands[0], operands[2]);
1747 DONE;
1748 }
1749 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1750 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1751 }
1752 else if (TARGET_DIVIDE_CALL_FP)
1753 {
1754 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1755 if (TARGET_FPU_SINGLE)
1756 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1757 else
1758 last = gen_udivsi3_i4 (operands[0], operands[3]);
1759 }
1760 else if (TARGET_SHMEDIA_FPU)
1761 {
1762 operands[1] = force_reg (SImode, operands[1]);
1763 operands[2] = force_reg (SImode, operands[2]);
1764 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1765 DONE;
1766 }
1767 else if (TARGET_SH2A)
1768 {
1769 operands[1] = force_reg (SImode, operands[1]);
1770 operands[2] = force_reg (SImode, operands[2]);
1771 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1772 DONE;
1773 }
1774 else if (TARGET_SH5)
1775 {
1776 function_symbol (operands[3],
1777 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1778 SFUNC_STATIC);
1779
1780 if (TARGET_SHMEDIA)
1781 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1782 else if (TARGET_FPU_ANY)
1783 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1784 else
1785 last = gen_udivsi3_i1 (operands[0], operands[3]);
1786 }
1787 else
1788 {
1789 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1790 last = gen_udivsi3_i1 (operands[0], operands[3]);
1791 }
1792 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1793 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1794 emit_insn (last);
1795 DONE;
1796 }")
1797
1798 (define_insn "divsi3_sh2a"
1799 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1800 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1801 (match_operand:SI 2 "arith_reg_operand" "z")))]
1802 "TARGET_SH2A"
1803 "divs %2,%1"
1804 [(set_attr "type" "arith")
1805 (set_attr "in_delay_slot" "no")])
1806
1807 (define_insn "divsi3_i1"
1808 [(set (match_operand:SI 0 "register_operand" "=z")
1809 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1810 (clobber (reg:SI T_REG))
1811 (clobber (reg:SI PR_REG))
1812 (clobber (reg:SI R1_REG))
1813 (clobber (reg:SI R2_REG))
1814 (clobber (reg:SI R3_REG))
1815 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1816 "TARGET_SH1 && ! TARGET_SH4"
1817 "jsr @%1%#"
1818 [(set_attr "type" "sfunc")
1819 (set_attr "needs_delay_slot" "yes")])
1820
1821 (define_insn "divsi3_i1_media"
1822 [(set (match_operand:SI 0 "register_operand" "=z")
1823 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1824 (clobber (reg:SI T_MEDIA_REG))
1825 (clobber (reg:SI PR_MEDIA_REG))
1826 (clobber (reg:SI R1_REG))
1827 (clobber (reg:SI R20_REG))
1828 (clobber (reg:SI R21_REG))
1829 (clobber (reg:SI TR0_REG))
1830 (use (match_operand 1 "target_reg_operand" "b"))]
1831 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1832 "blink %1, r18"
1833 [(set_attr "type" "sfunc")])
1834
1835 (define_insn "divsi3_media_2"
1836 [(set (match_operand:SI 0 "register_operand" "=z")
1837 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1838 (clobber (reg:SI T_MEDIA_REG))
1839 (clobber (reg:SI PR_MEDIA_REG))
1840 (clobber (reg:SI R1_REG))
1841 (clobber (reg:SI R21_REG))
1842 (clobber (reg:SI TR0_REG))
1843 (use (reg:SI R20_REG))
1844 (use (match_operand 1 "target_reg_operand" "b"))]
1845 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1846 "blink %1, r18"
1847 [(set_attr "type" "sfunc")])
1848
1849 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1850 ;; hard reg clobbers and data dependencies that we need when we want
1851 ;; to rematerialize the division into a call.
1852 (define_insn_and_split "divsi_inv_call"
1853 [(set (match_operand:SI 0 "register_operand" "=r")
1854 (div:SI (match_operand:SI 1 "register_operand" "r")
1855 (match_operand:SI 2 "register_operand" "r")))
1856 (clobber (reg:SI R4_REG))
1857 (clobber (reg:SI R5_REG))
1858 (clobber (reg:SI T_MEDIA_REG))
1859 (clobber (reg:SI PR_MEDIA_REG))
1860 (clobber (reg:SI R1_REG))
1861 (clobber (reg:SI R21_REG))
1862 (clobber (reg:SI TR0_REG))
1863 (clobber (reg:SI R20_REG))
1864 (use (match_operand:SI 3 "register_operand" "r"))]
1865 "TARGET_SHMEDIA"
1866 "#"
1867 "&& (high_life_started || reload_completed)"
1868 [(set (match_dup 0) (match_dup 3))]
1869 ""
1870 [(set_attr "highpart" "must_split")])
1871
1872 ;; This is the combiner pattern for -mdiv=inv:call .
1873 (define_insn_and_split "*divsi_inv_call_combine"
1874 [(set (match_operand:SI 0 "register_operand" "=z")
1875 (div:SI (match_operand:SI 1 "register_operand" "r")
1876 (match_operand:SI 2 "register_operand" "r")))
1877 (clobber (reg:SI R4_REG))
1878 (clobber (reg:SI R5_REG))
1879 (clobber (reg:SI T_MEDIA_REG))
1880 (clobber (reg:SI PR_MEDIA_REG))
1881 (clobber (reg:SI R1_REG))
1882 (clobber (reg:SI R21_REG))
1883 (clobber (reg:SI TR0_REG))
1884 (clobber (reg:SI R20_REG))
1885 (use (unspec:SI [(match_dup 1)
1886 (match_operand:SI 3 "" "")
1887 (unspec:SI [(match_operand:SI 4 "" "")
1888 (match_dup 3)
1889 (match_operand:DI 5 "" "")]
1890 UNSPEC_DIV_INV_M2)
1891 (match_operand:DI 6 "" "")
1892 (const_int 0)
1893 (const_int 0)]
1894 UNSPEC_DIV_INV_M3))]
1895 "TARGET_SHMEDIA"
1896 "#"
1897 "&& (high_life_started || reload_completed)"
1898 [(pc)]
1899 "
1900 {
1901 const char *name = sh_divsi3_libfunc;
1902 enum sh_function_kind kind = SFUNC_GOT;
1903 rtx sym;
1904
1905 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1906 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1907 while (TARGET_DIVIDE_INV_CALL2)
1908 {
1909 rtx x = operands[3];
1910
1911 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1912 break;
1913 x = XVECEXP (x, 0, 0);
1914 name = \"__sdivsi3_2\";
1915 kind = SFUNC_STATIC;
1916 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1917 break;
1918 }
1919 sym = function_symbol (NULL, name, kind);
1920 emit_insn (gen_divsi3_media_2 (operands[0], sym));
1921 DONE;
1922 }"
1923 [(set_attr "highpart" "must_split")])
1924
1925 (define_expand "divsi3_i4_media"
1926 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1927 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1928 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1929 (set (match_operand:SI 0 "register_operand" "=r")
1930 (fix:SI (match_dup 5)))]
1931 "TARGET_SHMEDIA_FPU"
1932 "
1933 {
1934 operands[3] = gen_reg_rtx (DFmode);
1935 operands[4] = gen_reg_rtx (DFmode);
1936 operands[5] = gen_reg_rtx (DFmode);
1937 }")
1938
1939 (define_insn "divsi3_i4"
1940 [(set (match_operand:SI 0 "register_operand" "=y")
1941 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1942 (clobber (reg:SI PR_REG))
1943 (clobber (reg:DF DR0_REG))
1944 (clobber (reg:DF DR2_REG))
1945 (use (reg:PSI FPSCR_REG))
1946 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1947 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1948 "jsr @%1%#"
1949 [(set_attr "type" "sfunc")
1950 (set_attr "fp_mode" "double")
1951 (set_attr "needs_delay_slot" "yes")])
1952
1953 (define_insn "divsi3_i4_single"
1954 [(set (match_operand:SI 0 "register_operand" "=y")
1955 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956 (clobber (reg:SI PR_REG))
1957 (clobber (reg:DF DR0_REG))
1958 (clobber (reg:DF DR2_REG))
1959 (clobber (reg:SI R2_REG))
1960 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1961 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1962 "jsr @%1%#"
1963 [(set_attr "type" "sfunc")
1964 (set_attr "needs_delay_slot" "yes")])
1965
1966 (define_insn "divsi3_i4_int"
1967 [(set (match_operand:SI 0 "register_operand" "=z")
1968 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1969 (clobber (reg:SI T_REG))
1970 (clobber (reg:SI PR_REG))
1971 (clobber (reg:SI R1_REG))
1972 (clobber (reg:SI MACH_REG))
1973 (clobber (reg:SI MACL_REG))
1974 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1975 "TARGET_SH1"
1976 "jsr @%1%#"
1977 [(set_attr "type" "sfunc")
1978 (set_attr "needs_delay_slot" "yes")])
1979
1980 (define_expand "divsi3"
1981 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1982 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1983 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1984 (parallel [(set (match_operand:SI 0 "register_operand" "")
1985 (div:SI (reg:SI R4_REG)
1986 (reg:SI R5_REG)))
1987 (clobber (reg:SI T_REG))
1988 (clobber (reg:SI PR_REG))
1989 (clobber (reg:SI R1_REG))
1990 (clobber (reg:SI R2_REG))
1991 (clobber (reg:SI R3_REG))
1992 (use (match_dup 3))])]
1993 ""
1994 "
1995 {
1996 rtx last;
1997
1998 operands[3] = gen_reg_rtx (Pmode);
1999 /* Emit the move of the address to a pseudo outside of the libcall. */
2000 if (TARGET_DIVIDE_CALL_TABLE)
2001 {
2002 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2003 last = gen_divsi3_i4_int (operands[0], operands[3]);
2004 }
2005 else if (TARGET_DIVIDE_CALL_FP)
2006 {
2007 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2008 if (TARGET_FPU_SINGLE)
2009 last = gen_divsi3_i4_single (operands[0], operands[3]);
2010 else
2011 last = gen_divsi3_i4 (operands[0], operands[3]);
2012 }
2013 else if (TARGET_SH2A)
2014 {
2015 operands[1] = force_reg (SImode, operands[1]);
2016 operands[2] = force_reg (SImode, operands[2]);
2017 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2018 DONE;
2019 }
2020 else if (TARGET_DIVIDE_INV)
2021 {
2022 rtx dividend = operands[1];
2023 rtx divisor = operands[2];
2024 rtx tab_base;
2025 rtx nsb_res = gen_reg_rtx (DImode);
2026 rtx norm64 = gen_reg_rtx (DImode);
2027 rtx tab_ix = gen_reg_rtx (DImode);
2028 rtx norm32 = gen_reg_rtx (SImode);
2029 rtx i92 = force_reg (DImode, GEN_INT (92));
2030 rtx scratch0a = gen_reg_rtx (DImode);
2031 rtx scratch0b = gen_reg_rtx (DImode);
2032 rtx inv0 = gen_reg_rtx (SImode);
2033 rtx scratch1a = gen_reg_rtx (DImode);
2034 rtx scratch1b = gen_reg_rtx (DImode);
2035 rtx shift = gen_reg_rtx (DImode);
2036 rtx i2p27, i43;
2037 rtx inv1 = gen_reg_rtx (SImode);
2038 rtx scratch2a = gen_reg_rtx (DImode);
2039 rtx scratch2b = gen_reg_rtx (SImode);
2040 rtx inv2 = gen_reg_rtx (SImode);
2041 rtx scratch3a = gen_reg_rtx (DImode);
2042 rtx scratch3b = gen_reg_rtx (DImode);
2043 rtx scratch3c = gen_reg_rtx (DImode);
2044 rtx scratch3d = gen_reg_rtx (SImode);
2045 rtx scratch3e = gen_reg_rtx (DImode);
2046 rtx result = gen_reg_rtx (SImode);
2047
2048 if (! arith_reg_or_0_operand (dividend, SImode))
2049 dividend = force_reg (SImode, dividend);
2050 if (! arith_reg_operand (divisor, SImode))
2051 divisor = force_reg (SImode, divisor);
2052 if (flag_pic && Pmode != DImode)
2053 {
2054 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2055 tab_base = gen_datalabel_ref (tab_base);
2056 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2057 }
2058 else
2059 {
2060 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2061 tab_base = gen_datalabel_ref (tab_base);
2062 tab_base = force_reg (DImode, tab_base);
2063 }
2064 if (TARGET_DIVIDE_INV20U)
2065 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2066 else
2067 i2p27 = GEN_INT (0);
2068 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2069 i43 = force_reg (DImode, GEN_INT (43));
2070 else
2071 i43 = GEN_INT (0);
2072 emit_insn (gen_nsbdi (nsb_res,
2073 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2074 emit_insn (gen_ashldi3_media (norm64,
2075 gen_rtx_SUBREG (DImode, divisor, 0),
2076 nsb_res));
2077 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2078 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2079 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2080 inv0, scratch0a, scratch0b,
2081 scratch1a, scratch1b));
2082 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2083 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2084 scratch2a));
2085 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2086 i2p27, i43,
2087 scratch3a, scratch3b, scratch3c,
2088 scratch2a, scratch2b, scratch3d, scratch3e));
2089 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2090 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2091 else if (TARGET_DIVIDE_INV_FP)
2092 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2093 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2094 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2095 gen_reg_rtx (DFmode)));
2096 else
2097 emit_move_insn (operands[0], result);
2098 DONE;
2099 }
2100 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2101 {
2102 operands[1] = force_reg (SImode, operands[1]);
2103 operands[2] = force_reg (SImode, operands[2]);
2104 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2105 DONE;
2106 }
2107 else if (TARGET_SH5)
2108 {
2109 if (TARGET_DIVIDE_CALL2)
2110 {
2111 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2112 tab_base = gen_datalabel_ref (tab_base);
2113 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2114 }
2115 if (TARGET_FPU_ANY && TARGET_SH1)
2116 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2117 else if (TARGET_DIVIDE_CALL2)
2118 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2119 else
2120 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2121
2122 if (TARGET_SHMEDIA)
2123 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2124 (operands[0], operands[3]));
2125 else if (TARGET_FPU_ANY)
2126 last = gen_divsi3_i4_single (operands[0], operands[3]);
2127 else
2128 last = gen_divsi3_i1 (operands[0], operands[3]);
2129 }
2130 else
2131 {
2132 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2133 last = gen_divsi3_i1 (operands[0], operands[3]);
2134 }
2135 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2136 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2137 emit_insn (last);
2138 DONE;
2139 }")
2140
2141 ;; operands: scratch, tab_base, tab_ix
2142 ;; These are unspecs because we could generate an indexed addressing mode
2143 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2144 ;; confuse reload. See PR27117.
2145
2146 (define_insn "divsi_inv_qitable"
2147 [(set (match_operand:DI 0 "register_operand" "=r")
2148 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2149 (match_operand:DI 2 "register_operand" "r")]
2150 UNSPEC_DIV_INV_TABLE)))]
2151 "TARGET_SHMEDIA"
2152 "@
2153 ldx.ub %1, %2, %0"
2154 [(set_attr "type" "load_media")
2155 (set_attr "highpart" "user")])
2156
2157 ;; operands: scratch, tab_base, tab_ix
2158 (define_insn "divsi_inv_hitable"
2159 [(set (match_operand:DI 0 "register_operand" "=r")
2160 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2161 (match_operand:DI 2 "register_operand" "r")]
2162 UNSPEC_DIV_INV_TABLE)))]
2163 "TARGET_SHMEDIA"
2164 "@
2165 ldx.w %1, %2, %0"
2166 [(set_attr "type" "load_media")
2167 (set_attr "highpart" "user")])
2168
2169 ;; operands: inv0, tab_base, tab_ix, norm32
2170 ;; scratch equiv in sdivsi3_2: r19, r21
2171 (define_expand "divsi_inv_m0"
2172 [(set (match_operand:SI 0 "register_operand" "=r")
2173 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2174 (match_operand:DI 2 "register_operand" "r")
2175 (match_operand:SI 3 "register_operand" "r")]
2176 UNSPEC_DIV_INV_M0))
2177 (clobber (match_operand:DI 4 "register_operand" "=r"))
2178 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2179 "TARGET_SHMEDIA"
2180 "
2181 {
2182 /*
2183 tab_base: r20
2184 tab_ix: r21
2185 norm32: r25
2186 ldx.ub r20, r21, r19 // u0.8
2187 shlli r21, 1, r21
2188 muls.l r25, r19, r19 // s2.38
2189 ldx.w r20, r21, r21 // s2.14
2190 shari r19, 24, r19 // truncate to s2.14
2191 sub r21, r19, r19 // some 11 bit inverse in s1.14
2192 */
2193
2194 rtx inv0 = operands[0];
2195 rtx tab_base = operands[1];
2196 rtx tab_ix = operands[2];
2197 rtx norm32 = operands[3];
2198 rtx scratch0 = operands[4];
2199 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2200 rtx scratch1 = operands[5];
2201
2202 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2203 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2204 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2205 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2206 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2207 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2208 DONE;
2209 }")
2210
2211 ;; operands: inv1, tab_base, tab_ix, norm32
2212 (define_insn_and_split "divsi_inv_m1"
2213 [(set (match_operand:SI 0 "register_operand" "=r")
2214 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2215 (match_operand:DI 2 "register_operand" "r")
2216 (match_operand:SI 3 "register_operand" "r")]
2217 UNSPEC_DIV_INV_M1))
2218 (clobber (match_operand:SI 4 "register_operand" "=r"))
2219 (clobber (match_operand:DI 5 "register_operand" "=r"))
2220 (clobber (match_operand:DI 6 "register_operand" "=r"))
2221 (clobber (match_operand:DI 7 "register_operand" "=r"))
2222 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2223 "TARGET_SHMEDIA"
2224 "#"
2225 "&& !can_create_pseudo_p ()"
2226 [(pc)]
2227 "
2228 {
2229 /* inv0: r19
2230 muls.l r19, r19, r18 // u0.28
2231 muls.l r25, r18, r18 // s2.58
2232 shlli r19, 45, r0 // multiply by two and convert to s2.58
2233 sub r0, r18, r18
2234 shari r18, 28, r18 // some 18 bit inverse in s1.30
2235 */
2236
2237 rtx inv1 = operands[0];
2238 rtx tab_base = operands[1];
2239 rtx tab_ix = operands[2];
2240 rtx norm32 = operands[3];
2241 rtx inv0 = operands[4];
2242 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2243 rtx scratch0a = operands[5];
2244 rtx scratch0b = operands[6];
2245 rtx scratch0 = operands[7];
2246 rtx scratch1 = operands[8];
2247 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2248
2249 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2250 scratch0a, scratch0b));
2251 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2252 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2253 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2254 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2255 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2256 DONE;
2257 }")
2258
2259 ;; operands: inv2, norm32, inv1, i92
2260 (define_insn_and_split "divsi_inv_m2"
2261 [(set (match_operand:SI 0 "register_operand" "=r")
2262 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2263 (match_operand:SI 2 "register_operand" "r")
2264 (match_operand:DI 3 "register_operand" "r")]
2265 UNSPEC_DIV_INV_M2))
2266 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2267 "TARGET_SHMEDIA"
2268 "#"
2269 "&& !can_create_pseudo_p ()"
2270 [(pc)]
2271 "
2272 {
2273 /*
2274 muls.l r18, r25, r0 // s2.60
2275 shari r0, 16, r0 // s-16.44
2276 sub
2277 muls.l r0, r18, r19 // s-16.74
2278 shari r19, 30, r19 // s-16.44
2279 */
2280 rtx inv2 = operands[0];
2281 rtx norm32 = operands[1];
2282 rtx inv1 = operands[2];
2283 rtx i92 = operands[3];
2284 rtx scratch0 = operands[4];
2285 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2286
2287 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2288 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2289 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2290 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2291 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2292 DONE;
2293 }")
2294
2295 (define_insn_and_split "divsi_inv_m3"
2296 [(set (match_operand:SI 0 "register_operand" "=r")
2297 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2298 (match_operand:SI 2 "register_operand" "r")
2299 (match_operand:SI 3 "register_operand" "r")
2300 (match_operand:DI 4 "register_operand" "r")
2301 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2302 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2303 UNSPEC_DIV_INV_M3))
2304 (clobber (match_operand:DI 7 "register_operand" "=r"))
2305 (clobber (match_operand:DI 8 "register_operand" "=r"))
2306 (clobber (match_operand:DI 9 "register_operand" "=r"))
2307 (clobber (match_operand:DI 10 "register_operand" "=r"))
2308 (clobber (match_operand:SI 11 "register_operand" "=r"))
2309 (clobber (match_operand:SI 12 "register_operand" "=r"))
2310 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2311 "TARGET_SHMEDIA"
2312 "#"
2313 "&& !can_create_pseudo_p ()"
2314 [(pc)]
2315 "
2316 {
2317 /*
2318 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2319 r0: scratch0 r19: scratch1 r21: scratch2
2320
2321 muls.l r18, r4, r25 // s32.30
2322 muls.l r19, r4, r19 // s15.30
2323 shari r25, 63, r21
2324 shari r19, 14, r19 // s18.-14
2325 sub r25, r19, r0
2326 shard r0, r1, r0
2327 sub r0, r21, r0
2328 */
2329
2330 rtx result = operands[0];
2331 rtx dividend = operands[1];
2332 rtx inv1 = operands[2];
2333 rtx inv2 = operands[3];
2334 rtx shift = operands[4];
2335 rtx scratch0 = operands[7];
2336 rtx scratch1 = operands[8];
2337 rtx scratch2 = operands[9];
2338
2339 if (satisfies_constraint_N (dividend))
2340 {
2341 emit_move_insn (result, dividend);
2342 DONE;
2343 }
2344
2345 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2346 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2347 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2348 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2349 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2350 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2351 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2352 DONE;
2353 }")
2354
2355 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2356 ;; inv1: tab_base, tab_ix, norm32
2357 ;; inv2: norm32, inv1, i92
2358 (define_insn_and_split "divsi_inv_m1_3"
2359 [(set (match_operand:SI 0 "register_operand" "=r")
2360 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2361 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2362 (match_operand:DI 3 "register_operand" "r")
2363 (match_operand:SI 4 "register_operand" "r")]
2364 UNSPEC_DIV_INV_M1)
2365 (unspec:SI [(match_dup 4)
2366 (unspec:SI [(match_dup 2)
2367 (match_dup 3)
2368 (match_dup 4)] UNSPEC_DIV_INV_M1)
2369 (match_operand:SI 5 "" "")]
2370 UNSPEC_DIV_INV_M2)
2371 (match_operand:DI 6 "register_operand" "r")
2372 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2373 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2374 UNSPEC_DIV_INV_M3))
2375 (clobber (match_operand:DI 9 "register_operand" "=r"))
2376 (clobber (match_operand:DI 10 "register_operand" "=r"))
2377 (clobber (match_operand:DI 11 "register_operand" "=r"))
2378 (clobber (match_operand:DI 12 "register_operand" "=r"))
2379 (clobber (match_operand:SI 13 "register_operand" "=r"))
2380 (clobber (match_operand:SI 14 "register_operand" "=r"))
2381 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2382 "TARGET_SHMEDIA
2383 && (TARGET_DIVIDE_INV_MINLAT
2384 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2385 "#"
2386 "&& !can_create_pseudo_p ()"
2387 [(pc)]
2388 "
2389 {
2390 rtx result = operands[0];
2391 rtx dividend = operands[1];
2392 rtx tab_base = operands[2];
2393 rtx tab_ix = operands[3];
2394 rtx norm32 = operands[4];
2395 /* rtx i92 = operands[5]; */
2396 rtx shift = operands[6];
2397 rtx i2p27 = operands[7];
2398 rtx i43 = operands[8];
2399 rtx scratch0 = operands[9];
2400 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2401 rtx scratch1 = operands[10];
2402 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2403 rtx scratch2 = operands[11];
2404 rtx scratch3 = operands[12];
2405 rtx scratch4 = operands[13];
2406 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2407 rtx scratch5 = operands[14];
2408 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2409 rtx scratch6 = operands[15];
2410
2411 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2412 scratch0, scratch1));
2413 /* inv0 == scratch4 */
2414 if (! TARGET_DIVIDE_INV20U)
2415 {
2416 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2417 i2p27 = scratch0;
2418 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2419 }
2420 else
2421 {
2422 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2423 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2424 }
2425 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2426 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2427 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2428 /* inv1 == scratch4 */
2429
2430 if (TARGET_DIVIDE_INV_MINLAT)
2431 {
2432 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2433 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2434 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2435 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2436 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2437 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2438 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2439 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2440 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2441 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2442 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2443 }
2444 else
2445 {
2446 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2447 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2448 emit_insn (gen_nsbdi (scratch6,
2449 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2450 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2451 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2452 emit_insn (gen_divsi_inv20 (scratch2,
2453 norm32, scratch4, dividend,
2454 scratch6, scratch3, i43,
2455 /* scratch0 may be shared with i2p27. */
2456 scratch0, scratch1, scratch5,
2457 label, label, i2p27));
2458 }
2459 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2460 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2461 DONE;
2462 }")
2463
2464 (define_insn "divsi_inv20"
2465 [(set (match_operand:DI 0 "register_operand" "=&r")
2466 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2467 (match_operand:SI 2 "register_operand" "r")
2468 (match_operand:SI 3 "register_operand" "r")
2469 (match_operand:DI 4 "register_operand" "r")
2470 (match_operand:DI 5 "register_operand" "r")
2471 (match_operand:DI 6 "register_operand" "r")
2472 (match_operand:DI 12 "register_operand" "r")
2473 (match_operand 10 "target_operand" "b")
2474 (match_operand 11 "immediate_operand" "i")]
2475 UNSPEC_DIV_INV20))
2476 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2477 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2478 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2479 "TARGET_SHMEDIA
2480 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2481 "*
2482 {
2483 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2484 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2485 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2486 %10 label (tr), %11 label (imm)
2487
2488 muls.l inv1, norm32, scratch0 // s2.60
2489 muls.l inv1, dividend, result // s32.30
2490 xor i2p27, result_sign, round_scratch
2491 bge/u dividend_nsb, i43, tr.. (label)
2492 shari scratch0, 16, scratch0 // s-16.44
2493 muls.l sratch0_si, inv1, scratch0 // s-16.74
2494 sub result, round_scratch, result
2495 shari dividend, 14, scratch1 // s19.-14
2496 shari scratch0, 30, scratch0 // s-16.44
2497 muls.l scratch0, scratch1, round_scratch // s15.30
2498 label:
2499 sub result, round_scratch, result */
2500
2501 int likely = TARGET_DIVIDE_INV20L;
2502
2503 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2504 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2505 output_asm_insn (likely
2506 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2507 : \"bge/u\t%4, %6, %10\", operands);
2508 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2509 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2510 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2511 return (likely
2512 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2513 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2514 }")
2515
2516 (define_insn_and_split "divsi_inv_fp"
2517 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2518 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2519 (match_operand:SI 2 "register_operand" "rf")))
2520 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2521 (clobber (match_operand:SI 4 "register_operand" "=r"))
2522 (clobber (match_operand:SI 5 "register_operand" "=r"))
2523 (clobber (match_operand:DF 6 "register_operand" "=r"))
2524 (clobber (match_operand:DF 7 "register_operand" "=r"))
2525 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2526 "TARGET_SHMEDIA_FPU"
2527 "#"
2528 "&& (high_life_started || reload_completed)"
2529 [(set (match_dup 0) (match_dup 3))]
2530 ""
2531 [(set_attr "highpart" "must_split")])
2532
2533 ;; If a matching group of divide-by-inverse instructions is in the same
2534 ;; basic block after gcse & loop optimizations, we want to transform them
2535 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2536 (define_insn_and_split "*divsi_inv_fp_combine"
2537 [(set (match_operand:SI 0 "register_operand" "=f")
2538 (div:SI (match_operand:SI 1 "register_operand" "f")
2539 (match_operand:SI 2 "register_operand" "f")))
2540 (use (unspec:SI [(match_dup 1)
2541 (match_operand:SI 3 "" "")
2542 (unspec:SI [(match_operand:SI 4 "" "")
2543 (match_dup 3)
2544 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2545 (match_operand:DI 6 "" "")
2546 (const_int 0)
2547 (const_int 0)] UNSPEC_DIV_INV_M3))
2548 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2549 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2550 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2551 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2552 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2553 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2554 "#"
2555 "&& 1"
2556 [(set (match_dup 9) (float:DF (match_dup 1)))
2557 (set (match_dup 10) (float:DF (match_dup 2)))
2558 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2559 (set (match_dup 8)
2560 (fix:SI (match_dup 11)))
2561 (set (match_dup 0) (match_dup 8))]
2562 "
2563 {
2564 if (! fp_arith_reg_operand (operands[1], SImode))
2565 {
2566 emit_move_insn (operands[7], operands[1]);
2567 operands[1] = operands[7];
2568 }
2569 if (! fp_arith_reg_operand (operands[2], SImode))
2570 {
2571 emit_move_insn (operands[8], operands[2]);
2572 operands[2] = operands[8];
2573 }
2574 }"
2575 [(set_attr "highpart" "must_split")])
2576 \f
2577 ;; -------------------------------------------------------------------------
2578 ;; Multiplication instructions
2579 ;; -------------------------------------------------------------------------
2580
2581 (define_insn "umulhisi3_i"
2582 [(set (reg:SI MACL_REG)
2583 (mult:SI (zero_extend:SI
2584 (match_operand:HI 0 "arith_reg_operand" "r"))
2585 (zero_extend:SI
2586 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2587 "TARGET_SH1"
2588 "mulu.w %1,%0"
2589 [(set_attr "type" "smpy")])
2590
2591 (define_insn "mulhisi3_i"
2592 [(set (reg:SI MACL_REG)
2593 (mult:SI (sign_extend:SI
2594 (match_operand:HI 0 "arith_reg_operand" "r"))
2595 (sign_extend:SI
2596 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2597 "TARGET_SH1"
2598 "muls.w %1,%0"
2599 [(set_attr "type" "smpy")])
2600
2601 (define_expand "mulhisi3"
2602 [(set (reg:SI MACL_REG)
2603 (mult:SI (sign_extend:SI
2604 (match_operand:HI 1 "arith_reg_operand" ""))
2605 (sign_extend:SI
2606 (match_operand:HI 2 "arith_reg_operand" ""))))
2607 (set (match_operand:SI 0 "arith_reg_operand" "")
2608 (reg:SI MACL_REG))]
2609 "TARGET_SH1"
2610 "
2611 {
2612 rtx insn, macl;
2613
2614 macl = gen_rtx_REG (SImode, MACL_REG);
2615 start_sequence ();
2616 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2617 insn = get_insns ();
2618 end_sequence ();
2619 /* expand_binop can't find a suitable code in umul_widen_optab to
2620 make a REG_EQUAL note from, so make one here.
2621 See also smulsi3_highpart.
2622 ??? Alternatively, we could put this at the calling site of expand_binop,
2623 i.e. expand_expr. */
2624 /* Use emit_libcall_block for loop invariant code motion and to make
2625 a REG_EQUAL note. */
2626 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2627
2628 DONE;
2629 }")
2630
2631 (define_expand "umulhisi3"
2632 [(set (reg:SI MACL_REG)
2633 (mult:SI (zero_extend:SI
2634 (match_operand:HI 1 "arith_reg_operand" ""))
2635 (zero_extend:SI
2636 (match_operand:HI 2 "arith_reg_operand" ""))))
2637 (set (match_operand:SI 0 "arith_reg_operand" "")
2638 (reg:SI MACL_REG))]
2639 "TARGET_SH1"
2640 "
2641 {
2642 rtx insn, macl;
2643
2644 macl = gen_rtx_REG (SImode, MACL_REG);
2645 start_sequence ();
2646 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2647 insn = get_insns ();
2648 end_sequence ();
2649 /* expand_binop can't find a suitable code in umul_widen_optab to
2650 make a REG_EQUAL note from, so make one here.
2651 See also smulsi3_highpart.
2652 ??? Alternatively, we could put this at the calling site of expand_binop,
2653 i.e. expand_expr. */
2654 /* Use emit_libcall_block for loop invariant code motion and to make
2655 a REG_EQUAL note. */
2656 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2657
2658 DONE;
2659 }")
2660
2661 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2662 ;; a call to a routine which clobbers known registers.
2663
2664 (define_insn ""
2665 [(set (match_operand:SI 1 "register_operand" "=z")
2666 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2667 (clobber (reg:SI MACL_REG))
2668 (clobber (reg:SI T_REG))
2669 (clobber (reg:SI PR_REG))
2670 (clobber (reg:SI R3_REG))
2671 (clobber (reg:SI R2_REG))
2672 (clobber (reg:SI R1_REG))
2673 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2674 "TARGET_SH1"
2675 "jsr @%0%#"
2676 [(set_attr "type" "sfunc")
2677 (set_attr "needs_delay_slot" "yes")])
2678
2679 (define_expand "mulsi3_call"
2680 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2681 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2682 (parallel[(set (match_operand:SI 0 "register_operand" "")
2683 (mult:SI (reg:SI R4_REG)
2684 (reg:SI R5_REG)))
2685 (clobber (reg:SI MACL_REG))
2686 (clobber (reg:SI T_REG))
2687 (clobber (reg:SI PR_REG))
2688 (clobber (reg:SI R3_REG))
2689 (clobber (reg:SI R2_REG))
2690 (clobber (reg:SI R1_REG))
2691 (use (match_operand:SI 3 "register_operand" ""))])]
2692 "TARGET_SH1"
2693 "")
2694
2695 (define_insn "mul_r"
2696 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2697 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2698 (match_operand:SI 2 "arith_reg_operand" "z")))]
2699 "TARGET_SH2A"
2700 "mulr %2,%0"
2701 [(set_attr "type" "dmpy")])
2702
2703 (define_insn "mul_l"
2704 [(set (reg:SI MACL_REG)
2705 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2706 (match_operand:SI 1 "arith_reg_operand" "r")))]
2707 "TARGET_SH2"
2708 "mul.l %1,%0"
2709 [(set_attr "type" "dmpy")])
2710
2711 (define_expand "mulsi3"
2712 [(set (reg:SI MACL_REG)
2713 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2714 (match_operand:SI 2 "arith_reg_operand" "")))
2715 (set (match_operand:SI 0 "arith_reg_operand" "")
2716 (reg:SI MACL_REG))]
2717 "TARGET_SH1"
2718 "
2719 {
2720 if (!TARGET_SH2)
2721 {
2722 /* The address must be set outside the libcall,
2723 since it goes into a pseudo. */
2724 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2725 rtx addr = force_reg (SImode, sym);
2726 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2727 operands[2], addr);
2728 emit_insn (insns);
2729 }
2730 else
2731 {
2732 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2733
2734 emit_insn (gen_mul_l (operands[1], operands[2]));
2735 /* consec_sets_giv can only recognize the first insn that sets a
2736 giv as the giv insn. So we must tag this also with a REG_EQUAL
2737 note. */
2738 emit_insn (gen_movsi_i ((operands[0]), macl));
2739 }
2740 DONE;
2741 }")
2742
2743 (define_insn "mulsidi3_i"
2744 [(set (reg:SI MACH_REG)
2745 (truncate:SI
2746 (lshiftrt:DI
2747 (mult:DI
2748 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2749 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2750 (const_int 32))))
2751 (set (reg:SI MACL_REG)
2752 (mult:SI (match_dup 0)
2753 (match_dup 1)))]
2754 "TARGET_SH2"
2755 "dmuls.l %1,%0"
2756 [(set_attr "type" "dmpy")])
2757
2758 (define_expand "mulsidi3"
2759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2760 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2761 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2762 "TARGET_SH2 || TARGET_SHMEDIA"
2763 "
2764 {
2765 if (TARGET_SH2)
2766 {
2767 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2768 operands[2]));
2769 DONE;
2770 }
2771 }")
2772
2773 (define_insn "mulsidi3_media"
2774 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2775 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2776 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2777 "TARGET_SHMEDIA"
2778 "muls.l %1, %2, %0"
2779 [(set_attr "type" "dmpy_media")
2780 (set_attr "highpart" "ignore")])
2781
2782 (define_insn "mulsidi3_compact"
2783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2784 (mult:DI
2785 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2786 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2787 (clobber (reg:SI MACH_REG))
2788 (clobber (reg:SI MACL_REG))]
2789 "TARGET_SH2"
2790 "#")
2791
2792 (define_split
2793 [(set (match_operand:DI 0 "arith_reg_dest" "")
2794 (mult:DI
2795 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2796 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2797 (clobber (reg:SI MACH_REG))
2798 (clobber (reg:SI MACL_REG))]
2799 "TARGET_SH2"
2800 [(const_int 0)]
2801 "
2802 {
2803 rtx low_dst = gen_lowpart (SImode, operands[0]);
2804 rtx high_dst = gen_highpart (SImode, operands[0]);
2805
2806 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2807
2808 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2809 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2810 /* We need something to tag the possible REG_EQUAL notes on to. */
2811 emit_move_insn (operands[0], operands[0]);
2812 DONE;
2813 }")
2814
2815 (define_insn "umulsidi3_i"
2816 [(set (reg:SI MACH_REG)
2817 (truncate:SI
2818 (lshiftrt:DI
2819 (mult:DI
2820 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2821 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2822 (const_int 32))))
2823 (set (reg:SI MACL_REG)
2824 (mult:SI (match_dup 0)
2825 (match_dup 1)))]
2826 "TARGET_SH2"
2827 "dmulu.l %1,%0"
2828 [(set_attr "type" "dmpy")])
2829
2830 (define_expand "umulsidi3"
2831 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2832 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2833 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2834 "TARGET_SH2 || TARGET_SHMEDIA"
2835 "
2836 {
2837 if (TARGET_SH2)
2838 {
2839 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2840 operands[2]));
2841 DONE;
2842 }
2843 }")
2844
2845 (define_insn "umulsidi3_media"
2846 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2847 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2848 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2849 "TARGET_SHMEDIA"
2850 "mulu.l %1, %2, %0"
2851 [(set_attr "type" "dmpy_media")
2852 (set_attr "highpart" "ignore")])
2853
2854 (define_insn "umulsidi3_compact"
2855 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2856 (mult:DI
2857 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2858 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2859 (clobber (reg:SI MACH_REG))
2860 (clobber (reg:SI MACL_REG))]
2861 "TARGET_SH2"
2862 "#")
2863
2864 (define_split
2865 [(set (match_operand:DI 0 "arith_reg_dest" "")
2866 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2867 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2868 (clobber (reg:SI MACH_REG))
2869 (clobber (reg:SI MACL_REG))]
2870 "TARGET_SH2"
2871 [(const_int 0)]
2872 "
2873 {
2874 rtx low_dst = gen_lowpart (SImode, operands[0]);
2875 rtx high_dst = gen_highpart (SImode, operands[0]);
2876
2877 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2878
2879 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2880 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2881 /* We need something to tag the possible REG_EQUAL notes on to. */
2882 emit_move_insn (operands[0], operands[0]);
2883 DONE;
2884 }")
2885
2886 (define_insn "smulsi3_highpart_i"
2887 [(set (reg:SI MACH_REG)
2888 (truncate:SI
2889 (lshiftrt:DI
2890 (mult:DI
2891 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2892 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2893 (const_int 32))))
2894 (clobber (reg:SI MACL_REG))]
2895 "TARGET_SH2"
2896 "dmuls.l %1,%0"
2897 [(set_attr "type" "dmpy")])
2898
2899 (define_expand "smulsi3_highpart"
2900 [(parallel
2901 [(set (reg:SI MACH_REG)
2902 (truncate:SI
2903 (lshiftrt:DI
2904 (mult:DI
2905 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2906 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2907 (const_int 32))))
2908 (clobber (reg:SI MACL_REG))])
2909 (set (match_operand:SI 0 "arith_reg_operand" "")
2910 (reg:SI MACH_REG))]
2911 "TARGET_SH2"
2912 "
2913 {
2914 rtx insn, mach;
2915
2916 mach = gen_rtx_REG (SImode, MACH_REG);
2917 start_sequence ();
2918 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2919 insn = get_insns ();
2920 end_sequence ();
2921 /* expand_binop can't find a suitable code in mul_highpart_optab to
2922 make a REG_EQUAL note from, so make one here.
2923 See also {,u}mulhisi.
2924 ??? Alternatively, we could put this at the calling site of expand_binop,
2925 i.e. expand_mult_highpart. */
2926 /* Use emit_libcall_block for loop invariant code motion and to make
2927 a REG_EQUAL note. */
2928 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2929
2930 DONE;
2931 }")
2932
2933 (define_insn "umulsi3_highpart_i"
2934 [(set (reg:SI MACH_REG)
2935 (truncate:SI
2936 (lshiftrt:DI
2937 (mult:DI
2938 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2939 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2940 (const_int 32))))
2941 (clobber (reg:SI MACL_REG))]
2942 "TARGET_SH2"
2943 "dmulu.l %1,%0"
2944 [(set_attr "type" "dmpy")])
2945
2946 (define_expand "umulsi3_highpart"
2947 [(parallel
2948 [(set (reg:SI MACH_REG)
2949 (truncate:SI
2950 (lshiftrt:DI
2951 (mult:DI
2952 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2953 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2954 (const_int 32))))
2955 (clobber (reg:SI MACL_REG))])
2956 (set (match_operand:SI 0 "arith_reg_operand" "")
2957 (reg:SI MACH_REG))]
2958 "TARGET_SH2"
2959 "
2960 {
2961 rtx insn, mach;
2962
2963 mach = gen_rtx_REG (SImode, MACH_REG);
2964 start_sequence ();
2965 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2966 insn = get_insns ();
2967 end_sequence ();
2968 /* Use emit_libcall_block for loop invariant code motion and to make
2969 a REG_EQUAL note. */
2970 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2971
2972 DONE;
2973 }")
2974
2975 (define_insn_and_split "muldi3"
2976 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2977 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2978 (match_operand:DI 2 "arith_reg_operand" "r")))
2979 (clobber (match_scratch:DI 3 "=&r"))
2980 (clobber (match_scratch:DI 4 "=r"))]
2981 "TARGET_SHMEDIA"
2982 "#"
2983 "reload_completed"
2984 [(const_int 0)]
2985 "
2986 {
2987 rtx op3_v2si, op2_v2si;
2988
2989 op3_v2si = operands[3];
2990 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2991 {
2992 op3_v2si = XEXP (op3_v2si, 0);
2993 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2994 }
2995 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2996 op2_v2si = operands[2];
2997 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2998 {
2999 op2_v2si = XEXP (op2_v2si, 0);
3000 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3001 }
3002 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3003 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3004 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3005 emit_insn (gen_umulsidi3_media (operands[4],
3006 sh_gen_truncate (SImode, operands[1], 0),
3007 sh_gen_truncate (SImode, operands[2], 0)));
3008 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3009 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3010 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3011 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3012 DONE;
3013 }")
3014
3015 \f
3016 ;; -------------------------------------------------------------------------
3017 ;; Logical operations
3018 ;; -------------------------------------------------------------------------
3019
3020 (define_insn "*andsi3_compact"
3021 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3022 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3023 (match_operand:SI 2 "logical_operand" "r,K08")))]
3024 "TARGET_SH1"
3025 "and %2,%0"
3026 [(set_attr "type" "arith")])
3027
3028 (define_insn "*andsi3_media"
3029 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3030 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3031 (match_operand:SI 2 "logical_operand" "r,I10")))]
3032 "TARGET_SHMEDIA"
3033 "@
3034 and %1, %2, %0
3035 andi %1, %2, %0"
3036 [(set_attr "type" "arith_media")])
3037
3038 (define_insn "*andsi3_bclr"
3039 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3040 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3041 (match_operand:SI 2 "const_int_operand" "Psz")))]
3042 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3043 "bclr\\t%W2,%0"
3044 [(set_attr "type" "arith")])
3045
3046 ;; If the constant is 255, then emit an extu.b instruction instead of an
3047 ;; and, since that will give better code.
3048
3049 (define_expand "andsi3"
3050 [(set (match_operand:SI 0 "arith_reg_operand" "")
3051 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3052 (match_operand:SI 2 "logical_operand" "")))]
3053 ""
3054 "
3055 {
3056 if (TARGET_SH1
3057 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3058 {
3059 emit_insn (gen_zero_extendqisi2 (operands[0],
3060 gen_lowpart (QImode, operands[1])));
3061 DONE;
3062 }
3063 }")
3064
3065 (define_insn_and_split "anddi3"
3066 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3067 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3068 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3069 "TARGET_SHMEDIA"
3070 "@
3071 and %1, %2, %0
3072 andi %1, %2, %0
3073 #"
3074 "reload_completed
3075 && ! logical_operand (operands[2], DImode)"
3076 [(const_int 0)]
3077 "
3078 {
3079 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3080 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3081 else
3082 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3083 DONE;
3084 }"
3085 [(set_attr "type" "arith_media")])
3086
3087 (define_insn "andcsi3"
3088 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3089 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3090 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3091 "TARGET_SHMEDIA"
3092 "andc %1,%2,%0"
3093 [(set_attr "type" "arith_media")])
3094
3095 (define_insn "andcdi3"
3096 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3097 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3098 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3099 "TARGET_SHMEDIA"
3100 "andc %1,%2,%0"
3101 [(set_attr "type" "arith_media")])
3102
3103 (define_expand "iorsi3"
3104 [(set (match_operand:SI 0 "arith_reg_operand" "")
3105 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3106 (match_operand:SI 2 "logical_operand" "")))]
3107 ""
3108 "")
3109
3110 (define_insn "*iorsi3_compact"
3111 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3112 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3113 (match_operand:SI 2 "logical_operand" "r,K08")))]
3114 "TARGET_SH1
3115 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3116 "or %2,%0"
3117 [(set_attr "type" "arith")])
3118
3119 (define_insn "*iorsi3_media"
3120 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3121 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3122 (match_operand:SI 2 "logical_operand" "r,I10")))]
3123 "TARGET_SHMEDIA"
3124 "@
3125 or %1, %2, %0
3126 ori %1, %2, %0"
3127 [(set_attr "type" "arith_media")])
3128
3129 (define_insn "*iorsi3_bset"
3130 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3131 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3132 (match_operand:SI 2 "const_int_operand" "Pso")))]
3133 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3134 "bset\\t%V2,%0"
3135 [(set_attr "type" "arith")])
3136
3137 (define_insn "iordi3"
3138 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3139 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3140 (match_operand:DI 2 "logical_operand" "r,I10")))]
3141 "TARGET_SHMEDIA"
3142 "@
3143 or %1, %2, %0
3144 ori %1, %2, %0"
3145 [(set_attr "type" "arith_media")])
3146
3147 (define_insn_and_split "*logical_sidi3"
3148 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3149 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3150 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3151 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3152 "TARGET_SHMEDIA"
3153 "#"
3154 "&& reload_completed"
3155 [(set (match_dup 0) (match_dup 3))]
3156 "
3157 {
3158 operands[3]
3159 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3160 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3161 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3162 }")
3163
3164 (define_insn_and_split "*logical_sidisi3"
3165 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3166 (truncate:SI (sign_extend:DI
3167 (match_operator:SI 3 "logical_operator"
3168 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3169 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3170 "TARGET_SHMEDIA"
3171 "#"
3172 "&& 1"
3173 [(set (match_dup 0) (match_dup 3))])
3174
3175 (define_insn_and_split "*logical_sidi3_2"
3176 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3177 (sign_extend:DI (truncate:SI (sign_extend:DI
3178 (match_operator:SI 3 "logical_operator"
3179 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3180 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3181 "TARGET_SHMEDIA"
3182 "#"
3183 "&& 1"
3184 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3185
3186 (define_expand "xorsi3"
3187 [(set (match_operand:SI 0 "arith_reg_operand" "")
3188 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3189 (match_operand:SI 2 "xor_operand" "")))]
3190 ""
3191 "")
3192
3193 (define_insn "*xorsi3_compact"
3194 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3195 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3196 (match_operand:SI 2 "logical_operand" "K08,r")))]
3197 "TARGET_SH1"
3198 "xor %2,%0"
3199 [(set_attr "type" "arith")])
3200
3201 (define_insn "*xorsi3_media"
3202 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3203 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3204 (match_operand:SI 2 "xor_operand" "r,I06")))]
3205 "TARGET_SHMEDIA"
3206 "@
3207 xor %1, %2, %0
3208 xori %1, %2, %0"
3209 [(set_attr "type" "arith_media")])
3210
3211 ;; Store the complements of the T bit in a register.
3212 (define_insn "xorsi3_movrt"
3213 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3214 (xor:SI (reg:SI T_REG)
3215 (const_int 1)))]
3216 "TARGET_SH2A"
3217 "movrt\\t%0"
3218 [(set_attr "type" "arith")])
3219
3220 (define_insn "xordi3"
3221 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3222 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3223 (match_operand:DI 2 "xor_operand" "r,I06")))]
3224 "TARGET_SHMEDIA"
3225 "@
3226 xor %1, %2, %0
3227 xori %1, %2, %0"
3228 [(set_attr "type" "arith_media")])
3229
3230 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3231 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3232 (define_split
3233 [(set (match_operand:DI 0 "arith_reg_dest" "")
3234 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3235 [(match_operand 1 "any_register_operand" "")
3236 (match_operand 2 "any_register_operand" "")])))]
3237 "TARGET_SHMEDIA"
3238 [(set (match_dup 5) (match_dup 4))
3239 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3240 "
3241 {
3242 enum machine_mode inmode = GET_MODE (operands[1]);
3243 int offset = 0;
3244
3245 if (GET_CODE (operands[0]) == SUBREG)
3246 {
3247 offset = SUBREG_BYTE (operands[0]);
3248 operands[0] = SUBREG_REG (operands[0]);
3249 }
3250 gcc_assert (REG_P (operands[0]));
3251 if (! TARGET_LITTLE_ENDIAN)
3252 offset += 8 - GET_MODE_SIZE (inmode);
3253 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3254 }")
3255 \f
3256 ;; -------------------------------------------------------------------------
3257 ;; Shifts and rotates
3258 ;; -------------------------------------------------------------------------
3259
3260 (define_expand "rotldi3"
3261 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3262 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3263 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3264 "TARGET_SHMEDIA"
3265 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3266
3267 (define_insn "rotldi3_mextr"
3268 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3269 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3270 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3271 "TARGET_SHMEDIA"
3272 "*
3273 {
3274 static char templ[16];
3275
3276 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3277 8 - (int) (INTVAL (operands[2]) >> 3));
3278 return templ;
3279 }"
3280 [(set_attr "type" "arith_media")])
3281
3282 (define_expand "rotrdi3"
3283 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3284 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3285 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3286 "TARGET_SHMEDIA"
3287 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3288
3289 (define_insn "rotrdi3_mextr"
3290 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3291 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3292 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3293 "TARGET_SHMEDIA"
3294 "*
3295 {
3296 static char templ[16];
3297
3298 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3299 return templ;
3300 }"
3301 [(set_attr "type" "arith_media")])
3302
3303 (define_split
3304 [(set (match_operand:DI 0 "arith_reg_dest" "")
3305 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3306 "ua_address_operand" "")))
3307 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3308 (const_int 8))))
3309 (clobber (match_operand:DI 3 "register_operand" ""))]
3310 "TARGET_SHMEDIA"
3311 [(match_dup 4) (match_dup 5)]
3312 "
3313 {
3314 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3315 (operands[3], operands[1]));
3316 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3317 GEN_INT (56), GEN_INT (8));
3318 }")
3319
3320 (define_insn "rotlsi3_1"
3321 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3322 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3323 (const_int 1)))
3324 (set (reg:SI T_REG)
3325 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3326 "TARGET_SH1"
3327 "rotl %0"
3328 [(set_attr "type" "arith")])
3329
3330 (define_insn "rotlsi3_31"
3331 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3332 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3333 (const_int 31)))
3334 (clobber (reg:SI T_REG))]
3335 "TARGET_SH1"
3336 "rotr %0"
3337 [(set_attr "type" "arith")])
3338
3339 (define_insn "rotlsi3_16"
3340 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3341 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3342 (const_int 16)))]
3343 "TARGET_SH1"
3344 "swap.w %1,%0"
3345 [(set_attr "type" "arith")])
3346
3347 (define_expand "rotlsi3"
3348 [(set (match_operand:SI 0 "arith_reg_dest" "")
3349 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3350 (match_operand:SI 2 "immediate_operand" "")))]
3351 "TARGET_SH1"
3352 "
3353 {
3354 static const char rot_tab[] = {
3355 000, 000, 000, 000, 000, 000, 010, 001,
3356 001, 001, 011, 013, 003, 003, 003, 003,
3357 003, 003, 003, 003, 003, 013, 012, 002,
3358 002, 002, 010, 000, 000, 000, 000, 000,
3359 };
3360
3361 int count, choice;
3362
3363 if (!CONST_INT_P (operands[2]))
3364 FAIL;
3365 count = INTVAL (operands[2]);
3366 choice = rot_tab[count];
3367 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3368 FAIL;
3369 choice &= 7;
3370 switch (choice)
3371 {
3372 case 0:
3373 emit_move_insn (operands[0], operands[1]);
3374 count -= (count & 16) * 2;
3375 break;
3376 case 3:
3377 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3378 count -= 16;
3379 break;
3380 case 1:
3381 case 2:
3382 {
3383 rtx parts[2];
3384 parts[0] = gen_reg_rtx (SImode);
3385 parts[1] = gen_reg_rtx (SImode);
3386 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3387 emit_move_insn (parts[choice-1], operands[1]);
3388 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3389 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3390 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3391 count = (count & ~16) - 8;
3392 }
3393 }
3394
3395 for (; count > 0; count--)
3396 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3397 for (; count < 0; count++)
3398 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3399
3400 DONE;
3401 }")
3402
3403 (define_insn "*rotlhi3_8"
3404 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3405 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3406 (const_int 8)))]
3407 "TARGET_SH1"
3408 "swap.b %1,%0"
3409 [(set_attr "type" "arith")])
3410
3411 (define_expand "rotlhi3"
3412 [(set (match_operand:HI 0 "arith_reg_operand" "")
3413 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3414 (match_operand:HI 2 "immediate_operand" "")))]
3415 "TARGET_SH1"
3416 "
3417 {
3418 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3419 FAIL;
3420 }")
3421
3422 ;;
3423 ;; shift left
3424
3425 (define_insn "ashlsi3_sh2a"
3426 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3427 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428 (match_operand:SI 2 "arith_reg_operand" "r")))]
3429 "TARGET_SH2A"
3430 "shad %2,%0"
3431 [(set_attr "type" "arith")
3432 (set_attr "length" "4")])
3433
3434 ;; This pattern is used by init_expmed for computing the costs of shift
3435 ;; insns.
3436
3437 (define_insn_and_split "ashlsi3_std"
3438 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3439 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3440 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3441 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3442 "TARGET_SH3
3443 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3444 "@
3445 shld %2,%0
3446 add %0,%0
3447 shll%O2 %0
3448 #"
3449 "TARGET_SH3
3450 && reload_completed
3451 && CONST_INT_P (operands[2])
3452 && ! satisfies_constraint_P27 (operands[2])"
3453 [(set (match_dup 3) (match_dup 2))
3454 (parallel
3455 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3456 (clobber (match_dup 4))])]
3457 "operands[4] = gen_rtx_SCRATCH (SImode);"
3458 [(set_attr "length" "*,*,*,4")
3459 (set_attr "type" "dyn_shift,arith,arith,arith")])
3460
3461 (define_insn "ashlhi3_k"
3462 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3463 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3464 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3465 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3466 "@
3467 add %0,%0
3468 shll%O2 %0"
3469 [(set_attr "type" "arith")])
3470
3471 (define_insn "ashlsi3_n"
3472 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3473 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3474 (match_operand:SI 2 "const_int_operand" "n")))
3475 (clobber (reg:SI T_REG))]
3476 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3477 "#"
3478 [(set (attr "length")
3479 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3480 (const_string "2")
3481 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3482 (const_string "4")
3483 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3484 (const_string "6")]
3485 (const_string "8")))
3486 (set_attr "type" "arith")])
3487
3488 (define_split
3489 [(set (match_operand:SI 0 "arith_reg_dest" "")
3490 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3491 (match_operand:SI 2 "const_int_operand" "")))
3492 (clobber (reg:SI T_REG))]
3493 "TARGET_SH1 && reload_completed"
3494 [(use (reg:SI R0_REG))]
3495 "
3496 {
3497 gen_shifty_op (ASHIFT, operands);
3498 DONE;
3499 }")
3500
3501 (define_insn "ashlsi3_media"
3502 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3503 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3504 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3505 "TARGET_SHMEDIA"
3506 "@
3507 shlld.l %1, %2, %0
3508 shlli.l %1, %2, %0"
3509 [(set_attr "type" "arith_media")
3510 (set_attr "highpart" "ignore")])
3511
3512 (define_expand "ashlsi3"
3513 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3514 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3515 (match_operand:SI 2 "nonmemory_operand" "")))
3516 (clobber (reg:SI T_REG))])]
3517 ""
3518 "
3519 {
3520 if (TARGET_SHMEDIA)
3521 {
3522 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3523 DONE;
3524 }
3525 if (CONST_INT_P (operands[2])
3526 && sh_dynamicalize_shift_p (operands[2]))
3527 operands[2] = force_reg (SImode, operands[2]);
3528 if (TARGET_SH3)
3529 {
3530 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3531 DONE;
3532 }
3533 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3534 FAIL;
3535 }")
3536
3537 (define_insn "*ashlhi3_n"
3538 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3539 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3540 (match_operand:HI 2 "const_int_operand" "n")))
3541 (clobber (reg:SI T_REG))]
3542 "TARGET_SH1"
3543 "#"
3544 [(set (attr "length")
3545 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3546 (const_string "2")
3547 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3548 (const_string "4")]
3549 (const_string "6")))
3550 (set_attr "type" "arith")])
3551
3552 (define_expand "ashlhi3"
3553 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3554 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3555 (match_operand:SI 2 "nonmemory_operand" "")))
3556 (clobber (reg:SI T_REG))])]
3557 "TARGET_SH1"
3558 "
3559 {
3560 if (!CONST_INT_P (operands[2]))
3561 FAIL;
3562 /* It may be possible to call gen_ashlhi3 directly with more generic
3563 operands. Make sure operands[1] is a HImode register here. */
3564 if (!arith_reg_operand (operands[1], HImode))
3565 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3566 }")
3567
3568 (define_split
3569 [(set (match_operand:HI 0 "arith_reg_dest" "")
3570 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3571 (match_operand:HI 2 "const_int_operand" "")))
3572 (clobber (reg:SI T_REG))]
3573 "TARGET_SH1 && reload_completed"
3574 [(use (reg:SI R0_REG))]
3575 "
3576 {
3577 gen_shifty_hi_op (ASHIFT, operands);
3578 DONE;
3579 }")
3580
3581 ;
3582 ; arithmetic shift right
3583 ;
3584
3585 (define_insn "ashrsi3_sh2a"
3586 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3587 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3588 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3589 "TARGET_SH2A"
3590 "shad %2,%0"
3591 [(set_attr "type" "dyn_shift")
3592 (set_attr "length" "4")])
3593
3594 (define_insn "ashrsi3_k"
3595 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3596 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3597 (match_operand:SI 2 "const_int_operand" "M")))
3598 (clobber (reg:SI T_REG))]
3599 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3600 "shar %0"
3601 [(set_attr "type" "arith")])
3602
3603 ;; We can't do HImode right shifts correctly unless we start out with an
3604 ;; explicit zero / sign extension; doing that would result in worse overall
3605 ;; code, so just let the machine independent code widen the mode.
3606 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3607
3608
3609 ;; ??? This should be a define expand.
3610
3611 (define_insn "ashrsi2_16"
3612 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3613 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3614 (const_int 16)))]
3615 "TARGET_SH1"
3616 "#"
3617 [(set_attr "length" "4")])
3618
3619 (define_split
3620 [(set (match_operand:SI 0 "arith_reg_dest" "")
3621 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3622 (const_int 16)))]
3623 "TARGET_SH1"
3624 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3625 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3626 "operands[2] = gen_lowpart (HImode, operands[0]);")
3627
3628 ;; ??? This should be a define expand.
3629
3630 (define_insn "ashrsi2_31"
3631 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3632 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3633 (const_int 31)))
3634 (clobber (reg:SI T_REG))]
3635 "TARGET_SH1"
3636 "#"
3637 [(set_attr "length" "4")])
3638
3639 (define_split
3640 [(set (match_operand:SI 0 "arith_reg_dest" "")
3641 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3642 (const_int 31)))
3643 (clobber (reg:SI T_REG))]
3644 "TARGET_SH1"
3645 [(const_int 0)]
3646 "
3647 {
3648 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3649 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3650 DONE;
3651 }")
3652
3653 (define_peephole2
3654 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3655 (set (reg:SI T_REG)
3656 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3657 "TARGET_SH1
3658 && peep2_reg_dead_p (2, operands[0])
3659 && peep2_reg_dead_p (2, operands[1])"
3660 [(const_int 0)]
3661 "
3662 {
3663 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3664 DONE;
3665 }")
3666
3667 (define_insn "ashlsi_c"
3668 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3669 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3670 (set (reg:SI T_REG)
3671 (lt:SI (match_dup 1) (const_int 0)))]
3672 "TARGET_SH1"
3673 "shll %0"
3674 [(set_attr "type" "arith")])
3675
3676 (define_insn "*ashlsi_c_void"
3677 [(set (reg:SI T_REG)
3678 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3679 (clobber (match_scratch:SI 1 "=0"))]
3680 "TARGET_SH1 && cse_not_expected"
3681 "shll %0"
3682 [(set_attr "type" "arith")])
3683
3684 (define_insn "ashrsi3_d"
3685 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3686 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3687 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3688 "TARGET_SH3"
3689 "shad %2,%0"
3690 [(set_attr "type" "dyn_shift")])
3691
3692 (define_insn "ashrsi3_n"
3693 [(set (reg:SI R4_REG)
3694 (ashiftrt:SI (reg:SI R4_REG)
3695 (match_operand:SI 0 "const_int_operand" "i")))
3696 (clobber (reg:SI T_REG))
3697 (clobber (reg:SI PR_REG))
3698 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3699 "TARGET_SH1"
3700 "jsr @%1%#"
3701 [(set_attr "type" "sfunc")
3702 (set_attr "needs_delay_slot" "yes")])
3703
3704 (define_insn "ashrsi3_media"
3705 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3706 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3707 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3708 "TARGET_SHMEDIA"
3709 "@
3710 shard.l %1, %2, %0
3711 shari.l %1, %2, %0"
3712 [(set_attr "type" "arith_media")
3713 (set_attr "highpart" "ignore")])
3714
3715 (define_expand "ashrsi3"
3716 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3717 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3718 (match_operand:SI 2 "nonmemory_operand" "")))
3719 (clobber (reg:SI T_REG))])]
3720 ""
3721 "
3722 {
3723 if (TARGET_SHMEDIA)
3724 {
3725 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3726 DONE;
3727 }
3728 if (expand_ashiftrt (operands))
3729 DONE;
3730 else
3731 FAIL;
3732 }")
3733
3734 ;; logical shift right
3735
3736 (define_insn "lshrsi3_sh2a"
3737 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3738 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3739 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3740 "TARGET_SH2A"
3741 "shld %2,%0"
3742 [(set_attr "type" "dyn_shift")
3743 (set_attr "length" "4")])
3744
3745 (define_insn "lshrsi3_d"
3746 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3747 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3748 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3749 "TARGET_SH3"
3750 "shld %2,%0"
3751 [(set_attr "type" "dyn_shift")])
3752
3753 ;; Only the single bit shift clobbers the T bit.
3754
3755 (define_insn "lshrsi3_m"
3756 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3757 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3758 (match_operand:SI 2 "const_int_operand" "M")))
3759 (clobber (reg:SI T_REG))]
3760 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3761 "shlr %0"
3762 [(set_attr "type" "arith")])
3763
3764 (define_insn "lshrsi3_k"
3765 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767 (match_operand:SI 2 "const_int_operand" "P27")))]
3768 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3769 && ! satisfies_constraint_M (operands[2])"
3770 "shlr%O2 %0"
3771 [(set_attr "type" "arith")])
3772
3773 (define_insn "lshrsi3_n"
3774 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3776 (match_operand:SI 2 "const_int_operand" "n")))
3777 (clobber (reg:SI T_REG))]
3778 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3779 "#"
3780 [(set (attr "length")
3781 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3782 (const_string "2")
3783 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3784 (const_string "4")
3785 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3786 (const_string "6")]
3787 (const_string "8")))
3788 (set_attr "type" "arith")])
3789
3790 (define_split
3791 [(set (match_operand:SI 0 "arith_reg_dest" "")
3792 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3793 (match_operand:SI 2 "const_int_operand" "")))
3794 (clobber (reg:SI T_REG))]
3795 "TARGET_SH1 && reload_completed"
3796 [(use (reg:SI R0_REG))]
3797 "
3798 {
3799 gen_shifty_op (LSHIFTRT, operands);
3800 DONE;
3801 }")
3802
3803 (define_insn "lshrsi3_media"
3804 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3805 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3806 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3807 "TARGET_SHMEDIA"
3808 "@
3809 shlrd.l %1, %2, %0
3810 shlri.l %1, %2, %0"
3811 [(set_attr "type" "arith_media")
3812 (set_attr "highpart" "ignore")])
3813
3814 (define_expand "lshrsi3"
3815 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3816 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3817 (match_operand:SI 2 "nonmemory_operand" "")))
3818 (clobber (reg:SI T_REG))])]
3819 ""
3820 "
3821 {
3822 if (TARGET_SHMEDIA)
3823 {
3824 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3825 DONE;
3826 }
3827 if (CONST_INT_P (operands[2])
3828 && sh_dynamicalize_shift_p (operands[2]))
3829 operands[2] = force_reg (SImode, operands[2]);
3830 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3831 {
3832 rtx count = copy_to_mode_reg (SImode, operands[2]);
3833 emit_insn (gen_negsi2 (count, count));
3834 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3835 DONE;
3836 }
3837 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3838 FAIL;
3839 }")
3840
3841 ;; ??? This should be a define expand.
3842
3843 (define_insn "ashldi3_k"
3844 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3845 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3846 (const_int 1)))
3847 (clobber (reg:SI T_REG))]
3848 "TARGET_SH1"
3849 "shll %R0\;rotcl %S0"
3850 [(set_attr "length" "4")
3851 (set_attr "type" "arith")])
3852
3853 ;; Expander for DImode shift left with SImode operations.
3854
3855 (define_expand "ashldi3_std"
3856 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3857 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3858 (match_operand:DI 2 "const_int_operand" "n")))]
3859 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3860 "
3861 {
3862 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3863 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3864 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3865 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3866 rtx dst = gen_reg_rtx (DImode);
3867 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3868 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3869 rtx tmp0, tmp1;
3870
3871 tmp0 = gen_reg_rtx (SImode);
3872 tmp1 = gen_reg_rtx (SImode);
3873 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3874 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3875 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3876 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3877 emit_move_insn (operands[0], dst);
3878 DONE;
3879 }")
3880
3881 (define_insn "ashldi3_media"
3882 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3883 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3884 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3885 "TARGET_SHMEDIA"
3886 "@
3887 shlld %1, %2, %0
3888 shlli %1, %2, %0"
3889 [(set_attr "type" "arith_media")])
3890
3891 (define_insn "*ashldisi3_media"
3892 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3893 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3894 (match_operand:DI 2 "const_int_operand" "n")))]
3895 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3896 "shlli.l %1, %2, %0"
3897 [(set_attr "type" "arith_media")
3898 (set_attr "highpart" "ignore")])
3899
3900 (define_expand "ashldi3"
3901 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3902 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3903 (match_operand:DI 2 "immediate_operand" "")))
3904 (clobber (reg:SI T_REG))])]
3905 ""
3906 "
3907 {
3908 if (TARGET_SHMEDIA)
3909 {
3910 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3911 DONE;
3912 }
3913 if (CONST_INT_P (operands[2])
3914 && INTVAL (operands[2]) == 1)
3915 {
3916 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3917 DONE;
3918 }
3919 else if (CONST_INT_P (operands[2])
3920 && INTVAL (operands[2]) < 32)
3921 {
3922 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3923 DONE;
3924 }
3925 else
3926 FAIL;
3927 }")
3928
3929 ;; ??? This should be a define expand.
3930
3931 (define_insn "lshrdi3_k"
3932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3933 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3934 (const_int 1)))
3935 (clobber (reg:SI T_REG))]
3936 "TARGET_SH1"
3937 "shlr %S0\;rotcr %R0"
3938 [(set_attr "length" "4")
3939 (set_attr "type" "arith")])
3940
3941 (define_insn "lshrdi3_media"
3942 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3943 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3944 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3945 "TARGET_SHMEDIA
3946 && (arith_reg_dest (operands[0], DImode)
3947 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3948 "@
3949 shlrd %1, %2, %0
3950 shlri %1, %2, %0"
3951 [(set_attr "type" "arith_media")])
3952
3953 (define_insn "*lshrdisi3_media"
3954 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3955 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3956 (match_operand:DI 2 "const_int_operand" "n")))]
3957 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3958 "shlri.l %1, %2, %0"
3959 [(set_attr "type" "arith_media")
3960 (set_attr "highpart" "ignore")])
3961
3962 (define_expand "lshrdi3"
3963 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3964 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3965 (match_operand:DI 2 "immediate_operand" "")))
3966 (clobber (reg:SI T_REG))])]
3967 ""
3968 "
3969 {
3970 if (TARGET_SHMEDIA)
3971 {
3972 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3973 DONE;
3974 }
3975 if (!CONST_INT_P (operands[2])
3976 || INTVAL (operands[2]) != 1)
3977 FAIL;
3978 }")
3979
3980 ;; ??? This should be a define expand.
3981
3982 (define_insn "ashrdi3_k"
3983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3984 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3985 (const_int 1)))
3986 (clobber (reg:SI T_REG))]
3987 "TARGET_SH1"
3988 "shar %S0\;rotcr %R0"
3989 [(set_attr "length" "4")
3990 (set_attr "type" "arith")])
3991
3992 (define_insn "ashrdi3_media"
3993 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3994 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3995 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3996 "TARGET_SHMEDIA
3997 && (arith_reg_dest (operands[0], DImode)
3998 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
3999 "@
4000 shard %1, %2, %0
4001 shari %1, %2, %0"
4002 [(set_attr "type" "arith_media")])
4003
4004 (define_insn "*ashrdisi3_media"
4005 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4006 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4007 (match_operand:DI 2 "const_int_operand" "n")))]
4008 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4009 "shari.l %1, %2, %0"
4010 [(set_attr "type" "arith_media")
4011 (set_attr "highpart" "ignore")])
4012
4013 (define_insn "ashrdisi3_media_high"
4014 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4015 (truncate:SI
4016 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4017 (match_operand:DI 2 "const_int_operand" "n"))))]
4018 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4019 "shari %1, %2, %0"
4020 [(set_attr "type" "arith_media")])
4021
4022 (define_insn "ashrdisi3_media_opaque"
4023 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4024 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4025 (match_operand:DI 2 "const_int_operand" "n")]
4026 UNSPEC_ASHIFTRT))]
4027 "TARGET_SHMEDIA"
4028 "shari %1, %2, %0"
4029 [(set_attr "type" "arith_media")])
4030
4031 (define_expand "ashrdi3"
4032 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4033 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4034 (match_operand:DI 2 "immediate_operand" "")))
4035 (clobber (reg:SI T_REG))])]
4036 ""
4037 "
4038 {
4039 if (TARGET_SHMEDIA)
4040 {
4041 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4042 DONE;
4043 }
4044 if (!CONST_INT_P (operands[2])
4045 || INTVAL (operands[2]) != 1)
4046 FAIL;
4047 }")
4048
4049 ;; combined left/right shift
4050
4051 (define_split
4052 [(set (match_operand:SI 0 "register_operand" "")
4053 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4054 (match_operand:SI 2 "const_int_operand" ""))
4055 (match_operand:SI 3 "const_int_operand" "")))]
4056 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4057 [(use (reg:SI R0_REG))]
4058 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4059 DONE;")
4060
4061 (define_split
4062 [(set (match_operand:SI 0 "register_operand" "")
4063 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4064 (match_operand:SI 2 "const_int_operand" ""))
4065 (match_operand:SI 3 "const_int_operand" "")))
4066 (clobber (reg:SI T_REG))]
4067 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4068 [(use (reg:SI R0_REG))]
4069 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4070 DONE;")
4071
4072 (define_insn ""
4073 [(set (match_operand:SI 0 "register_operand" "=r")
4074 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4075 (match_operand:SI 2 "const_int_operand" "n"))
4076 (match_operand:SI 3 "const_int_operand" "n")))
4077 (clobber (reg:SI T_REG))]
4078 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4079 "#"
4080 [(set (attr "length")
4081 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4082 (const_string "4")
4083 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4084 (const_string "6")
4085 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4086 (const_string "8")
4087 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4088 (const_string "10")
4089 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4090 (const_string "12")
4091 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4092 (const_string "14")
4093 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4094 (const_string "16")]
4095 (const_string "18")))
4096 (set_attr "type" "arith")])
4097
4098 (define_insn ""
4099 [(set (match_operand:SI 0 "register_operand" "=z")
4100 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101 (match_operand:SI 2 "const_int_operand" "n"))
4102 (match_operand:SI 3 "const_int_operand" "n")))
4103 (clobber (reg:SI T_REG))]
4104 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4105 "#"
4106 [(set (attr "length")
4107 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4108 (const_string "4")
4109 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4110 (const_string "6")
4111 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4112 (const_string "8")]
4113 (const_string "10")))
4114 (set_attr "type" "arith")])
4115
4116 ;; shift left / and combination with a scratch register: The combine pass
4117 ;; does not accept the individual instructions, even though they are
4118 ;; cheap. But it needs a precise description so that it is usable after
4119 ;; reload.
4120 (define_insn "and_shl_scratch"
4121 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4122 (lshiftrt:SI
4123 (ashift:SI
4124 (and:SI
4125 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4126 (match_operand:SI 2 "const_int_operand" "N,n"))
4127 (match_operand:SI 3 "" "0,r"))
4128 (match_operand:SI 4 "const_int_operand" "n,n"))
4129 (match_operand:SI 5 "const_int_operand" "n,n")))
4130 (clobber (reg:SI T_REG))]
4131 "TARGET_SH1"
4132 "#"
4133 [(set (attr "length")
4134 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4135 (const_string "4")
4136 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4137 (const_string "6")
4138 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4139 (const_string "8")
4140 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4141 (const_string "10")]
4142 (const_string "12")))
4143 (set_attr "type" "arith")])
4144
4145 (define_split
4146 [(set (match_operand:SI 0 "register_operand" "")
4147 (lshiftrt:SI
4148 (ashift:SI
4149 (and:SI
4150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4151 (match_operand:SI 2 "const_int_operand" ""))
4152 (match_operand:SI 3 "register_operand" ""))
4153 (match_operand:SI 4 "const_int_operand" ""))
4154 (match_operand:SI 5 "const_int_operand" "")))
4155 (clobber (reg:SI T_REG))]
4156 "TARGET_SH1"
4157 [(use (reg:SI R0_REG))]
4158 "
4159 {
4160 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4161
4162 if (INTVAL (operands[2]))
4163 {
4164 gen_shifty_op (LSHIFTRT, operands);
4165 }
4166 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4167 operands[2] = operands[4];
4168 gen_shifty_op (ASHIFT, operands);
4169 if (INTVAL (operands[5]))
4170 {
4171 operands[2] = operands[5];
4172 gen_shifty_op (LSHIFTRT, operands);
4173 }
4174 DONE;
4175 }")
4176
4177 ;; signed left/right shift combination.
4178 (define_split
4179 [(set (match_operand:SI 0 "register_operand" "")
4180 (sign_extract:SI
4181 (ashift:SI (match_operand:SI 1 "register_operand" "")
4182 (match_operand:SI 2 "const_int_operand" ""))
4183 (match_operand:SI 3 "const_int_operand" "")
4184 (const_int 0)))
4185 (clobber (reg:SI T_REG))]
4186 "TARGET_SH1"
4187 [(use (reg:SI R0_REG))]
4188 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4189 DONE;")
4190
4191 (define_insn "shl_sext_ext"
4192 [(set (match_operand:SI 0 "register_operand" "=r")
4193 (sign_extract:SI
4194 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4195 (match_operand:SI 2 "const_int_operand" "n"))
4196 (match_operand:SI 3 "const_int_operand" "n")
4197 (const_int 0)))
4198 (clobber (reg:SI T_REG))]
4199 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4200 "#"
4201 [(set (attr "length")
4202 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4203 (const_string "2")
4204 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4205 (const_string "4")
4206 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4207 (const_string "6")
4208 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4209 (const_string "8")
4210 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4211 (const_string "10")
4212 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4213 (const_string "12")
4214 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4215 (const_string "14")
4216 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4217 (const_string "16")]
4218 (const_string "18")))
4219 (set_attr "type" "arith")])
4220
4221 (define_insn "shl_sext_sub"
4222 [(set (match_operand:SI 0 "register_operand" "=z")
4223 (sign_extract:SI
4224 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4225 (match_operand:SI 2 "const_int_operand" "n"))
4226 (match_operand:SI 3 "const_int_operand" "n")
4227 (const_int 0)))
4228 (clobber (reg:SI T_REG))]
4229 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4230 "#"
4231 [(set (attr "length")
4232 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4233 (const_string "6")
4234 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4235 (const_string "8")
4236 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4237 (const_string "10")
4238 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4239 (const_string "12")]
4240 (const_string "14")))
4241 (set_attr "type" "arith")])
4242
4243 ;; These patterns are found in expansions of DImode shifts by 16, and
4244 ;; allow the xtrct instruction to be generated from C source.
4245
4246 (define_insn "xtrct_left"
4247 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4248 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4249 (const_int 16))
4250 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4251 (const_int 16))))]
4252 "TARGET_SH1"
4253 "xtrct %1,%0"
4254 [(set_attr "type" "arith")])
4255
4256 (define_insn "xtrct_right"
4257 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4258 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4259 (const_int 16))
4260 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4261 (const_int 16))))]
4262 "TARGET_SH1"
4263 "xtrct %2,%0"
4264 [(set_attr "type" "arith")])
4265
4266 ;; -------------------------------------------------------------------------
4267 ;; Unary arithmetic
4268 ;; -------------------------------------------------------------------------
4269
4270 (define_insn "negc"
4271 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4272 (neg:SI (plus:SI (reg:SI T_REG)
4273 (match_operand:SI 1 "arith_reg_operand" "r"))))
4274 (set (reg:SI T_REG)
4275 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4276 (const_int 0)))]
4277 "TARGET_SH1"
4278 "negc %1,%0"
4279 [(set_attr "type" "arith")])
4280
4281 (define_insn "*negdi_media"
4282 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4283 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4284 "TARGET_SHMEDIA"
4285 "sub r63, %1, %0"
4286 [(set_attr "type" "arith_media")])
4287
4288 (define_expand "negdi2"
4289 [(set (match_operand:DI 0 "arith_reg_operand" "")
4290 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4291 ""
4292 "
4293 {
4294 if (TARGET_SH1)
4295 {
4296 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4297 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4298
4299 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4300 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4301
4302 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4303 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4304
4305 emit_insn (gen_clrt ());
4306 emit_insn (gen_negc (low_dst, low_src));
4307 emit_insn (gen_negc (high_dst, high_src));
4308 DONE;
4309 }
4310 }")
4311
4312 (define_insn "negsi2"
4313 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4314 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4315 "TARGET_SH1"
4316 "neg %1,%0"
4317 [(set_attr "type" "arith")])
4318
4319 (define_insn "one_cmplsi2"
4320 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4321 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4322 "TARGET_SH1"
4323 "not %1,%0"
4324 [(set_attr "type" "arith")])
4325
4326 (define_expand "one_cmpldi2"
4327 [(set (match_operand:DI 0 "arith_reg_dest" "")
4328 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4329 (const_int -1)))]
4330 "TARGET_SHMEDIA" "")
4331
4332 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4333 This can be used as some kind of conditional execution, which is useful
4334 for abs. */
4335 (define_split
4336 [(set (match_operand:SI 0 "arith_reg_dest" "")
4337 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4338 (match_operand:SI 1 "arith_reg_operand" ""))
4339 (reg:SI T_REG)))]
4340 "TARGET_HARD_SH4"
4341 [(const_int 0)]
4342 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4343 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4344 DONE;")
4345
4346 (define_insn "cneg"
4347 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4348 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4349 (match_operand:SI 1 "arith_reg_operand" "0")
4350 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4351 "TARGET_HARD_SH4"
4352 "bf 0f\;neg %2,%0\\n0:"
4353 [(set_attr "type" "arith") ;; poor approximation
4354 (set_attr "length" "4")])
4355
4356 \f
4357 ;; -------------------------------------------------------------------------
4358 ;; Zero extension instructions
4359 ;; -------------------------------------------------------------------------
4360
4361 (define_insn "zero_extendsidi2"
4362 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4363 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4364 "TARGET_SHMEDIA"
4365 "addz.l %1, r63, %0"
4366 [(set_attr "type" "arith_media")
4367 (set_attr "highpart" "extend")])
4368
4369 (define_insn "zero_extendhidi2"
4370 [(set (match_operand:DI 0 "register_operand" "=r,r")
4371 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4372 "TARGET_SHMEDIA"
4373 "@
4374 #
4375 ld%M1.uw %m1, %0"
4376 [(set_attr "type" "*,load_media")
4377 (set (attr "highpart")
4378 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4379 (const_string "user")]
4380 (const_string "ignore")))])
4381
4382 (define_split
4383 [(set (match_operand:DI 0 "register_operand" "")
4384 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4385 "TARGET_SHMEDIA && reload_completed"
4386 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4387 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4388 "
4389 {
4390 if (GET_CODE (operands[1]) == TRUNCATE)
4391 operands[1] = XEXP (operands[1], 0);
4392 }")
4393
4394 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4395 ;; reload the entire truncate expression.
4396 (define_insn_and_split "*loaddi_trunc"
4397 [(set (match_operand 0 "any_register_operand" "=r")
4398 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4399 "TARGET_SHMEDIA && reload_completed"
4400 "#"
4401 "TARGET_SHMEDIA && reload_completed"
4402 [(set (match_dup 0) (match_dup 1))]
4403 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4404
4405 (define_insn "zero_extendqidi2"
4406 [(set (match_operand:DI 0 "register_operand" "=r,r")
4407 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4408 "TARGET_SHMEDIA"
4409 "@
4410 andi %1, 255, %0
4411 ld%M1.ub %m1, %0"
4412 [(set_attr "type" "arith_media,load_media")
4413 (set (attr "highpart")
4414 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4415 (const_string "user")]
4416 (const_string "ignore")))])
4417
4418 (define_expand "zero_extendhisi2"
4419 [(set (match_operand:SI 0 "arith_reg_operand" "")
4420 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4421 ""
4422 "
4423 {
4424 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4425 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4426 }")
4427
4428 (define_insn "*zero_extendhisi2_compact"
4429 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4430 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4431 "TARGET_SH1"
4432 "extu.w %1,%0"
4433 [(set_attr "type" "arith")])
4434
4435 (define_insn "*zero_extendhisi2_media"
4436 [(set (match_operand:SI 0 "register_operand" "=r,r")
4437 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4438 "TARGET_SHMEDIA"
4439 "@
4440 #
4441 ld%M1.uw %m1, %0"
4442 [(set_attr "type" "arith_media,load_media")
4443 (set (attr "highpart")
4444 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4445 (const_string "user")]
4446 (const_string "ignore")))])
4447
4448 (define_split
4449 [(set (match_operand:SI 0 "register_operand" "")
4450 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4451 "TARGET_SHMEDIA && reload_completed"
4452 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4453 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4454 "
4455 {
4456 rtx op1 = operands[1];
4457
4458 if (GET_CODE (op1) == TRUNCATE)
4459 op1 = XEXP (op1, 0);
4460 operands[2]
4461 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4462 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4463 }")
4464
4465 (define_expand "zero_extendqisi2"
4466 [(set (match_operand:SI 0 "arith_reg_operand" "")
4467 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4468 ""
4469 "
4470 {
4471 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4472 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4473 }")
4474
4475 (define_insn "*zero_extendqisi2_compact"
4476 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4477 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4478 "TARGET_SH1"
4479 "extu.b %1,%0"
4480 [(set_attr "type" "arith")])
4481
4482 (define_insn "*zero_extendqisi2_media"
4483 [(set (match_operand:SI 0 "register_operand" "=r,r")
4484 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4485 "TARGET_SHMEDIA"
4486 "@
4487 andi %1, 255, %0
4488 ld%M1.ub %m1, %0"
4489 [(set_attr "type" "arith_media,load_media")
4490 (set (attr "highpart")
4491 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4492 (const_string "user")]
4493 (const_string "ignore")))])
4494
4495 (define_insn "zero_extendqihi2"
4496 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4497 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4498 "TARGET_SH1"
4499 "extu.b %1,%0"
4500 [(set_attr "type" "arith")])
4501
4502 ;; -------------------------------------------------------------------------
4503 ;; Sign extension instructions
4504 ;; -------------------------------------------------------------------------
4505
4506 ;; ??? This should be a define expand.
4507 ;; ??? Or perhaps it should be dropped?
4508
4509 ;; convert_move generates good code for SH[1-4].
4510 (define_insn "extendsidi2"
4511 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4512 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4513 "TARGET_SHMEDIA"
4514 "@
4515 add.l %1, r63, %0
4516 ld%M1.l %m1, %0
4517 fmov.sl %1, %0"
4518 [(set_attr "type" "arith_media,load_media,fpconv_media")
4519 (set (attr "highpart")
4520 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4521 (const_string "user")]
4522 (const_string "extend")))])
4523
4524 (define_insn "extendhidi2"
4525 [(set (match_operand:DI 0 "register_operand" "=r,r")
4526 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4527 "TARGET_SHMEDIA"
4528 "@
4529 #
4530 ld%M1.w %m1, %0"
4531 [(set_attr "type" "*,load_media")
4532 (set (attr "highpart")
4533 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4534 (const_string "user")]
4535 (const_string "ignore")))])
4536
4537 (define_split
4538 [(set (match_operand:DI 0 "register_operand" "")
4539 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4540 "TARGET_SHMEDIA && reload_completed"
4541 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4542 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4543 "
4544 {
4545 if (GET_CODE (operands[1]) == TRUNCATE)
4546 operands[1] = XEXP (operands[1], 0);
4547 }")
4548
4549 (define_insn "extendqidi2"
4550 [(set (match_operand:DI 0 "register_operand" "=r,r")
4551 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4552 "TARGET_SHMEDIA"
4553 "@
4554 #
4555 ld%M1.b %m1, %0"
4556 [(set_attr "type" "*,load_media")
4557 (set (attr "highpart")
4558 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4559 (const_string "user")]
4560 (const_string "ignore")))])
4561
4562 (define_split
4563 [(set (match_operand:DI 0 "register_operand" "")
4564 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4565 "TARGET_SHMEDIA && reload_completed"
4566 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4567 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4568 "
4569 {
4570 if (GET_CODE (operands[1]) == TRUNCATE)
4571 operands[1] = XEXP (operands[1], 0);
4572 }")
4573
4574 (define_expand "extendhisi2"
4575 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4576 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4577 ""
4578 "")
4579
4580 (define_insn "*extendhisi2_compact"
4581 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4582 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4583 "TARGET_SH1"
4584 "@
4585 exts.w %1,%0
4586 mov.w %1,%0"
4587 [(set_attr "type" "arith,load")])
4588
4589 (define_insn "*extendhisi2_media"
4590 [(set (match_operand:SI 0 "register_operand" "=r,r")
4591 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4592 "TARGET_SHMEDIA"
4593 "@
4594 #
4595 ld%M1.w %m1, %0"
4596 [(set_attr "type" "arith_media,load_media")
4597 (set (attr "highpart")
4598 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4599 (const_string "user")]
4600 (const_string "ignore")))])
4601
4602 (define_split
4603 [(set (match_operand:SI 0 "register_operand" "")
4604 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4605 "TARGET_SHMEDIA && reload_completed"
4606 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4607 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4608 "
4609 {
4610 rtx op1 = operands[1];
4611 if (GET_CODE (op1) == TRUNCATE)
4612 op1 = XEXP (op1, 0);
4613 operands[2]
4614 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4615 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4616 }")
4617
4618 (define_expand "extendqisi2"
4619 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4620 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4621 ""
4622 "")
4623
4624 (define_insn "*extendqisi2_compact"
4625 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4626 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4627 "TARGET_SH1"
4628 "@
4629 exts.b %1,%0
4630 mov.b %1,%0"
4631 [(set_attr "type" "arith,load")
4632 (set_attr_alternative "length"
4633 [(const_int 2)
4634 (if_then_else
4635 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4636 (const_int 4) (const_int 2))])])
4637
4638 (define_insn "*extendqisi2_media"
4639 [(set (match_operand:SI 0 "register_operand" "=r,r")
4640 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4641 "TARGET_SHMEDIA"
4642 "@
4643 #
4644 ld%M1.b %m1, %0"
4645 [(set_attr "type" "arith_media,load_media")
4646 (set (attr "highpart")
4647 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4648 (const_string "user")]
4649 (const_string "ignore")))])
4650
4651 (define_split
4652 [(set (match_operand:SI 0 "register_operand" "")
4653 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4654 "TARGET_SHMEDIA && reload_completed"
4655 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4656 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4657 "
4658 {
4659 rtx op1 = operands[1];
4660 if (GET_CODE (op1) == TRUNCATE)
4661 op1 = XEXP (op1, 0);
4662 operands[2]
4663 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4664 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4665 }")
4666
4667 (define_insn "extendqihi2"
4668 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4669 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4670 "TARGET_SH1"
4671 "@
4672 exts.b %1,%0
4673 mov.b %1,%0"
4674 [(set_attr "type" "arith,load")
4675 (set_attr_alternative "length"
4676 [(const_int 2)
4677 (if_then_else
4678 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4679 (const_int 4) (const_int 2))])])
4680
4681 /* It would seem useful to combine the truncXi patterns into the movXi
4682 patterns, but unary operators are ignored when matching constraints,
4683 so we need separate patterns. */
4684 (define_insn "truncdisi2"
4685 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4686 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4687 "TARGET_SHMEDIA"
4688 "@
4689 add.l %1, r63, %0
4690 st%M0.l %m0, %1
4691 fst%M0.s %m0, %T1
4692 fmov.ls %1, %0
4693 fmov.sl %T1, %0
4694 fmov.s %T1, %0"
4695 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4696 (set (attr "highpart")
4697 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4698 (const_string "user")]
4699 (const_string "extend")))])
4700
4701 (define_insn "truncdihi2"
4702 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4703 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4704 "TARGET_SHMEDIA"
4705 "@
4706 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4707 st%M0.w %m0, %1"
4708 [(set_attr "type" "arith_media,store_media")
4709 (set_attr "length" "8,4")
4710 (set (attr "highpart")
4711 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712 (const_string "user")]
4713 (const_string "extend")))])
4714
4715 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4716 ; Because we use zero extension, we can't provide signed QImode compares
4717 ; using a simple compare or conditional branch insn.
4718 (define_insn "truncdiqi2"
4719 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4720 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4721 "TARGET_SHMEDIA"
4722 "@
4723 andi %1, 255, %0
4724 st%M0.b %m0, %1"
4725 [(set_attr "type" "arith_media,store")
4726 (set (attr "highpart")
4727 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4728 (const_string "user")]
4729 (const_string "extend")))])
4730 ;; -------------------------------------------------------------------------
4731 ;; Move instructions
4732 ;; -------------------------------------------------------------------------
4733
4734 ;; define push and pop so it is easy for sh.c
4735 ;; We can't use push and pop on SHcompact because the stack must always
4736 ;; be 8-byte aligned.
4737
4738 (define_expand "push"
4739 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4740 (match_operand:SI 0 "register_operand" "r,l,x"))]
4741 "TARGET_SH1 && ! TARGET_SH5"
4742 "")
4743
4744 (define_expand "pop"
4745 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4746 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4747 "TARGET_SH1 && ! TARGET_SH5"
4748 "")
4749
4750 (define_expand "push_e"
4751 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4752 (match_operand:SF 0 "" ""))
4753 (use (reg:PSI FPSCR_REG))
4754 (clobber (scratch:SI))])]
4755 "TARGET_SH1 && ! TARGET_SH5"
4756 "")
4757
4758 (define_insn "push_fpul"
4759 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4760 "TARGET_SH2E && ! TARGET_SH5"
4761 "sts.l fpul,@-r15"
4762 [(set_attr "type" "fstore")
4763 (set_attr "late_fp_use" "yes")
4764 (set_attr "hit_stack" "yes")])
4765
4766 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4767 ;; so use that.
4768 (define_expand "push_4"
4769 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4770 (match_operand:DF 0 "" ""))
4771 (use (reg:PSI FPSCR_REG))
4772 (clobber (scratch:SI))])]
4773 "TARGET_SH1 && ! TARGET_SH5"
4774 "")
4775
4776 (define_expand "pop_e"
4777 [(parallel [(set (match_operand:SF 0 "" "")
4778 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4779 (use (reg:PSI FPSCR_REG))
4780 (clobber (scratch:SI))])]
4781 "TARGET_SH1 && ! TARGET_SH5"
4782 "")
4783
4784 (define_insn "pop_fpul"
4785 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4786 "TARGET_SH2E && ! TARGET_SH5"
4787 "lds.l @r15+,fpul"
4788 [(set_attr "type" "load")
4789 (set_attr "hit_stack" "yes")])
4790
4791 (define_expand "pop_4"
4792 [(parallel [(set (match_operand:DF 0 "" "")
4793 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4794 (use (reg:PSI FPSCR_REG))
4795 (clobber (scratch:SI))])]
4796 "TARGET_SH1 && ! TARGET_SH5"
4797 "")
4798
4799 (define_expand "push_fpscr"
4800 [(const_int 0)]
4801 "TARGET_SH2E"
4802 "
4803 {
4804 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4805 gen_rtx_PRE_DEC (Pmode,
4806 stack_pointer_rtx)),
4807 get_fpscr_rtx ()));
4808 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4809 DONE;
4810 }")
4811
4812 (define_expand "pop_fpscr"
4813 [(const_int 0)]
4814 "TARGET_SH2E"
4815 "
4816 {
4817 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4818 gen_frame_mem (PSImode,
4819 gen_rtx_POST_INC (Pmode,
4820 stack_pointer_rtx))));
4821 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4822 DONE;
4823 }")
4824
4825 ;; These two patterns can happen as the result of optimization, when
4826 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4827 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4828
4829 (define_insn "clrt"
4830 [(set (reg:SI T_REG) (const_int 0))]
4831 "TARGET_SH1"
4832 "clrt")
4833
4834 (define_insn "sett"
4835 [(set (reg:SI T_REG) (const_int 1))]
4836 "TARGET_SH1"
4837 "sett")
4838
4839 ;; t/r must come after r/r, lest reload will try to reload stuff like
4840 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4841 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4842 (define_insn "movsi_i"
4843 [(set (match_operand:SI 0 "general_movdst_operand"
4844 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4845 (match_operand:SI 1 "general_movsrc_operand"
4846 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4847 "TARGET_SH1
4848 && ! TARGET_SH2E
4849 && ! TARGET_SH2A
4850 && (register_operand (operands[0], SImode)
4851 || register_operand (operands[1], SImode))"
4852 "@
4853 mov.l %1,%0
4854 mov %1,%0
4855 mov %1,%0
4856 cmp/pl %1
4857 mov.l %1,%0
4858 sts %1,%0
4859 sts %1,%0
4860 movt %0
4861 mov.l %1,%0
4862 sts.l %1,%0
4863 sts.l %1,%0
4864 lds %1,%0
4865 lds %1,%0
4866 lds.l %1,%0
4867 lds.l %1,%0
4868 fake %1,%0"
4869 [(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")
4870 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4871
4872 ;; t/r must come after r/r, lest reload will try to reload stuff like
4873 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4874 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4875 ;; will require a reload.
4876 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4877 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4878 (define_insn "movsi_ie"
4879 [(set (match_operand:SI 0 "general_movdst_operand"
4880 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4881 (match_operand:SI 1 "general_movsrc_operand"
4882 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4883 "(TARGET_SH2E || TARGET_SH2A)
4884 && (register_operand (operands[0], SImode)
4885 || register_operand (operands[1], SImode))"
4886 "@
4887 mov.l %1,%0
4888 mov %1,%0
4889 mov %1,%0
4890 movi20 %1,%0
4891 movi20s %1,%0
4892 cmp/pl %1
4893 mov.l %1,%0
4894 sts %1,%0
4895 sts %1,%0
4896 movt %0
4897 mov.l %1,%0
4898 sts.l %1,%0
4899 sts.l %1,%0
4900 lds %1,%0
4901 lds %1,%0
4902 lds.l %1,%0
4903 lds.l %1,%0
4904 lds.l %1,%0
4905 sts.l %1,%0
4906 fake %1,%0
4907 lds %1,%0
4908 sts %1,%0
4909 fsts fpul,%0
4910 flds %1,fpul
4911 fmov %1,%0
4912 ! move optimized away"
4913 [(set_attr "type" "pcload_si,move,movi8,move,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")
4914 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4915 (set_attr_alternative "length"
4916 [(const_int 2)
4917 (const_int 2)
4918 (const_int 2)
4919 (const_int 4)
4920 (const_int 4)
4921 (const_int 2)
4922 (if_then_else
4923 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4924 (const_int 4) (const_int 2))
4925 (const_int 2)
4926 (const_int 2)
4927 (const_int 2)
4928 (if_then_else
4929 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4930 (const_int 4) (const_int 2))
4931 (const_int 2)
4932 (const_int 2)
4933 (const_int 2)
4934 (const_int 2)
4935 (const_int 2)
4936 (const_int 2)
4937 (const_int 2)
4938 (const_int 2)
4939 (const_int 2)
4940 (const_int 2)
4941 (const_int 2)
4942 (const_int 2)
4943 (const_int 2)
4944 (const_int 2)
4945 (const_int 0)])])
4946
4947 (define_insn "movsi_i_lowpart"
4948 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4949 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4950 "TARGET_SH1
4951 && (register_operand (operands[0], SImode)
4952 || register_operand (operands[1], SImode))"
4953 "@
4954 mov.l %1,%0
4955 mov %1,%0
4956 mov %1,%0
4957 mov.l %1,%0
4958 sts %1,%0
4959 sts %1,%0
4960 movt %0
4961 mov.l %1,%0
4962 fake %1,%0"
4963 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4964
4965 (define_insn_and_split "load_ra"
4966 [(set (match_operand:SI 0 "general_movdst_operand" "")
4967 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4968 "TARGET_SH1"
4969 "#"
4970 "&& ! currently_expanding_to_rtl"
4971 [(set (match_dup 0) (match_dup 1))]
4972 "
4973 {
4974 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4975 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4976 }")
4977
4978 ;; The '?'s in the following constraints may not reflect the time taken
4979 ;; to perform the move. They are there to discourage the use of floating-
4980 ;; point registers for storing integer values.
4981 (define_insn "*movsi_media"
4982 [(set (match_operand:SI 0 "general_movdst_operand"
4983 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4984 (match_operand:SI 1 "general_movsrc_operand"
4985 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4986 "TARGET_SHMEDIA_FPU
4987 && (register_operand (operands[0], SImode)
4988 || sh_register_operand (operands[1], SImode)
4989 || GET_CODE (operands[1]) == TRUNCATE)"
4990 "@
4991 add.l %1, r63, %0
4992 movi %1, %0
4993 #
4994 ld%M1.l %m1, %0
4995 st%M0.l %m0, %N1
4996 fld%M1.s %m1, %0
4997 fst%M0.s %m0, %1
4998 fmov.ls %N1, %0
4999 fmov.sl %1, %0
5000 fmov.s %1, %0
5001 ptabs %1, %0
5002 gettr %1, %0
5003 pt %1, %0"
5004 [(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")
5005 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5006 (set (attr "highpart")
5007 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5008 (const_string "user")]
5009 (const_string "ignore")))])
5010
5011 (define_insn "*movsi_media_nofpu"
5012 [(set (match_operand:SI 0 "general_movdst_operand"
5013 "=r,r,r,r,m,*b,r,*b")
5014 (match_operand:SI 1 "general_movsrc_operand"
5015 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5016 "TARGET_SHMEDIA
5017 && (register_operand (operands[0], SImode)
5018 || sh_register_operand (operands[1], SImode)
5019 || GET_CODE (operands[1]) == TRUNCATE)"
5020 "@
5021 add.l %1, r63, %0
5022 movi %1, %0
5023 #
5024 ld%M1.l %m1, %0
5025 st%M0.l %m0, %N1
5026 ptabs %1, %0
5027 gettr %1, %0
5028 pt %1, %0"
5029 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5030 (set_attr "length" "4,4,8,4,4,4,4,12")
5031 (set (attr "highpart")
5032 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5033 (const_string "user")]
5034 (const_string "ignore")))])
5035
5036 (define_expand "movsi_const"
5037 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5038 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5039 (const_int 16)] UNSPEC_EXTRACT_S16)))
5040 (set (match_dup 0)
5041 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5042 (const:SI (unspec:SI [(match_dup 1)
5043 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5044 "TARGET_SHMEDIA && reload_completed
5045 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5046 "
5047 {
5048 if (GET_CODE (operands[1]) == LABEL_REF
5049 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5050 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5051 else if (GOTOFF_P (operands[1]))
5052 {
5053 rtx unspec = XEXP (operands[1], 0);
5054
5055 if (! UNSPEC_GOTOFF_P (unspec))
5056 {
5057 unspec = XEXP (unspec, 0);
5058 if (! UNSPEC_GOTOFF_P (unspec))
5059 abort ();
5060 }
5061 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5062 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5063 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5064 }
5065 }")
5066
5067 (define_expand "movsi_const_16bit"
5068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5069 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5070 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5071 "TARGET_SHMEDIA && flag_pic && reload_completed
5072 && GET_CODE (operands[1]) == SYMBOL_REF"
5073 "")
5074
5075 (define_split
5076 [(set (match_operand:SI 0 "arith_reg_dest" "")
5077 (match_operand:SI 1 "immediate_operand" ""))]
5078 "TARGET_SHMEDIA && reload_completed
5079 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5080 [(const_int 0)]
5081 "
5082 {
5083 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5084
5085 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5086
5087 DONE;
5088 }")
5089
5090 (define_split
5091 [(set (match_operand:SI 0 "register_operand" "")
5092 (match_operand:SI 1 "immediate_operand" ""))]
5093 "TARGET_SHMEDIA && reload_completed
5094 && ((CONST_INT_P (operands[1])
5095 && ! satisfies_constraint_I16 (operands[1]))
5096 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5097 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5098
5099 (define_expand "movsi"
5100 [(set (match_operand:SI 0 "general_movdst_operand" "")
5101 (match_operand:SI 1 "general_movsrc_operand" ""))]
5102 ""
5103 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5104
5105 (define_expand "ic_invalidate_line"
5106 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5107 (match_dup 1)] UNSPEC_ICACHE)
5108 (clobber (scratch:SI))])]
5109 "TARGET_HARD_SH4 || TARGET_SH5"
5110 "
5111 {
5112 if (TARGET_SHMEDIA)
5113 {
5114 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5115 DONE;
5116 }
5117 else if (TARGET_SHCOMPACT)
5118 {
5119 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5120 operands[1] = force_reg (Pmode, operands[1]);
5121 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5122 DONE;
5123 }
5124 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5125 {
5126 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5127 DONE;
5128 }
5129 operands[0] = force_reg (Pmode, operands[0]);
5130 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5131 Pmode)));
5132 }")
5133
5134 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5135 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5136 ;; the requirement *1*00 for associative address writes. The alignment of
5137 ;; %0 implies that its least significant bit is cleared,
5138 ;; thus we clear the V bit of a matching entry if there is one.
5139 (define_insn "ic_invalidate_line_i"
5140 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5141 (match_operand:SI 1 "register_operand" "r")]
5142 UNSPEC_ICACHE)
5143 (clobber (match_scratch:SI 2 "=&r"))]
5144 "TARGET_HARD_SH4"
5145 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5146 [(set_attr "length" "8")
5147 (set_attr "type" "cwb")])
5148
5149 (define_insn "ic_invalidate_line_sh4a"
5150 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5151 UNSPEC_ICACHE)]
5152 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5153 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5154 [(set_attr "length" "16")
5155 (set_attr "type" "cwb")])
5156
5157 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5158 ;; an add in the code that calculates the address.
5159 (define_insn "ic_invalidate_line_media"
5160 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5161 UNSPEC_ICACHE)]
5162 "TARGET_SHMEDIA"
5163 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5164 [(set_attr "length" "16")
5165 (set_attr "type" "invalidate_line_media")])
5166
5167 (define_insn "ic_invalidate_line_compact"
5168 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5169 (match_operand:SI 1 "register_operand" "r")]
5170 UNSPEC_ICACHE)
5171 (clobber (reg:SI PR_REG))]
5172 "TARGET_SHCOMPACT"
5173 "jsr @%1%#"
5174 [(set_attr "type" "sfunc")
5175 (set_attr "needs_delay_slot" "yes")])
5176
5177 (define_expand "initialize_trampoline"
5178 [(match_operand:SI 0 "" "")
5179 (match_operand:SI 1 "" "")
5180 (match_operand:SI 2 "" "")]
5181 "TARGET_SHCOMPACT"
5182 "
5183 {
5184 rtx sfun, tramp;
5185
5186 tramp = force_reg (Pmode, operands[0]);
5187 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5188 SFUNC_STATIC));
5189 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5190 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5191
5192 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5193 DONE;
5194 }")
5195
5196 (define_insn "initialize_trampoline_compact"
5197 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5198 (match_operand:SI 1 "register_operand" "r")
5199 (reg:SI R2_REG) (reg:SI R3_REG)]
5200 UNSPEC_INIT_TRAMP)
5201
5202 (clobber (reg:SI PR_REG))]
5203 "TARGET_SHCOMPACT"
5204 "jsr @%1%#"
5205 [(set_attr "type" "sfunc")
5206 (set_attr "needs_delay_slot" "yes")])
5207
5208 (define_insn "movqi_i"
5209 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5210 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5211 "TARGET_SH1
5212 && (arith_reg_operand (operands[0], QImode)
5213 || arith_reg_operand (operands[1], QImode))"
5214 "@
5215 mov %1,%0
5216 mov %1,%0
5217 mov.b %1,%0
5218 mov.b %1,%0
5219 movt %0
5220 sts %1,%0
5221 lds %1,%0"
5222 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5223 (set_attr_alternative "length"
5224 [(const_int 2)
5225 (const_int 2)
5226 (if_then_else
5227 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5228 (const_int 4) (const_int 2))
5229 (if_then_else
5230 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5231 (const_int 4) (const_int 2))
5232 (const_int 2)
5233 (const_int 2)
5234 (const_int 2)])])
5235
5236 (define_insn "*movqi_media"
5237 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5238 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5239 "TARGET_SHMEDIA
5240 && (arith_reg_operand (operands[0], QImode)
5241 || extend_reg_or_0_operand (operands[1], QImode))"
5242 "@
5243 add.l %1, r63, %0
5244 movi %1, %0
5245 ld%M1.ub %m1, %0
5246 st%M0.b %m0, %N1"
5247 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5248 (set (attr "highpart")
5249 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5250 (const_string "user")]
5251 (const_string "ignore")))])
5252
5253 (define_expand "movqi"
5254 [(set (match_operand:QI 0 "general_operand" "")
5255 (match_operand:QI 1 "general_operand" ""))]
5256 ""
5257 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5258
5259 (define_expand "reload_inqi"
5260 [(set (match_operand:SI 2 "" "=&r")
5261 (match_operand:QI 1 "inqhi_operand" ""))
5262 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5263 (truncate:QI (match_dup 3)))]
5264 "TARGET_SHMEDIA"
5265 "
5266 {
5267 rtx inner = XEXP (operands[1], 0);
5268 int regno = REGNO (inner);
5269
5270 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5271 operands[1] = gen_rtx_REG (SImode, regno);
5272 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5273 }")
5274
5275 /* When storing r0, we have to avoid reg+reg addressing. */
5276 (define_insn "movhi_i"
5277 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5278 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5279 "TARGET_SH1
5280 && (arith_reg_operand (operands[0], HImode)
5281 || arith_reg_operand (operands[1], HImode))
5282 && (!MEM_P (operands[0])
5283 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5284 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5285 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5286 "@
5287 mov.w %1,%0
5288 mov %1,%0
5289 mov.w %1,%0
5290 movt %0
5291 mov.w %1,%0
5292 sts %1,%0
5293 lds %1,%0
5294 fake %1,%0"
5295 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5296
5297 (define_insn "*movhi_media"
5298 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5299 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5300 "TARGET_SHMEDIA
5301 && (arith_reg_operand (operands[0], HImode)
5302 || arith_reg_or_0_operand (operands[1], HImode))"
5303 "@
5304 add.l %1, r63, %0
5305 movi %1, %0
5306 #
5307 ld%M1.w %m1, %0
5308 st%M0.w %m0, %N1"
5309 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5310 (set (attr "highpart")
5311 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5312 (const_string "user")]
5313 (const_string "ignore")))])
5314
5315 (define_split
5316 [(set (match_operand:HI 0 "register_operand" "")
5317 (match_operand:HI 1 "immediate_operand" ""))]
5318 "TARGET_SHMEDIA && reload_completed
5319 && ! satisfies_constraint_I16 (operands[1])"
5320 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5321
5322 (define_expand "movhi"
5323 [(set (match_operand:HI 0 "general_movdst_operand" "")
5324 (match_operand:HI 1 "general_movsrc_operand" ""))]
5325 ""
5326 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5327
5328 (define_expand "reload_inhi"
5329 [(set (match_operand:SI 2 "" "=&r")
5330 (match_operand:HI 1 "inqhi_operand" ""))
5331 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5332 (truncate:HI (match_dup 3)))]
5333 "TARGET_SHMEDIA"
5334 "
5335 {
5336 rtx inner = XEXP (operands[1], 0);
5337 int regno = REGNO (inner);
5338
5339 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5340 operands[1] = gen_rtx_REG (SImode, regno);
5341 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5342 }")
5343
5344 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5345 ;; compiled with -m2 -ml -O3 -funroll-loops
5346 (define_insn "*movdi_i"
5347 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5348 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5349 "TARGET_SH1
5350 && (arith_reg_operand (operands[0], DImode)
5351 || arith_reg_operand (operands[1], DImode))"
5352 "* return output_movedouble (insn, operands, DImode);"
5353 [(set_attr "length" "4")
5354 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5355
5356 ;; If the output is a register and the input is memory or a register, we have
5357 ;; to be careful and see which word needs to be loaded first.
5358
5359 (define_split
5360 [(set (match_operand:DI 0 "general_movdst_operand" "")
5361 (match_operand:DI 1 "general_movsrc_operand" ""))]
5362 "TARGET_SH1 && reload_completed"
5363 [(set (match_dup 2) (match_dup 3))
5364 (set (match_dup 4) (match_dup 5))]
5365 "
5366 {
5367 int regno;
5368
5369 if ((MEM_P (operands[0])
5370 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5371 || (MEM_P (operands[1])
5372 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5373 FAIL;
5374
5375 switch (GET_CODE (operands[0]))
5376 {
5377 case REG:
5378 regno = REGNO (operands[0]);
5379 break;
5380 case SUBREG:
5381 regno = subreg_regno (operands[0]);
5382 break;
5383 case MEM:
5384 regno = -1;
5385 break;
5386 default:
5387 gcc_unreachable ();
5388 }
5389
5390 if (regno == -1
5391 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5392 {
5393 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5394 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5395 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5396 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5397 }
5398 else
5399 {
5400 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5401 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5402 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5403 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5404 }
5405
5406 if (operands[2] == 0 || operands[3] == 0
5407 || operands[4] == 0 || operands[5] == 0)
5408 FAIL;
5409 }")
5410
5411 ;; The '?'s in the following constraints may not reflect the time taken
5412 ;; to perform the move. They are there to discourage the use of floating-
5413 ;; point registers for storing integer values.
5414 (define_insn "*movdi_media"
5415 [(set (match_operand:DI 0 "general_movdst_operand"
5416 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5417 (match_operand:DI 1 "general_movsrc_operand"
5418 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5419 "TARGET_SHMEDIA_FPU
5420 && (register_operand (operands[0], DImode)
5421 || sh_register_operand (operands[1], DImode))"
5422 "@
5423 add %1, r63, %0
5424 movi %1, %0
5425 #
5426 ld%M1.q %m1, %0
5427 st%M0.q %m0, %N1
5428 fld%M1.d %m1, %0
5429 fst%M0.d %m0, %1
5430 fmov.qd %N1, %0
5431 fmov.dq %1, %0
5432 fmov.d %1, %0
5433 ptabs %1, %0
5434 gettr %1, %0
5435 pt %1, %0"
5436 [(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")
5437 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5438
5439 (define_insn "*movdi_media_nofpu"
5440 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5441 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5442 "TARGET_SHMEDIA
5443 && (register_operand (operands[0], DImode)
5444 || sh_register_operand (operands[1], DImode))"
5445 "@
5446 add %1, r63, %0
5447 movi %1, %0
5448 #
5449 ld%M1.q %m1, %0
5450 st%M0.q %m0, %N1
5451 ptabs %1, %0
5452 gettr %1, %0
5453 pt %1, %0"
5454 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5455 (set_attr "length" "4,4,16,4,4,4,4,*")])
5456
5457 (define_insn "*movdi_media_I16"
5458 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5459 (match_operand:DI 1 "const_int_operand" "I16"))]
5460 "TARGET_SHMEDIA && reload_completed"
5461 "movi %1, %0"
5462 [(set_attr "type" "arith_media")
5463 (set_attr "length" "4")])
5464
5465 (define_split
5466 [(set (match_operand:DI 0 "arith_reg_dest" "")
5467 (match_operand:DI 1 "immediate_operand" ""))]
5468 "TARGET_SHMEDIA && reload_completed
5469 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5470 [(set (match_dup 0) (match_dup 1))]
5471 "
5472 {
5473 rtx insn;
5474
5475 if (TARGET_SHMEDIA64)
5476 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5477 else
5478 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5479
5480 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5481
5482 DONE;
5483 }")
5484
5485 (define_expand "movdi_const"
5486 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5487 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5488 (const_int 48)] UNSPEC_EXTRACT_S16)))
5489 (set (match_dup 0)
5490 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5491 (const:DI (unspec:DI [(match_dup 1)
5492 (const_int 32)] UNSPEC_EXTRACT_U16))))
5493 (set (match_dup 0)
5494 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5495 (const:DI (unspec:DI [(match_dup 1)
5496 (const_int 16)] UNSPEC_EXTRACT_U16))))
5497 (set (match_dup 0)
5498 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5499 (const:DI (unspec:DI [(match_dup 1)
5500 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5501 "TARGET_SHMEDIA64 && reload_completed
5502 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5503 "
5504 {
5505 sh_mark_label (operands[1], 4);
5506 }")
5507
5508 (define_expand "movdi_const_32bit"
5509 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5510 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5511 (const_int 16)] UNSPEC_EXTRACT_S16)))
5512 (set (match_dup 0)
5513 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5514 (const:DI (unspec:DI [(match_dup 1)
5515 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5516 "TARGET_SHMEDIA32 && reload_completed
5517 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5518 "
5519 {
5520 sh_mark_label (operands[1], 2);
5521 }")
5522
5523 (define_expand "movdi_const_16bit"
5524 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5525 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5526 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5527 "TARGET_SHMEDIA && flag_pic && reload_completed
5528 && GET_CODE (operands[1]) == SYMBOL_REF"
5529 "")
5530
5531 (define_split
5532 [(set (match_operand:DI 0 "ext_dest_operand" "")
5533 (match_operand:DI 1 "immediate_operand" ""))]
5534 "TARGET_SHMEDIA && reload_completed
5535 && CONST_INT_P (operands[1])
5536 && ! satisfies_constraint_I16 (operands[1])"
5537 [(set (match_dup 0) (match_dup 2))
5538 (match_dup 1)]
5539 "
5540 {
5541 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5542 unsigned HOST_WIDE_INT low = val;
5543 unsigned HOST_WIDE_INT high = val;
5544 unsigned HOST_WIDE_INT sign;
5545 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5546
5547 /* Zero-extend the 16 least-significant bits. */
5548 low &= 0xffff;
5549
5550 /* Arithmetic shift right the word by 16 bits. */
5551 high >>= 16;
5552 if (GET_CODE (operands[0]) == SUBREG
5553 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5554 {
5555 high &= 0xffff;
5556 high ^= 0x8000;
5557 high -= 0x8000;
5558 }
5559 else
5560 {
5561 sign = 1;
5562 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5563 high ^= sign;
5564 high -= sign;
5565 }
5566 do
5567 {
5568 /* If we can't generate the constant with a two-insn movi / shori
5569 sequence, try some other strategies. */
5570 if (! CONST_OK_FOR_I16 (high))
5571 {
5572 /* Try constant load / left shift. We know VAL != 0. */
5573 val2 = val ^ (val-1);
5574 if (val2 > 0x1ffff)
5575 {
5576 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5577
5578 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5579 || (! CONST_OK_FOR_I16 (high >> 16)
5580 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5581 {
5582 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5583 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5584 GEN_INT (trailing_zeroes));
5585 break;
5586 }
5587 }
5588 /* Try constant load / right shift. */
5589 val2 = (val >> 15) + 1;
5590 if (val2 == (val2 & -val2))
5591 {
5592 int shift = 49 - exact_log2 (val2);
5593
5594 val2 = trunc_int_for_mode (val << shift, DImode);
5595 if (CONST_OK_FOR_I16 (val2))
5596 {
5597 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5598 GEN_INT (shift));
5599 break;
5600 }
5601 }
5602 /* Try mperm.w . */
5603 val2 = val & 0xffff;
5604 if ((val >> 16 & 0xffff) == val2
5605 && (val >> 32 & 0xffff) == val2
5606 && (val >> 48 & 0xffff) == val2)
5607 {
5608 val2 = (HOST_WIDE_INT) val >> 48;
5609 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5610 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5611 break;
5612 }
5613 /* Try movi / mshflo.l */
5614 val2 = (HOST_WIDE_INT) val >> 32;
5615 if (val2 == ((unsigned HOST_WIDE_INT)
5616 trunc_int_for_mode (val, SImode)))
5617 {
5618 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5619 operands[0]);
5620 break;
5621 }
5622 /* Try movi / mshflo.l w/ r63. */
5623 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5624 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5625 {
5626 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5627 const0_rtx);
5628 break;
5629 }
5630 }
5631 val2 = high;
5632 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5633 }
5634 while (0);
5635 operands[2] = GEN_INT (val2);
5636 }")
5637
5638 (define_split
5639 [(set (match_operand:DI 0 "ext_dest_operand" "")
5640 (match_operand:DI 1 "immediate_operand" ""))]
5641 "TARGET_SHMEDIA && reload_completed
5642 && GET_CODE (operands[1]) == CONST_DOUBLE"
5643 [(set (match_dup 0) (match_dup 2))
5644 (set (match_dup 0)
5645 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5646 "
5647 {
5648 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5649 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5650 unsigned HOST_WIDE_INT val = low;
5651 unsigned HOST_WIDE_INT sign;
5652
5653 /* Zero-extend the 16 least-significant bits. */
5654 val &= 0xffff;
5655 operands[1] = GEN_INT (val);
5656
5657 /* Arithmetic shift right the double-word by 16 bits. */
5658 low >>= 16;
5659 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5660 high >>= 16;
5661 sign = 1;
5662 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5663 high ^= sign;
5664 high -= sign;
5665
5666 /* This will only be true if high is a sign-extension of low, i.e.,
5667 it must be either 0 or (unsigned)-1, and be zero iff the
5668 most-significant bit of low is set. */
5669 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5670 operands[2] = GEN_INT (low);
5671 else
5672 operands[2] = immed_double_const (low, high, DImode);
5673 }")
5674
5675 (define_insn "shori_media"
5676 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5677 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5678 (const_int 16))
5679 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5680 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5681 "@
5682 shori %u2, %0
5683 #"
5684 [(set_attr "type" "arith_media,*")])
5685
5686 (define_insn "*shori_media_si"
5687 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5688 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5689 (const_int 16))
5690 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5691 "TARGET_SHMEDIA"
5692 "shori %u2, %0")
5693
5694 (define_expand "movdi"
5695 [(set (match_operand:DI 0 "general_movdst_operand" "")
5696 (match_operand:DI 1 "general_movsrc_operand" ""))]
5697 ""
5698 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5699
5700 (define_insn "movdf_media"
5701 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5702 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5703 "TARGET_SHMEDIA_FPU
5704 && (register_operand (operands[0], DFmode)
5705 || sh_register_operand (operands[1], DFmode))"
5706 "@
5707 fmov.d %1, %0
5708 fmov.qd %N1, %0
5709 fmov.dq %1, %0
5710 add %1, r63, %0
5711 #
5712 fld%M1.d %m1, %0
5713 fst%M0.d %m0, %1
5714 ld%M1.q %m1, %0
5715 st%M0.q %m0, %N1"
5716 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5717
5718 (define_insn "movdf_media_nofpu"
5719 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5720 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5721 "TARGET_SHMEDIA
5722 && (register_operand (operands[0], DFmode)
5723 || sh_register_operand (operands[1], DFmode))"
5724 "@
5725 add %1, r63, %0
5726 #
5727 ld%M1.q %m1, %0
5728 st%M0.q %m0, %N1"
5729 [(set_attr "type" "arith_media,*,load_media,store_media")])
5730
5731 (define_split
5732 [(set (match_operand:DF 0 "arith_reg_dest" "")
5733 (match_operand:DF 1 "immediate_operand" ""))]
5734 "TARGET_SHMEDIA && reload_completed"
5735 [(set (match_dup 3) (match_dup 2))]
5736 "
5737 {
5738 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5739 long values[2];
5740 REAL_VALUE_TYPE value;
5741
5742 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5743 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5744
5745 if (HOST_BITS_PER_WIDE_INT >= 64)
5746 operands[2] = immed_double_const ((unsigned long) values[endian]
5747 | ((HOST_WIDE_INT) values[1 - endian]
5748 << 32), 0, DImode);
5749 else
5750 {
5751 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5752 operands[2] = immed_double_const (values[endian], values[1 - endian],
5753 DImode);
5754 }
5755
5756 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5757 }")
5758
5759 ;; ??? This should be a define expand.
5760
5761 (define_insn "movdf_k"
5762 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5763 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5764 "TARGET_SH1
5765 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5766 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5767 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5768 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5769 && (arith_reg_operand (operands[0], DFmode)
5770 || arith_reg_operand (operands[1], DFmode))"
5771 "* return output_movedouble (insn, operands, DFmode);"
5772 [(set_attr "length" "4")
5773 (set_attr "type" "move,pcload,load,store")])
5774
5775 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5776 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5777 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5778 ;; the d/m/c/X alternative, which is split later into single-precision
5779 ;; instructions. And when not optimizing, no splits are done before fixing
5780 ;; up pcloads, so we need usable length information for that.
5781 (define_insn "movdf_i4"
5782 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5783 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5784 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5785 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5786 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5787 && (arith_reg_operand (operands[0], DFmode)
5788 || arith_reg_operand (operands[1], DFmode))"
5789 {
5790 switch (which_alternative)
5791 {
5792 case 0:
5793 if (TARGET_FMOVD)
5794 return "fmov %1,%0";
5795 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5796 return "fmov %R1,%R0\n\tfmov %S1,%S0";
5797 else
5798 return "fmov %S1,%S0\n\tfmov %R1,%R0";
5799 case 3:
5800 case 4:
5801 return "fmov.d %1,%0";
5802 default:
5803 return "#";
5804 }
5805 }
5806 [(set_attr_alternative "length"
5807 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5808 (const_int 4)
5809 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5810 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5811 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5812 (const_int 4)
5813 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5814 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5815 ;; increment or decrement r15 explicitly.
5816 (if_then_else
5817 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5818 (const_int 10) (const_int 8))
5819 (if_then_else
5820 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5821 (const_int 10) (const_int 8))])
5822 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5823 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5824 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5825 (const_string "double")
5826 (const_string "none")))])
5827
5828 ;; Moving DFmode between fp/general registers through memory
5829 ;; (the top of the stack) is faster than moving through fpul even for
5830 ;; little endian. Because the type of an instruction is important for its
5831 ;; scheduling, it is beneficial to split these operations, rather than
5832 ;; emitting them in one single chunk, even if this will expose a stack
5833 ;; use that will prevent scheduling of other stack accesses beyond this
5834 ;; instruction.
5835 (define_split
5836 [(set (match_operand:DF 0 "register_operand" "")
5837 (match_operand:DF 1 "register_operand" ""))
5838 (use (match_operand:PSI 2 "fpscr_operand" ""))
5839 (clobber (match_scratch:SI 3 "=X"))]
5840 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5841 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5842 [(const_int 0)]
5843 "
5844 {
5845 rtx insn, tos;
5846
5847 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5848 {
5849 emit_move_insn (stack_pointer_rtx,
5850 plus_constant (stack_pointer_rtx, -8));
5851 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5852 }
5853 else
5854 tos = gen_tmp_stack_mem (DFmode,
5855 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5856 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5857 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5858 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5859 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5860 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5861 else
5862 tos = gen_tmp_stack_mem (DFmode,
5863 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5864 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5865 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5866 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5867 else
5868 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5869 DONE;
5870 }")
5871
5872 ;; local-alloc sometimes allocates scratch registers even when not required,
5873 ;; so we must be prepared to handle these.
5874
5875 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5876 (define_split
5877 [(set (match_operand:DF 0 "general_movdst_operand" "")
5878 (match_operand:DF 1 "general_movsrc_operand" ""))
5879 (use (match_operand:PSI 2 "fpscr_operand" ""))
5880 (clobber (match_scratch:SI 3 ""))]
5881 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5882 && reload_completed
5883 && true_regnum (operands[0]) < 16
5884 && true_regnum (operands[1]) < 16"
5885 [(set (match_dup 0) (match_dup 1))]
5886 "
5887 {
5888 /* If this was a reg <-> mem operation with base + index reg addressing,
5889 we have to handle this in a special way. */
5890 rtx mem = operands[0];
5891 int store_p = 1;
5892 if (! memory_operand (mem, DFmode))
5893 {
5894 mem = operands[1];
5895 store_p = 0;
5896 }
5897 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5898 mem = SUBREG_REG (mem);
5899 if (MEM_P (mem))
5900 {
5901 rtx addr = XEXP (mem, 0);
5902 if (GET_CODE (addr) == PLUS
5903 && REG_P (XEXP (addr, 0))
5904 && REG_P (XEXP (addr, 1)))
5905 {
5906 int offset;
5907 rtx reg0 = gen_rtx_REG (Pmode, 0);
5908 rtx regop = operands[store_p], word0 ,word1;
5909
5910 if (GET_CODE (regop) == SUBREG)
5911 alter_subreg (&regop);
5912 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5913 offset = 2;
5914 else
5915 offset = 4;
5916 mem = copy_rtx (mem);
5917 PUT_MODE (mem, SImode);
5918 word0 = gen_rtx_SUBREG (SImode, regop, 0);
5919 alter_subreg (&word0);
5920 word1 = gen_rtx_SUBREG (SImode, regop, 4);
5921 alter_subreg (&word1);
5922 if (store_p || ! refers_to_regno_p (REGNO (word0),
5923 REGNO (word0) + 1, addr, 0))
5924 {
5925 emit_insn (store_p
5926 ? gen_movsi_ie (mem, word0)
5927 : gen_movsi_ie (word0, mem));
5928 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5929 mem = copy_rtx (mem);
5930 emit_insn (store_p
5931 ? gen_movsi_ie (mem, word1)
5932 : gen_movsi_ie (word1, mem));
5933 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5934 }
5935 else
5936 {
5937 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5938 emit_insn (gen_movsi_ie (word1, mem));
5939 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5940 mem = copy_rtx (mem);
5941 emit_insn (gen_movsi_ie (word0, mem));
5942 }
5943 DONE;
5944 }
5945 }
5946 }")
5947
5948 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5949 (define_split
5950 [(set (match_operand:DF 0 "register_operand" "")
5951 (match_operand:DF 1 "memory_operand" ""))
5952 (use (match_operand:PSI 2 "fpscr_operand" ""))
5953 (clobber (reg:SI R0_REG))]
5954 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5955 [(parallel [(set (match_dup 0) (match_dup 1))
5956 (use (match_dup 2))
5957 (clobber (scratch:SI))])]
5958 "")
5959
5960 (define_expand "reload_indf__frn"
5961 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5962 (match_operand:DF 1 "immediate_operand" "FQ"))
5963 (use (reg:PSI FPSCR_REG))
5964 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5965 "TARGET_SH1"
5966 "")
5967
5968 (define_expand "reload_outdf__RnFRm"
5969 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5970 (match_operand:DF 1 "register_operand" "af,r"))
5971 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5972 "TARGET_SH1"
5973 "")
5974
5975 ;; Simplify no-op moves.
5976 (define_split
5977 [(set (match_operand:SF 0 "register_operand" "")
5978 (match_operand:SF 1 "register_operand" ""))
5979 (use (match_operand:PSI 2 "fpscr_operand" ""))
5980 (clobber (match_scratch:SI 3 ""))]
5981 "TARGET_SH2E && reload_completed
5982 && true_regnum (operands[0]) == true_regnum (operands[1])"
5983 [(set (match_dup 0) (match_dup 0))]
5984 "")
5985
5986 ;; fmovd substitute post-reload splits
5987 (define_split
5988 [(set (match_operand:DF 0 "register_operand" "")
5989 (match_operand:DF 1 "register_operand" ""))
5990 (use (match_operand:PSI 2 "fpscr_operand" ""))
5991 (clobber (match_scratch:SI 3 ""))]
5992 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5993 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5994 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5995 [(const_int 0)]
5996 "
5997 {
5998 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5999 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6000 gen_rtx_REG (SFmode, src), operands[2]));
6001 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6002 gen_rtx_REG (SFmode, src + 1), operands[2]));
6003 DONE;
6004 }")
6005
6006 (define_split
6007 [(set (match_operand:DF 0 "register_operand" "")
6008 (mem:DF (match_operand:SI 1 "register_operand" "")))
6009 (use (match_operand:PSI 2 "fpscr_operand" ""))
6010 (clobber (match_scratch:SI 3 ""))]
6011 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6012 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6013 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6014 [(const_int 0)]
6015 "
6016 {
6017 int regno = true_regnum (operands[0]);
6018 rtx insn;
6019 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6020 rtx mem2
6021 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6022 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6023 regno + !! TARGET_LITTLE_ENDIAN),
6024 mem2, operands[2]));
6025 add_reg_note (insn, REG_INC, operands[1]);
6026 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6027 regno + ! TARGET_LITTLE_ENDIAN),
6028 change_address (mem, SFmode, NULL_RTX),
6029 operands[2]));
6030 DONE;
6031 }")
6032
6033 (define_split
6034 [(set (match_operand:DF 0 "register_operand" "")
6035 (match_operand:DF 1 "memory_operand" ""))
6036 (use (match_operand:PSI 2 "fpscr_operand" ""))
6037 (clobber (match_scratch:SI 3 ""))]
6038 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6039 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6040 [(const_int 0)]
6041 {
6042 int regno = true_regnum (operands[0]);
6043 rtx addr, insn;
6044 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6045 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6046 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6047
6048 operands[1] = copy_rtx (mem2);
6049 addr = XEXP (mem2, 0);
6050
6051 switch (GET_CODE (addr))
6052 {
6053 case REG:
6054 /* This is complicated. If the register is an arithmetic register
6055 we can just fall through to the REG+DISP case below. Otherwise
6056 we have to use a combination of POST_INC and REG addressing... */
6057 if (! arith_reg_operand (operands[1], SFmode))
6058 {
6059 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6060 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6061 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6062
6063 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6064
6065 /* If we have modified the stack pointer, the value that we have
6066 read with post-increment might be modified by an interrupt,
6067 so write it back. */
6068 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6069 emit_insn (gen_push_e (reg0));
6070 else
6071 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6072 break;
6073 }
6074 /* Fall through. */
6075
6076 case PLUS:
6077 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6078 operands[1] = copy_rtx (operands[1]);
6079 XEXP (operands[1], 0) = plus_constant (addr, 4);
6080 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6081 break;
6082
6083 case POST_INC:
6084 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6085 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6086
6087 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6088 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6089 break;
6090
6091 default:
6092 debug_rtx (addr);
6093 gcc_unreachable ();
6094 }
6095
6096 DONE;
6097 })
6098
6099 (define_split
6100 [(set (match_operand:DF 0 "memory_operand" "")
6101 (match_operand:DF 1 "register_operand" ""))
6102 (use (match_operand:PSI 2 "fpscr_operand" ""))
6103 (clobber (match_scratch:SI 3 ""))]
6104 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6105 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6106 [(const_int 0)]
6107 {
6108 int regno = true_regnum (operands[1]);
6109 rtx insn, addr;
6110 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6111 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6112
6113 operands[0] = copy_rtx (operands[0]);
6114 PUT_MODE (operands[0], SFmode);
6115 addr = XEXP (operands[0], 0);
6116
6117 switch (GET_CODE (addr))
6118 {
6119 case REG:
6120 /* This is complicated. If the register is an arithmetic register
6121 we can just fall through to the REG+DISP case below. Otherwise
6122 we have to use a combination of REG and PRE_DEC addressing... */
6123 if (! arith_reg_operand (operands[0], SFmode))
6124 {
6125 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6126 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6127
6128 operands[0] = copy_rtx (operands[0]);
6129 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6130
6131 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6132 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6133 break;
6134 }
6135 /* Fall through. */
6136
6137 case PLUS:
6138 /* Since REG+DISP addressing has already been decided upon by gcc
6139 we can rely upon it having chosen an arithmetic register as the
6140 register component of the address. Just emit the lower numbered
6141 register first, to the lower address, then the higher numbered
6142 register to the higher address. */
6143 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6144
6145 operands[0] = copy_rtx (operands[0]);
6146 XEXP (operands[0], 0) = plus_constant (addr, 4);
6147
6148 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6149 break;
6150
6151 case PRE_DEC:
6152 /* This is easy. Output the word to go to the higher address
6153 first (ie the word in the higher numbered register) then the
6154 word to go to the lower address. */
6155
6156 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6157 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6158
6159 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6160 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6161 break;
6162
6163 default:
6164 /* FAIL; */
6165 debug_rtx (addr);
6166 gcc_unreachable ();
6167 }
6168
6169 DONE;
6170 })
6171
6172 ;; If the output is a register and the input is memory or a register, we have
6173 ;; to be careful and see which word needs to be loaded first.
6174
6175 (define_split
6176 [(set (match_operand:DF 0 "general_movdst_operand" "")
6177 (match_operand:DF 1 "general_movsrc_operand" ""))]
6178 "TARGET_SH1 && reload_completed"
6179 [(set (match_dup 2) (match_dup 3))
6180 (set (match_dup 4) (match_dup 5))]
6181 "
6182 {
6183 int regno;
6184
6185 if ((MEM_P (operands[0])
6186 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6187 || (MEM_P (operands[1])
6188 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6189 FAIL;
6190
6191 switch (GET_CODE (operands[0]))
6192 {
6193 case REG:
6194 regno = REGNO (operands[0]);
6195 break;
6196 case SUBREG:
6197 regno = subreg_regno (operands[0]);
6198 break;
6199 case MEM:
6200 regno = -1;
6201 break;
6202 default:
6203 gcc_unreachable ();
6204 }
6205
6206 if (regno == -1
6207 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6208 {
6209 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6210 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6211 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6212 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6213 }
6214 else
6215 {
6216 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6217 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6218 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6219 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6220 }
6221
6222 if (operands[2] == 0 || operands[3] == 0
6223 || operands[4] == 0 || operands[5] == 0)
6224 FAIL;
6225 }")
6226
6227 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6228 ;; used only once, let combine add in the index again.
6229
6230 (define_split
6231 [(set (match_operand:SI 0 "register_operand" "")
6232 (match_operand:SI 1 "" ""))
6233 (clobber (match_operand 2 "register_operand" ""))]
6234 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6235 && ALLOW_INDEXED_ADDRESS"
6236 [(use (reg:SI R0_REG))]
6237 "
6238 {
6239 rtx addr, reg, const_int;
6240
6241 if (!MEM_P (operands[1]))
6242 FAIL;
6243 addr = XEXP (operands[1], 0);
6244 if (GET_CODE (addr) != PLUS)
6245 FAIL;
6246 reg = XEXP (addr, 0);
6247 const_int = XEXP (addr, 1);
6248 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6249 && CONST_INT_P (const_int)))
6250 FAIL;
6251 emit_move_insn (operands[2], const_int);
6252 emit_move_insn (operands[0],
6253 change_address (operands[1], VOIDmode,
6254 gen_rtx_PLUS (SImode, reg, operands[2])));
6255 DONE;
6256 }")
6257
6258 (define_split
6259 [(set (match_operand:SI 1 "" "")
6260 (match_operand:SI 0 "register_operand" ""))
6261 (clobber (match_operand 2 "register_operand" ""))]
6262 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6263 && ALLOW_INDEXED_ADDRESS"
6264 [(use (reg:SI R0_REG))]
6265 "
6266 {
6267 rtx addr, reg, const_int;
6268
6269 if (!MEM_P (operands[1]))
6270 FAIL;
6271 addr = XEXP (operands[1], 0);
6272 if (GET_CODE (addr) != PLUS)
6273 FAIL;
6274 reg = XEXP (addr, 0);
6275 const_int = XEXP (addr, 1);
6276 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6277 && CONST_INT_P (const_int)))
6278 FAIL;
6279 emit_move_insn (operands[2], const_int);
6280 emit_move_insn (change_address (operands[1], VOIDmode,
6281 gen_rtx_PLUS (SImode, reg, operands[2])),
6282 operands[0]);
6283 DONE;
6284 }")
6285
6286 (define_expand "movdf"
6287 [(set (match_operand:DF 0 "general_movdst_operand" "")
6288 (match_operand:DF 1 "general_movsrc_operand" ""))]
6289 ""
6290 "
6291 {
6292 if (prepare_move_operands (operands, DFmode)) DONE;
6293 if (TARGET_SHMEDIA)
6294 {
6295 if (TARGET_SHMEDIA_FPU)
6296 emit_insn (gen_movdf_media (operands[0], operands[1]));
6297 else
6298 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6299 DONE;
6300 }
6301 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6302 {
6303 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6304 DONE;
6305 }
6306 }")
6307
6308 ;;This is incompatible with the way gcc uses subregs.
6309 ;;(define_insn "movv2sf_i"
6310 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6311 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6312 ;; "TARGET_SHMEDIA_FPU
6313 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6314 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6315 ;; "@
6316 ;; #
6317 ;; fld%M1.p %m1, %0
6318 ;; fst%M0.p %m0, %1"
6319 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6320
6321 (define_insn_and_split "movv2sf_i"
6322 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6323 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6324 "TARGET_SHMEDIA_FPU"
6325 "#"
6326 "TARGET_SHMEDIA_FPU && reload_completed"
6327 [(set (match_dup 0) (match_dup 1))]
6328 "
6329 {
6330 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6331 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6332 }")
6333
6334 (define_expand "movv2sf"
6335 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6336 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6337 "TARGET_SHMEDIA_FPU"
6338 "
6339 {
6340 if (prepare_move_operands (operands, V2SFmode))
6341 DONE;
6342 }")
6343
6344 (define_expand "addv2sf3"
6345 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6346 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6347 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6348 "TARGET_SHMEDIA_FPU"
6349 "
6350 {
6351 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6352 DONE;
6353 }")
6354
6355 (define_expand "subv2sf3"
6356 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6357 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6358 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6359 "TARGET_SHMEDIA_FPU"
6360 "
6361 {
6362 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6363 DONE;
6364 }")
6365
6366 (define_expand "mulv2sf3"
6367 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6368 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6369 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6370 "TARGET_SHMEDIA_FPU"
6371 "
6372 {
6373 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6374 DONE;
6375 }")
6376
6377 (define_expand "divv2sf3"
6378 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6379 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6380 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6381 "TARGET_SHMEDIA_FPU"
6382 "
6383 {
6384 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6385 DONE;
6386 }")
6387
6388 (define_insn_and_split "*movv4sf_i"
6389 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6390 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6391 "TARGET_SHMEDIA_FPU"
6392 "#"
6393 "&& reload_completed"
6394 [(const_int 0)]
6395 "
6396 {
6397 int i;
6398
6399 for (i = 0; i < 4/2; i++)
6400 {
6401 rtx x, y;
6402
6403 if (MEM_P (operands[0]))
6404 x = adjust_address (operands[0], V2SFmode,
6405 i * GET_MODE_SIZE (V2SFmode));
6406 else
6407 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6408
6409 if (MEM_P (operands[1]))
6410 y = adjust_address (operands[1], V2SFmode,
6411 i * GET_MODE_SIZE (V2SFmode));
6412 else
6413 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6414
6415 emit_insn (gen_movv2sf_i (x, y));
6416 }
6417
6418 DONE;
6419 }"
6420 [(set_attr "length" "8")])
6421
6422 (define_expand "movv4sf"
6423 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6424 (match_operand:V4SF 1 "general_operand" ""))]
6425 "TARGET_SHMEDIA_FPU"
6426 "
6427 {
6428 if (prepare_move_operands (operands, V4SFmode))
6429 DONE;
6430 }")
6431
6432 (define_insn_and_split "*movv16sf_i"
6433 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6434 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6435 "TARGET_SHMEDIA_FPU"
6436 "#"
6437 "&& reload_completed"
6438 [(const_int 0)]
6439 "
6440 {
6441 int i;
6442
6443 for (i = 0; i < 16/2; i++)
6444 {
6445 rtx x,y;
6446
6447 if (MEM_P (operands[0]))
6448 x = adjust_address (operands[0], V2SFmode,
6449 i * GET_MODE_SIZE (V2SFmode));
6450 else
6451 {
6452 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6453 alter_subreg (&x);
6454 }
6455
6456 if (MEM_P (operands[1]))
6457 y = adjust_address (operands[1], V2SFmode,
6458 i * GET_MODE_SIZE (V2SFmode));
6459 else
6460 {
6461 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6462 alter_subreg (&y);
6463 }
6464
6465 emit_insn (gen_movv2sf_i (x, y));
6466 }
6467
6468 DONE;
6469 }"
6470 [(set_attr "length" "32")])
6471
6472 (define_expand "movv16sf"
6473 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6474 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6475 "TARGET_SHMEDIA_FPU"
6476 "
6477 {
6478 if (prepare_move_operands (operands, V16SFmode))
6479 DONE;
6480 }")
6481
6482 (define_insn "movsf_media"
6483 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6484 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6485 "TARGET_SHMEDIA_FPU
6486 && (register_operand (operands[0], SFmode)
6487 || sh_register_operand (operands[1], SFmode))"
6488 "@
6489 fmov.s %1, %0
6490 fmov.ls %N1, %0
6491 fmov.sl %1, %0
6492 add.l %1, r63, %0
6493 #
6494 fld%M1.s %m1, %0
6495 fst%M0.s %m0, %1
6496 ld%M1.l %m1, %0
6497 st%M0.l %m0, %N1"
6498 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6499 (set (attr "highpart")
6500 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6501 (const_string "user")]
6502 (const_string "ignore")))])
6503
6504 (define_insn "movsf_media_nofpu"
6505 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6506 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6507 "TARGET_SHMEDIA
6508 && (register_operand (operands[0], SFmode)
6509 || sh_register_operand (operands[1], SFmode))"
6510 "@
6511 add.l %1, r63, %0
6512 #
6513 ld%M1.l %m1, %0
6514 st%M0.l %m0, %N1"
6515 [(set_attr "type" "arith_media,*,load_media,store_media")
6516 (set (attr "highpart")
6517 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6518 (const_string "user")]
6519 (const_string "ignore")))])
6520
6521 (define_split
6522 [(set (match_operand:SF 0 "arith_reg_dest" "")
6523 (match_operand:SF 1 "immediate_operand" ""))]
6524 "TARGET_SHMEDIA && reload_completed
6525 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6526 [(set (match_dup 3) (match_dup 2))]
6527 "
6528 {
6529 long values;
6530 REAL_VALUE_TYPE value;
6531
6532 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6533 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6534 operands[2] = GEN_INT (values);
6535
6536 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6537 }")
6538
6539 (define_insn "movsf_i"
6540 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6541 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6542 "TARGET_SH1
6543 && (! TARGET_SH2E
6544 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6545 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6546 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6547 && (arith_reg_operand (operands[0], SFmode)
6548 || arith_reg_operand (operands[1], SFmode))"
6549 "@
6550 mov %1,%0
6551 mov #0,%0
6552 mov.l %1,%0
6553 mov.l %1,%0
6554 mov.l %1,%0
6555 lds %1,%0
6556 sts %1,%0"
6557 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6558
6559 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6560 ;; update_flow_info would not know where to put REG_EQUAL notes
6561 ;; when the destination changes mode.
6562 (define_insn "movsf_ie"
6563 [(set (match_operand:SF 0 "general_movdst_operand"
6564 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6565 (match_operand:SF 1 "general_movsrc_operand"
6566 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6567 (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"))
6568 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6569
6570 "TARGET_SH2E
6571 && (arith_reg_operand (operands[0], SFmode)
6572 || arith_reg_operand (operands[1], SFmode)
6573 || arith_reg_operand (operands[3], SImode)
6574 || (fpul_operand (operands[0], SFmode)
6575 && memory_operand (operands[1], SFmode)
6576 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6577 || (fpul_operand (operands[1], SFmode)
6578 && memory_operand (operands[0], SFmode)
6579 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6580 "@
6581 fmov %1,%0
6582 mov %1,%0
6583 fldi0 %0
6584 fldi1 %0
6585 #
6586 fmov.s %1,%0
6587 fmov.s %1,%0
6588 mov.l %1,%0
6589 mov.l %1,%0
6590 mov.l %1,%0
6591 fsts fpul,%0
6592 flds %1,fpul
6593 lds.l %1,%0
6594 #
6595 sts %1,%0
6596 lds %1,%0
6597 sts.l %1,%0
6598 lds.l %1,%0
6599 ! move optimized away"
6600 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6601 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6602 (set_attr_alternative "length"
6603 [(const_int 2)
6604 (const_int 2)
6605 (const_int 2)
6606 (const_int 2)
6607 (const_int 4)
6608 (if_then_else
6609 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6610 (const_int 4) (const_int 2))
6611 (if_then_else
6612 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6613 (const_int 4) (const_int 2))
6614 (const_int 2)
6615 (if_then_else
6616 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6617 (const_int 4) (const_int 2))
6618 (if_then_else
6619 (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6620 (const_int 4) (const_int 2))
6621 (const_int 2)
6622 (const_int 2)
6623 (const_int 2)
6624 (const_int 4)
6625 (const_int 2)
6626 (const_int 2)
6627 (const_int 2)
6628 (const_int 2)
6629 (const_int 0)])
6630 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6631 (const_string "single")
6632 (const_string "single")))])
6633
6634 (define_split
6635 [(set (match_operand:SF 0 "register_operand" "")
6636 (match_operand:SF 1 "register_operand" ""))
6637 (use (match_operand:PSI 2 "fpscr_operand" ""))
6638 (clobber (reg:SI FPUL_REG))]
6639 "TARGET_SH1"
6640 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6641 (use (match_dup 2))
6642 (clobber (scratch:SI))])
6643 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6644 (use (match_dup 2))
6645 (clobber (scratch:SI))])]
6646 "")
6647
6648 (define_expand "movsf"
6649 [(set (match_operand:SF 0 "general_movdst_operand" "")
6650 (match_operand:SF 1 "general_movsrc_operand" ""))]
6651 ""
6652 "
6653 {
6654 if (prepare_move_operands (operands, SFmode))
6655 DONE;
6656 if (TARGET_SHMEDIA)
6657 {
6658 if (TARGET_SHMEDIA_FPU)
6659 emit_insn (gen_movsf_media (operands[0], operands[1]));
6660 else
6661 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6662 DONE;
6663 }
6664 if (TARGET_SH2E)
6665 {
6666 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6667 DONE;
6668 }
6669 }")
6670
6671 (define_insn "mov_nop"
6672 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6673 "TARGET_SH2E"
6674 ""
6675 [(set_attr "length" "0")
6676 (set_attr "type" "nil")])
6677
6678 (define_expand "reload_insf__frn"
6679 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6680 (match_operand:SF 1 "immediate_operand" "FQ"))
6681 (use (reg:PSI FPSCR_REG))
6682 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6683 "TARGET_SH1"
6684 "")
6685
6686 (define_expand "reload_insi__i_fpul"
6687 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6688 (match_operand:SI 1 "immediate_operand" "i"))
6689 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6690 "TARGET_SH1"
6691 "")
6692
6693 (define_expand "ptabs"
6694 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6695 "TARGET_SHMEDIA"
6696 "
6697 {
6698 if (!TARGET_PT_FIXED)
6699 {
6700 rtx eq = operands[1];
6701
6702 /* ??? For canonical RTL we really should remove any CONST from EQ
6703 before wrapping it in the AND, and finally wrap the EQ into a
6704 const if is constant. However, for reload we must expose the
6705 input register or symbolic constant, and we can't have
6706 different insn structures outside of the operands for different
6707 alternatives of the same pattern. */
6708 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6709 GEN_INT (3));
6710 operands[1]
6711 = (gen_rtx_IF_THEN_ELSE
6712 (PDImode,
6713 eq,
6714 gen_rtx_MEM (PDImode, operands[1]),
6715 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6716 PDImode, operands[1])));
6717 }
6718 }")
6719
6720 ;; expanded by ptabs expander.
6721 (define_insn "*extendsipdi_media"
6722 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6723 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6724 "r,Csy")
6725 (const_int 3))
6726 (const_int 3))
6727 (mem:PDI (match_dup 1))
6728 (sign_extend:PDI (match_dup 1))))]
6729 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6730 "@
6731 ptabs %1, %0
6732 pt %1, %0"
6733 [(set_attr "type" "ptabs_media,pt_media")
6734 (set_attr "length" "4,*")])
6735
6736 (define_insn "*truncdipdi_media"
6737 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6738 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6739 "r,Csy")
6740 (const_int 3))
6741 (const_int 3))
6742 (mem:PDI (match_dup 1))
6743 (truncate:PDI (match_dup 1))))]
6744 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6745 "@
6746 ptabs %1, %0
6747 pt %1, %0"
6748 [(set_attr "type" "ptabs_media,pt_media")
6749 (set_attr "length" "4,*")])
6750
6751 (define_insn "*movsi_y"
6752 [(set (match_operand:SI 0 "register_operand" "=y,y")
6753 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6754 (clobber (match_scratch:SI 2 "=&z,r"))]
6755 "TARGET_SH2E
6756 && (reload_in_progress || reload_completed)"
6757 "#"
6758 [(set_attr "length" "4")
6759 (set_attr "type" "pcload,move")])
6760
6761 (define_split
6762 [(set (match_operand:SI 0 "register_operand" "")
6763 (match_operand:SI 1 "immediate_operand" ""))
6764 (clobber (match_operand:SI 2 "register_operand" ""))]
6765 "TARGET_SH1"
6766 [(set (match_dup 2) (match_dup 1))
6767 (set (match_dup 0) (match_dup 2))]
6768 "")
6769
6770 (define_split
6771 [(set (match_operand:SI 0 "register_operand" "")
6772 (match_operand:SI 1 "memory_operand" ""))
6773 (clobber (reg:SI R0_REG))]
6774 "TARGET_SH1"
6775 [(set (match_dup 0) (match_dup 1))]
6776 "")
6777 \f
6778 ;; ------------------------------------------------------------------------
6779 ;; Define the real conditional branch instructions.
6780 ;; ------------------------------------------------------------------------
6781
6782 (define_insn "branch_true"
6783 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6784 (label_ref (match_operand 0 "" ""))
6785 (pc)))]
6786 "TARGET_SH1"
6787 "* return output_branch (1, insn, operands);"
6788 [(set_attr "type" "cbranch")])
6789
6790 (define_insn "branch_false"
6791 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6792 (label_ref (match_operand 0 "" ""))
6793 (pc)))]
6794 "TARGET_SH1"
6795 "* return output_branch (0, insn, operands);"
6796 [(set_attr "type" "cbranch")])
6797
6798 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6799 ;; which destination is too far away.
6800 ;; The const_int_operand is distinct for each branch target; it avoids
6801 ;; unwanted matches with redundant_insn.
6802 (define_insn "block_branch_redirect"
6803 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6804 "TARGET_SH1"
6805 ""
6806 [(set_attr "length" "0")])
6807
6808 ;; This one has the additional purpose to record a possible scratch register
6809 ;; for the following branch.
6810 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6811 ;; because the insn then might be deemed dead and deleted. And we can't
6812 ;; make the use in the jump insn explicit because that would disable
6813 ;; delay slot scheduling from the target.
6814 (define_insn "indirect_jump_scratch"
6815 [(set (match_operand:SI 0 "register_operand" "=r")
6816 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6817 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6818 "TARGET_SH1"
6819 ""
6820 [(set_attr "length" "0")])
6821
6822 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6823 ;; being pulled into the delay slot of a condbranch that has been made to
6824 ;; jump around the unconditional jump because it was out of range.
6825 (define_insn "stuff_delay_slot"
6826 [(set (pc)
6827 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6828 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6829 "TARGET_SH1"
6830 ""
6831 [(set_attr "length" "0")
6832 (set_attr "cond_delay_slot" "yes")])
6833 \f
6834 ;; Conditional branch insns
6835
6836 (define_expand "cbranchint4_media"
6837 [(set (pc)
6838 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6839 [(match_operand 1 "" "")
6840 (match_operand 2 "" "")])
6841 (match_operand 3 "" "")
6842 (pc)))]
6843 "TARGET_SHMEDIA"
6844 "
6845 {
6846 enum machine_mode mode = GET_MODE (operands[1]);
6847 if (mode == VOIDmode)
6848 mode = GET_MODE (operands[2]);
6849 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6850 {
6851 operands[1] = force_reg (mode, operands[1]);
6852 if (CONSTANT_P (operands[2])
6853 && (! satisfies_constraint_I06 (operands[2])))
6854 operands[2] = force_reg (mode, operands[2]);
6855 }
6856 else
6857 {
6858 if (operands[1] != const0_rtx)
6859 operands[1] = force_reg (mode, operands[1]);
6860 if (operands[2] != const0_rtx)
6861 operands[2] = force_reg (mode, operands[2]);
6862 }
6863 switch (GET_CODE (operands[0]))
6864 {
6865 case LEU:
6866 case LE:
6867 case LTU:
6868 case LT:
6869 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6870 VOIDmode, operands[2], operands[1]);
6871 operands[1] = XEXP (operands[0], 0);
6872 operands[2] = XEXP (operands[0], 1);
6873 break;
6874 default:
6875 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6876 VOIDmode, operands[1], operands[2]);
6877 break;
6878 }
6879 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6880 }")
6881
6882 (define_expand "cbranchfp4_media"
6883 [(set (pc)
6884 (if_then_else (match_operator 0 "sh_float_comparison_operator"
6885 [(match_operand 1 "" "")
6886 (match_operand 2 "" "")])
6887 (match_operand 3 "" "")
6888 (pc)))]
6889 "TARGET_SHMEDIA"
6890 "
6891 {
6892 /* hack to generate same code. */
6893 rtx tmp_di = GET_CODE (operands[0]) == UNORDERED ? NULL : gen_reg_rtx (DImode);
6894 rtx tmp = gen_reg_rtx (SImode);
6895 rtx cmp;
6896 if (GET_CODE (operands[0]) == NE)
6897 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6898 else
6899 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6900 operands[1], operands[2]);
6901
6902 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6903 if (tmp_di) emit_insn (gen_extendsidi2 (tmp_di, tmp)); else tmp_di = tmp;
6904
6905 if (GET_CODE (cmp) == GET_CODE (operands[0]))
6906 operands[0] = gen_rtx_NE (VOIDmode, tmp_di, const0_rtx);
6907 else
6908 operands[0] = gen_rtx_EQ (VOIDmode, tmp_di, const0_rtx);
6909 operands[1] = tmp_di;
6910 operands[2] = const0_rtx;
6911 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6912 }")
6913
6914 (define_insn "*beq_media_i"
6915 [(set (pc)
6916 (if_then_else (match_operator 3 "equality_comparison_operator"
6917 [(match_operand:DI 1 "arith_reg_operand" "r,r")
6918 (match_operand:DI 2 "arith_operand" "r,I06")])
6919 (match_operand 0 "target_operand" "b,b")
6920 (pc)))]
6921 "TARGET_SHMEDIA"
6922 "@
6923 b%o3%' %1, %2, %0%>
6924 b%o3i%' %1, %2, %0%>"
6925 [(set_attr "type" "cbranch_media")])
6926
6927 (define_insn "*beq_media_i32"
6928 [(set (pc)
6929 (if_then_else (match_operator 3 "equality_comparison_operator"
6930 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6931 (match_operand:SI 2 "arith_operand" "r,I06")])
6932 (match_operand 0 "target_operand" "b,b")
6933 (pc)))]
6934 "TARGET_SHMEDIA"
6935 "@
6936 b%o3%' %1, %2, %0%>
6937 b%o3i%' %1, %2, %0%>"
6938 [(set_attr "type" "cbranch_media")])
6939
6940 (define_insn "*bgt_media_i"
6941 [(set (pc)
6942 (if_then_else (match_operator 3 "greater_comparison_operator"
6943 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6944 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6945 (match_operand 0 "target_operand" "b")
6946 (pc)))]
6947 "TARGET_SHMEDIA"
6948 "b%o3%' %N1, %N2, %0%>"
6949 [(set_attr "type" "cbranch_media")])
6950
6951 (define_insn "*bgt_media_i32"
6952 [(set (pc)
6953 (if_then_else (match_operator 3 "greater_comparison_operator"
6954 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6955 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6956 (match_operand 0 "target_operand" "b")
6957 (pc)))]
6958 "TARGET_SHMEDIA"
6959 "b%o3%' %N1, %N2, %0%>"
6960 [(set_attr "type" "cbranch_media")])
6961
6962 ;; These are only needed to make invert_jump() happy - otherwise, jump
6963 ;; optimization will be silently disabled.
6964 (define_insn "*blt_media_i"
6965 [(set (pc)
6966 (if_then_else (match_operator 3 "less_comparison_operator"
6967 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6968 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6969 (match_operand 0 "target_operand" "b")
6970 (pc)))]
6971 "TARGET_SHMEDIA"
6972 "b%o3%' %N2, %N1, %0%>"
6973 [(set_attr "type" "cbranch_media")])
6974
6975 (define_insn "*blt_media_i32"
6976 [(set (pc)
6977 (if_then_else (match_operator 3 "less_comparison_operator"
6978 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6979 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6980 (match_operand 0 "target_operand" "b")
6981 (pc)))]
6982 "TARGET_SHMEDIA"
6983 "b%o3%' %N2, %N1, %0%>"
6984 [(set_attr "type" "cbranch_media")])
6985
6986 ;; combiner splitter for test-and-branch on single bit in register. This
6987 ;; is endian dependent because the non-paradoxical subreg looks different
6988 ;; on big endian.
6989 (define_split
6990 [(set (pc)
6991 (if_then_else
6992 (match_operator 3 "equality_comparison_operator"
6993 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
6994 "extend_reg_operand" "")
6995 0)
6996 (const_int 1)
6997 (match_operand 2
6998 "const_int_operand" "")) 0)
6999 (const_int 0)])
7000 (match_operand 0 "target_operand" "")
7001 (pc)))
7002 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7003 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7004 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7005 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7006
7007 "
7008 {
7009 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7010 operands[6] = (GET_CODE (operands[3]) == EQ
7011 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7012 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7013 }")
7014
7015 ; operand 0 is the loop count pseudo register
7016 ; operand 1 is the number of loop iterations or 0 if it is unknown
7017 ; operand 2 is the maximum number of loop iterations
7018 ; operand 3 is the number of levels of enclosed loops
7019 ; operand 4 is the label to jump to at the top of the loop
7020
7021 (define_expand "doloop_end"
7022 [(parallel [(set (pc) (if_then_else
7023 (ne:SI (match_operand:SI 0 "" "")
7024 (const_int 1))
7025 (label_ref (match_operand 4 "" ""))
7026 (pc)))
7027 (set (match_dup 0)
7028 (plus:SI (match_dup 0) (const_int -1)))
7029 (clobber (reg:SI T_REG))])]
7030 "TARGET_SH2"
7031 "
7032 {
7033 if (GET_MODE (operands[0]) != SImode)
7034 FAIL;
7035 }
7036 ")
7037
7038 (define_insn_and_split "doloop_end_split"
7039 [(set (pc)
7040 (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7041 (const_int 1))
7042 (label_ref (match_operand 1 "" ""))
7043 (pc)))
7044 (set (match_dup 0)
7045 (plus (match_dup 0) (const_int -1)))
7046 (clobber (reg:SI T_REG))]
7047 "TARGET_SH2"
7048 "#"
7049 ""
7050 [(parallel [(set (reg:SI T_REG)
7051 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7052 (const_int 1)))
7053 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7054 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7055 (label_ref (match_operand 1 "" ""))
7056 (pc)))]
7057 ""
7058 [(set_attr "type" "cbranch")])
7059
7060 \f
7061 ;; ------------------------------------------------------------------------
7062 ;; Jump and linkage insns
7063 ;; ------------------------------------------------------------------------
7064
7065 (define_insn "jump_compact"
7066 [(set (pc)
7067 (label_ref (match_operand 0 "" "")))]
7068 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7069 "*
7070 {
7071 /* The length is 16 if the delay slot is unfilled. */
7072 if (get_attr_length(insn) > 4)
7073 return output_far_jump(insn, operands[0]);
7074 else
7075 return \"bra %l0%#\";
7076 }"
7077 [(set_attr "type" "jump")
7078 (set_attr "needs_delay_slot" "yes")])
7079
7080 ;; ??? It would be much saner to explicitly use the scratch register
7081 ;; in the jump insn, and have indirect_jump_scratch only set it,
7082 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7083 ;; from the target then, as it uses simplejump_p.
7084 ;;(define_insn "jump_compact_far"
7085 ;; [(set (pc)
7086 ;; (label_ref (match_operand 0 "" "")))
7087 ;; (use (match_operand 1 "register_operand" "r")]
7088 ;; "TARGET_SH1"
7089 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7090 ;; [(set_attr "type" "jump")
7091 ;; (set_attr "needs_delay_slot" "yes")])
7092
7093 (define_insn "jump_media"
7094 [(set (pc)
7095 (match_operand 0 "target_operand" "b"))]
7096 "TARGET_SHMEDIA"
7097 "blink %0, r63%>"
7098 [(set_attr "type" "jump_media")])
7099
7100 (define_expand "jump"
7101 [(set (pc)
7102 (label_ref (match_operand 0 "" "")))]
7103 ""
7104 "
7105 {
7106 if (TARGET_SH1)
7107 emit_jump_insn (gen_jump_compact (operands[0]));
7108 else if (TARGET_SHMEDIA)
7109 {
7110 if (reload_in_progress || reload_completed)
7111 FAIL;
7112 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7113 operands[0])));
7114 }
7115 DONE;
7116 }")
7117
7118 (define_insn "force_mode_for_call"
7119 [(use (reg:PSI FPSCR_REG))]
7120 "TARGET_SHCOMPACT"
7121 ""
7122 [(set_attr "length" "0")
7123 (set (attr "fp_mode")
7124 (if_then_else (eq_attr "fpu_single" "yes")
7125 (const_string "single") (const_string "double")))])
7126
7127 (define_insn "calli"
7128 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7129 (match_operand 1 "" ""))
7130 (use (reg:PSI FPSCR_REG))
7131 (clobber (reg:SI PR_REG))]
7132 "TARGET_SH1"
7133 "*
7134 {
7135 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7136 return \"jsr/n\\t@%0\";
7137 else
7138 return \"jsr\\t@%0%#\";
7139 }"
7140
7141 [(set_attr "type" "call")
7142 (set (attr "fp_mode")
7143 (if_then_else (eq_attr "fpu_single" "yes")
7144 (const_string "single") (const_string "double")))
7145 (set_attr "needs_delay_slot" "yes")
7146 (set_attr "fp_set" "unknown")])
7147
7148 ;; This is TBR relative jump instruction for SH2A architecture.
7149 ;; Its use is enabled assigning an attribute "function_vector"
7150 ;; and the vector number to a function during its declaration.
7151
7152 (define_insn "calli_tbr_rel"
7153 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7154 (match_operand 1 "" ""))
7155 (use (reg:PSI FPSCR_REG))
7156 (clobber (reg:SI PR_REG))]
7157 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7158 "*
7159 {
7160 unsigned HOST_WIDE_INT vect_num;
7161 vect_num = sh2a_get_function_vector_number (operands[0]);
7162 operands[2] = GEN_INT (vect_num * 4);
7163
7164 return \"jsr/n\\t@@(%O2,tbr)\";
7165 }"
7166 [(set_attr "type" "call")
7167 (set (attr "fp_mode")
7168 (if_then_else (eq_attr "fpu_single" "yes")
7169 (const_string "single") (const_string "double")))
7170 (set_attr "needs_delay_slot" "no")
7171 (set_attr "fp_set" "unknown")])
7172
7173 ;; This is a pc-rel call, using bsrf, for use with PIC.
7174
7175 (define_insn "calli_pcrel"
7176 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7177 (match_operand 1 "" ""))
7178 (use (reg:PSI FPSCR_REG))
7179 (use (reg:SI PIC_REG))
7180 (use (match_operand 2 "" ""))
7181 (clobber (reg:SI PR_REG))]
7182 "TARGET_SH2"
7183 "bsrf %0\\n%O2:%#"
7184 [(set_attr "type" "call")
7185 (set (attr "fp_mode")
7186 (if_then_else (eq_attr "fpu_single" "yes")
7187 (const_string "single") (const_string "double")))
7188 (set_attr "needs_delay_slot" "yes")
7189 (set_attr "fp_set" "unknown")])
7190
7191 (define_insn_and_split "call_pcrel"
7192 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7193 (match_operand 1 "" ""))
7194 (use (reg:PSI FPSCR_REG))
7195 (use (reg:SI PIC_REG))
7196 (clobber (reg:SI PR_REG))
7197 (clobber (match_scratch:SI 2 "=r"))]
7198 "TARGET_SH2"
7199 "#"
7200 "reload_completed"
7201 [(const_int 0)]
7202 "
7203 {
7204 rtx lab = PATTERN (gen_call_site ());
7205
7206 if (SYMBOL_REF_LOCAL_P (operands[0]))
7207 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7208 else
7209 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7210 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7211 DONE;
7212 }"
7213 [(set_attr "type" "call")
7214 (set (attr "fp_mode")
7215 (if_then_else (eq_attr "fpu_single" "yes")
7216 (const_string "single") (const_string "double")))
7217 (set_attr "needs_delay_slot" "yes")
7218 (set_attr "fp_set" "unknown")])
7219
7220 (define_insn "call_compact"
7221 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7222 (match_operand 1 "" ""))
7223 (match_operand 2 "immediate_operand" "n")
7224 (use (reg:SI R0_REG))
7225 (use (reg:SI R1_REG))
7226 (use (reg:PSI FPSCR_REG))
7227 (clobber (reg:SI PR_REG))]
7228 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7229 "jsr @%0%#"
7230 [(set_attr "type" "call")
7231 (set (attr "fp_mode")
7232 (if_then_else (eq_attr "fpu_single" "yes")
7233 (const_string "single") (const_string "double")))
7234 (set_attr "needs_delay_slot" "yes")])
7235
7236 (define_insn "call_compact_rettramp"
7237 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7238 (match_operand 1 "" ""))
7239 (match_operand 2 "immediate_operand" "n")
7240 (use (reg:SI R0_REG))
7241 (use (reg:SI R1_REG))
7242 (use (reg:PSI FPSCR_REG))
7243 (clobber (reg:SI R10_REG))
7244 (clobber (reg:SI PR_REG))]
7245 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7246 "jsr @%0%#"
7247 [(set_attr "type" "call")
7248 (set (attr "fp_mode")
7249 (if_then_else (eq_attr "fpu_single" "yes")
7250 (const_string "single") (const_string "double")))
7251 (set_attr "needs_delay_slot" "yes")])
7252
7253 (define_insn "call_media"
7254 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7255 (match_operand 1 "" ""))
7256 (clobber (reg:DI PR_MEDIA_REG))]
7257 "TARGET_SHMEDIA"
7258 "blink %0, r18"
7259 [(set_attr "type" "jump_media")])
7260
7261 (define_insn "call_valuei"
7262 [(set (match_operand 0 "" "=rf")
7263 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7264 (match_operand 2 "" "")))
7265 (use (reg:PSI FPSCR_REG))
7266 (clobber (reg:SI PR_REG))]
7267 "TARGET_SH1"
7268 "*
7269 {
7270 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7271 return \"jsr/n\\t@%1\";
7272 else
7273 return \"jsr\\t@%1%#\";
7274 }"
7275 [(set_attr "type" "call")
7276 (set (attr "fp_mode")
7277 (if_then_else (eq_attr "fpu_single" "yes")
7278 (const_string "single") (const_string "double")))
7279 (set_attr "needs_delay_slot" "yes")
7280 (set_attr "fp_set" "unknown")])
7281
7282 ;; This is TBR relative jump instruction for SH2A architecture.
7283 ;; Its use is enabled assigning an attribute "function_vector"
7284 ;; and the vector number to a function during its declaration.
7285
7286 (define_insn "call_valuei_tbr_rel"
7287 [(set (match_operand 0 "" "=rf")
7288 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7289 (match_operand 2 "" "")))
7290 (use (reg:PSI FPSCR_REG))
7291 (clobber (reg:SI PR_REG))]
7292 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7293 "*
7294 {
7295 unsigned HOST_WIDE_INT vect_num;
7296 vect_num = sh2a_get_function_vector_number (operands[1]);
7297 operands[3] = GEN_INT (vect_num * 4);
7298
7299 return \"jsr/n\\t@@(%O3,tbr)\";
7300 }"
7301 [(set_attr "type" "call")
7302 (set (attr "fp_mode")
7303 (if_then_else (eq_attr "fpu_single" "yes")
7304 (const_string "single") (const_string "double")))
7305 (set_attr "needs_delay_slot" "no")
7306 (set_attr "fp_set" "unknown")])
7307
7308 (define_insn "call_valuei_pcrel"
7309 [(set (match_operand 0 "" "=rf")
7310 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7311 (match_operand 2 "" "")))
7312 (use (reg:PSI FPSCR_REG))
7313 (use (reg:SI PIC_REG))
7314 (use (match_operand 3 "" ""))
7315 (clobber (reg:SI PR_REG))]
7316 "TARGET_SH2"
7317 "bsrf %1\\n%O3:%#"
7318 [(set_attr "type" "call")
7319 (set (attr "fp_mode")
7320 (if_then_else (eq_attr "fpu_single" "yes")
7321 (const_string "single") (const_string "double")))
7322 (set_attr "needs_delay_slot" "yes")
7323 (set_attr "fp_set" "unknown")])
7324
7325 (define_insn_and_split "call_value_pcrel"
7326 [(set (match_operand 0 "" "=rf")
7327 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7328 (match_operand 2 "" "")))
7329 (use (reg:PSI FPSCR_REG))
7330 (use (reg:SI PIC_REG))
7331 (clobber (reg:SI PR_REG))
7332 (clobber (match_scratch:SI 3 "=r"))]
7333 "TARGET_SH2"
7334 "#"
7335 "reload_completed"
7336 [(const_int 0)]
7337 "
7338 {
7339 rtx lab = PATTERN (gen_call_site ());
7340
7341 if (SYMBOL_REF_LOCAL_P (operands[1]))
7342 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7343 else
7344 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7345 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7346 operands[2], copy_rtx (lab)));
7347 DONE;
7348 }"
7349 [(set_attr "type" "call")
7350 (set (attr "fp_mode")
7351 (if_then_else (eq_attr "fpu_single" "yes")
7352 (const_string "single") (const_string "double")))
7353 (set_attr "needs_delay_slot" "yes")
7354 (set_attr "fp_set" "unknown")])
7355
7356 (define_insn "call_value_compact"
7357 [(set (match_operand 0 "" "=rf")
7358 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7359 (match_operand 2 "" "")))
7360 (match_operand 3 "immediate_operand" "n")
7361 (use (reg:SI R0_REG))
7362 (use (reg:SI R1_REG))
7363 (use (reg:PSI FPSCR_REG))
7364 (clobber (reg:SI PR_REG))]
7365 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7366 "jsr @%1%#"
7367 [(set_attr "type" "call")
7368 (set (attr "fp_mode")
7369 (if_then_else (eq_attr "fpu_single" "yes")
7370 (const_string "single") (const_string "double")))
7371 (set_attr "needs_delay_slot" "yes")])
7372
7373 (define_insn "call_value_compact_rettramp"
7374 [(set (match_operand 0 "" "=rf")
7375 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7376 (match_operand 2 "" "")))
7377 (match_operand 3 "immediate_operand" "n")
7378 (use (reg:SI R0_REG))
7379 (use (reg:SI R1_REG))
7380 (use (reg:PSI FPSCR_REG))
7381 (clobber (reg:SI R10_REG))
7382 (clobber (reg:SI PR_REG))]
7383 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7384 "jsr @%1%#"
7385 [(set_attr "type" "call")
7386 (set (attr "fp_mode")
7387 (if_then_else (eq_attr "fpu_single" "yes")
7388 (const_string "single") (const_string "double")))
7389 (set_attr "needs_delay_slot" "yes")])
7390
7391 (define_insn "call_value_media"
7392 [(set (match_operand 0 "" "=rf")
7393 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7394 (match_operand 2 "" "")))
7395 (clobber (reg:DI PR_MEDIA_REG))]
7396 "TARGET_SHMEDIA"
7397 "blink %1, r18"
7398 [(set_attr "type" "jump_media")])
7399
7400 (define_expand "call"
7401 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7402 (match_operand 1 "" ""))
7403 (match_operand 2 "" "")
7404 (use (reg:PSI FPSCR_REG))
7405 (clobber (reg:SI PR_REG))])]
7406 ""
7407 "
7408 {
7409 if (TARGET_SHMEDIA)
7410 {
7411 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7412 emit_call_insn (gen_call_media (operands[0], operands[1]));
7413 DONE;
7414 }
7415 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7416 {
7417 rtx cookie_rtx = operands[2];
7418 long cookie = INTVAL (cookie_rtx);
7419 rtx func = XEXP (operands[0], 0);
7420 rtx r0, r1;
7421
7422 if (flag_pic)
7423 {
7424 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7425 {
7426 rtx reg = gen_reg_rtx (Pmode);
7427
7428 emit_insn (gen_symGOTPLT2reg (reg, func));
7429 func = reg;
7430 }
7431 else
7432 func = legitimize_pic_address (func, Pmode, 0);
7433 }
7434
7435 r0 = gen_rtx_REG (SImode, R0_REG);
7436 r1 = gen_rtx_REG (SImode, R1_REG);
7437
7438 /* Since such a call function may use all call-clobbered
7439 registers, we force a mode switch earlier, so that we don't
7440 run out of registers when adjusting fpscr for the call. */
7441 emit_insn (gen_force_mode_for_call ());
7442
7443 operands[0]
7444 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7445 SFUNC_GOT);
7446 operands[0] = force_reg (SImode, operands[0]);
7447
7448 emit_move_insn (r0, func);
7449 emit_move_insn (r1, cookie_rtx);
7450
7451 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7452 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7453 operands[2]));
7454 else
7455 emit_call_insn (gen_call_compact (operands[0], operands[1],
7456 operands[2]));
7457
7458 DONE;
7459 }
7460 else if (TARGET_SHCOMPACT && flag_pic
7461 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7462 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7463 {
7464 rtx reg = gen_reg_rtx (Pmode);
7465
7466 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7467 XEXP (operands[0], 0) = reg;
7468 }
7469 if (!flag_pic && TARGET_SH2A
7470 && MEM_P (operands[0])
7471 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7472 {
7473 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7474 {
7475 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7476 operands[1]));
7477 DONE;
7478 }
7479 }
7480 if (flag_pic && TARGET_SH2
7481 && MEM_P (operands[0])
7482 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7483 {
7484 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7485 DONE;
7486 }
7487 else
7488 {
7489 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7490 operands[1] = operands[2];
7491 }
7492
7493 emit_call_insn (gen_calli (operands[0], operands[1]));
7494 DONE;
7495 }")
7496
7497 (define_insn "call_pop_compact"
7498 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7499 (match_operand 1 "" ""))
7500 (match_operand 2 "immediate_operand" "n")
7501 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7502 (match_operand 3 "immediate_operand" "n")))
7503 (use (reg:SI R0_REG))
7504 (use (reg:SI R1_REG))
7505 (use (reg:PSI FPSCR_REG))
7506 (clobber (reg:SI PR_REG))]
7507 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7508 "jsr @%0%#"
7509 [(set_attr "type" "call")
7510 (set (attr "fp_mode")
7511 (if_then_else (eq_attr "fpu_single" "yes")
7512 (const_string "single") (const_string "double")))
7513 (set_attr "needs_delay_slot" "yes")])
7514
7515 (define_insn "call_pop_compact_rettramp"
7516 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7517 (match_operand 1 "" ""))
7518 (match_operand 2 "immediate_operand" "n")
7519 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7520 (match_operand 3 "immediate_operand" "n")))
7521 (use (reg:SI R0_REG))
7522 (use (reg:SI R1_REG))
7523 (use (reg:PSI FPSCR_REG))
7524 (clobber (reg:SI R10_REG))
7525 (clobber (reg:SI PR_REG))]
7526 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7527 "jsr @%0%#"
7528 [(set_attr "type" "call")
7529 (set (attr "fp_mode")
7530 (if_then_else (eq_attr "fpu_single" "yes")
7531 (const_string "single") (const_string "double")))
7532 (set_attr "needs_delay_slot" "yes")])
7533
7534 (define_expand "call_pop"
7535 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7536 (match_operand 1 "" ""))
7537 (match_operand 2 "" "")
7538 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7539 (match_operand 3 "" "")))])]
7540 "TARGET_SHCOMPACT"
7541 "
7542 {
7543 rtx cookie_rtx;
7544 long cookie;
7545 rtx func;
7546 rtx r0, r1;
7547
7548 gcc_assert (operands[2] && INTVAL (operands[2]));
7549 cookie_rtx = operands[2];
7550 cookie = INTVAL (cookie_rtx);
7551 func = XEXP (operands[0], 0);
7552
7553 if (flag_pic)
7554 {
7555 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7556 {
7557 rtx reg = gen_reg_rtx (Pmode);
7558 emit_insn (gen_symGOTPLT2reg (reg, func));
7559 func = reg;
7560 }
7561 else
7562 func = legitimize_pic_address (func, Pmode, 0);
7563 }
7564
7565 r0 = gen_rtx_REG (SImode, R0_REG);
7566 r1 = gen_rtx_REG (SImode, R1_REG);
7567
7568 /* Since such a call function may use all call-clobbered
7569 registers, we force a mode switch earlier, so that we don't
7570 run out of registers when adjusting fpscr for the call. */
7571 emit_insn (gen_force_mode_for_call ());
7572
7573 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7574 SFUNC_GOT);
7575 operands[0] = force_reg (SImode, operands[0]);
7576
7577 emit_move_insn (r0, func);
7578 emit_move_insn (r1, cookie_rtx);
7579
7580 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7581 emit_call_insn (gen_call_pop_compact_rettramp
7582 (operands[0], operands[1], operands[2], operands[3]));
7583 else
7584 emit_call_insn (gen_call_pop_compact
7585 (operands[0], operands[1], operands[2], operands[3]));
7586
7587 DONE;
7588 }")
7589
7590 (define_expand "call_value"
7591 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7592 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7593 (match_operand 2 "" "")))
7594 (match_operand 3 "" "")
7595 (use (reg:PSI FPSCR_REG))
7596 (clobber (reg:SI PR_REG))])]
7597 ""
7598 "
7599 {
7600 if (TARGET_SHMEDIA)
7601 {
7602 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7603 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7604 operands[2]));
7605 DONE;
7606 }
7607 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7608 {
7609 rtx cookie_rtx = operands[3];
7610 long cookie = INTVAL (cookie_rtx);
7611 rtx func = XEXP (operands[1], 0);
7612 rtx r0, r1;
7613
7614 if (flag_pic)
7615 {
7616 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7617 {
7618 rtx reg = gen_reg_rtx (Pmode);
7619
7620 emit_insn (gen_symGOTPLT2reg (reg, func));
7621 func = reg;
7622 }
7623 else
7624 func = legitimize_pic_address (func, Pmode, 0);
7625 }
7626
7627 r0 = gen_rtx_REG (SImode, R0_REG);
7628 r1 = gen_rtx_REG (SImode, R1_REG);
7629
7630 /* Since such a call function may use all call-clobbered
7631 registers, we force a mode switch earlier, so that we don't
7632 run out of registers when adjusting fpscr for the call. */
7633 emit_insn (gen_force_mode_for_call ());
7634
7635 operands[1]
7636 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7637 SFUNC_GOT);
7638 operands[1] = force_reg (SImode, operands[1]);
7639
7640 emit_move_insn (r0, func);
7641 emit_move_insn (r1, cookie_rtx);
7642
7643 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7644 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7645 operands[1],
7646 operands[2],
7647 operands[3]));
7648 else
7649 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7650 operands[2], operands[3]));
7651
7652 DONE;
7653 }
7654 else if (TARGET_SHCOMPACT && flag_pic
7655 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7656 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7657 {
7658 rtx reg = gen_reg_rtx (Pmode);
7659
7660 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7661 XEXP (operands[1], 0) = reg;
7662 }
7663 if (!flag_pic && TARGET_SH2A
7664 && MEM_P (operands[1])
7665 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7666 {
7667 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7668 {
7669 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7670 XEXP (operands[1], 0), operands[2]));
7671 DONE;
7672 }
7673 }
7674 if (flag_pic && TARGET_SH2
7675 && MEM_P (operands[1])
7676 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7677 {
7678 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7679 operands[2]));
7680 DONE;
7681 }
7682 else
7683 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7684
7685 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7686 DONE;
7687 }")
7688
7689 (define_insn "sibcalli"
7690 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7691 (match_operand 1 "" ""))
7692 (use (reg:PSI FPSCR_REG))
7693 (return)]
7694 "TARGET_SH1"
7695 "jmp @%0%#"
7696 [(set_attr "needs_delay_slot" "yes")
7697 (set (attr "fp_mode")
7698 (if_then_else (eq_attr "fpu_single" "yes")
7699 (const_string "single") (const_string "double")))
7700 (set_attr "type" "jump_ind")])
7701
7702 (define_insn "sibcalli_pcrel"
7703 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7704 (match_operand 1 "" ""))
7705 (use (match_operand 2 "" ""))
7706 (use (reg:PSI FPSCR_REG))
7707 (return)]
7708 "TARGET_SH2"
7709 "braf %0\\n%O2:%#"
7710 [(set_attr "needs_delay_slot" "yes")
7711 (set (attr "fp_mode")
7712 (if_then_else (eq_attr "fpu_single" "yes")
7713 (const_string "single") (const_string "double")))
7714 (set_attr "type" "jump_ind")])
7715
7716 ;; This uses an unspec to describe that the symbol_ref is very close.
7717 (define_insn "sibcalli_thunk"
7718 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7719 UNSPEC_THUNK))
7720 (match_operand 1 "" ""))
7721 (use (reg:PSI FPSCR_REG))
7722 (return)]
7723 "TARGET_SH1"
7724 "bra %O0"
7725 [(set_attr "needs_delay_slot" "yes")
7726 (set (attr "fp_mode")
7727 (if_then_else (eq_attr "fpu_single" "yes")
7728 (const_string "single") (const_string "double")))
7729 (set_attr "type" "jump")
7730 (set_attr "length" "2")])
7731
7732 (define_insn_and_split "sibcall_pcrel"
7733 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7734 (match_operand 1 "" ""))
7735 (use (reg:PSI FPSCR_REG))
7736 (clobber (match_scratch:SI 2 "=k"))
7737 (return)]
7738 "TARGET_SH2"
7739 "#"
7740 "reload_completed"
7741 [(const_int 0)]
7742 "
7743 {
7744 rtx lab = PATTERN (gen_call_site ());
7745 rtx call_insn;
7746
7747 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7748 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7749 copy_rtx (lab)));
7750 SIBLING_CALL_P (call_insn) = 1;
7751 DONE;
7752 }"
7753 [(set_attr "needs_delay_slot" "yes")
7754 (set (attr "fp_mode")
7755 (if_then_else (eq_attr "fpu_single" "yes")
7756 (const_string "single") (const_string "double")))
7757 (set_attr "type" "jump_ind")])
7758
7759 (define_insn "sibcall_compact"
7760 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7761 (match_operand 1 "" ""))
7762 (return)
7763 (use (match_operand:SI 2 "register_operand" "z,x"))
7764 (use (reg:SI R1_REG))
7765 (use (reg:PSI FPSCR_REG))
7766 ;; We want to make sure the `x' above will only match MACH_REG
7767 ;; because sibcall_epilogue may clobber MACL_REG.
7768 (clobber (reg:SI MACL_REG))]
7769 "TARGET_SHCOMPACT"
7770 "@
7771 jmp @%0%#
7772 jmp @%0\\n sts %2, r0"
7773 [(set_attr "needs_delay_slot" "yes,no")
7774 (set_attr "length" "2,4")
7775 (set (attr "fp_mode") (const_string "single"))
7776 (set_attr "type" "jump_ind")])
7777
7778 (define_insn "sibcall_media"
7779 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7780 (match_operand 1 "" ""))
7781 (use (reg:SI PR_MEDIA_REG))
7782 (return)]
7783 "TARGET_SHMEDIA"
7784 "blink %0, r63"
7785 [(set_attr "type" "jump_media")])
7786
7787 (define_expand "sibcall"
7788 [(parallel
7789 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7790 (match_operand 1 "" ""))
7791 (match_operand 2 "" "")
7792 (use (reg:PSI FPSCR_REG))
7793 (return)])]
7794 ""
7795 "
7796 {
7797 if (TARGET_SHMEDIA)
7798 {
7799 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7800 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7801 DONE;
7802 }
7803 else if (TARGET_SHCOMPACT && operands[2]
7804 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7805 {
7806 rtx cookie_rtx = operands[2];
7807 long cookie = INTVAL (cookie_rtx);
7808 rtx func = XEXP (operands[0], 0);
7809 rtx mach, r1;
7810
7811 if (flag_pic)
7812 {
7813 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7814 {
7815 rtx reg = gen_reg_rtx (Pmode);
7816
7817 emit_insn (gen_symGOT2reg (reg, func));
7818 func = reg;
7819 }
7820 else
7821 func = legitimize_pic_address (func, Pmode, 0);
7822 }
7823
7824 /* FIXME: if we could tell whether all argument registers are
7825 already taken, we could decide whether to force the use of
7826 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7827 simple way to tell. We could use the CALL_COOKIE, but we
7828 can't currently tell a register used for regular argument
7829 passing from one that is unused. If we leave it up to reload
7830 to decide which register to use, it seems to always choose
7831 R0_REG, which leaves no available registers in SIBCALL_REGS
7832 to hold the address of the trampoline. */
7833 mach = gen_rtx_REG (SImode, MACH_REG);
7834 r1 = gen_rtx_REG (SImode, R1_REG);
7835
7836 /* Since such a call function may use all call-clobbered
7837 registers, we force a mode switch earlier, so that we don't
7838 run out of registers when adjusting fpscr for the call. */
7839 emit_insn (gen_force_mode_for_call ());
7840
7841 operands[0]
7842 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7843 SFUNC_GOT);
7844 operands[0] = force_reg (SImode, operands[0]);
7845
7846 /* We don't need a return trampoline, since the callee will
7847 return directly to the upper caller. */
7848 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7849 {
7850 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7851 cookie_rtx = GEN_INT (cookie);
7852 }
7853
7854 emit_move_insn (mach, func);
7855 emit_move_insn (r1, cookie_rtx);
7856
7857 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7858 DONE;
7859 }
7860 else if (TARGET_SHCOMPACT && flag_pic
7861 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7862 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7863 {
7864 rtx reg = gen_reg_rtx (Pmode);
7865
7866 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7867 XEXP (operands[0], 0) = reg;
7868 }
7869 if (flag_pic && TARGET_SH2
7870 && MEM_P (operands[0])
7871 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7872 /* The PLT needs the PIC register, but the epilogue would have
7873 to restore it, so we can only use PC-relative PIC calls for
7874 static functions. */
7875 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7876 {
7877 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7878 DONE;
7879 }
7880 else
7881 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7882
7883 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7884 DONE;
7885 }")
7886
7887 (define_insn "sibcall_valuei"
7888 [(set (match_operand 0 "" "=rf")
7889 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7890 (match_operand 2 "" "")))
7891 (use (reg:PSI FPSCR_REG))
7892 (return)]
7893 "TARGET_SH1"
7894 "jmp @%1%#"
7895 [(set_attr "needs_delay_slot" "yes")
7896 (set (attr "fp_mode")
7897 (if_then_else (eq_attr "fpu_single" "yes")
7898 (const_string "single") (const_string "double")))
7899 (set_attr "type" "jump_ind")])
7900
7901 (define_insn "sibcall_valuei_pcrel"
7902 [(set (match_operand 0 "" "=rf")
7903 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7904 (match_operand 2 "" "")))
7905 (use (match_operand 3 "" ""))
7906 (use (reg:PSI FPSCR_REG))
7907 (return)]
7908 "TARGET_SH2"
7909 "braf %1\\n%O3:%#"
7910 [(set_attr "needs_delay_slot" "yes")
7911 (set (attr "fp_mode")
7912 (if_then_else (eq_attr "fpu_single" "yes")
7913 (const_string "single") (const_string "double")))
7914 (set_attr "type" "jump_ind")])
7915
7916 (define_insn_and_split "sibcall_value_pcrel"
7917 [(set (match_operand 0 "" "=rf")
7918 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7919 (match_operand 2 "" "")))
7920 (use (reg:PSI FPSCR_REG))
7921 (clobber (match_scratch:SI 3 "=k"))
7922 (return)]
7923 "TARGET_SH2"
7924 "#"
7925 "reload_completed"
7926 [(const_int 0)]
7927 "
7928 {
7929 rtx lab = PATTERN (gen_call_site ());
7930 rtx call_insn;
7931
7932 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7933 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7934 operands[3],
7935 operands[2],
7936 copy_rtx (lab)));
7937 SIBLING_CALL_P (call_insn) = 1;
7938 DONE;
7939 }"
7940 [(set_attr "needs_delay_slot" "yes")
7941 (set (attr "fp_mode")
7942 (if_then_else (eq_attr "fpu_single" "yes")
7943 (const_string "single") (const_string "double")))
7944 (set_attr "type" "jump_ind")])
7945
7946 (define_insn "sibcall_value_compact"
7947 [(set (match_operand 0 "" "=rf,rf")
7948 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7949 (match_operand 2 "" "")))
7950 (return)
7951 (use (match_operand:SI 3 "register_operand" "z,x"))
7952 (use (reg:SI R1_REG))
7953 (use (reg:PSI FPSCR_REG))
7954 ;; We want to make sure the `x' above will only match MACH_REG
7955 ;; because sibcall_epilogue may clobber MACL_REG.
7956 (clobber (reg:SI MACL_REG))]
7957 "TARGET_SHCOMPACT"
7958 "@
7959 jmp @%1%#
7960 jmp @%1\\n sts %3, r0"
7961 [(set_attr "needs_delay_slot" "yes,no")
7962 (set_attr "length" "2,4")
7963 (set (attr "fp_mode") (const_string "single"))
7964 (set_attr "type" "jump_ind")])
7965
7966 (define_insn "sibcall_value_media"
7967 [(set (match_operand 0 "" "=rf")
7968 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7969 (match_operand 2 "" "")))
7970 (use (reg:SI PR_MEDIA_REG))
7971 (return)]
7972 "TARGET_SHMEDIA"
7973 "blink %1, r63"
7974 [(set_attr "type" "jump_media")])
7975
7976 (define_expand "sibcall_value"
7977 [(parallel
7978 [(set (match_operand 0 "arith_reg_operand" "")
7979 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7980 (match_operand 2 "" "")))
7981 (match_operand 3 "" "")
7982 (use (reg:PSI FPSCR_REG))
7983 (return)])]
7984 ""
7985 "
7986 {
7987 if (TARGET_SHMEDIA)
7988 {
7989 operands[1] = shmedia_prepare_call_address (operands[1], 1);
7990 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
7991 operands[2]));
7992 DONE;
7993 }
7994 else if (TARGET_SHCOMPACT && operands[3]
7995 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7996 {
7997 rtx cookie_rtx = operands[3];
7998 long cookie = INTVAL (cookie_rtx);
7999 rtx func = XEXP (operands[1], 0);
8000 rtx mach, r1;
8001
8002 if (flag_pic)
8003 {
8004 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8005 {
8006 rtx reg = gen_reg_rtx (Pmode);
8007
8008 emit_insn (gen_symGOT2reg (reg, func));
8009 func = reg;
8010 }
8011 else
8012 func = legitimize_pic_address (func, Pmode, 0);
8013 }
8014
8015 /* FIXME: if we could tell whether all argument registers are
8016 already taken, we could decide whether to force the use of
8017 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8018 simple way to tell. We could use the CALL_COOKIE, but we
8019 can't currently tell a register used for regular argument
8020 passing from one that is unused. If we leave it up to reload
8021 to decide which register to use, it seems to always choose
8022 R0_REG, which leaves no available registers in SIBCALL_REGS
8023 to hold the address of the trampoline. */
8024 mach = gen_rtx_REG (SImode, MACH_REG);
8025 r1 = gen_rtx_REG (SImode, R1_REG);
8026
8027 /* Since such a call function may use all call-clobbered
8028 registers, we force a mode switch earlier, so that we don't
8029 run out of registers when adjusting fpscr for the call. */
8030 emit_insn (gen_force_mode_for_call ());
8031
8032 operands[1]
8033 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8034 SFUNC_GOT);
8035 operands[1] = force_reg (SImode, operands[1]);
8036
8037 /* We don't need a return trampoline, since the callee will
8038 return directly to the upper caller. */
8039 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8040 {
8041 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8042 cookie_rtx = GEN_INT (cookie);
8043 }
8044
8045 emit_move_insn (mach, func);
8046 emit_move_insn (r1, cookie_rtx);
8047
8048 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8049 operands[2], mach));
8050 DONE;
8051 }
8052 else if (TARGET_SHCOMPACT && flag_pic
8053 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8054 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8055 {
8056 rtx reg = gen_reg_rtx (Pmode);
8057
8058 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8059 XEXP (operands[1], 0) = reg;
8060 }
8061 if (flag_pic && TARGET_SH2
8062 && MEM_P (operands[1])
8063 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8064 /* The PLT needs the PIC register, but the epilogue would have
8065 to restore it, so we can only use PC-relative PIC calls for
8066 static functions. */
8067 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8068 {
8069 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8070 XEXP (operands[1], 0),
8071 operands[2]));
8072 DONE;
8073 }
8074 else
8075 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8076
8077 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8078 DONE;
8079 }")
8080
8081 (define_insn "call_value_pop_compact"
8082 [(set (match_operand 0 "" "=rf")
8083 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8084 (match_operand 2 "" "")))
8085 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8086 (match_operand 4 "immediate_operand" "n")))
8087 (match_operand 3 "immediate_operand" "n")
8088 (use (reg:SI R0_REG))
8089 (use (reg:SI R1_REG))
8090 (use (reg:PSI FPSCR_REG))
8091 (clobber (reg:SI PR_REG))]
8092 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8093 "jsr @%1%#"
8094 [(set_attr "type" "call")
8095 (set (attr "fp_mode")
8096 (if_then_else (eq_attr "fpu_single" "yes")
8097 (const_string "single") (const_string "double")))
8098 (set_attr "needs_delay_slot" "yes")])
8099
8100 (define_insn "call_value_pop_compact_rettramp"
8101 [(set (match_operand 0 "" "=rf")
8102 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8103 (match_operand 2 "" "")))
8104 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8105 (match_operand 4 "immediate_operand" "n")))
8106 (match_operand 3 "immediate_operand" "n")
8107 (use (reg:SI R0_REG))
8108 (use (reg:SI R1_REG))
8109 (use (reg:PSI FPSCR_REG))
8110 (clobber (reg:SI R10_REG))
8111 (clobber (reg:SI PR_REG))]
8112 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8113 "jsr @%1%#"
8114 [(set_attr "type" "call")
8115 (set (attr "fp_mode")
8116 (if_then_else (eq_attr "fpu_single" "yes")
8117 (const_string "single") (const_string "double")))
8118 (set_attr "needs_delay_slot" "yes")])
8119
8120 (define_expand "call_value_pop"
8121 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8122 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8123 (match_operand 2 "" "")))
8124 (match_operand 3 "" "")
8125 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8126 (match_operand 4 "" "")))])]
8127 "TARGET_SHCOMPACT"
8128 "
8129 {
8130 rtx cookie_rtx;
8131 long cookie;
8132 rtx func;
8133 rtx r0, r1;
8134
8135 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8136 cookie_rtx = operands[3];
8137 cookie = INTVAL (cookie_rtx);
8138 func = XEXP (operands[1], 0);
8139
8140 if (flag_pic)
8141 {
8142 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8143 {
8144 rtx reg = gen_reg_rtx (Pmode);
8145
8146 emit_insn (gen_symGOTPLT2reg (reg, func));
8147 func = reg;
8148 }
8149 else
8150 func = legitimize_pic_address (func, Pmode, 0);
8151 }
8152
8153 r0 = gen_rtx_REG (SImode, R0_REG);
8154 r1 = gen_rtx_REG (SImode, R1_REG);
8155
8156 /* Since such a call function may use all call-clobbered
8157 registers, we force a mode switch earlier, so that we don't
8158 run out of registers when adjusting fpscr for the call. */
8159 emit_insn (gen_force_mode_for_call ());
8160
8161 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8162 SFUNC_GOT);
8163 operands[1] = force_reg (SImode, operands[1]);
8164
8165 emit_move_insn (r0, func);
8166 emit_move_insn (r1, cookie_rtx);
8167
8168 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8169 emit_call_insn (gen_call_value_pop_compact_rettramp
8170 (operands[0], operands[1], operands[2],
8171 operands[3], operands[4]));
8172 else
8173 emit_call_insn (gen_call_value_pop_compact
8174 (operands[0], operands[1], operands[2],
8175 operands[3], operands[4]));
8176
8177 DONE;
8178 }")
8179
8180 (define_expand "sibcall_epilogue"
8181 [(return)]
8182 ""
8183 "
8184 {
8185 sh_expand_epilogue (1);
8186 if (TARGET_SHCOMPACT)
8187 {
8188 rtx insn, set;
8189
8190 /* If epilogue clobbers r0, preserve it in macl. */
8191 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8192 if ((set = single_set (insn))
8193 && REG_P (SET_DEST (set))
8194 && REGNO (SET_DEST (set)) == R0_REG)
8195 {
8196 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8197 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8198
8199 /* We can't tell at this point whether the sibcall is a
8200 sibcall_compact and, if it is, whether it uses r0 or
8201 mach as operand 2, so let the instructions that
8202 preserve r0 be optimized away if r0 turns out to be
8203 dead. */
8204 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8205 emit_move_insn (r0, tmp);
8206 break;
8207 }
8208 }
8209 DONE;
8210 }")
8211
8212 (define_insn "indirect_jump_compact"
8213 [(set (pc)
8214 (match_operand:SI 0 "arith_reg_operand" "r"))]
8215 "TARGET_SH1"
8216 "jmp @%0%#"
8217 [(set_attr "needs_delay_slot" "yes")
8218 (set_attr "type" "jump_ind")])
8219
8220 (define_expand "indirect_jump"
8221 [(set (pc)
8222 (match_operand 0 "register_operand" ""))]
8223 ""
8224 "
8225 {
8226 if (GET_MODE (operands[0]) != Pmode)
8227 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8228 }")
8229
8230 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8231 ;; which can be present in structured code from indirect jumps which can not
8232 ;; be present in structured code. This allows -fprofile-arcs to work.
8233
8234 ;; For SH1 processors.
8235 (define_insn "casesi_jump_1"
8236 [(set (pc)
8237 (match_operand:SI 0 "register_operand" "r"))
8238 (use (label_ref (match_operand 1 "" "")))]
8239 "TARGET_SH1"
8240 "jmp @%0%#"
8241 [(set_attr "needs_delay_slot" "yes")
8242 (set_attr "type" "jump_ind")])
8243
8244 ;; For all later processors.
8245 (define_insn "casesi_jump_2"
8246 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8247 (label_ref (match_operand 1 "" ""))))
8248 (use (label_ref (match_operand 2 "" "")))]
8249 "TARGET_SH2
8250 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8251 "braf %0%#"
8252 [(set_attr "needs_delay_slot" "yes")
8253 (set_attr "type" "jump_ind")])
8254
8255 (define_insn "casesi_jump_media"
8256 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8257 (use (label_ref (match_operand 1 "" "")))]
8258 "TARGET_SHMEDIA"
8259 "blink %0, r63"
8260 [(set_attr "type" "jump_media")])
8261
8262 ;; Call subroutine returning any type.
8263 ;; ??? This probably doesn't work.
8264
8265 (define_expand "untyped_call"
8266 [(parallel [(call (match_operand 0 "" "")
8267 (const_int 0))
8268 (match_operand 1 "" "")
8269 (match_operand 2 "" "")])]
8270 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8271 "
8272 {
8273 int i;
8274
8275 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8276
8277 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8278 {
8279 rtx set = XVECEXP (operands[2], 0, i);
8280 emit_move_insn (SET_DEST (set), SET_SRC (set));
8281 }
8282
8283 /* The optimizer does not know that the call sets the function value
8284 registers we stored in the result block. We avoid problems by
8285 claiming that all hard registers are used and clobbered at this
8286 point. */
8287 emit_insn (gen_blockage ());
8288
8289 DONE;
8290 }")
8291 \f
8292 ;; ------------------------------------------------------------------------
8293 ;; Misc insns
8294 ;; ------------------------------------------------------------------------
8295
8296 (define_insn "dect"
8297 [(set (reg:SI T_REG)
8298 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8299 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8300 "TARGET_SH2"
8301 "dt %0"
8302 [(set_attr "type" "arith")])
8303
8304 (define_insn "nop"
8305 [(const_int 0)]
8306 ""
8307 "nop")
8308
8309 ;; Load address of a label. This is only generated by the casesi expand,
8310 ;; and by machine_dependent_reorg (fixing up fp moves).
8311 ;; This must use unspec, because this only works for labels that are
8312 ;; within range,
8313
8314 (define_insn "mova"
8315 [(set (reg:SI R0_REG)
8316 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8317 "TARGET_SH1"
8318 "mova %O0,r0"
8319 [(set_attr "in_delay_slot" "no")
8320 (set_attr "type" "arith")])
8321
8322 ;; machine_dependent_reorg will make this a `mova'.
8323 (define_insn "mova_const"
8324 [(set (reg:SI R0_REG)
8325 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8326 "TARGET_SH1"
8327 "#"
8328 [(set_attr "in_delay_slot" "no")
8329 (set_attr "type" "arith")])
8330
8331 (define_expand "GOTaddr2picreg"
8332 [(set (reg:SI R0_REG)
8333 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8334 UNSPEC_MOVA))
8335 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8336 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8337 "" "
8338 {
8339 if (TARGET_VXWORKS_RTP)
8340 {
8341 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8342 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8343 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8344 DONE;
8345 }
8346
8347 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8348 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8349
8350 if (TARGET_SHMEDIA)
8351 {
8352 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8353 rtx pic = operands[0];
8354 rtx lab = PATTERN (gen_call_site ());
8355 rtx insn, equiv;
8356
8357 equiv = operands[1];
8358 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8359 UNSPEC_PCREL_SYMOFF);
8360 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8361
8362 if (Pmode == SImode)
8363 {
8364 emit_insn (gen_movsi_const (pic, operands[1]));
8365 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8366 }
8367 else
8368 {
8369 emit_insn (gen_movdi_const (pic, operands[1]));
8370 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8371 }
8372
8373 insn = emit_move_insn (operands[0], tr);
8374
8375 set_unique_reg_note (insn, REG_EQUAL, equiv);
8376
8377 DONE;
8378 }
8379 }
8380 ")
8381
8382 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8383 ;; PIC register.
8384
8385 (define_expand "vxworks_picreg"
8386 [(set (reg:SI PIC_REG)
8387 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8388 (set (reg:SI R0_REG)
8389 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8390 (set (reg:SI PIC_REG)
8391 (mem:SI (reg:SI PIC_REG)))
8392 (set (reg:SI PIC_REG)
8393 (mem:SI (plus:SI (reg:SI PIC_REG)
8394 (reg:SI R0_REG))))]
8395 "TARGET_VXWORKS_RTP")
8396
8397 (define_insn "*ptb"
8398 [(set (match_operand 0 "target_reg_operand" "=b")
8399 (const (unspec [(match_operand 1 "" "Csy")]
8400 UNSPEC_DATALABEL)))]
8401 "TARGET_SHMEDIA && flag_pic
8402 && satisfies_constraint_Csy (operands[1])"
8403 "ptb/u datalabel %1, %0"
8404 [(set_attr "type" "ptabs_media")
8405 (set_attr "length" "*")])
8406
8407 (define_insn "ptrel_si"
8408 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8409 (plus:SI (match_operand:SI 1 "register_operand" "r")
8410 (pc)))
8411 (match_operand:SI 2 "" "")]
8412 "TARGET_SHMEDIA"
8413 "%O2: ptrel/u %1, %0"
8414 [(set_attr "type" "ptabs_media")])
8415
8416 (define_insn "ptrel_di"
8417 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8418 (plus:DI (match_operand:DI 1 "register_operand" "r")
8419 (pc)))
8420 (match_operand:DI 2 "" "")]
8421 "TARGET_SHMEDIA"
8422 "%O2: ptrel/u %1, %0"
8423 [(set_attr "type" "ptabs_media")])
8424
8425 (define_expand "builtin_setjmp_receiver"
8426 [(match_operand 0 "" "")]
8427 "flag_pic"
8428 "
8429 {
8430 emit_insn (gen_GOTaddr2picreg ());
8431 DONE;
8432 }")
8433
8434 (define_expand "call_site"
8435 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8436 "TARGET_SH1"
8437 "
8438 {
8439 static HOST_WIDE_INT i = 0;
8440 operands[0] = GEN_INT (i);
8441 i++;
8442 }")
8443
8444 (define_expand "sym_label2reg"
8445 [(set (match_operand:SI 0 "" "")
8446 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8447 (const (plus:SI (match_operand:SI 2 "" "")
8448 (const_int 2)))]
8449 UNSPEC_SYMOFF)))]
8450 "TARGET_SH1" "")
8451
8452 (define_expand "symGOT_load"
8453 [(set (match_dup 2) (match_operand 1 "" ""))
8454 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8455 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8456 ""
8457 "
8458 {
8459 rtx insn, mem;
8460
8461 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8462 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8463
8464 if (TARGET_SHMEDIA)
8465 {
8466 rtx reg = operands[2];
8467
8468 if (Pmode == DImode)
8469 {
8470 if (flag_pic > 1)
8471 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8472 else
8473 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8474 }
8475 else
8476 {
8477 if (flag_pic > 1)
8478 emit_insn (gen_movsi_const (reg, operands[1]));
8479 else
8480 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8481 }
8482 }
8483 else
8484 emit_move_insn (operands[2], operands[1]);
8485
8486 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8487 operands[2],
8488 gen_rtx_REG (Pmode, PIC_REG)));
8489
8490 /* When stack protector inserts codes after the result is set to
8491 R0, @(rX, r12) will cause a spill failure for R0. Don't schedule
8492 insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8493 when rX is a GOT address for the guard symbol. Ugly but doesn't
8494 matter because this is a rare situation. */
8495 if (!TARGET_SHMEDIA
8496 && flag_stack_protect
8497 && GET_CODE (operands[1]) == CONST
8498 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8499 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8500 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8501 \"__stack_chk_guard\") == 0)
8502 emit_insn (gen_blockage ());
8503
8504 /* N.B. This is not constant for a GOTPLT relocation. */
8505 mem = gen_rtx_MEM (Pmode, operands[3]);
8506 MEM_NOTRAP_P (mem) = 1;
8507 /* ??? Should we have a special alias set for the GOT? */
8508 insn = emit_move_insn (operands[0], mem);
8509
8510 DONE;
8511 }")
8512
8513 (define_expand "sym2GOT"
8514 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8515 ""
8516 "")
8517
8518 (define_expand "symGOT2reg"
8519 [(match_operand 0 "" "") (match_operand 1 "" "")]
8520 ""
8521 "
8522 {
8523 rtx gotsym, insn;
8524
8525 gotsym = gen_sym2GOT (operands[1]);
8526 PUT_MODE (gotsym, Pmode);
8527 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8528
8529 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8530
8531 DONE;
8532 }")
8533
8534 (define_expand "symGOTPLT2reg"
8535 [(match_operand 0 "" "") (match_operand 1 "" "")]
8536 ""
8537 "
8538 {
8539 rtx pltsym = gen_rtx_CONST (Pmode,
8540 gen_rtx_UNSPEC (Pmode,
8541 gen_rtvec (1, operands[1]),
8542 UNSPEC_GOTPLT));
8543 emit_insn (gen_symGOT_load (operands[0], pltsym));
8544 DONE;
8545 }")
8546
8547 (define_expand "sym2GOTOFF"
8548 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8549 ""
8550 "")
8551
8552 (define_expand "symGOTOFF2reg"
8553 [(match_operand 0 "" "") (match_operand 1 "" "")]
8554 ""
8555 "
8556 {
8557 rtx gotoffsym, insn;
8558 rtx t = (!can_create_pseudo_p ()
8559 ? operands[0]
8560 : gen_reg_rtx (GET_MODE (operands[0])));
8561
8562 gotoffsym = gen_sym2GOTOFF (operands[1]);
8563 PUT_MODE (gotoffsym, Pmode);
8564 emit_move_insn (t, gotoffsym);
8565 insn = emit_move_insn (operands[0],
8566 gen_rtx_PLUS (Pmode, t,
8567 gen_rtx_REG (Pmode, PIC_REG)));
8568
8569 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8570
8571 DONE;
8572 }")
8573
8574 (define_expand "symPLT_label2reg"
8575 [(set (match_operand:SI 0 "" "")
8576 (const:SI
8577 (unspec:SI
8578 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8579 (const:SI (plus:SI (match_operand:SI 2 "" "")
8580 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8581 ;; Even though the PIC register is not really used by the call
8582 ;; sequence in which this is expanded, the PLT code assumes the PIC
8583 ;; register is set, so we must not skip its initialization. Since
8584 ;; we only use this expand as part of calling sequences, and never
8585 ;; to take the address of a function, this is the best point to
8586 ;; insert the (use). Using the PLT to take the address of a
8587 ;; function would be wrong, not only because the PLT entry could
8588 ;; then be called from a function that doesn't initialize the PIC
8589 ;; register to the proper GOT, but also because pointers to the
8590 ;; same function might not compare equal, should they be set by
8591 ;; different shared libraries.
8592 (use (reg:SI PIC_REG))]
8593 "TARGET_SH1"
8594 "")
8595
8596 (define_expand "sym2PIC"
8597 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8598 ""
8599 "")
8600
8601 ;; TLS code generation.
8602 ;; ??? this should be a define_insn_and_split
8603 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8604 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8605 ;; for details.
8606
8607 (define_insn "tls_global_dynamic"
8608 [(set (match_operand:SI 0 "register_operand" "=&z")
8609 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8610 UNSPEC_TLSGD))
8611 (const_int 0)))
8612 (use (reg:PSI FPSCR_REG))
8613 (use (reg:SI PIC_REG))
8614 (clobber (reg:SI PR_REG))
8615 (clobber (scratch:SI))]
8616 "TARGET_SH1"
8617 "*
8618 {
8619 return \"\\
8620 mov.l\\t1f,r4\\n\\
8621 \\tmova\\t2f,r0\\n\\
8622 \\tmov.l\\t2f,r1\\n\\
8623 \\tadd\\tr0,r1\\n\\
8624 \\tjsr\\t@r1\\n\\
8625 \\tadd\\tr12,r4\\n\\
8626 \\tbra\\t3f\\n\\
8627 \\tnop\\n\\
8628 \\t.align\\t2\\n\\
8629 1:\\t.long\\t%a1@TLSGD\\n\\
8630 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8631 3:\";
8632 }"
8633 [(set_attr "type" "tls_load")
8634 (set_attr "length" "26")])
8635
8636 (define_insn "tls_local_dynamic"
8637 [(set (match_operand:SI 0 "register_operand" "=&z")
8638 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8639 UNSPEC_TLSLDM))
8640 (const_int 0)))
8641 (use (reg:PSI FPSCR_REG))
8642 (use (reg:SI PIC_REG))
8643 (clobber (reg:SI PR_REG))
8644 (clobber (scratch:SI))]
8645 "TARGET_SH1"
8646 "*
8647 {
8648 return \"\\
8649 mov.l\\t1f,r4\\n\\
8650 \\tmova\\t2f,r0\\n\\
8651 \\tmov.l\\t2f,r1\\n\\
8652 \\tadd\\tr0,r1\\n\\
8653 \\tjsr\\t@r1\\n\\
8654 \\tadd\\tr12,r4\\n\\
8655 \\tbra\\t3f\\n\\
8656 \\tnop\\n\\
8657 \\t.align\\t2\\n\\
8658 1:\\t.long\\t%a1@TLSLDM\\n\\
8659 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8660 3:\";
8661 }"
8662 [(set_attr "type" "tls_load")
8663 (set_attr "length" "26")])
8664
8665 (define_expand "sym2DTPOFF"
8666 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8667 ""
8668 "")
8669
8670 (define_expand "symDTPOFF2reg"
8671 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8672 ""
8673 "
8674 {
8675 rtx dtpoffsym, insn;
8676 rtx t = (!can_create_pseudo_p ()
8677 ? operands[0]
8678 : gen_reg_rtx (GET_MODE (operands[0])));
8679
8680 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8681 PUT_MODE (dtpoffsym, Pmode);
8682 emit_move_insn (t, dtpoffsym);
8683 insn = emit_move_insn (operands[0],
8684 gen_rtx_PLUS (Pmode, t, operands[2]));
8685 DONE;
8686 }")
8687
8688 (define_expand "sym2GOTTPOFF"
8689 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8690 ""
8691 "")
8692
8693 (define_insn "tls_initial_exec"
8694 [(set (match_operand:SI 0 "register_operand" "=&r")
8695 (unspec:SI [(match_operand:SI 1 "" "")]
8696 UNSPEC_TLSIE))
8697 (use (reg:SI GBR_REG))
8698 (use (reg:SI PIC_REG))
8699 (clobber (reg:SI R0_REG))]
8700 ""
8701 "*
8702 {
8703 return \"\\
8704 mov.l\\t1f,r0\\n\\
8705 \\tstc\\tgbr,%0\\n\\
8706 \\tmov.l\\t@(r0,r12),r0\\n\\
8707 \\tbra\\t2f\\n\\
8708 \\tadd\\tr0,%0\\n\\
8709 \\t.align\\t2\\n\\
8710 1:\\t.long\\t%a1\\n\\
8711 2:\";
8712 }"
8713 [(set_attr "type" "tls_load")
8714 (set_attr "length" "16")])
8715
8716 (define_expand "sym2TPOFF"
8717 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8718 ""
8719 "")
8720
8721 (define_expand "symTPOFF2reg"
8722 [(match_operand 0 "" "") (match_operand 1 "" "")]
8723 ""
8724 "
8725 {
8726 rtx tpoffsym, insn;
8727
8728 tpoffsym = gen_sym2TPOFF (operands[1]);
8729 PUT_MODE (tpoffsym, Pmode);
8730 insn = emit_move_insn (operands[0], tpoffsym);
8731 DONE;
8732 }")
8733
8734 (define_insn "load_gbr"
8735 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8736 (use (reg:SI GBR_REG))]
8737 ""
8738 "stc gbr,%0"
8739 [(set_attr "type" "tls_load")])
8740
8741 ;; case instruction for switch statements.
8742
8743 ;; Operand 0 is index
8744 ;; operand 1 is the minimum bound
8745 ;; operand 2 is the maximum bound - minimum bound + 1
8746 ;; operand 3 is CODE_LABEL for the table;
8747 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8748
8749 (define_expand "casesi"
8750 [(match_operand:SI 0 "arith_reg_operand" "")
8751 (match_operand:SI 1 "arith_reg_operand" "")
8752 (match_operand:SI 2 "arith_reg_operand" "")
8753 (match_operand 3 "" "") (match_operand 4 "" "")]
8754 ""
8755 "
8756 {
8757 rtx reg = gen_reg_rtx (SImode);
8758 rtx reg2 = gen_reg_rtx (SImode);
8759 if (TARGET_SHMEDIA)
8760 {
8761 rtx reg = gen_reg_rtx (DImode);
8762 rtx reg2 = gen_reg_rtx (DImode);
8763 rtx reg3 = gen_reg_rtx (Pmode);
8764 rtx reg4 = gen_reg_rtx (Pmode);
8765 rtx reg5 = gen_reg_rtx (Pmode);
8766 rtx load, test;
8767
8768 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8769 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8770 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8771
8772 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8773 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8774 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8775 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8776 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8777 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8778 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8779 (Pmode, operands[3])));
8780 /* Messy: can we subreg to clean this up? */
8781 if (Pmode == DImode)
8782 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8783 else
8784 load = gen_casesi_load_media (reg4,
8785 gen_rtx_SUBREG (DImode, reg3, 0),
8786 reg2, operands[3]);
8787 PUT_MODE (SET_SRC (load), Pmode);
8788 emit_insn (load);
8789 /* ??? The following add could be eliminated if we used ptrel. */
8790 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8791 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8792 emit_barrier ();
8793 DONE;
8794 }
8795 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8796 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8797 /* If optimizing, casesi_worker depends on the mode of the instruction
8798 before label it 'uses' - operands[3]. */
8799 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8800 reg));
8801 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8802 if (TARGET_SH2)
8803 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8804 else
8805 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8806 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8807 operands[3], but to lab. We will fix this up in
8808 machine_dependent_reorg. */
8809 emit_barrier ();
8810 DONE;
8811 }")
8812
8813 (define_expand "casesi_0"
8814 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8815 (set (match_dup 4) (minus:SI (match_dup 4)
8816 (match_operand:SI 1 "arith_operand" "")))
8817 (set (reg:SI T_REG)
8818 (gtu:SI (match_dup 4)
8819 (match_operand:SI 2 "arith_reg_operand" "")))
8820 (set (pc)
8821 (if_then_else (ne (reg:SI T_REG)
8822 (const_int 0))
8823 (label_ref (match_operand 3 "" ""))
8824 (pc)))]
8825 "TARGET_SH1"
8826 "")
8827
8828 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8829 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8830 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8831
8832 (define_insn "casesi_worker_0"
8833 [(set (match_operand:SI 0 "register_operand" "=r,r")
8834 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8835 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8836 (clobber (match_scratch:SI 3 "=X,1"))
8837 (clobber (match_scratch:SI 4 "=&z,z"))]
8838 "TARGET_SH1"
8839 "#")
8840
8841 (define_split
8842 [(set (match_operand:SI 0 "register_operand" "")
8843 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8844 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8845 (clobber (match_scratch:SI 3 ""))
8846 (clobber (match_scratch:SI 4 ""))]
8847 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8848 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8849 (parallel [(set (match_dup 0)
8850 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8851 (label_ref (match_dup 2))] UNSPEC_CASESI))
8852 (clobber (match_dup 3))])
8853 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8854 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8855
8856 (define_split
8857 [(set (match_operand:SI 0 "register_operand" "")
8858 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8859 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8860 (clobber (match_scratch:SI 3 ""))
8861 (clobber (match_scratch:SI 4 ""))]
8862 "TARGET_SH2 && reload_completed"
8863 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8864 (parallel [(set (match_dup 0)
8865 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8866 (label_ref (match_dup 2))] UNSPEC_CASESI))
8867 (clobber (match_dup 3))])]
8868 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8869
8870 (define_insn "casesi_worker_1"
8871 [(set (match_operand:SI 0 "register_operand" "=r,r")
8872 (unspec:SI [(reg:SI R0_REG)
8873 (match_operand:SI 1 "register_operand" "0,r")
8874 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8875 (clobber (match_scratch:SI 3 "=X,1"))]
8876 "TARGET_SH1"
8877 "*
8878 {
8879 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8880
8881 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8882
8883 switch (GET_MODE (diff_vec))
8884 {
8885 case SImode:
8886 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8887 case HImode:
8888 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8889 case QImode:
8890 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8891 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8892 return \"mov.b @(r0,%1),%0\";
8893 default:
8894 gcc_unreachable ();
8895 }
8896 }"
8897 [(set_attr "length" "4")])
8898
8899 (define_insn "casesi_worker_2"
8900 [(set (match_operand:SI 0 "register_operand" "=r,r")
8901 (unspec:SI [(reg:SI R0_REG)
8902 (match_operand:SI 1 "register_operand" "0,r")
8903 (label_ref (match_operand 2 "" ""))
8904 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8905 (clobber (match_operand:SI 4 "" "=X,1"))]
8906 "TARGET_SH2 && reload_completed && flag_pic"
8907 "*
8908 {
8909 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8910 const char *load;
8911
8912 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8913
8914 switch (GET_MODE (diff_vec))
8915 {
8916 case SImode:
8917 output_asm_insn (\"shll2 %1\", operands);
8918 load = \"mov.l @(r0,%1),%0\"; break;
8919 case HImode:
8920 output_asm_insn (\"add %1,%1\", operands);
8921 load = \"mov.w @(r0,%1),%0\"; break;
8922 case QImode:
8923 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8924 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8925 else
8926 load = \"mov.b @(r0,%1),%0\";
8927 break;
8928 default:
8929 gcc_unreachable ();
8930 }
8931 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8932 return load;
8933 }"
8934 [(set_attr "length" "8")])
8935
8936 (define_insn "casesi_shift_media"
8937 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8938 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8939 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8940 UNSPEC_CASESI)))]
8941 "TARGET_SHMEDIA"
8942 "*
8943 {
8944 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8945
8946 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8947
8948 switch (GET_MODE (diff_vec))
8949 {
8950 case SImode:
8951 return \"shlli %1, 2, %0\";
8952 case HImode:
8953 return \"shlli %1, 1, %0\";
8954 case QImode:
8955 if (rtx_equal_p (operands[0], operands[1]))
8956 return \"\";
8957 return \"add %1, r63, %0\";
8958 default:
8959 gcc_unreachable ();
8960 }
8961 }"
8962 [(set_attr "type" "arith_media")])
8963
8964 (define_insn "casesi_load_media"
8965 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8966 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8967 (match_operand:DI 2 "arith_reg_operand" "r")
8968 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8969 "TARGET_SHMEDIA"
8970 "*
8971 {
8972 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8973
8974 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8975
8976 switch (GET_MODE (diff_vec))
8977 {
8978 case SImode:
8979 return \"ldx.l %1, %2, %0\";
8980 case HImode:
8981 #if 0
8982 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8983 return \"ldx.uw %1, %2, %0\";
8984 #endif
8985 return \"ldx.w %1, %2, %0\";
8986 case QImode:
8987 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8988 return \"ldx.ub %1, %2, %0\";
8989 return \"ldx.b %1, %2, %0\";
8990 default:
8991 gcc_unreachable ();
8992 }
8993 }"
8994 [(set_attr "type" "load_media")])
8995
8996 (define_expand "return"
8997 [(return)]
8998 "reload_completed && ! sh_need_epilogue ()"
8999 "
9000 {
9001 if (TARGET_SHMEDIA)
9002 {
9003 emit_jump_insn (gen_return_media ());
9004 DONE;
9005 }
9006
9007 if (TARGET_SHCOMPACT
9008 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9009 {
9010 emit_jump_insn (gen_shcompact_return_tramp ());
9011 DONE;
9012 }
9013 }")
9014
9015 (define_insn "*return_i"
9016 [(return)]
9017 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9018 && (crtl->args.info.call_cookie
9019 & CALL_COOKIE_RET_TRAMP (1)))
9020 && reload_completed
9021 && lookup_attribute (\"trap_exit\",
9022 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9023 "*
9024 {
9025 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9026 && !current_function_interrupt)
9027 return \"rts/n\";
9028 else
9029 return \"%@ %#\";
9030 }"
9031 [(set_attr "type" "return")
9032 (set_attr "needs_delay_slot" "yes")])
9033
9034 ;; trapa has no delay slot.
9035 (define_insn "*return_trapa"
9036 [(return)]
9037 "TARGET_SH1 && !TARGET_SHCOMPACT
9038 && reload_completed"
9039 "%@"
9040 [(set_attr "type" "return")])
9041
9042 (define_expand "shcompact_return_tramp"
9043 [(return)]
9044 "TARGET_SHCOMPACT
9045 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9046 "
9047 {
9048 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9049
9050 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9051 emit_jump_insn (gen_shcompact_return_tramp_i ());
9052 DONE;
9053 }")
9054
9055 (define_insn "shcompact_return_tramp_i"
9056 [(parallel [(return) (use (reg:SI R0_REG))])]
9057 "TARGET_SHCOMPACT
9058 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9059 "jmp @r0%#"
9060 [(set_attr "type" "jump_ind")
9061 (set_attr "needs_delay_slot" "yes")])
9062
9063 (define_insn "return_media_i"
9064 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9065 "TARGET_SHMEDIA && reload_completed"
9066 "blink %0, r63"
9067 [(set_attr "type" "jump_media")])
9068
9069 (define_insn "return_media_rte"
9070 [(return)]
9071 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9072 "rte"
9073 [(set_attr "type" "jump_media")])
9074
9075 (define_expand "return_media"
9076 [(return)]
9077 "TARGET_SHMEDIA && reload_completed"
9078 "
9079 {
9080 int tr_regno = sh_media_register_for_return ();
9081 rtx tr;
9082
9083 if (current_function_interrupt)
9084 {
9085 emit_jump_insn (gen_return_media_rte ());
9086 DONE;
9087 }
9088 if (tr_regno < 0)
9089 {
9090 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9091
9092 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9093 tr_regno = TR0_REG;
9094 tr = gen_rtx_REG (Pmode, tr_regno);
9095 emit_move_insn (tr, r18);
9096 }
9097 else
9098 tr = gen_rtx_REG (Pmode, tr_regno);
9099
9100 emit_jump_insn (gen_return_media_i (tr));
9101 DONE;
9102 }")
9103
9104 (define_insn "shcompact_preserve_incoming_args"
9105 [(set (match_operand:SI 0 "register_operand" "+r")
9106 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9107 "TARGET_SHCOMPACT"
9108 ""
9109 [(set_attr "length" "0")])
9110
9111 (define_insn "shcompact_incoming_args"
9112 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9113 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9114 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9115 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9116 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9117 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9118 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9119 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9120 (set (mem:BLK (reg:SI MACL_REG))
9121 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9122 (use (reg:SI R0_REG))
9123 (clobber (reg:SI R0_REG))
9124 (clobber (reg:SI MACL_REG))
9125 (clobber (reg:SI MACH_REG))
9126 (clobber (reg:SI PR_REG))]
9127 "TARGET_SHCOMPACT"
9128 "jsr @r0%#"
9129 [(set_attr "needs_delay_slot" "yes")])
9130
9131 (define_insn "shmedia_save_restore_regs_compact"
9132 [(set (reg:SI SP_REG)
9133 (plus:SI (reg:SI SP_REG)
9134 (match_operand:SI 0 "immediate_operand" "i")))
9135 (use (reg:SI R0_REG))
9136 (clobber (reg:SI PR_REG))]
9137 "TARGET_SHCOMPACT
9138 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9139 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9140 "jsr @r0%#"
9141 [(set_attr "needs_delay_slot" "yes")])
9142
9143 (define_expand "prologue"
9144 [(const_int 0)]
9145 ""
9146 "sh_expand_prologue (); DONE;")
9147
9148 (define_expand "epilogue"
9149 [(return)]
9150 ""
9151 "
9152 {
9153 sh_expand_epilogue (0);
9154 emit_jump_insn (gen_return ());
9155 DONE;
9156 }")
9157
9158 (define_expand "eh_return"
9159 [(use (match_operand 0 "register_operand" ""))]
9160 ""
9161 {
9162 rtx ra = operands[0];
9163
9164 if (TARGET_SHMEDIA64)
9165 emit_insn (gen_eh_set_ra_di (ra));
9166 else
9167 emit_insn (gen_eh_set_ra_si (ra));
9168
9169 DONE;
9170 })
9171
9172 ;; Clobber the return address on the stack. We can't expand this
9173 ;; until we know where it will be put in the stack frame.
9174
9175 (define_insn "eh_set_ra_si"
9176 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9177 UNSPECV_EH_RETURN)
9178 (clobber (match_scratch:SI 1 "=&r"))]
9179 "! TARGET_SHMEDIA64"
9180 "#")
9181
9182 (define_insn "eh_set_ra_di"
9183 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9184 UNSPECV_EH_RETURN)
9185 (clobber (match_scratch:DI 1 "=&r"))]
9186 "TARGET_SHMEDIA64"
9187 "#")
9188
9189 (define_split
9190 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9191 UNSPECV_EH_RETURN)
9192 (clobber (match_scratch 1 ""))]
9193 "reload_completed"
9194 [(const_int 0)]
9195 "
9196 {
9197 sh_set_return_address (operands[0], operands[1]);
9198 DONE;
9199 }")
9200
9201 (define_insn "blockage"
9202 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9203 ""
9204 ""
9205 [(set_attr "length" "0")])
9206 \f
9207 ;; ------------------------------------------------------------------------
9208 ;; Scc instructions
9209 ;; ------------------------------------------------------------------------
9210
9211 (define_insn "movt"
9212 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9213 (eq:SI (reg:SI T_REG) (const_int 1)))]
9214 "TARGET_SH1"
9215 "movt %0"
9216 [(set_attr "type" "arith")])
9217
9218 (define_expand "cstore4_media"
9219 [(set (match_operand:SI 0 "register_operand" "=r")
9220 (match_operator:SI 1 "sh_float_comparison_operator"
9221 [(match_operand 2 "logical_operand" "")
9222 (match_operand 3 "cmp_operand" "")]))]
9223 "TARGET_SHMEDIA"
9224 "
9225 {
9226 enum machine_mode mode = GET_MODE (operands[2]);
9227 enum rtx_code code = GET_CODE (operands[1]);
9228 bool invert, swap;
9229 if (mode == VOIDmode)
9230 mode = GET_MODE (operands[3]);
9231 if (operands[2] == const0_rtx)
9232 {
9233 if (code == EQ || code == NE)
9234 operands[2] = operands[3], operands[3] = const0_rtx;
9235 }
9236 else
9237 operands[2] = force_reg (mode, operands[2]);
9238 if (operands[3] != const0_rtx)
9239 operands[3] = force_reg (mode, operands[3]);
9240
9241 switch (code)
9242 {
9243 case GEU:
9244 case GE:
9245 swap = invert = !FLOAT_MODE_P (mode);
9246 break;
9247
9248 case LEU:
9249 case LE:
9250 swap = FLOAT_MODE_P (mode), invert = !swap;
9251 break;
9252
9253 case LTU:
9254 case LT:
9255 swap = true, invert = false;
9256 break;
9257
9258 case GTU:
9259 case GT:
9260 case EQ:
9261 case UNORDERED:
9262 swap = invert = false;
9263 break;
9264
9265 case NE:
9266 swap = invert = true;
9267 break;
9268
9269 default:
9270 gcc_unreachable ();
9271 }
9272
9273 if (swap)
9274 {
9275 rtx tem = operands[2];
9276 operands[2] = operands[3];
9277 operands[3] = tem;
9278 code = swap_condition (code);
9279 }
9280
9281 if (invert)
9282 {
9283 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9284 code = reverse_condition (code);
9285 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9286 emit_insn (gen_cstore4_media (tem, operands[1],
9287 operands[2], operands[3]));
9288 code = EQ;
9289 operands[2] = tem;
9290 operands[3] = const0_rtx;
9291 }
9292
9293 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9294 }")
9295
9296 (define_expand "cstoresi4"
9297 [(set (match_operand:SI 0 "register_operand" "=r")
9298 (match_operator:SI 1 "comparison_operator"
9299 [(match_operand:SI 2 "cmpsi_operand" "")
9300 (match_operand:SI 3 "arith_operand" "")]))]
9301 "TARGET_SH1 || TARGET_SHMEDIA"
9302 "if (TARGET_SHMEDIA)
9303 {
9304 emit_insn (gen_cstore4_media (operands[0], operands[1],
9305 operands[2], operands[3]));
9306 DONE;
9307 }
9308
9309 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9310 && sh_expand_t_scc (operands))
9311 DONE;
9312
9313 if (! currently_expanding_to_rtl)
9314 FAIL;
9315
9316 sh_emit_compare_and_set (operands, SImode);
9317 DONE;
9318 ")
9319
9320 (define_expand "cstoredi4"
9321 [(set (match_operand:SI 0 "register_operand" "=r")
9322 (match_operator:SI 1 "comparison_operator"
9323 [(match_operand:DI 2 "arith_operand" "")
9324 (match_operand:DI 3 "arith_operand" "")]))]
9325 "TARGET_SH2 || TARGET_SHMEDIA"
9326 "if (TARGET_SHMEDIA)
9327 {
9328 emit_insn (gen_cstore4_media (operands[0], operands[1],
9329 operands[2], operands[3]));
9330 DONE;
9331 }
9332
9333 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9334 && sh_expand_t_scc (operands))
9335 DONE;
9336
9337 if (! currently_expanding_to_rtl)
9338 FAIL;
9339
9340 sh_emit_compare_and_set (operands, DImode);
9341 DONE;
9342 ")
9343
9344
9345
9346 ;; sne moves the complement of the T reg to DEST like this:
9347 ;; cmp/eq ...
9348 ;; mov #-1,temp
9349 ;; negc temp,dest
9350 ;; This is better than xoring compare result with 1 because it does
9351 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9352 ;; loop.
9353
9354 (define_expand "movnegt"
9355 [(set (match_dup 1) (const_int -1))
9356 (parallel [(set (match_operand:SI 0 "" "")
9357 (neg:SI (plus:SI (reg:SI T_REG)
9358 (match_dup 1))))
9359 (set (reg:SI T_REG)
9360 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9361 (const_int 0)))])]
9362 ""
9363 "
9364 {
9365 operands[1] = gen_reg_rtx (SImode);
9366 }")
9367
9368
9369 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9370 ;; This prevents a regression that occurred when we switched from xor to
9371 ;; mov/neg for sne.
9372
9373 (define_split
9374 [(set (match_operand:SI 0 "arith_reg_dest" "")
9375 (plus:SI (reg:SI T_REG)
9376 (const_int -1)))]
9377 "TARGET_SH1"
9378 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9379 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9380 "")
9381
9382 (define_expand "cstoresf4"
9383 [(set (match_operand:SI 0 "register_operand" "=r")
9384 (match_operator:SI 1 "sh_float_comparison_operator"
9385 [(match_operand:SF 2 "arith_operand" "")
9386 (match_operand:SF 3 "arith_operand" "")]))]
9387 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9388 "if (TARGET_SHMEDIA)
9389 {
9390 emit_insn (gen_cstore4_media (operands[0], operands[1],
9391 operands[2], operands[3]));
9392 DONE;
9393 }
9394
9395 if (! currently_expanding_to_rtl)
9396 FAIL;
9397
9398 sh_emit_compare_and_set (operands, SFmode);
9399 DONE;
9400 ")
9401
9402 (define_expand "cstoredf4"
9403 [(set (match_operand:SI 0 "register_operand" "=r")
9404 (match_operator:SI 1 "sh_float_comparison_operator"
9405 [(match_operand:DF 2 "arith_operand" "")
9406 (match_operand:DF 3 "arith_operand" "")]))]
9407 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9408 "if (TARGET_SHMEDIA)
9409 {
9410 emit_insn (gen_cstore4_media (operands[0], operands[1],
9411 operands[2], operands[3]));
9412 DONE;
9413 }
9414
9415 if (! currently_expanding_to_rtl)
9416 FAIL;
9417
9418 sh_emit_compare_and_set (operands, DFmode);
9419 DONE;
9420 ")
9421
9422
9423 ;; -------------------------------------------------------------------------
9424 ;; Instructions to cope with inline literal tables
9425 ;; -------------------------------------------------------------------------
9426
9427 ; 2 byte integer in line
9428
9429 (define_insn "consttable_2"
9430 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9431 (match_operand 1 "" "")]
9432 UNSPECV_CONST2)]
9433 ""
9434 "*
9435 {
9436 if (operands[1] != const0_rtx)
9437 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9438 return \"\";
9439 }"
9440 [(set_attr "length" "2")
9441 (set_attr "in_delay_slot" "no")])
9442
9443 ; 4 byte integer in line
9444
9445 (define_insn "consttable_4"
9446 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9447 (match_operand 1 "" "")]
9448 UNSPECV_CONST4)]
9449 ""
9450 "*
9451 {
9452 if (operands[1] != const0_rtx)
9453 {
9454 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9455 mark_symbol_refs_as_used (operands[0]);
9456 }
9457 return \"\";
9458 }"
9459 [(set_attr "length" "4")
9460 (set_attr "in_delay_slot" "no")])
9461
9462 ; 8 byte integer in line
9463
9464 (define_insn "consttable_8"
9465 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9466 (match_operand 1 "" "")]
9467 UNSPECV_CONST8)]
9468 ""
9469 "*
9470 {
9471 if (operands[1] != const0_rtx)
9472 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9473 return \"\";
9474 }"
9475 [(set_attr "length" "8")
9476 (set_attr "in_delay_slot" "no")])
9477
9478 ; 4 byte floating point
9479
9480 (define_insn "consttable_sf"
9481 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9482 (match_operand 1 "" "")]
9483 UNSPECV_CONST4)]
9484 ""
9485 "*
9486 {
9487 if (operands[1] != const0_rtx)
9488 {
9489 REAL_VALUE_TYPE d;
9490 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9491 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9492 }
9493 return \"\";
9494 }"
9495 [(set_attr "length" "4")
9496 (set_attr "in_delay_slot" "no")])
9497
9498 ; 8 byte floating point
9499
9500 (define_insn "consttable_df"
9501 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9502 (match_operand 1 "" "")]
9503 UNSPECV_CONST8)]
9504 ""
9505 "*
9506 {
9507 if (operands[1] != const0_rtx)
9508 {
9509 REAL_VALUE_TYPE d;
9510 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9511 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9512 }
9513 return \"\";
9514 }"
9515 [(set_attr "length" "8")
9516 (set_attr "in_delay_slot" "no")])
9517
9518 ;; Alignment is needed for some constant tables; it may also be added for
9519 ;; Instructions at the start of loops, or after unconditional branches.
9520 ;; ??? We would get more accurate lengths if we did instruction
9521 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9522 ;; here is too conservative.
9523
9524 ; align to a two byte boundary
9525
9526 (define_expand "align_2"
9527 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9528 ""
9529 "")
9530
9531 ; align to a four byte boundary
9532 ;; align_4 and align_log are instructions for the starts of loops, or
9533 ;; after unconditional branches, which may take up extra room.
9534
9535 (define_expand "align_4"
9536 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9537 ""
9538 "")
9539
9540 ; align to a cache line boundary
9541
9542 (define_insn "align_log"
9543 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9544 ""
9545 ""
9546 [(set_attr "length" "0")
9547 (set_attr "in_delay_slot" "no")])
9548
9549 ; emitted at the end of the literal table, used to emit the
9550 ; 32bit branch labels if needed.
9551
9552 (define_insn "consttable_end"
9553 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9554 ""
9555 "* return output_jump_label_table ();"
9556 [(set_attr "in_delay_slot" "no")])
9557
9558 ; emitted at the end of the window in the literal table.
9559
9560 (define_insn "consttable_window_end"
9561 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9562 ""
9563 ""
9564 [(set_attr "length" "0")
9565 (set_attr "in_delay_slot" "no")])
9566
9567 ;; -------------------------------------------------------------------------
9568 ;; Misc
9569 ;; -------------------------------------------------------------------------
9570
9571 ;; String/block move insn.
9572
9573 (define_expand "movmemsi"
9574 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9575 (mem:BLK (match_operand:BLK 1 "" "")))
9576 (use (match_operand:SI 2 "nonmemory_operand" ""))
9577 (use (match_operand:SI 3 "immediate_operand" ""))
9578 (clobber (reg:SI PR_REG))
9579 (clobber (reg:SI R4_REG))
9580 (clobber (reg:SI R5_REG))
9581 (clobber (reg:SI R0_REG))])]
9582 "TARGET_SH1 && ! TARGET_SH5"
9583 "
9584 {
9585 if(expand_block_move (operands))
9586 DONE;
9587 else FAIL;
9588 }")
9589
9590 (define_insn "block_move_real"
9591 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9592 (mem:BLK (reg:SI R5_REG)))
9593 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9594 (clobber (reg:SI PR_REG))
9595 (clobber (reg:SI R0_REG))])]
9596 "TARGET_SH1 && ! TARGET_HARD_SH4"
9597 "jsr @%0%#"
9598 [(set_attr "type" "sfunc")
9599 (set_attr "needs_delay_slot" "yes")])
9600
9601 (define_insn "block_lump_real"
9602 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9603 (mem:BLK (reg:SI R5_REG)))
9604 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9605 (use (reg:SI R6_REG))
9606 (clobber (reg:SI PR_REG))
9607 (clobber (reg:SI T_REG))
9608 (clobber (reg:SI R4_REG))
9609 (clobber (reg:SI R5_REG))
9610 (clobber (reg:SI R6_REG))
9611 (clobber (reg:SI R0_REG))])]
9612 "TARGET_SH1 && ! TARGET_HARD_SH4"
9613 "jsr @%0%#"
9614 [(set_attr "type" "sfunc")
9615 (set_attr "needs_delay_slot" "yes")])
9616
9617 (define_insn "block_move_real_i4"
9618 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9619 (mem:BLK (reg:SI R5_REG)))
9620 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9621 (clobber (reg:SI PR_REG))
9622 (clobber (reg:SI R0_REG))
9623 (clobber (reg:SI R1_REG))
9624 (clobber (reg:SI R2_REG))])]
9625 "TARGET_HARD_SH4"
9626 "jsr @%0%#"
9627 [(set_attr "type" "sfunc")
9628 (set_attr "needs_delay_slot" "yes")])
9629
9630 (define_insn "block_lump_real_i4"
9631 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9632 (mem:BLK (reg:SI R5_REG)))
9633 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9634 (use (reg:SI R6_REG))
9635 (clobber (reg:SI PR_REG))
9636 (clobber (reg:SI T_REG))
9637 (clobber (reg:SI R4_REG))
9638 (clobber (reg:SI R5_REG))
9639 (clobber (reg:SI R6_REG))
9640 (clobber (reg:SI R0_REG))
9641 (clobber (reg:SI R1_REG))
9642 (clobber (reg:SI R2_REG))
9643 (clobber (reg:SI R3_REG))])]
9644 "TARGET_HARD_SH4"
9645 "jsr @%0%#"
9646 [(set_attr "type" "sfunc")
9647 (set_attr "needs_delay_slot" "yes")])
9648 \f
9649 ;; -------------------------------------------------------------------------
9650 ;; Floating point instructions.
9651 ;; -------------------------------------------------------------------------
9652
9653 ;; ??? All patterns should have a type attribute.
9654
9655 (define_expand "movpsi"
9656 [(set (match_operand:PSI 0 "register_operand" "")
9657 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9658 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9659 "")
9660
9661 ;; The c / m alternative is a fake to guide reload to load directly into
9662 ;; fpscr, since reload doesn't know how to use post-increment.
9663 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9664 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9665 ;; predicate after reload.
9666 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9667 ;; like a mac -> gpr move.
9668 (define_insn "fpu_switch"
9669 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9670 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9671 "TARGET_SH2E
9672 && (! reload_completed
9673 || true_regnum (operands[0]) != FPSCR_REG
9674 || !MEM_P (operands[1])
9675 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9676 "@
9677 ! precision stays the same
9678 lds.l %1,fpscr
9679 mov.l %1,%0
9680 #
9681 lds %1,fpscr
9682 mov %1,%0
9683 mov.l %1,%0
9684 sts fpscr,%0
9685 sts.l fpscr,%0"
9686 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9687 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9688
9689 (define_peephole2
9690 [(set (reg:PSI FPSCR_REG)
9691 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9692 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9693 [(const_int 0)]
9694 {
9695 rtx fpscr, mem, new_insn;
9696
9697 fpscr = SET_DEST (PATTERN (curr_insn));
9698 mem = SET_SRC (PATTERN (curr_insn));
9699 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9700
9701 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9702 add_reg_note (new_insn, REG_INC, operands[0]);
9703 DONE;
9704 })
9705
9706 (define_split
9707 [(set (reg:PSI FPSCR_REG)
9708 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9709 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9710 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9711 [(const_int 0)]
9712 {
9713 rtx fpscr, mem, new_insn;
9714
9715 fpscr = SET_DEST (PATTERN (curr_insn));
9716 mem = SET_SRC (PATTERN (curr_insn));
9717 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9718
9719 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9720 add_reg_note (new_insn, REG_INC, operands[0]);
9721
9722 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9723 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9724 DONE;
9725 })
9726
9727 ;; ??? This uses the fp unit, but has no type indicating that.
9728 ;; If we did that, this would either give a bogus latency or introduce
9729 ;; a bogus FIFO constraint.
9730 ;; Since this insn is currently only used for prologues/epilogues,
9731 ;; it is probably best to claim no function unit, which matches the
9732 ;; current setting.
9733 (define_insn "toggle_sz"
9734 [(set (reg:PSI FPSCR_REG)
9735 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9736 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9737 "fschg"
9738 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9739
9740 ;; There's no way we can use it today, since optimize mode switching
9741 ;; doesn't enable us to know from which mode we're switching to the
9742 ;; mode it requests, to tell whether we can use a relative mode switch
9743 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9744 ;; memory).
9745 (define_insn "toggle_pr"
9746 [(set (reg:PSI FPSCR_REG)
9747 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9748 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9749 "fpchg"
9750 [(set_attr "type" "fpscr_toggle")])
9751
9752 (define_expand "addsf3"
9753 [(set (match_operand:SF 0 "arith_reg_operand" "")
9754 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9755 (match_operand:SF 2 "arith_reg_operand" "")))]
9756 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9757 "
9758 {
9759 if (TARGET_SH2E)
9760 {
9761 expand_sf_binop (&gen_addsf3_i, operands);
9762 DONE;
9763 }
9764 }")
9765
9766 (define_insn "*addsf3_media"
9767 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9768 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9769 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9770 "TARGET_SHMEDIA_FPU"
9771 "fadd.s %1, %2, %0"
9772 [(set_attr "type" "fparith_media")])
9773
9774 (define_insn_and_split "unary_sf_op"
9775 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9776 (vec_select:V2SF
9777 (vec_concat:V2SF
9778 (vec_select:SF
9779 (match_dup 0)
9780 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9781 (match_operator:SF 2 "unary_float_operator"
9782 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9783 (parallel [(match_operand 4
9784 "const_int_operand" "n")]))]))
9785 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9786 "TARGET_SHMEDIA_FPU"
9787 "#"
9788 "TARGET_SHMEDIA_FPU && reload_completed"
9789 [(set (match_dup 5) (match_dup 6))]
9790 "
9791 {
9792 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9793 rtx op1 = gen_rtx_REG (SFmode,
9794 (true_regnum (operands[1])
9795 + (INTVAL (operands[4]) ^ endian)));
9796
9797 operands[7] = gen_rtx_REG (SFmode,
9798 (true_regnum (operands[0])
9799 + (INTVAL (operands[3]) ^ endian)));
9800 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9801 }"
9802 [(set_attr "type" "fparith_media")])
9803
9804 (define_insn_and_split "binary_sf_op0"
9805 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9806 (vec_concat:V2SF
9807 (match_operator:SF 3 "binary_float_operator"
9808 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9809 (parallel [(const_int 0)]))
9810 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9811 (parallel [(const_int 0)]))])
9812 (vec_select:SF
9813 (match_dup 0)
9814 (parallel [(const_int 1)]))))]
9815 "TARGET_SHMEDIA_FPU"
9816 "#"
9817 "&& reload_completed"
9818 [(set (match_dup 4) (match_dup 5))]
9819 "
9820 {
9821 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9822 rtx op1 = gen_rtx_REG (SFmode,
9823 true_regnum (operands[1]) + endian);
9824 rtx op2 = gen_rtx_REG (SFmode,
9825 true_regnum (operands[2]) + endian);
9826
9827 operands[4] = gen_rtx_REG (SFmode,
9828 true_regnum (operands[0]) + endian);
9829 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9830 }"
9831 [(set_attr "type" "fparith_media")])
9832
9833 (define_insn_and_split "binary_sf_op1"
9834 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9835 (vec_concat:V2SF
9836 (vec_select:SF
9837 (match_dup 0)
9838 (parallel [(const_int 0)]))
9839 (match_operator:SF 3 "binary_float_operator"
9840 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9841 (parallel [(const_int 1)]))
9842 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9843 (parallel [(const_int 1)]))])))]
9844 "TARGET_SHMEDIA_FPU"
9845 "#"
9846 "&& reload_completed"
9847 [(set (match_dup 4) (match_dup 5))]
9848 "
9849 {
9850 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9851 rtx op1 = gen_rtx_REG (SFmode,
9852 true_regnum (operands[1]) + (1 ^ endian));
9853 rtx op2 = gen_rtx_REG (SFmode,
9854 true_regnum (operands[2]) + (1 ^ endian));
9855
9856 operands[4] = gen_rtx_REG (SFmode,
9857 true_regnum (operands[0]) + (1 ^ endian));
9858 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9859 }"
9860 [(set_attr "type" "fparith_media")])
9861
9862 (define_insn "addsf3_i"
9863 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9864 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9865 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9866 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9867 "TARGET_SH2E"
9868 "fadd %2,%0"
9869 [(set_attr "type" "fp")
9870 (set_attr "fp_mode" "single")])
9871
9872 (define_expand "subsf3"
9873 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9874 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9875 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9876 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9877 "
9878 {
9879 if (TARGET_SH2E)
9880 {
9881 expand_sf_binop (&gen_subsf3_i, operands);
9882 DONE;
9883 }
9884 }")
9885
9886 (define_insn "*subsf3_media"
9887 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9888 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9889 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9890 "TARGET_SHMEDIA_FPU"
9891 "fsub.s %1, %2, %0"
9892 [(set_attr "type" "fparith_media")])
9893
9894 (define_insn "subsf3_i"
9895 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9896 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9897 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9898 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9899 "TARGET_SH2E"
9900 "fsub %2,%0"
9901 [(set_attr "type" "fp")
9902 (set_attr "fp_mode" "single")])
9903
9904 (define_expand "mulsf3"
9905 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9906 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9907 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9908 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9909 "")
9910
9911 (define_insn "*mulsf3_media"
9912 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9913 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9914 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9915 "TARGET_SHMEDIA_FPU"
9916 "fmul.s %1, %2, %0"
9917 [(set_attr "type" "fparith_media")])
9918
9919 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9920 ;; register in feeding fp instructions. Thus, in order to generate fmac,
9921 ;; we start out with a mulsf pattern that does not depend on fpscr.
9922 ;; This is split after combine to introduce the dependency, in order to
9923 ;; get mode switching and scheduling right.
9924 (define_insn_and_split "mulsf3_ie"
9925 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9926 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9927 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9928 "TARGET_SH2E"
9929 "fmul %2,%0"
9930 "TARGET_SH4 || TARGET_SH2A_SINGLE"
9931 [(const_int 0)]
9932 "
9933 {
9934 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9935 get_fpscr_rtx ()));
9936 DONE;
9937 }"
9938 [(set_attr "type" "fp")])
9939
9940 (define_insn "mulsf3_i4"
9941 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9942 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9943 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9944 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9945 "TARGET_SH2E"
9946 "fmul %2,%0"
9947 [(set_attr "type" "fp")
9948 (set_attr "fp_mode" "single")])
9949
9950 (define_insn "mac_media"
9951 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9952 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9953 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9954 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
9955 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
9956 "fmac.s %1, %2, %0"
9957 [(set_attr "type" "fparith_media")])
9958
9959 (define_insn "*macsf3"
9960 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9961 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
9962 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9963 (match_operand:SF 3 "arith_reg_operand" "0")))
9964 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
9965 "TARGET_SH2E && TARGET_FMAC"
9966 "fmac fr0,%2,%0"
9967 [(set_attr "type" "fp")
9968 (set_attr "fp_mode" "single")])
9969
9970 (define_expand "divsf3"
9971 [(set (match_operand:SF 0 "arith_reg_operand" "")
9972 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
9973 (match_operand:SF 2 "arith_reg_operand" "")))]
9974 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9975 "
9976 {
9977 if (TARGET_SH2E)
9978 {
9979 expand_sf_binop (&gen_divsf3_i, operands);
9980 DONE;
9981 }
9982 }")
9983
9984 (define_insn "*divsf3_media"
9985 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9986 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9987 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9988 "TARGET_SHMEDIA_FPU"
9989 "fdiv.s %1, %2, %0"
9990 [(set_attr "type" "fdiv_media")])
9991
9992 (define_insn "divsf3_i"
9993 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
9994 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
9995 (match_operand:SF 2 "arith_reg_operand" "f")))
9996 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9997 "TARGET_SH2E"
9998 "fdiv %2,%0"
9999 [(set_attr "type" "fdiv")
10000 (set_attr "fp_mode" "single")])
10001
10002 (define_insn "floatdisf2"
10003 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10004 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10005 "TARGET_SHMEDIA_FPU"
10006 "float.qs %1, %0"
10007 [(set_attr "type" "fpconv_media")])
10008
10009 (define_expand "floatsisf2"
10010 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10011 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10012 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10013 "
10014 {
10015 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10016 {
10017 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10018 DONE;
10019 }
10020 }")
10021
10022 (define_insn "*floatsisf2_media"
10023 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10024 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10025 "TARGET_SHMEDIA_FPU"
10026 "float.ls %1, %0"
10027 [(set_attr "type" "fpconv_media")])
10028
10029 (define_insn "floatsisf2_i4"
10030 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10031 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10032 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10033 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10034 "float %1,%0"
10035 [(set_attr "type" "fp")
10036 (set_attr "fp_mode" "single")])
10037
10038 (define_insn "*floatsisf2_ie"
10039 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10040 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10041 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10042 "float %1,%0"
10043 [(set_attr "type" "fp")])
10044
10045 (define_insn "fix_truncsfdi2"
10046 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10047 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10048 "TARGET_SHMEDIA_FPU"
10049 "ftrc.sq %1, %0"
10050 [(set_attr "type" "fpconv_media")])
10051
10052 (define_expand "fix_truncsfsi2"
10053 [(set (match_operand:SI 0 "fpul_operand" "=y")
10054 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10055 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10056 "
10057 {
10058 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10059 {
10060 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10061 DONE;
10062 }
10063 }")
10064
10065 (define_insn "*fix_truncsfsi2_media"
10066 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10067 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10068 "TARGET_SHMEDIA_FPU"
10069 "ftrc.sl %1, %0"
10070 [(set_attr "type" "fpconv_media")])
10071
10072 (define_insn "fix_truncsfsi2_i4"
10073 [(set (match_operand:SI 0 "fpul_operand" "=y")
10074 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10075 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10076 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10077 "ftrc %1,%0"
10078 [(set_attr "type" "ftrc_s")
10079 (set_attr "fp_mode" "single")])
10080
10081 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10082 ;; fix_truncsfsi2_i4.
10083 ;; (define_insn "fix_truncsfsi2_i4_2"
10084 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10085 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10086 ;; (use (reg:PSI FPSCR_REG))
10087 ;; (clobber (reg:SI FPUL_REG))]
10088 ;; "TARGET_SH4"
10089 ;; "#"
10090 ;; [(set_attr "length" "4")
10091 ;; (set_attr "fp_mode" "single")])
10092
10093 ;;(define_split
10094 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10095 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10096 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10097 ;; (clobber (reg:SI FPUL_REG))]
10098 ;; "TARGET_SH4"
10099 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10100 ;; (use (match_dup 2))])
10101 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10102
10103 (define_insn "*fixsfsi"
10104 [(set (match_operand:SI 0 "fpul_operand" "=y")
10105 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10106 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10107 "ftrc %1,%0"
10108 [(set_attr "type" "fp")])
10109
10110 (define_insn "cmpgtsf_t"
10111 [(set (reg:SI T_REG)
10112 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10113 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10114 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10115 "fcmp/gt %1,%0"
10116 [(set_attr "type" "fp_cmp")
10117 (set_attr "fp_mode" "single")])
10118
10119 (define_insn "cmpeqsf_t"
10120 [(set (reg:SI T_REG)
10121 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10122 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10123 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10124 "fcmp/eq %1,%0"
10125 [(set_attr "type" "fp_cmp")
10126 (set_attr "fp_mode" "single")])
10127
10128 (define_insn "ieee_ccmpeqsf_t"
10129 [(set (reg:SI T_REG)
10130 (ior:SI (reg:SI T_REG)
10131 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10132 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10133 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10134 "* return output_ieee_ccmpeq (insn, operands);"
10135 [(set_attr "length" "4")])
10136
10137
10138 (define_insn "cmpgtsf_t_i4"
10139 [(set (reg:SI T_REG)
10140 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10141 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10142 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10143 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10144 "fcmp/gt %1,%0"
10145 [(set_attr "type" "fp_cmp")
10146 (set_attr "fp_mode" "single")])
10147
10148 (define_insn "cmpeqsf_t_i4"
10149 [(set (reg:SI T_REG)
10150 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10151 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10152 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10153 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10154 "fcmp/eq %1,%0"
10155 [(set_attr "type" "fp_cmp")
10156 (set_attr "fp_mode" "single")])
10157
10158 (define_insn "*ieee_ccmpeqsf_t_4"
10159 [(set (reg:SI T_REG)
10160 (ior:SI (reg:SI T_REG)
10161 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10162 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10163 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10164 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10165 "* return output_ieee_ccmpeq (insn, operands);"
10166 [(set_attr "length" "4")
10167 (set_attr "fp_mode" "single")])
10168
10169 (define_insn "cmpeqsf_media"
10170 [(set (match_operand:SI 0 "register_operand" "=r")
10171 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10172 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10173 "TARGET_SHMEDIA_FPU"
10174 "fcmpeq.s %1, %2, %0"
10175 [(set_attr "type" "fcmp_media")])
10176
10177 (define_insn "cmpgtsf_media"
10178 [(set (match_operand:SI 0 "register_operand" "=r")
10179 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10180 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10181 "TARGET_SHMEDIA_FPU"
10182 "fcmpgt.s %1, %2, %0"
10183 [(set_attr "type" "fcmp_media")])
10184
10185 (define_insn "cmpgesf_media"
10186 [(set (match_operand:SI 0 "register_operand" "=r")
10187 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10188 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10189 "TARGET_SHMEDIA_FPU"
10190 "fcmpge.s %1, %2, %0"
10191 [(set_attr "type" "fcmp_media")])
10192
10193 (define_insn "cmpunsf_media"
10194 [(set (match_operand:SI 0 "register_operand" "=r")
10195 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10196 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10197 "TARGET_SHMEDIA_FPU"
10198 "fcmpun.s %1, %2, %0"
10199 [(set_attr "type" "fcmp_media")])
10200
10201 (define_expand "cbranchsf4"
10202 [(set (pc)
10203 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10204 [(match_operand:SF 1 "arith_operand" "")
10205 (match_operand:SF 2 "arith_operand" "")])
10206 (match_operand 3 "" "")
10207 (pc)))]
10208 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10209 "
10210 {
10211 if (TARGET_SHMEDIA)
10212 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10213 operands[3]));
10214 else
10215 sh_emit_compare_and_branch (operands, SFmode);
10216 DONE;
10217 }")
10218
10219 (define_expand "negsf2"
10220 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10221 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10222 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10223 "
10224 {
10225 if (TARGET_SH2E)
10226 {
10227 expand_sf_unop (&gen_negsf2_i, operands);
10228 DONE;
10229 }
10230 }")
10231
10232 (define_insn "*negsf2_media"
10233 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10234 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10235 "TARGET_SHMEDIA_FPU"
10236 "fneg.s %1, %0"
10237 [(set_attr "type" "fmove_media")])
10238
10239 (define_insn "negsf2_i"
10240 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10241 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10242 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10243 "TARGET_SH2E"
10244 "fneg %0"
10245 [(set_attr "type" "fmove")
10246 (set_attr "fp_mode" "single")])
10247
10248 (define_expand "sqrtsf2"
10249 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10250 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10251 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10252 "
10253 {
10254 if (TARGET_SH3E)
10255 {
10256 expand_sf_unop (&gen_sqrtsf2_i, operands);
10257 DONE;
10258 }
10259 }")
10260
10261 (define_insn "*sqrtsf2_media"
10262 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10263 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10264 "TARGET_SHMEDIA_FPU"
10265 "fsqrt.s %1, %0"
10266 [(set_attr "type" "fdiv_media")])
10267
10268 (define_insn "sqrtsf2_i"
10269 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10270 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10271 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10272 "TARGET_SH3E"
10273 "fsqrt %0"
10274 [(set_attr "type" "fdiv")
10275 (set_attr "fp_mode" "single")])
10276
10277 (define_insn "rsqrtsf2"
10278 [(set (match_operand:SF 0 "register_operand" "=f")
10279 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10280 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10281 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10282 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10283 && operands[1] == CONST1_RTX (SFmode)"
10284 "fsrra %0"
10285 [(set_attr "type" "fsrra")
10286 (set_attr "fp_mode" "single")])
10287
10288 (define_insn "fsca"
10289 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10290 (vec_concat:V2SF
10291 (unspec:SF [(mult:SF
10292 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10293 (match_operand:SF 2 "immediate_operand" "i"))
10294 ] UNSPEC_FSINA)
10295 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10296 ] UNSPEC_FCOSA)))
10297 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10298 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10299 && operands[2] == sh_fsca_int2sf ()"
10300 "fsca fpul,%d0"
10301 [(set_attr "type" "fsca")
10302 (set_attr "fp_mode" "single")])
10303
10304 (define_expand "sinsf2"
10305 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10306 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10307 UNSPEC_FSINA))]
10308 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10309 "
10310 {
10311 rtx scaled = gen_reg_rtx (SFmode);
10312 rtx truncated = gen_reg_rtx (SImode);
10313 rtx fsca = gen_reg_rtx (V2SFmode);
10314 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10315
10316 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10317 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10318 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10319 get_fpscr_rtx ()));
10320 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10321 DONE;
10322 }")
10323
10324 (define_expand "cossf2"
10325 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10326 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10327 UNSPEC_FCOSA))]
10328 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10329 "
10330 {
10331 rtx scaled = gen_reg_rtx (SFmode);
10332 rtx truncated = gen_reg_rtx (SImode);
10333 rtx fsca = gen_reg_rtx (V2SFmode);
10334 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10335
10336 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10337 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10338 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10339 get_fpscr_rtx ()));
10340 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10341 DONE;
10342 }")
10343
10344 (define_expand "sindf2"
10345 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10346 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10347 UNSPEC_FSINA))]
10348 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10349 "
10350 {
10351 rtx scaled = gen_reg_rtx (DFmode);
10352 rtx truncated = gen_reg_rtx (SImode);
10353 rtx fsca = gen_reg_rtx (V2SFmode);
10354 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10355 rtx sfresult = gen_reg_rtx (SFmode);
10356
10357 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10358 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10359 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10360 get_fpscr_rtx ()));
10361 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10362 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10363 DONE;
10364 }")
10365
10366 (define_expand "cosdf2"
10367 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10368 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10369 UNSPEC_FCOSA))]
10370 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10371 "
10372 {
10373 rtx scaled = gen_reg_rtx (DFmode);
10374 rtx truncated = gen_reg_rtx (SImode);
10375 rtx fsca = gen_reg_rtx (V2SFmode);
10376 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10377 rtx sfresult = gen_reg_rtx (SFmode);
10378
10379 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10380 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10381 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10382 get_fpscr_rtx ()));
10383 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10384 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10385 DONE;
10386 }")
10387
10388 (define_expand "abssf2"
10389 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10390 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10391 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10392 "
10393 {
10394 if (TARGET_SH2E)
10395 {
10396 expand_sf_unop (&gen_abssf2_i, operands);
10397 DONE;
10398 }
10399 }")
10400
10401 (define_insn "*abssf2_media"
10402 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10403 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10404 "TARGET_SHMEDIA_FPU"
10405 "fabs.s %1, %0"
10406 [(set_attr "type" "fmove_media")])
10407
10408 (define_insn "abssf2_i"
10409 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10410 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10411 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10412 "TARGET_SH2E"
10413 "fabs %0"
10414 [(set_attr "type" "fmove")
10415 (set_attr "fp_mode" "single")])
10416
10417 (define_expand "adddf3"
10418 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10419 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10420 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10421 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10422 "
10423 {
10424 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10425 {
10426 expand_df_binop (&gen_adddf3_i, operands);
10427 DONE;
10428 }
10429 }")
10430
10431 (define_insn "*adddf3_media"
10432 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10433 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10434 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10435 "TARGET_SHMEDIA_FPU"
10436 "fadd.d %1, %2, %0"
10437 [(set_attr "type" "dfparith_media")])
10438
10439 (define_insn "adddf3_i"
10440 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10441 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10442 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10443 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10444 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10445 "fadd %2,%0"
10446 [(set_attr "type" "dfp_arith")
10447 (set_attr "fp_mode" "double")])
10448
10449 (define_expand "subdf3"
10450 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10451 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10452 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10453 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10454 "
10455 {
10456 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10457 {
10458 expand_df_binop (&gen_subdf3_i, operands);
10459 DONE;
10460 }
10461 }")
10462
10463 (define_insn "*subdf3_media"
10464 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10465 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10466 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10467 "TARGET_SHMEDIA_FPU"
10468 "fsub.d %1, %2, %0"
10469 [(set_attr "type" "dfparith_media")])
10470
10471 (define_insn "subdf3_i"
10472 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10473 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10474 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10475 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10476 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10477 "fsub %2,%0"
10478 [(set_attr "type" "dfp_arith")
10479 (set_attr "fp_mode" "double")])
10480
10481 (define_expand "muldf3"
10482 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10483 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10484 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10485 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10486 "
10487 {
10488 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10489 {
10490 expand_df_binop (&gen_muldf3_i, operands);
10491 DONE;
10492 }
10493 }")
10494
10495 (define_insn "*muldf3_media"
10496 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10497 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10498 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10499 "TARGET_SHMEDIA_FPU"
10500 "fmul.d %1, %2, %0"
10501 [(set_attr "type" "dfmul_media")])
10502
10503 (define_insn "muldf3_i"
10504 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10505 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10506 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10507 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10508 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10509 "fmul %2,%0"
10510 [(set_attr "type" "dfp_mul")
10511 (set_attr "fp_mode" "double")])
10512
10513 (define_expand "divdf3"
10514 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10515 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10516 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10517 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10518 "
10519 {
10520 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10521 {
10522 expand_df_binop (&gen_divdf3_i, operands);
10523 DONE;
10524 }
10525 }")
10526
10527 (define_insn "*divdf3_media"
10528 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10529 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10530 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10531 "TARGET_SHMEDIA_FPU"
10532 "fdiv.d %1, %2, %0"
10533 [(set_attr "type" "dfdiv_media")])
10534
10535 (define_insn "divdf3_i"
10536 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10537 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10538 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10539 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10540 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10541 "fdiv %2,%0"
10542 [(set_attr "type" "dfdiv")
10543 (set_attr "fp_mode" "double")])
10544
10545 (define_insn "floatdidf2"
10546 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10547 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10548 "TARGET_SHMEDIA_FPU"
10549 "float.qd %1, %0"
10550 [(set_attr "type" "dfpconv_media")])
10551
10552 (define_expand "floatsidf2"
10553 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10554 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10555 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10556 "
10557 {
10558 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10559 {
10560 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10561 get_fpscr_rtx ()));
10562 DONE;
10563 }
10564 }")
10565
10566 (define_insn "*floatsidf2_media"
10567 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10568 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10569 "TARGET_SHMEDIA_FPU"
10570 "float.ld %1, %0"
10571 [(set_attr "type" "dfpconv_media")])
10572
10573 (define_insn "floatsidf2_i"
10574 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10575 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10576 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10577 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10578 "float %1,%0"
10579 [(set_attr "type" "dfp_conv")
10580 (set_attr "fp_mode" "double")])
10581
10582 (define_insn "fix_truncdfdi2"
10583 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10584 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10585 "TARGET_SHMEDIA_FPU"
10586 "ftrc.dq %1, %0"
10587 [(set_attr "type" "dfpconv_media")])
10588
10589 (define_expand "fix_truncdfsi2"
10590 [(set (match_operand:SI 0 "fpul_operand" "")
10591 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10592 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10593 "
10594 {
10595 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10596 {
10597 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10598 get_fpscr_rtx ()));
10599 DONE;
10600 }
10601 }")
10602
10603 (define_insn "*fix_truncdfsi2_media"
10604 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10605 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10606 "TARGET_SHMEDIA_FPU"
10607 "ftrc.dl %1, %0"
10608 [(set_attr "type" "dfpconv_media")])
10609
10610 (define_insn "fix_truncdfsi2_i"
10611 [(set (match_operand:SI 0 "fpul_operand" "=y")
10612 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10613 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10614 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10615 "ftrc %1,%0"
10616 [(set_attr "type" "dfp_conv")
10617 (set_attr "dfp_comp" "no")
10618 (set_attr "fp_mode" "double")])
10619
10620 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10621 ;; fix_truncdfsi2_i.
10622 ;; (define_insn "fix_truncdfsi2_i4"
10623 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10624 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10625 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10626 ;; (clobber (reg:SI FPUL_REG))]
10627 ;; "TARGET_SH4"
10628 ;; "#"
10629 ;; [(set_attr "length" "4")
10630 ;; (set_attr "fp_mode" "double")])
10631 ;;
10632 ;; (define_split
10633 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10634 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10635 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10636 ;; (clobber (reg:SI FPUL_REG))]
10637 ;; "TARGET_SH4"
10638 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10639 ;; (use (match_dup 2))])
10640 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10641
10642 (define_insn "cmpgtdf_t"
10643 [(set (reg:SI T_REG)
10644 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10645 (match_operand:DF 1 "arith_reg_operand" "f")))
10646 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10647 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10648 "fcmp/gt %1,%0"
10649 [(set_attr "type" "dfp_cmp")
10650 (set_attr "fp_mode" "double")])
10651
10652 (define_insn "cmpeqdf_t"
10653 [(set (reg:SI T_REG)
10654 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10655 (match_operand:DF 1 "arith_reg_operand" "f")))
10656 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10657 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10658 "fcmp/eq %1,%0"
10659 [(set_attr "type" "dfp_cmp")
10660 (set_attr "fp_mode" "double")])
10661
10662 (define_insn "*ieee_ccmpeqdf_t"
10663 [(set (reg:SI T_REG)
10664 (ior:SI (reg:SI T_REG)
10665 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10666 (match_operand:DF 1 "arith_reg_operand" "f"))))
10667 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10668 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10669 "* return output_ieee_ccmpeq (insn, operands);"
10670 [(set_attr "length" "4")
10671 (set_attr "fp_mode" "double")])
10672
10673 (define_insn "cmpeqdf_media"
10674 [(set (match_operand:SI 0 "register_operand" "=r")
10675 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10676 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10677 "TARGET_SHMEDIA_FPU"
10678 "fcmpeq.d %1,%2,%0"
10679 [(set_attr "type" "fcmp_media")])
10680
10681 (define_insn "cmpgtdf_media"
10682 [(set (match_operand:SI 0 "register_operand" "=r")
10683 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10684 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10685 "TARGET_SHMEDIA_FPU"
10686 "fcmpgt.d %1,%2,%0"
10687 [(set_attr "type" "fcmp_media")])
10688
10689 (define_insn "cmpgedf_media"
10690 [(set (match_operand:SI 0 "register_operand" "=r")
10691 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10692 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10693 "TARGET_SHMEDIA_FPU"
10694 "fcmpge.d %1,%2,%0"
10695 [(set_attr "type" "fcmp_media")])
10696
10697 (define_insn "cmpundf_media"
10698 [(set (match_operand:SI 0 "register_operand" "=r")
10699 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10700 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10701 "TARGET_SHMEDIA_FPU"
10702 "fcmpun.d %1,%2,%0"
10703 [(set_attr "type" "fcmp_media")])
10704
10705 (define_expand "cbranchdf4"
10706 [(set (pc)
10707 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10708 [(match_operand:DF 1 "arith_operand" "")
10709 (match_operand:DF 2 "arith_operand" "")])
10710 (match_operand 3 "" "")
10711 (pc)))]
10712 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10713 "
10714 {
10715 if (TARGET_SHMEDIA)
10716 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10717 operands[3]));
10718 else
10719 sh_emit_compare_and_branch (operands, DFmode);
10720 DONE;
10721 }")
10722
10723
10724 (define_expand "negdf2"
10725 [(set (match_operand:DF 0 "arith_reg_operand" "")
10726 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10727 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10728 "
10729 {
10730 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10731 {
10732 expand_df_unop (&gen_negdf2_i, operands);
10733 DONE;
10734 }
10735 }")
10736
10737 (define_insn "*negdf2_media"
10738 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10739 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10740 "TARGET_SHMEDIA_FPU"
10741 "fneg.d %1, %0"
10742 [(set_attr "type" "fmove_media")])
10743
10744 (define_insn "negdf2_i"
10745 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10746 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10747 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10748 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10749 "fneg %0"
10750 [(set_attr "type" "fmove")
10751 (set_attr "fp_mode" "double")])
10752
10753 (define_expand "sqrtdf2"
10754 [(set (match_operand:DF 0 "arith_reg_operand" "")
10755 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10756 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10757 "
10758 {
10759 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10760 {
10761 expand_df_unop (&gen_sqrtdf2_i, operands);
10762 DONE;
10763 }
10764 }")
10765
10766 (define_insn "*sqrtdf2_media"
10767 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10768 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10769 "TARGET_SHMEDIA_FPU"
10770 "fsqrt.d %1, %0"
10771 [(set_attr "type" "dfdiv_media")])
10772
10773 (define_insn "sqrtdf2_i"
10774 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10775 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10776 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10777 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10778 "fsqrt %0"
10779 [(set_attr "type" "dfdiv")
10780 (set_attr "fp_mode" "double")])
10781
10782 (define_expand "absdf2"
10783 [(set (match_operand:DF 0 "arith_reg_operand" "")
10784 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10785 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10786 "
10787 {
10788 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10789 {
10790 expand_df_unop (&gen_absdf2_i, operands);
10791 DONE;
10792 }
10793 }")
10794
10795 (define_insn "*absdf2_media"
10796 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10797 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10798 "TARGET_SHMEDIA_FPU"
10799 "fabs.d %1, %0"
10800 [(set_attr "type" "fmove_media")])
10801
10802 (define_insn "absdf2_i"
10803 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10804 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10805 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10806 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10807 "fabs %0"
10808 [(set_attr "type" "fmove")
10809 (set_attr "fp_mode" "double")])
10810
10811 (define_expand "extendsfdf2"
10812 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10813 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10814 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10815 "
10816 {
10817 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10818 {
10819 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10820 get_fpscr_rtx ()));
10821 DONE;
10822 }
10823 }")
10824
10825 (define_insn "*extendsfdf2_media"
10826 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10827 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10828 "TARGET_SHMEDIA_FPU"
10829 "fcnv.sd %1, %0"
10830 [(set_attr "type" "dfpconv_media")])
10831
10832 (define_insn "extendsfdf2_i4"
10833 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10834 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10835 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10836 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10837 "fcnvsd %1,%0"
10838 [(set_attr "type" "fp")
10839 (set_attr "fp_mode" "double")])
10840
10841 (define_expand "truncdfsf2"
10842 [(set (match_operand:SF 0 "fpul_operand" "")
10843 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10844 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10845 "
10846 {
10847 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10848 {
10849 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10850 get_fpscr_rtx ()));
10851 DONE;
10852 }
10853 }")
10854
10855 (define_insn "*truncdfsf2_media"
10856 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10857 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10858 "TARGET_SHMEDIA_FPU"
10859 "fcnv.ds %1, %0"
10860 [(set_attr "type" "dfpconv_media")])
10861
10862 (define_insn "truncdfsf2_i4"
10863 [(set (match_operand:SF 0 "fpul_operand" "=y")
10864 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10865 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10866 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10867 "fcnvds %1,%0"
10868 [(set_attr "type" "fp")
10869 (set_attr "fp_mode" "double")])
10870 \f
10871 ;; Bit field extract patterns. These give better code for packed bitfields,
10872 ;; because they allow auto-increment addresses to be generated.
10873
10874 (define_expand "insv"
10875 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10876 (match_operand:SI 1 "immediate_operand" "")
10877 (match_operand:SI 2 "immediate_operand" ""))
10878 (match_operand:SI 3 "general_operand" ""))]
10879 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10880 "
10881 {
10882 rtx addr_target, orig_address, shift_reg, qi_val;
10883 HOST_WIDE_INT bitsize, size, v = 0;
10884 rtx x = operands[3];
10885
10886 if (TARGET_SH2A && TARGET_BITOPS
10887 && (satisfies_constraint_Sbw (operands[0])
10888 || satisfies_constraint_Sbv (operands[0]))
10889 && satisfies_constraint_M (operands[1])
10890 && satisfies_constraint_K03 (operands[2]))
10891 {
10892 if (satisfies_constraint_N (operands[3]))
10893 {
10894 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10895 DONE;
10896 }
10897 else if (satisfies_constraint_M (operands[3]))
10898 {
10899 emit_insn (gen_bset_m2a (operands[0], operands[2]));
10900 DONE;
10901 }
10902 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10903 && satisfies_constraint_M (operands[1]))
10904 {
10905 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10906 DONE;
10907 }
10908 else if (REG_P (operands[3])
10909 && satisfies_constraint_M (operands[1]))
10910 {
10911 emit_insn (gen_bld_reg (operands[3], const0_rtx));
10912 emit_insn (gen_bst_m2a (operands[0], operands[2]));
10913 DONE;
10914 }
10915 }
10916 /* ??? expmed doesn't care for non-register predicates. */
10917 if (! memory_operand (operands[0], VOIDmode)
10918 || ! immediate_operand (operands[1], VOIDmode)
10919 || ! immediate_operand (operands[2], VOIDmode)
10920 || ! general_operand (x, VOIDmode))
10921 FAIL;
10922 /* If this isn't a 16 / 24 / 32 bit field, or if
10923 it doesn't start on a byte boundary, then fail. */
10924 bitsize = INTVAL (operands[1]);
10925 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10926 || (INTVAL (operands[2]) % 8) != 0)
10927 FAIL;
10928
10929 size = bitsize / 8;
10930 orig_address = XEXP (operands[0], 0);
10931 shift_reg = gen_reg_rtx (SImode);
10932 if (CONST_INT_P (x))
10933 {
10934 v = INTVAL (x);
10935 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10936 }
10937 else
10938 {
10939 emit_insn (gen_movsi (shift_reg, operands[3]));
10940 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10941 }
10942 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10943
10944 operands[0] = replace_equiv_address (operands[0], addr_target);
10945 emit_insn (gen_movqi (operands[0], qi_val));
10946
10947 while (size -= 1)
10948 {
10949 if (CONST_INT_P (x))
10950 qi_val
10951 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10952 else
10953 {
10954 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
10955 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10956 }
10957 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
10958 emit_insn (gen_movqi (operands[0], qi_val));
10959 }
10960
10961 DONE;
10962 }")
10963
10964 (define_insn "movua"
10965 [(set (match_operand:SI 0 "register_operand" "=z")
10966 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
10967 UNSPEC_MOVUA))]
10968 "TARGET_SH4A_ARCH"
10969 "movua.l %1,%0"
10970 [(set_attr "type" "movua")])
10971
10972 ;; We shouldn't need this, but cse replaces increments with references
10973 ;; to other regs before flow has a chance to create post_inc
10974 ;; addressing modes, and only postreload's cse_move2add brings the
10975 ;; increments back to a usable form.
10976 (define_peephole2
10977 [(set (match_operand:SI 0 "register_operand" "")
10978 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
10979 (const_int 32) (const_int 0)))
10980 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
10981 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
10982 [(set (match_operand:SI 0 "register_operand" "")
10983 (sign_extract:SI (mem:SI (post_inc:SI
10984 (match_operand:SI 1 "register_operand" "")))
10985 (const_int 32) (const_int 0)))]
10986 "")
10987
10988 (define_expand "extv"
10989 [(set (match_operand:SI 0 "register_operand" "")
10990 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
10991 (match_operand 2 "const_int_operand" "")
10992 (match_operand 3 "const_int_operand" "")))]
10993 "TARGET_SH4A_ARCH || TARGET_SH2A"
10994 {
10995 if (TARGET_SH2A && TARGET_BITOPS
10996 && (satisfies_constraint_Sbw (operands[1])
10997 || satisfies_constraint_Sbv (operands[1]))
10998 && satisfies_constraint_M (operands[2])
10999 && satisfies_constraint_K03 (operands[3]))
11000 {
11001 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11002 if (REGNO (operands[0]) != T_REG)
11003 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11004 DONE;
11005 }
11006 if (TARGET_SH4A_ARCH
11007 && INTVAL (operands[2]) == 32
11008 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11009 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11010 {
11011 rtx src = adjust_address (operands[1], BLKmode, 0);
11012 set_mem_size (src, GEN_INT (4));
11013 emit_insn (gen_movua (operands[0], src));
11014 DONE;
11015 }
11016
11017 FAIL;
11018 })
11019
11020 (define_expand "extzv"
11021 [(set (match_operand:SI 0 "register_operand" "")
11022 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11023 (match_operand 2 "const_int_operand" "")
11024 (match_operand 3 "const_int_operand" "")))]
11025 "TARGET_SH4A_ARCH || TARGET_SH2A"
11026 {
11027 if (TARGET_SH2A && TARGET_BITOPS
11028 && (satisfies_constraint_Sbw (operands[1])
11029 || satisfies_constraint_Sbv (operands[1]))
11030 && satisfies_constraint_M (operands[2])
11031 && satisfies_constraint_K03 (operands[3]))
11032 {
11033 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11034 if (REGNO (operands[0]) != T_REG)
11035 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11036 DONE;
11037 }
11038 if (TARGET_SH4A_ARCH
11039 && INTVAL (operands[2]) == 32
11040 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11041 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11042 {
11043 rtx src = adjust_address (operands[1], BLKmode, 0);
11044 set_mem_size (src, GEN_INT (4));
11045 emit_insn (gen_movua (operands[0], src));
11046 DONE;
11047 }
11048
11049 FAIL;
11050 })
11051
11052 ;; SH2A instructions for bitwise operations.
11053
11054 ;; Clear a bit in a memory location.
11055 (define_insn "bclr_m2a"
11056 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11057 (and:QI
11058 (not:QI (ashift:QI (const_int 1)
11059 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11060 (match_dup 0)))]
11061 "TARGET_SH2A && TARGET_BITOPS"
11062 "@
11063 bclr.b\\t%1,%0
11064 bclr.b\\t%1,@(0,%t0)"
11065 [(set_attr "length" "4,4")])
11066
11067 (define_insn "bclrmem_m2a"
11068 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11069 (and:QI (match_dup 0)
11070 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11071 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11072 "@
11073 bclr.b\\t%W1,%0
11074 bclr.b\\t%W1,@(0,%t0)"
11075 [(set_attr "length" "4,4")])
11076
11077 ;; Set a bit in a memory location.
11078 (define_insn "bset_m2a"
11079 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11080 (ior:QI
11081 (ashift:QI (const_int 1)
11082 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11083 (match_dup 0)))]
11084 "TARGET_SH2A && TARGET_BITOPS"
11085 "@
11086 bset.b\\t%1,%0
11087 bset.b\\t%1,@(0,%t0)"
11088 [(set_attr "length" "4,4")])
11089
11090 (define_insn "bsetmem_m2a"
11091 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11092 (ior:QI (match_dup 0)
11093 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11094 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11095 "@
11096 bset.b\\t%V1,%0
11097 bset.b\\t%V1,@(0,%t0)"
11098 [(set_attr "length" "4,4")])
11099
11100 ;;; Transfer the contents of the T bit to a specified bit of memory.
11101 (define_insn "bst_m2a"
11102 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11103 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11104 (and:QI
11105 (not:QI (ashift:QI (const_int 1)
11106 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11107 (match_dup 0))
11108 (ior:QI
11109 (ashift:QI (const_int 1) (match_dup 1))
11110 (match_dup 0))))]
11111 "TARGET_SH2A && TARGET_BITOPS"
11112 "@
11113 bst.b\\t%1,%0
11114 bst.b\\t%1,@(0,%t0)"
11115 [(set_attr "length" "4")])
11116
11117 ;; Store a specified bit of memory in the T bit.
11118 (define_insn "bld_m2a"
11119 [(set (reg:SI T_REG)
11120 (zero_extract:SI
11121 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11122 (const_int 1)
11123 (match_operand 1 "const_int_operand" "K03,K03")))]
11124 "TARGET_SH2A && TARGET_BITOPS"
11125 "@
11126 bld.b\\t%1,%0
11127 bld.b\\t%1,@(0,%t0)"
11128 [(set_attr "length" "4,4")])
11129
11130 ;; Store a specified bit of memory in the T bit.
11131 (define_insn "bldsign_m2a"
11132 [(set (reg:SI T_REG)
11133 (sign_extract:SI
11134 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11135 (const_int 1)
11136 (match_operand 1 "const_int_operand" "K03,K03")))]
11137 "TARGET_SH2A && TARGET_BITOPS"
11138 "@
11139 bld.b\\t%1,%0
11140 bld.b\\t%1,@(0,%t0)"
11141 [(set_attr "length" "4,4")])
11142
11143 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11144 (define_insn "bld_reg"
11145 [(set (reg:SI T_REG)
11146 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11147 (const_int 1)
11148 (match_operand 1 "const_int_operand" "K03")))]
11149 "TARGET_SH2A"
11150 "bld\\t%1,%0")
11151
11152 (define_insn "*bld_regqi"
11153 [(set (reg:SI T_REG)
11154 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11155 (const_int 1)
11156 (match_operand 1 "const_int_operand" "K03")))]
11157 "TARGET_SH2A"
11158 "bld\\t%1,%0")
11159
11160 ;; Take logical and of a specified bit of memory with the T bit and
11161 ;; store its result in the T bit.
11162 (define_insn "band_m2a"
11163 [(set (reg:SI T_REG)
11164 (and:SI (reg:SI T_REG)
11165 (zero_extract:SI
11166 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11167 (const_int 1)
11168 (match_operand 1 "const_int_operand" "K03,K03"))))]
11169 "TARGET_SH2A && TARGET_BITOPS"
11170 "@
11171 band.b\\t%1,%0
11172 band.b\\t%1,@(0,%t0)"
11173 [(set_attr "length" "4,4")])
11174
11175 (define_insn "bandreg_m2a"
11176 [(set (match_operand:SI 0 "register_operand" "=r,r")
11177 (and:SI (zero_extract:SI
11178 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11179 (const_int 1)
11180 (match_operand 2 "const_int_operand" "K03,K03"))
11181 (match_operand:SI 3 "register_operand" "r,r")))]
11182 "TARGET_SH2A && TARGET_BITOPS"
11183 "@
11184 band.b\\t%2,%1\;movt\\t%0
11185 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11186 [(set_attr "length" "6,6")])
11187
11188 ;; Take logical or of a specified bit of memory with the T bit and
11189 ;; store its result in the T bit.
11190 (define_insn "bor_m2a"
11191 [(set (reg:SI T_REG)
11192 (ior:SI (reg:SI T_REG)
11193 (zero_extract:SI
11194 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11195 (const_int 1)
11196 (match_operand 1 "const_int_operand" "K03,K03"))))]
11197 "TARGET_SH2A && TARGET_BITOPS"
11198 "@
11199 bor.b\\t%1,%0
11200 bor.b\\t%1,@(0,%t0)"
11201 [(set_attr "length" "4,4")])
11202
11203 (define_insn "borreg_m2a"
11204 [(set (match_operand:SI 0 "register_operand" "=r,r")
11205 (ior:SI (zero_extract:SI
11206 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11207 (const_int 1)
11208 (match_operand 2 "const_int_operand" "K03,K03"))
11209 (match_operand:SI 3 "register_operand" "=r,r")))]
11210 "TARGET_SH2A && TARGET_BITOPS"
11211 "@
11212 bor.b\\t%2,%1\;movt\\t%0
11213 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11214 [(set_attr "length" "6,6")])
11215
11216 ;; Take exclusive or of a specified bit of memory with the T bit and
11217 ;; store its result in the T bit.
11218 (define_insn "bxor_m2a"
11219 [(set (reg:SI T_REG)
11220 (xor:SI (reg:SI T_REG)
11221 (zero_extract:SI
11222 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11223 (const_int 1)
11224 (match_operand 1 "const_int_operand" "K03,K03"))))]
11225 "TARGET_SH2A && TARGET_BITOPS"
11226 "@
11227 bxor.b\\t%1,%0
11228 bxor.b\\t%1,@(0,%t0)"
11229 [(set_attr "length" "4,4")])
11230
11231 (define_insn "bxorreg_m2a"
11232 [(set (match_operand:SI 0 "register_operand" "=r,r")
11233 (xor:SI (zero_extract:SI
11234 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11235 (const_int 1)
11236 (match_operand 2 "const_int_operand" "K03,K03"))
11237 (match_operand:SI 3 "register_operand" "=r,r")))]
11238 "TARGET_SH2A && TARGET_BITOPS"
11239 "@
11240 bxor.b\\t%2,%1\;movt\\t%0
11241 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11242 [(set_attr "length" "6,6")])
11243
11244 \f
11245 ;; -------------------------------------------------------------------------
11246 ;; Peepholes
11247 ;; -------------------------------------------------------------------------
11248 ;; This matches cases where the bit in a memory location is set.
11249 (define_peephole2
11250 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11251 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11252 (set (match_dup 0)
11253 (ior:SI (match_dup 0)
11254 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11255 (set (match_dup 1)
11256 (match_operand 3 "arith_reg_operand" "r,r"))]
11257 "TARGET_SH2A && TARGET_BITOPS
11258 && satisfies_constraint_Pso (operands[2])
11259 && REGNO (operands[0]) == REGNO (operands[3])"
11260 [(set (match_dup 1)
11261 (ior:QI (match_dup 1)
11262 (match_dup 2)))]
11263 "")
11264
11265 ;; This matches cases where the bit in a memory location is cleared.
11266 (define_peephole2
11267 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11268 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11269 (set (match_dup 0)
11270 (and:SI (match_dup 0)
11271 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11272 (set (match_dup 1)
11273 (match_operand 3 "arith_reg_operand" "r,r"))]
11274 "TARGET_SH2A && TARGET_BITOPS
11275 && satisfies_constraint_Psz (operands[2])
11276 && REGNO (operands[0]) == REGNO (operands[3])"
11277 [(set (match_dup 1)
11278 (and:QI (match_dup 1)
11279 (match_dup 2)))]
11280 "")
11281
11282 ;; This matches cases where a stack pointer increment at the start of the
11283 ;; epilogue combines with a stack slot read loading the return value.
11284
11285 (define_peephole
11286 [(set (match_operand:SI 0 "arith_reg_operand" "")
11287 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11288 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11289 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11290 "mov.l @%1+,%0")
11291
11292 ;; See the comment on the dt combiner pattern above.
11293
11294 (define_peephole
11295 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11296 (plus:SI (match_dup 0)
11297 (const_int -1)))
11298 (set (reg:SI T_REG)
11299 (eq:SI (match_dup 0)
11300 (const_int 0)))]
11301 "TARGET_SH2"
11302 "dt %0")
11303
11304 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11305 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11306 ;; reload when the constant is too large for a reg+offset address.
11307
11308 ;; ??? We would get much better code if this was done in reload. This would
11309 ;; require modifying find_reloads_address to recognize that if the constant
11310 ;; is out-of-range for an immediate add, then we get better code by reloading
11311 ;; the constant into a register than by reloading the sum into a register,
11312 ;; since the former is one instruction shorter if the address does not need
11313 ;; to be offsettable. Unfortunately this does not work, because there is
11314 ;; only one register, r0, that can be used as an index register. This register
11315 ;; is also the function return value register. So, if we try to force reload
11316 ;; to use double-reg addresses, then we end up with some instructions that
11317 ;; need to use r0 twice. The only way to fix this is to change the calling
11318 ;; convention so that r0 is not used to return values.
11319
11320 (define_peephole
11321 [(set (match_operand:SI 0 "register_operand" "=r")
11322 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11323 (set (mem:SI (match_dup 0))
11324 (match_operand:SI 2 "general_movsrc_operand" ""))]
11325 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11326 "mov.l %2,@(%0,%1)")
11327
11328 (define_peephole
11329 [(set (match_operand:SI 0 "register_operand" "=r")
11330 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11331 (set (match_operand:SI 2 "general_movdst_operand" "")
11332 (mem:SI (match_dup 0)))]
11333 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11334 "mov.l @(%0,%1),%2")
11335
11336 (define_peephole
11337 [(set (match_operand:SI 0 "register_operand" "=r")
11338 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11339 (set (mem:HI (match_dup 0))
11340 (match_operand:HI 2 "general_movsrc_operand" ""))]
11341 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11342 "mov.w %2,@(%0,%1)")
11343
11344 (define_peephole
11345 [(set (match_operand:SI 0 "register_operand" "=r")
11346 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11347 (set (match_operand:HI 2 "general_movdst_operand" "")
11348 (mem:HI (match_dup 0)))]
11349 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11350 "mov.w @(%0,%1),%2")
11351
11352 (define_peephole
11353 [(set (match_operand:SI 0 "register_operand" "=r")
11354 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11355 (set (mem:QI (match_dup 0))
11356 (match_operand:QI 2 "general_movsrc_operand" ""))]
11357 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11358 "mov.b %2,@(%0,%1)")
11359
11360 (define_peephole
11361 [(set (match_operand:SI 0 "register_operand" "=r")
11362 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11363 (set (match_operand:QI 2 "general_movdst_operand" "")
11364 (mem:QI (match_dup 0)))]
11365 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11366 "mov.b @(%0,%1),%2")
11367
11368 (define_peephole
11369 [(set (match_operand:SI 0 "register_operand" "=r")
11370 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11371 (set (mem:SF (match_dup 0))
11372 (match_operand:SF 2 "general_movsrc_operand" ""))]
11373 "TARGET_SH1 && REGNO (operands[0]) == 0
11374 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11375 || (GET_CODE (operands[2]) == SUBREG
11376 && REGNO (SUBREG_REG (operands[2])) < 16))
11377 && reg_unused_after (operands[0], insn)"
11378 "mov.l %2,@(%0,%1)")
11379
11380 (define_peephole
11381 [(set (match_operand:SI 0 "register_operand" "=r")
11382 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11383 (set (match_operand:SF 2 "general_movdst_operand" "")
11384
11385 (mem:SF (match_dup 0)))]
11386 "TARGET_SH1 && REGNO (operands[0]) == 0
11387 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11388 || (GET_CODE (operands[2]) == SUBREG
11389 && REGNO (SUBREG_REG (operands[2])) < 16))
11390 && reg_unused_after (operands[0], insn)"
11391 "mov.l @(%0,%1),%2")
11392
11393 (define_peephole
11394 [(set (match_operand:SI 0 "register_operand" "=r")
11395 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11396 (set (mem:SF (match_dup 0))
11397 (match_operand:SF 2 "general_movsrc_operand" ""))]
11398 "TARGET_SH2E && REGNO (operands[0]) == 0
11399 && ((REG_P (operands[2])
11400 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11401 || (GET_CODE (operands[2]) == SUBREG
11402 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11403 && reg_unused_after (operands[0], insn)"
11404 "fmov{.s|} %2,@(%0,%1)")
11405
11406 (define_peephole
11407 [(set (match_operand:SI 0 "register_operand" "=r")
11408 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11409 (set (match_operand:SF 2 "general_movdst_operand" "")
11410
11411 (mem:SF (match_dup 0)))]
11412 "TARGET_SH2E && REGNO (operands[0]) == 0
11413 && ((REG_P (operands[2])
11414 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11415 || (GET_CODE (operands[2]) == SUBREG
11416 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11417 && reg_unused_after (operands[0], insn)"
11418 "fmov{.s|} @(%0,%1),%2")
11419
11420 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11421 (define_insn "sp_switch_1"
11422 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11423 "TARGET_SH1"
11424 "*
11425 {
11426 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11427 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11428 return \"mov r0,r15\";
11429 }"
11430 [(set_attr "length" "10")])
11431
11432 ;; Switch back to the original stack for interrupt functions with the
11433 ;; sp_switch attribute. */
11434 (define_insn "sp_switch_2"
11435 [(const_int 2)]
11436 "TARGET_SH1"
11437 "mov.l @r15+,r15\;mov.l @r15+,r0"
11438 [(set_attr "length" "4")])
11439
11440 ;; Integer vector moves
11441
11442 (define_expand "movv8qi"
11443 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11444 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11445 "TARGET_SHMEDIA"
11446 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11447
11448 (define_insn "movv8qi_i"
11449 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11450 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11451 "TARGET_SHMEDIA
11452 && (register_operand (operands[0], V8QImode)
11453 || sh_register_operand (operands[1], V8QImode))"
11454 "@
11455 add %1, r63, %0
11456 movi %1, %0
11457 #
11458 ld%M1.q %m1, %0
11459 st%M0.q %m0, %N1"
11460 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11461 (set_attr "length" "4,4,16,4,4")])
11462
11463 (define_split
11464 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11465 (subreg:V8QI (const_int 0) 0))]
11466 "TARGET_SHMEDIA"
11467 [(set (match_dup 0)
11468 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11469 (const_int 0) (const_int 0) (const_int 0)
11470 (const_int 0) (const_int 0)]))])
11471
11472 (define_split
11473 [(set (match_operand 0 "arith_reg_dest" "")
11474 (match_operand 1 "sh_rep_vec" ""))]
11475 "TARGET_SHMEDIA && reload_completed
11476 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11477 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11478 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11479 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11480 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11481 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11482 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11483 [(set (match_dup 0) (match_dup 1))
11484 (match_dup 2)]
11485 "
11486 {
11487 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11488 rtx elt1 = XVECEXP (operands[1], 0, 1);
11489
11490 if (unit_size > 2)
11491 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11492 else
11493 {
11494 if (unit_size < 2)
11495 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11496 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11497 }
11498 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11499 operands[1] = XVECEXP (operands[1], 0, 0);
11500 if (unit_size < 2)
11501 {
11502 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11503 operands[1]
11504 = GEN_INT (TARGET_LITTLE_ENDIAN
11505 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11506 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11507 else
11508 {
11509 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11510 operands[1]
11511 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11512 }
11513 }
11514 }")
11515
11516 (define_split
11517 [(set (match_operand 0 "arith_reg_dest" "")
11518 (match_operand 1 "sh_const_vec" ""))]
11519 "TARGET_SHMEDIA && reload_completed
11520 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11521 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11522 [(set (match_dup 0) (match_dup 1))]
11523 "
11524 {
11525 rtx v = operands[1];
11526 enum machine_mode new_mode
11527 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11528
11529 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11530 operands[1]
11531 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11532 }")
11533
11534 (define_expand "movv2hi"
11535 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11536 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11537 "TARGET_SHMEDIA"
11538 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11539
11540 (define_insn "movv2hi_i"
11541 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11542 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11543 "TARGET_SHMEDIA
11544 && (register_operand (operands[0], V2HImode)
11545 || sh_register_operand (operands[1], V2HImode))"
11546 "@
11547 add.l %1, r63, %0
11548 movi %1, %0
11549 #
11550 ld%M1.l %m1, %0
11551 st%M0.l %m0, %N1"
11552 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11553 (set_attr "length" "4,4,16,4,4")
11554 (set (attr "highpart")
11555 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11556 (const_string "user")]
11557 (const_string "ignore")))])
11558
11559 (define_expand "movv4hi"
11560 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11561 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11562 "TARGET_SHMEDIA"
11563 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11564
11565 (define_insn "movv4hi_i"
11566 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11567 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11568 "TARGET_SHMEDIA
11569 && (register_operand (operands[0], V4HImode)
11570 || sh_register_operand (operands[1], V4HImode))"
11571 "@
11572 add %1, r63, %0
11573 movi %1, %0
11574 #
11575 ld%M1.q %m1, %0
11576 st%M0.q %m0, %N1"
11577 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11578 (set_attr "length" "4,4,16,4,4")
11579 (set_attr "highpart" "depend")])
11580
11581 (define_expand "movv2si"
11582 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11583 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11584 "TARGET_SHMEDIA"
11585 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11586
11587 (define_insn "movv2si_i"
11588 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11589 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11590 "TARGET_SHMEDIA
11591 && (register_operand (operands[0], V2SImode)
11592 || sh_register_operand (operands[1], V2SImode))"
11593 "@
11594 add %1, r63, %0
11595 #
11596 #
11597 ld%M1.q %m1, %0
11598 st%M0.q %m0, %N1"
11599 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11600 (set_attr "length" "4,4,16,4,4")
11601 (set_attr "highpart" "depend")])
11602
11603 ;; Multimedia Intrinsics
11604
11605 (define_insn "absv2si2"
11606 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11607 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11608 "TARGET_SHMEDIA"
11609 "mabs.l %1, %0"
11610 [(set_attr "type" "mcmp_media")
11611 (set_attr "highpart" "depend")])
11612
11613 (define_insn "absv4hi2"
11614 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11615 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11616 "TARGET_SHMEDIA"
11617 "mabs.w %1, %0"
11618 [(set_attr "type" "mcmp_media")
11619 (set_attr "highpart" "depend")])
11620
11621 (define_insn "addv2si3"
11622 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11623 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11624 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11625 "TARGET_SHMEDIA"
11626 "madd.l %1, %2, %0"
11627 [(set_attr "type" "arith_media")
11628 (set_attr "highpart" "depend")])
11629
11630 (define_insn "addv4hi3"
11631 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11632 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11633 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11634 "TARGET_SHMEDIA"
11635 "madd.w %1, %2, %0"
11636 [(set_attr "type" "arith_media")
11637 (set_attr "highpart" "depend")])
11638
11639 (define_insn_and_split "addv2hi3"
11640 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11641 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11642 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11643 "TARGET_SHMEDIA"
11644 "#"
11645 "TARGET_SHMEDIA"
11646 [(const_int 0)]
11647 "
11648 {
11649 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11650 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11651 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11652 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11653 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11654
11655 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11656 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11657 DONE;
11658 }"
11659 [(set_attr "highpart" "must_split")])
11660
11661 (define_insn "ssaddv2si3"
11662 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11663 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11664 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11665 "TARGET_SHMEDIA"
11666 "madds.l %1, %2, %0"
11667 [(set_attr "type" "mcmp_media")
11668 (set_attr "highpart" "depend")])
11669
11670 (define_insn "usaddv8qi3"
11671 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11672 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11673 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11674 "TARGET_SHMEDIA"
11675 "madds.ub %1, %2, %0"
11676 [(set_attr "type" "mcmp_media")
11677 (set_attr "highpart" "depend")])
11678
11679 (define_insn "ssaddv4hi3"
11680 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11681 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11682 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11683 "TARGET_SHMEDIA"
11684 "madds.w %1, %2, %0"
11685 [(set_attr "type" "mcmp_media")
11686 (set_attr "highpart" "depend")])
11687
11688 (define_insn "negcmpeqv8qi"
11689 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11690 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11691 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11692 "TARGET_SHMEDIA"
11693 "mcmpeq.b %N1, %N2, %0"
11694 [(set_attr "type" "mcmp_media")
11695 (set_attr "highpart" "depend")])
11696
11697 (define_insn "negcmpeqv2si"
11698 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11699 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11700 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11701 "TARGET_SHMEDIA"
11702 "mcmpeq.l %N1, %N2, %0"
11703 [(set_attr "type" "mcmp_media")
11704 (set_attr "highpart" "depend")])
11705
11706 (define_insn "negcmpeqv4hi"
11707 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11708 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11709 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11710 "TARGET_SHMEDIA"
11711 "mcmpeq.w %N1, %N2, %0"
11712 [(set_attr "type" "mcmp_media")
11713 (set_attr "highpart" "depend")])
11714
11715 (define_insn "negcmpgtuv8qi"
11716 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11717 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11718 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11719 "TARGET_SHMEDIA"
11720 "mcmpgt.ub %N1, %N2, %0"
11721 [(set_attr "type" "mcmp_media")
11722 (set_attr "highpart" "depend")])
11723
11724 (define_insn "negcmpgtv2si"
11725 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11726 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11727 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11728 "TARGET_SHMEDIA"
11729 "mcmpgt.l %N1, %N2, %0"
11730 [(set_attr "type" "mcmp_media")
11731 (set_attr "highpart" "depend")])
11732
11733 (define_insn "negcmpgtv4hi"
11734 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11735 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11736 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11737 "TARGET_SHMEDIA"
11738 "mcmpgt.w %N1, %N2, %0"
11739 [(set_attr "type" "mcmp_media")
11740 (set_attr "highpart" "depend")])
11741
11742 (define_insn "mcmv"
11743 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11744 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11745 (match_operand:DI 2 "arith_reg_operand" "r"))
11746 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11747 (not:DI (match_dup 2)))))]
11748 "TARGET_SHMEDIA"
11749 "mcmv %N1, %2, %0"
11750 [(set_attr "type" "arith_media")
11751 (set_attr "highpart" "depend")])
11752
11753 (define_insn "mcnvs_lw"
11754 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11755 (vec_concat:V4HI
11756 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11757 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11758 "TARGET_SHMEDIA"
11759 "mcnvs.lw %N1, %N2, %0"
11760 [(set_attr "type" "mcmp_media")])
11761
11762 (define_insn "mcnvs_wb"
11763 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11764 (vec_concat:V8QI
11765 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11766 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11767 "TARGET_SHMEDIA"
11768 "mcnvs.wb %N1, %N2, %0"
11769 [(set_attr "type" "mcmp_media")])
11770
11771 (define_insn "mcnvs_wub"
11772 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11773 (vec_concat:V8QI
11774 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11775 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11776 "TARGET_SHMEDIA"
11777 "mcnvs.wub %N1, %N2, %0"
11778 [(set_attr "type" "mcmp_media")])
11779
11780 (define_insn "mextr_rl"
11781 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11782 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11783 (match_operand:HI 3 "mextr_bit_offset" "i"))
11784 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11785 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11786 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11787 "*
11788 {
11789 static char templ[21];
11790
11791 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11792 (int) INTVAL (operands[3]) >> 3);
11793 return templ;
11794 }"
11795 [(set_attr "type" "arith_media")])
11796
11797 (define_insn "*mextr_lr"
11798 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11799 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11800 (match_operand:HI 3 "mextr_bit_offset" "i"))
11801 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11802 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11803 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11804 "*
11805 {
11806 static char templ[21];
11807
11808 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11809 (int) INTVAL (operands[4]) >> 3);
11810 return templ;
11811 }"
11812 [(set_attr "type" "arith_media")])
11813
11814 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11815 ; vector then varies depending on endianness.
11816 (define_expand "mextr1"
11817 [(match_operand:DI 0 "arith_reg_dest" "")
11818 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11819 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11820 "TARGET_SHMEDIA"
11821 "
11822 {
11823 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11824 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11825 DONE;
11826 }")
11827
11828 (define_expand "mextr2"
11829 [(match_operand:DI 0 "arith_reg_dest" "")
11830 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11831 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11832 "TARGET_SHMEDIA"
11833 "
11834 {
11835 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11836 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11837 DONE;
11838 }")
11839
11840 (define_expand "mextr3"
11841 [(match_operand:DI 0 "arith_reg_dest" "")
11842 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11843 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11844 "TARGET_SHMEDIA"
11845 "
11846 {
11847 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11848 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11849 DONE;
11850 }")
11851
11852 (define_expand "mextr4"
11853 [(match_operand:DI 0 "arith_reg_dest" "")
11854 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11855 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11856 "TARGET_SHMEDIA"
11857 "
11858 {
11859 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11860 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11861 DONE;
11862 }")
11863
11864 (define_expand "mextr5"
11865 [(match_operand:DI 0 "arith_reg_dest" "")
11866 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11867 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11868 "TARGET_SHMEDIA"
11869 "
11870 {
11871 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11872 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11873 DONE;
11874 }")
11875
11876 (define_expand "mextr6"
11877 [(match_operand:DI 0 "arith_reg_dest" "")
11878 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11879 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11880 "TARGET_SHMEDIA"
11881 "
11882 {
11883 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11884 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11885 DONE;
11886 }")
11887
11888 (define_expand "mextr7"
11889 [(match_operand:DI 0 "arith_reg_dest" "")
11890 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11891 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11892 "TARGET_SHMEDIA"
11893 "
11894 {
11895 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11896 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11897 DONE;
11898 }")
11899
11900 (define_expand "mmacfx_wl"
11901 [(match_operand:V2SI 0 "arith_reg_dest" "")
11902 (match_operand:V2HI 1 "extend_reg_operand" "")
11903 (match_operand:V2HI 2 "extend_reg_operand" "")
11904 (match_operand:V2SI 3 "arith_reg_operand" "")]
11905 "TARGET_SHMEDIA"
11906 "
11907 {
11908 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11909 operands[1], operands[2]));
11910 DONE;
11911 }")
11912
11913 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11914 ;; is depend
11915 (define_insn "mmacfx_wl_i"
11916 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11917 (ss_plus:V2SI
11918 (match_operand:V2SI 1 "arith_reg_operand" "0")
11919 (ss_truncate:V2SI
11920 (ashift:V2DI
11921 (sign_extend:V2DI
11922 (mult:V2SI
11923 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11924 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11925 (const_int 1)))))]
11926 "TARGET_SHMEDIA"
11927 "mmacfx.wl %2, %3, %0"
11928 [(set_attr "type" "mac_media")
11929 (set_attr "highpart" "depend")])
11930
11931 (define_expand "mmacnfx_wl"
11932 [(match_operand:V2SI 0 "arith_reg_dest" "")
11933 (match_operand:V2HI 1 "extend_reg_operand" "")
11934 (match_operand:V2HI 2 "extend_reg_operand" "")
11935 (match_operand:V2SI 3 "arith_reg_operand" "")]
11936 "TARGET_SHMEDIA"
11937 "
11938 {
11939 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11940 operands[1], operands[2]));
11941 DONE;
11942 }")
11943
11944 (define_insn "mmacnfx_wl_i"
11945 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11946 (ss_minus:V2SI
11947 (match_operand:V2SI 1 "arith_reg_operand" "0")
11948 (ss_truncate:V2SI
11949 (ashift:V2DI
11950 (sign_extend:V2DI
11951 (mult:V2SI
11952 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11953 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11954 (const_int 1)))))]
11955 "TARGET_SHMEDIA"
11956 "mmacnfx.wl %2, %3, %0"
11957 [(set_attr "type" "mac_media")
11958 (set_attr "highpart" "depend")])
11959
11960 (define_insn "mulv2si3"
11961 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11962 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11963 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11964 "TARGET_SHMEDIA"
11965 "mmul.l %1, %2, %0"
11966 [(set_attr "type" "d2mpy_media")
11967 (set_attr "highpart" "depend")])
11968
11969 (define_insn "mulv4hi3"
11970 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11971 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11972 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11973 "TARGET_SHMEDIA"
11974 "mmul.w %1, %2, %0"
11975 [(set_attr "type" "dmpy_media")
11976 (set_attr "highpart" "depend")])
11977
11978 (define_insn "mmulfx_l"
11979 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11980 (ss_truncate:V2SI
11981 (ashiftrt:V2DI
11982 (mult:V2DI
11983 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11984 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11985 (const_int 31))))]
11986 "TARGET_SHMEDIA"
11987 "mmulfx.l %1, %2, %0"
11988 [(set_attr "type" "d2mpy_media")
11989 (set_attr "highpart" "depend")])
11990
11991 (define_insn "mmulfx_w"
11992 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11993 (ss_truncate:V4HI
11994 (ashiftrt:V4SI
11995 (mult:V4SI
11996 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11997 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11998 (const_int 15))))]
11999 "TARGET_SHMEDIA"
12000 "mmulfx.w %1, %2, %0"
12001 [(set_attr "type" "dmpy_media")
12002 (set_attr "highpart" "depend")])
12003
12004 (define_insn "mmulfxrp_w"
12005 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12006 (ss_truncate:V4HI
12007 (ashiftrt:V4SI
12008 (plus:V4SI
12009 (mult:V4SI
12010 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12011 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12012 (const_int 16384))
12013 (const_int 15))))]
12014 "TARGET_SHMEDIA"
12015 "mmulfxrp.w %1, %2, %0"
12016 [(set_attr "type" "dmpy_media")
12017 (set_attr "highpart" "depend")])
12018
12019
12020 (define_expand "mmulhi_wl"
12021 [(match_operand:V2SI 0 "arith_reg_dest" "")
12022 (match_operand:V4HI 1 "arith_reg_operand" "")
12023 (match_operand:V4HI 2 "arith_reg_operand" "")]
12024 "TARGET_SHMEDIA"
12025 "
12026 {
12027 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12028 (operands[0], operands[1], operands[2]));
12029 DONE;
12030 }")
12031
12032 (define_expand "mmullo_wl"
12033 [(match_operand:V2SI 0 "arith_reg_dest" "")
12034 (match_operand:V4HI 1 "arith_reg_operand" "")
12035 (match_operand:V4HI 2 "arith_reg_operand" "")]
12036 "TARGET_SHMEDIA"
12037 "
12038 {
12039 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12040 (operands[0], operands[1], operands[2]));
12041 DONE;
12042 }")
12043
12044 (define_insn "mmul23_wl"
12045 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12046 (vec_select:V2SI
12047 (mult:V4SI
12048 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12049 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12050 (parallel [(const_int 2) (const_int 3)])))]
12051 "TARGET_SHMEDIA"
12052 "* return (TARGET_LITTLE_ENDIAN
12053 ? \"mmulhi.wl %1, %2, %0\"
12054 : \"mmullo.wl %1, %2, %0\");"
12055 [(set_attr "type" "dmpy_media")
12056 (set (attr "highpart")
12057 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12058 (const_string "user")))])
12059
12060 (define_insn "mmul01_wl"
12061 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12062 (vec_select:V2SI
12063 (mult:V4SI
12064 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12065 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12066 (parallel [(const_int 0) (const_int 1)])))]
12067 "TARGET_SHMEDIA"
12068 "* return (TARGET_LITTLE_ENDIAN
12069 ? \"mmullo.wl %1, %2, %0\"
12070 : \"mmulhi.wl %1, %2, %0\");"
12071 [(set_attr "type" "dmpy_media")
12072 (set (attr "highpart")
12073 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12074 (const_string "user")))])
12075
12076
12077 (define_expand "mmulsum_wq"
12078 [(match_operand:DI 0 "arith_reg_dest" "")
12079 (match_operand:V4HI 1 "arith_reg_operand" "")
12080 (match_operand:V4HI 2 "arith_reg_operand" "")
12081 (match_operand:DI 3 "arith_reg_operand" "")]
12082 "TARGET_SHMEDIA"
12083 "
12084 {
12085 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12086 operands[1], operands[2]));
12087 DONE;
12088 }")
12089
12090 (define_insn "mmulsum_wq_i"
12091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12092 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12093 (plus:DI
12094 (plus:DI
12095 (vec_select:DI
12096 (mult:V4DI
12097 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12098 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12099 (parallel [(const_int 0)]))
12100 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12101 (sign_extend:V4DI (match_dup 3)))
12102 (parallel [(const_int 1)])))
12103 (plus:DI
12104 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12105 (sign_extend:V4DI (match_dup 3)))
12106 (parallel [(const_int 2)]))
12107 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12108 (sign_extend:V4DI (match_dup 3)))
12109 (parallel [(const_int 3)]))))))]
12110 "TARGET_SHMEDIA"
12111 "mmulsum.wq %2, %3, %0"
12112 [(set_attr "type" "mac_media")])
12113
12114 (define_expand "mperm_w"
12115 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12116 (match_operand:V4HI 1 "arith_reg_operand" "r")
12117 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12118 "TARGET_SHMEDIA"
12119 "
12120 {
12121 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12122 (operands[0], operands[1], operands[2]));
12123 DONE;
12124 }")
12125
12126 ; This use of vec_select isn't exactly correct according to rtl.texi
12127 ; (because not constant), but it seems a straightforward extension.
12128 (define_insn "mperm_w_little"
12129 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12130 (vec_select:V4HI
12131 (match_operand:V4HI 1 "arith_reg_operand" "r")
12132 (parallel
12133 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12134 (const_int 2) (const_int 0))
12135 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12136 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12137 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12138 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12139 "mperm.w %1, %N2, %0"
12140 [(set_attr "type" "arith_media")])
12141
12142 (define_insn "mperm_w_big"
12143 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12144 (vec_select:V4HI
12145 (match_operand:V4HI 1 "arith_reg_operand" "r")
12146 (parallel
12147 [(zero_extract:QI (not:QI (match_operand:QI 2
12148 "extend_reg_or_0_operand" "rZ"))
12149 (const_int 2) (const_int 0))
12150 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12151 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12152 (zero_extract:QI (not:QI (match_dup 2))
12153 (const_int 2) (const_int 6))])))]
12154 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12155 "mperm.w %1, %N2, %0"
12156 [(set_attr "type" "arith_media")])
12157
12158 (define_insn "mperm_w0"
12159 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12160 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12161 "trunc_hi_operand" "r"))))]
12162 "TARGET_SHMEDIA"
12163 "mperm.w %1, r63, %0"
12164 [(set_attr "type" "arith_media")
12165 (set_attr "highpart" "ignore")])
12166
12167 (define_expand "msad_ubq"
12168 [(match_operand:DI 0 "arith_reg_dest" "")
12169 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12170 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12171 (match_operand:DI 3 "arith_reg_operand" "")]
12172 "TARGET_SHMEDIA"
12173 "
12174 {
12175 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12176 operands[1], operands[2]));
12177 DONE;
12178 }")
12179
12180 (define_insn "msad_ubq_i"
12181 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12182 (plus:DI
12183 (plus:DI
12184 (plus:DI
12185 (plus:DI
12186 (match_operand:DI 1 "arith_reg_operand" "0")
12187 (abs:DI (vec_select:DI
12188 (minus:V8DI
12189 (zero_extend:V8DI
12190 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12191 (zero_extend:V8DI
12192 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12193 (parallel [(const_int 0)]))))
12194 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12195 (zero_extend:V8DI (match_dup 3)))
12196 (parallel [(const_int 1)]))))
12197 (plus:DI
12198 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12199 (zero_extend:V8DI (match_dup 3)))
12200 (parallel [(const_int 2)])))
12201 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12202 (zero_extend:V8DI (match_dup 3)))
12203 (parallel [(const_int 3)])))))
12204 (plus:DI
12205 (plus:DI
12206 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12207 (zero_extend:V8DI (match_dup 3)))
12208 (parallel [(const_int 4)])))
12209 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12210 (zero_extend:V8DI (match_dup 3)))
12211 (parallel [(const_int 5)]))))
12212 (plus:DI
12213 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12214 (zero_extend:V8DI (match_dup 3)))
12215 (parallel [(const_int 6)])))
12216 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12217 (zero_extend:V8DI (match_dup 3)))
12218 (parallel [(const_int 7)])))))))]
12219 "TARGET_SHMEDIA"
12220 "msad.ubq %N2, %N3, %0"
12221 [(set_attr "type" "mac_media")])
12222
12223 (define_insn "mshalds_l"
12224 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12225 (ss_truncate:V2SI
12226 (ashift:V2DI
12227 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12228 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12229 (const_int 31)))))]
12230 "TARGET_SHMEDIA"
12231 "mshalds.l %1, %2, %0"
12232 [(set_attr "type" "mcmp_media")
12233 (set_attr "highpart" "depend")])
12234
12235 (define_insn "mshalds_w"
12236 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12237 (ss_truncate:V4HI
12238 (ashift:V4SI
12239 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12240 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12241 (const_int 15)))))]
12242 "TARGET_SHMEDIA"
12243 "mshalds.w %1, %2, %0"
12244 [(set_attr "type" "mcmp_media")
12245 (set_attr "highpart" "depend")])
12246
12247 (define_insn "ashrv2si3"
12248 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12249 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12250 (match_operand:DI 2 "arith_reg_operand" "r")))]
12251 "TARGET_SHMEDIA"
12252 "mshard.l %1, %2, %0"
12253 [(set_attr "type" "arith_media")
12254 (set_attr "highpart" "depend")])
12255
12256 (define_insn "ashrv4hi3"
12257 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12258 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12259 (match_operand:DI 2 "arith_reg_operand" "r")))]
12260 "TARGET_SHMEDIA"
12261 "mshard.w %1, %2, %0"
12262 [(set_attr "type" "arith_media")
12263 (set_attr "highpart" "depend")])
12264
12265 (define_insn "mshards_q"
12266 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12267 (ss_truncate:HI
12268 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12269 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12270 "TARGET_SHMEDIA"
12271 "mshards.q %1, %N2, %0"
12272 [(set_attr "type" "mcmp_media")])
12273
12274 (define_expand "mshfhi_b"
12275 [(match_operand:V8QI 0 "arith_reg_dest" "")
12276 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12277 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12278 "TARGET_SHMEDIA"
12279 "
12280 {
12281 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12282 (operands[0], operands[1], operands[2]));
12283 DONE;
12284 }")
12285
12286 (define_expand "mshflo_b"
12287 [(match_operand:V8QI 0 "arith_reg_dest" "")
12288 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12289 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12290 "TARGET_SHMEDIA"
12291 "
12292 {
12293 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12294 (operands[0], operands[1], operands[2]));
12295 DONE;
12296 }")
12297
12298 (define_insn "mshf4_b"
12299 [(set
12300 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12301 (vec_select:V8QI
12302 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12303 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12304 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12305 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12306 "TARGET_SHMEDIA"
12307 "* return (TARGET_LITTLE_ENDIAN
12308 ? \"mshfhi.b %N1, %N2, %0\"
12309 : \"mshflo.b %N1, %N2, %0\");"
12310 [(set_attr "type" "arith_media")
12311 (set (attr "highpart")
12312 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12313 (const_string "user")))])
12314
12315 (define_insn "mshf0_b"
12316 [(set
12317 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12318 (vec_select:V8QI
12319 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12320 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12321 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12322 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12323 "TARGET_SHMEDIA"
12324 "* return (TARGET_LITTLE_ENDIAN
12325 ? \"mshflo.b %N1, %N2, %0\"
12326 : \"mshfhi.b %N1, %N2, %0\");"
12327 [(set_attr "type" "arith_media")
12328 (set (attr "highpart")
12329 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12330 (const_string "user")))])
12331
12332 (define_expand "mshfhi_l"
12333 [(match_operand:V2SI 0 "arith_reg_dest" "")
12334 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12335 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12336 "TARGET_SHMEDIA"
12337 "
12338 {
12339 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12340 (operands[0], operands[1], operands[2]));
12341 DONE;
12342 }")
12343
12344 (define_expand "mshflo_l"
12345 [(match_operand:V2SI 0 "arith_reg_dest" "")
12346 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12347 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12348 "TARGET_SHMEDIA"
12349 "
12350 {
12351 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12352 (operands[0], operands[1], operands[2]));
12353 DONE;
12354 }")
12355
12356 (define_insn "mshf4_l"
12357 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12358 (vec_select:V2SI
12359 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12360 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12361 (parallel [(const_int 1) (const_int 3)])))]
12362 "TARGET_SHMEDIA"
12363 "* return (TARGET_LITTLE_ENDIAN
12364 ? \"mshfhi.l %N1, %N2, %0\"
12365 : \"mshflo.l %N1, %N2, %0\");"
12366 [(set_attr "type" "arith_media")
12367 (set (attr "highpart")
12368 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12369 (const_string "user")))])
12370
12371 (define_insn "mshf0_l"
12372 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12373 (vec_select:V2SI
12374 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12375 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12376 (parallel [(const_int 0) (const_int 2)])))]
12377 "TARGET_SHMEDIA"
12378 "* return (TARGET_LITTLE_ENDIAN
12379 ? \"mshflo.l %N1, %N2, %0\"
12380 : \"mshfhi.l %N1, %N2, %0\");"
12381 [(set_attr "type" "arith_media")
12382 (set (attr "highpart")
12383 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12384 (const_string "user")))])
12385
12386 (define_expand "mshfhi_w"
12387 [(match_operand:V4HI 0 "arith_reg_dest" "")
12388 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12389 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12390 "TARGET_SHMEDIA"
12391 "
12392 {
12393 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12394 (operands[0], operands[1], operands[2]));
12395 DONE;
12396 }")
12397
12398 (define_expand "mshflo_w"
12399 [(match_operand:V4HI 0 "arith_reg_dest" "")
12400 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12401 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12402 "TARGET_SHMEDIA"
12403 "
12404 {
12405 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12406 (operands[0], operands[1], operands[2]));
12407 DONE;
12408 }")
12409
12410 (define_insn "mshf4_w"
12411 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12412 (vec_select:V4HI
12413 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12414 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12415 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12416 "TARGET_SHMEDIA"
12417 "* return (TARGET_LITTLE_ENDIAN
12418 ? \"mshfhi.w %N1, %N2, %0\"
12419 : \"mshflo.w %N1, %N2, %0\");"
12420 [(set_attr "type" "arith_media")
12421 (set (attr "highpart")
12422 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12423 (const_string "user")))])
12424
12425 (define_insn "mshf0_w"
12426 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12427 (vec_select:V4HI
12428 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12429 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12430 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12431 "TARGET_SHMEDIA"
12432 "* return (TARGET_LITTLE_ENDIAN
12433 ? \"mshflo.w %N1, %N2, %0\"
12434 : \"mshfhi.w %N1, %N2, %0\");"
12435 [(set_attr "type" "arith_media")
12436 (set (attr "highpart")
12437 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12438 (const_string "user")))])
12439
12440 (define_insn "mshflo_w_x"
12441 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12442 (vec_select:V4HI
12443 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12444 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12445 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12446 "TARGET_SHMEDIA"
12447 "mshflo.w %N1, %N2, %0"
12448 [(set_attr "type" "arith_media")
12449 (set_attr "highpart" "ignore")])
12450
12451 /* These are useful to expand ANDs and as combiner patterns. */
12452 (define_insn_and_split "mshfhi_l_di"
12453 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12454 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12455 (const_int 32))
12456 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12457 (const_int -4294967296))))]
12458 "TARGET_SHMEDIA"
12459 "@
12460 mshfhi.l %N1, %N2, %0
12461 #"
12462 "TARGET_SHMEDIA && reload_completed
12463 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12464 [(set (match_dup 3) (match_dup 4))
12465 (set (match_dup 5) (match_dup 6))]
12466 "
12467 {
12468 operands[3] = gen_lowpart (SImode, operands[0]);
12469 operands[4] = gen_highpart (SImode, operands[1]);
12470 operands[5] = gen_highpart (SImode, operands[0]);
12471 operands[6] = gen_highpart (SImode, operands[2]);
12472 }"
12473 [(set_attr "type" "arith_media")])
12474
12475 (define_insn "*mshfhi_l_di_rev"
12476 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12477 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12478 (const_int -4294967296))
12479 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12480 (const_int 32))))]
12481 "TARGET_SHMEDIA"
12482 "mshfhi.l %N2, %N1, %0"
12483 [(set_attr "type" "arith_media")])
12484
12485 (define_split
12486 [(set (match_operand:DI 0 "arith_reg_dest" "")
12487 (ior:DI (zero_extend:DI (match_operand:SI 1
12488 "extend_reg_or_0_operand" ""))
12489 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12490 (const_int -4294967296))))
12491 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12492 "TARGET_SHMEDIA"
12493 [(const_int 0)]
12494 "
12495 {
12496 emit_insn (gen_ashldi3_media (operands[3],
12497 simplify_gen_subreg (DImode, operands[1],
12498 SImode, 0),
12499 GEN_INT (32)));
12500 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12501 DONE;
12502 }")
12503
12504 (define_insn "mshflo_l_di"
12505 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12506 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12507 (const_int 4294967295))
12508 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12509 (const_int 32))))]
12510
12511 "TARGET_SHMEDIA"
12512 "mshflo.l %N1, %N2, %0"
12513 [(set_attr "type" "arith_media")
12514 (set_attr "highpart" "ignore")])
12515
12516 (define_insn "*mshflo_l_di_rev"
12517 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12518 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12519 (const_int 32))
12520 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12521 (const_int 4294967295))))]
12522
12523 "TARGET_SHMEDIA"
12524 "mshflo.l %N2, %N1, %0"
12525 [(set_attr "type" "arith_media")
12526 (set_attr "highpart" "ignore")])
12527
12528 ;; Combiner pattern for trampoline initialization.
12529 (define_insn_and_split "*double_shori"
12530 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12531 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12532 (const_int 32))
12533 (match_operand:DI 2 "const_int_operand" "n")))]
12534 "TARGET_SHMEDIA
12535 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12536 "#"
12537 "rtx_equal_p (operands[0], operands[1])"
12538 [(const_int 0)]
12539 "
12540 {
12541 HOST_WIDE_INT v = INTVAL (operands[2]);
12542
12543 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12544 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12545 DONE;
12546 }"
12547 [(set_attr "highpart" "ignore")])
12548
12549
12550 (define_insn "*mshflo_l_di_x"
12551 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12552 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12553 "rZ"))
12554 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12555 (const_int 32))))]
12556
12557 "TARGET_SHMEDIA"
12558 "mshflo.l %N1, %N2, %0"
12559 [(set_attr "type" "arith_media")
12560 (set_attr "highpart" "ignore")])
12561
12562 (define_insn_and_split "concat_v2sf"
12563 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12564 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12565 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12566 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12567
12568 "TARGET_SHMEDIA"
12569 "@
12570 mshflo.l %N1, %N2, %0
12571 #
12572 #"
12573 "TARGET_SHMEDIA && reload_completed
12574 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12575 [(set (match_dup 3) (match_dup 1))
12576 (set (match_dup 4) (match_dup 2))]
12577 "
12578 {
12579 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12580 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12581 }"
12582 [(set_attr "type" "arith_media")
12583 (set_attr "highpart" "ignore")])
12584
12585 (define_insn "*mshflo_l_di_x_rev"
12586 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12587 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12588 (const_int 32))
12589 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12590
12591 "TARGET_SHMEDIA"
12592 "mshflo.l %N2, %N1, %0"
12593 [(set_attr "type" "arith_media")
12594 (set_attr "highpart" "ignore")])
12595
12596 (define_insn "ashlv2si3"
12597 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12598 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12599 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12600 "TARGET_SHMEDIA"
12601 "mshlld.l %1, %2, %0"
12602 [(set_attr "type" "arith_media")
12603 (set_attr "highpart" "depend")])
12604
12605 (define_split
12606 [(set (match_operand 0 "any_register_operand" "")
12607 (match_operator 3 "shift_operator"
12608 [(match_operand 1 "any_register_operand" "")
12609 (match_operand 2 "shift_count_reg_operand" "")]))]
12610 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12611 [(set (match_dup 0) (match_dup 3))]
12612 "
12613 {
12614 rtx count = operands[2];
12615 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12616
12617 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12618 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12619 || GET_CODE (count) == TRUNCATE)
12620 count = XEXP (count, 0);
12621 inner_mode = GET_MODE (count);
12622 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12623 subreg_lowpart_offset (outer_mode, inner_mode));
12624 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12625 operands[1], count);
12626 }")
12627
12628 (define_insn "ashlv4hi3"
12629 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12630 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12631 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12632 "TARGET_SHMEDIA"
12633 "mshlld.w %1, %2, %0"
12634 [(set_attr "type" "arith_media")
12635 (set_attr "highpart" "depend")])
12636
12637 (define_insn "lshrv2si3"
12638 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12639 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12640 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12641 "TARGET_SHMEDIA"
12642 "mshlrd.l %1, %2, %0"
12643 [(set_attr "type" "arith_media")
12644 (set_attr "highpart" "depend")])
12645
12646 (define_insn "lshrv4hi3"
12647 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12648 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12649 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12650 "TARGET_SHMEDIA"
12651 "mshlrd.w %1, %2, %0"
12652 [(set_attr "type" "arith_media")
12653 (set_attr "highpart" "depend")])
12654
12655 (define_insn "subv2si3"
12656 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12657 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12658 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12659 "TARGET_SHMEDIA"
12660 "msub.l %N1, %2, %0"
12661 [(set_attr "type" "arith_media")
12662 (set_attr "highpart" "depend")])
12663
12664 (define_insn "subv4hi3"
12665 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12666 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12667 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12668 "TARGET_SHMEDIA"
12669 "msub.w %N1, %2, %0"
12670 [(set_attr "type" "arith_media")
12671 (set_attr "highpart" "depend")])
12672
12673 (define_insn_and_split "subv2hi3"
12674 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12675 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12676 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12677 "TARGET_SHMEDIA"
12678 "#"
12679 "TARGET_SHMEDIA"
12680 [(const_int 0)]
12681 "
12682 {
12683 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12684 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12685 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12686 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12687 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12688
12689 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12690 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12691 DONE;
12692 }"
12693 [(set_attr "highpart" "must_split")])
12694
12695 (define_insn "sssubv2si3"
12696 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12697 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12698 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12699 "TARGET_SHMEDIA"
12700 "msubs.l %N1, %2, %0"
12701 [(set_attr "type" "mcmp_media")
12702 (set_attr "highpart" "depend")])
12703
12704 (define_insn "ussubv8qi3"
12705 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12706 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12707 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12708 "TARGET_SHMEDIA"
12709 "msubs.ub %N1, %2, %0"
12710 [(set_attr "type" "mcmp_media")
12711 (set_attr "highpart" "depend")])
12712
12713 (define_insn "sssubv4hi3"
12714 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12715 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12716 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12717 "TARGET_SHMEDIA"
12718 "msubs.w %N1, %2, %0"
12719 [(set_attr "type" "mcmp_media")
12720 (set_attr "highpart" "depend")])
12721
12722 ;; Floating Point Intrinsics
12723
12724 (define_insn "fcosa_s"
12725 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12726 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12727 UNSPEC_FCOSA))]
12728 "TARGET_SHMEDIA"
12729 "fcosa.s %1, %0"
12730 [(set_attr "type" "atrans_media")])
12731
12732 (define_insn "fsina_s"
12733 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12734 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12735 UNSPEC_FSINA))]
12736 "TARGET_SHMEDIA"
12737 "fsina.s %1, %0"
12738 [(set_attr "type" "atrans_media")])
12739
12740 (define_insn "fipr"
12741 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12742 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12743 "fp_arith_reg_operand" "f")
12744 (match_operand:V4SF 2
12745 "fp_arith_reg_operand" "f"))
12746 (parallel [(const_int 0)]))
12747 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12748 (parallel [(const_int 1)])))
12749 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12750 (parallel [(const_int 2)]))
12751 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12752 (parallel [(const_int 3)])))))]
12753 "TARGET_SHMEDIA"
12754 "fipr.s %1, %2, %0"
12755 [(set_attr "type" "fparith_media")])
12756
12757 (define_insn "fsrra_s"
12758 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12759 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12760 UNSPEC_FSRRA))]
12761 "TARGET_SHMEDIA"
12762 "fsrra.s %1, %0"
12763 [(set_attr "type" "atrans_media")])
12764
12765 (define_insn "ftrv"
12766 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12767 (plus:V4SF
12768 (plus:V4SF
12769 (mult:V4SF
12770 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12771 (parallel [(const_int 0) (const_int 5)
12772 (const_int 10) (const_int 15)]))
12773 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12774 (mult:V4SF
12775 (vec_select:V4SF (match_dup 1)
12776 (parallel [(const_int 4) (const_int 9)
12777 (const_int 14) (const_int 3)]))
12778 (vec_select:V4SF (match_dup 2)
12779 (parallel [(const_int 1) (const_int 2)
12780 (const_int 3) (const_int 0)]))))
12781 (plus:V4SF
12782 (mult:V4SF
12783 (vec_select:V4SF (match_dup 1)
12784 (parallel [(const_int 8) (const_int 13)
12785 (const_int 2) (const_int 7)]))
12786 (vec_select:V4SF (match_dup 2)
12787 (parallel [(const_int 2) (const_int 3)
12788 (const_int 0) (const_int 1)])))
12789 (mult:V4SF
12790 (vec_select:V4SF (match_dup 1)
12791 (parallel [(const_int 12) (const_int 1)
12792 (const_int 6) (const_int 11)]))
12793 (vec_select:V4SF (match_dup 2)
12794 (parallel [(const_int 3) (const_int 0)
12795 (const_int 1) (const_int 2)]))))))]
12796 "TARGET_SHMEDIA"
12797 "ftrv.s %1, %2, %0"
12798 [(set_attr "type" "fparith_media")])
12799
12800 (define_insn "ldhi_l"
12801 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12802 (zero_extract:SI
12803 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12804 (const_int 3))
12805 (const_int -3)))
12806 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12807 (const_int 0)))]
12808 "TARGET_SHMEDIA32"
12809 "ldhi.l %U1, %0"
12810 [(set_attr "type" "load_media")])
12811
12812 (define_insn "ldhi_q"
12813 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12814 (zero_extract:DI
12815 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12816 (const_int 7))
12817 (const_int -7)))
12818 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12819 (const_int 0)))]
12820 "TARGET_SHMEDIA32"
12821 "ldhi.q %U1, %0"
12822 [(set_attr "type" "load_media")])
12823
12824 (define_insn_and_split "*ldhi_q_comb0"
12825 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12826 (zero_extract:DI
12827 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12828 "register_operand" "r")
12829 (match_operand:SI 2
12830 "ua_offset" "I06"))
12831 (const_int 7))
12832 (const_int -7)))
12833 (plus:SI (and:SI (match_dup 1) (const_int 7))
12834 (const_int 1))
12835 (const_int 0)))]
12836 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12837 "#"
12838 ""
12839 [(pc)]
12840 "emit_insn (gen_ldhi_q (operands[0],
12841 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12842 DONE;")
12843
12844
12845 (define_insn_and_split "*ldhi_q_comb1"
12846 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12847 (zero_extract:DI
12848 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12849 "register_operand" "r")
12850 (match_operand:SI 2
12851 "ua_offset" "I06"))
12852 (const_int 7))
12853 (const_int -7)))
12854 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12855 "ua_offset" "I06"))
12856 (const_int 7))
12857 (const_int 1))
12858 (const_int 0)))]
12859 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12860 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12861 "#"
12862 ""
12863 [(pc)]
12864 "emit_insn (gen_ldhi_q (operands[0],
12865 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12866 DONE;")
12867
12868
12869 (define_insn "ldlo_l"
12870 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12871 (zero_extract:SI
12872 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12873 (const_int -4)))
12874 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12875 (and:SI (match_dup 1) (const_int 3))))]
12876 "TARGET_SHMEDIA32"
12877 "ldlo.l %U1, %0"
12878 [(set_attr "type" "load_media")])
12879
12880 (define_insn "ldlo_q"
12881 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12882 (zero_extract:DI
12883 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12884 (const_int -8)))
12885 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12886 (and:SI (match_dup 1) (const_int 7))))]
12887 "TARGET_SHMEDIA32"
12888 "ldlo.q %U1, %0"
12889 [(set_attr "type" "load_media")])
12890
12891 (define_insn_and_split "*ldlo_q_comb0"
12892 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12893 (zero_extract:DI
12894 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12895 (match_operand:SI 2 "ua_offset" "I06"))
12896 (const_int -8)))
12897 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12898 (and:SI (match_dup 1) (const_int 7))))]
12899 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12900 "#"
12901 ""
12902 [(pc)]
12903 "emit_insn (gen_ldlo_q (operands[0],
12904 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12905 DONE;")
12906
12907 (define_insn_and_split "*ldlo_q_comb1"
12908 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12909 (zero_extract:DI
12910 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12911 (match_operand:SI 2 "ua_offset" "I06"))
12912 (const_int -8)))
12913 (minus:SI (const_int 8)
12914 (and:SI (plus:SI (match_dup 1)
12915 (match_operand:SI 3 "ua_offset" "I06"))
12916 (const_int 7)))
12917 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12918 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12919 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12920 "#"
12921 ""
12922 [(pc)]
12923 "emit_insn (gen_ldlo_q (operands[0],
12924 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12925 DONE;")
12926
12927 (define_insn "sthi_l"
12928 [(set (zero_extract:SI
12929 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12930 (const_int 3))
12931 (const_int -3)))
12932 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12933 (const_int 0))
12934 (match_operand:SI 1 "arith_reg_operand" "r"))]
12935 "TARGET_SHMEDIA32"
12936 "sthi.l %U0, %1"
12937 [(set_attr "type" "ustore_media")])
12938
12939 ;; All unaligned stores are considered to be 'narrow' because they typically
12940 ;; operate on less that a quadword, and when they operate on a full quadword,
12941 ;; the vanilla store high / store low sequence will cause a stall if not
12942 ;; scheduled apart.
12943 (define_insn "sthi_q"
12944 [(set (zero_extract:DI
12945 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12946 (const_int 7))
12947 (const_int -7)))
12948 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12949 (const_int 0))
12950 (match_operand:DI 1 "arith_reg_operand" "r"))]
12951 "TARGET_SHMEDIA32"
12952 "sthi.q %U0, %1"
12953 [(set_attr "type" "ustore_media")])
12954
12955 (define_insn_and_split "*sthi_q_comb0"
12956 [(set (zero_extract:DI
12957 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12958 "register_operand" "r")
12959 (match_operand:SI 1 "ua_offset"
12960 "I06"))
12961 (const_int 7))
12962 (const_int -7)))
12963 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12964 (const_int 0))
12965 (match_operand:DI 2 "arith_reg_operand" "r"))]
12966 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12967 "#"
12968 ""
12969 [(pc)]
12970 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12971 operands[2]));
12972 DONE;")
12973
12974 (define_insn_and_split "*sthi_q_comb1"
12975 [(set (zero_extract:DI
12976 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12977 "register_operand" "r")
12978 (match_operand:SI 1 "ua_offset"
12979 "I06"))
12980 (const_int 7))
12981 (const_int -7)))
12982 (plus:SI (and:SI (plus:SI (match_dup 0)
12983 (match_operand:SI 2 "ua_offset" "I06"))
12984 (const_int 7))
12985 (const_int 1))
12986 (const_int 0))
12987 (match_operand:DI 3 "arith_reg_operand" "r"))]
12988 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12989 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12990 "#"
12991 ""
12992 [(pc)]
12993 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12994 operands[3]));
12995 DONE;")
12996
12997 ;; This is highpart user because the address is used as full 64 bit.
12998 (define_insn "stlo_l"
12999 [(set (zero_extract:SI
13000 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13001 (const_int -4)))
13002 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13003 (and:SI (match_dup 0) (const_int 3)))
13004 (match_operand:SI 1 "arith_reg_operand" "r"))]
13005 "TARGET_SHMEDIA32"
13006 "stlo.l %U0, %1"
13007 [(set_attr "type" "ustore_media")])
13008
13009 (define_insn "stlo_q"
13010 [(set (zero_extract:DI
13011 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13012 (const_int -8)))
13013 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13014 (and:SI (match_dup 0) (const_int 7)))
13015 (match_operand:DI 1 "arith_reg_operand" "r"))]
13016 "TARGET_SHMEDIA32"
13017 "stlo.q %U0, %1"
13018 [(set_attr "type" "ustore_media")])
13019
13020 (define_insn_and_split "*stlo_q_comb0"
13021 [(set (zero_extract:DI
13022 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13023 (match_operand:SI 1 "ua_offset" "I06"))
13024 (const_int -8)))
13025 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13026 (and:SI (match_dup 0) (const_int 7)))
13027 (match_operand:DI 2 "arith_reg_operand" "r"))]
13028 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13029 "#"
13030 ""
13031 [(pc)]
13032 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13033 operands[2]));
13034 DONE;")
13035
13036 (define_insn_and_split "*stlo_q_comb1"
13037 [(set (zero_extract:DI
13038 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13039 (match_operand:SI 1 "ua_offset" "I06"))
13040 (const_int -8)))
13041 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13042 (match_operand:SI 2
13043 "ua_offset" "I06"))
13044 (const_int 7)))
13045 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13046 (match_operand:DI 3 "arith_reg_operand" "r"))]
13047 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13048 "#"
13049 ""
13050 [(pc)]
13051 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13052 operands[3]));
13053 DONE;")
13054
13055 (define_insn "ldhi_l64"
13056 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13057 (zero_extract:SI
13058 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13059 (const_int 3))
13060 (const_int -3)))
13061 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13062 (const_int 0)))]
13063 "TARGET_SHMEDIA64"
13064 "ldhi.l %U1, %0"
13065 [(set_attr "type" "load_media")])
13066
13067 (define_insn "ldhi_q64"
13068 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13069 (zero_extract:DI
13070 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13071 (const_int 7))
13072 (const_int -7)))
13073 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13074 (const_int 0)))]
13075 "TARGET_SHMEDIA64"
13076 "ldhi.q %U1, %0"
13077 [(set_attr "type" "load_media")])
13078
13079 (define_insn "ldlo_l64"
13080 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13081 (zero_extract:SI
13082 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13083 (const_int -4)))
13084 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13085 (and:DI (match_dup 1) (const_int 3))))]
13086 "TARGET_SHMEDIA64"
13087 "ldlo.l %U1, %0"
13088 [(set_attr "type" "load_media")])
13089
13090 (define_insn "ldlo_q64"
13091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13092 (zero_extract:DI
13093 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13094 (const_int -8)))
13095 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13096 (and:DI (match_dup 1) (const_int 7))))]
13097 "TARGET_SHMEDIA64"
13098 "ldlo.q %U1, %0"
13099 [(set_attr "type" "load_media")])
13100
13101 (define_insn "sthi_l64"
13102 [(set (zero_extract:SI
13103 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13104 (const_int 3))
13105 (const_int -3)))
13106 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13107 (const_int 0))
13108 (match_operand:SI 1 "arith_reg_operand" "r"))]
13109 "TARGET_SHMEDIA64"
13110 "sthi.l %U0, %1"
13111 [(set_attr "type" "ustore_media")])
13112
13113 (define_insn "sthi_q64"
13114 [(set (zero_extract:DI
13115 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13116 (const_int 7))
13117 (const_int -7)))
13118 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13119 (const_int 0))
13120 (match_operand:DI 1 "arith_reg_operand" "r"))]
13121 "TARGET_SHMEDIA64"
13122 "sthi.q %U0, %1"
13123 [(set_attr "type" "ustore_media")])
13124
13125 (define_insn "stlo_l64"
13126 [(set (zero_extract:SI
13127 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13128 (const_int -4)))
13129 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13130 (and:DI (match_dup 0) (const_int 3)))
13131 (match_operand:SI 1 "arith_reg_operand" "r"))]
13132 "TARGET_SHMEDIA64"
13133 "stlo.l %U0, %1"
13134 [(set_attr "type" "ustore_media")])
13135
13136 (define_insn "stlo_q64"
13137 [(set (zero_extract:DI
13138 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13139 (const_int -8)))
13140 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13141 (and:DI (match_dup 0) (const_int 7)))
13142 (match_operand:DI 1 "arith_reg_operand" "r"))]
13143 "TARGET_SHMEDIA64"
13144 "stlo.q %U0, %1"
13145 [(set_attr "type" "ustore_media")])
13146
13147 (define_insn "nsb"
13148 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13149 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13150 UNSPEC_NSB))]
13151 "TARGET_SHMEDIA"
13152 "nsb %1, %0"
13153 [(set_attr "type" "arith_media")])
13154
13155 (define_insn "nsbsi"
13156 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13157 (zero_extend:SI
13158 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13159 UNSPEC_NSB)))]
13160 "TARGET_SHMEDIA"
13161 "nsb %1, %0"
13162 [(set_attr "type" "arith_media")])
13163
13164 (define_insn "nsbdi"
13165 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13166 (zero_extend:DI
13167 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13168 UNSPEC_NSB)))]
13169 "TARGET_SHMEDIA"
13170 "nsb %1, %0"
13171 [(set_attr "type" "arith_media")])
13172
13173 (define_expand "ffsdi2"
13174 [(set (match_operand:DI 0 "arith_reg_dest" "")
13175 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13176 "TARGET_SHMEDIA"
13177 "
13178 {
13179 rtx scratch = gen_reg_rtx (DImode);
13180 rtx last;
13181
13182 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13183 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13184 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13185 emit_insn (gen_nsbdi (scratch, scratch));
13186 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13187 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13188 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13189 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13190
13191 DONE;
13192 }")
13193
13194 (define_expand "ffssi2"
13195 [(set (match_operand:SI 0 "arith_reg_dest" "")
13196 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13197 "TARGET_SHMEDIA"
13198 "
13199 {
13200 rtx scratch = gen_reg_rtx (SImode);
13201 rtx discratch = gen_reg_rtx (DImode);
13202 rtx last;
13203
13204 emit_insn (gen_adddi3 (discratch,
13205 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13206 constm1_rtx));
13207 emit_insn (gen_andcdi3 (discratch,
13208 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13209 discratch));
13210 emit_insn (gen_nsbsi (scratch, discratch));
13211 last = emit_insn (gen_subsi3 (operands[0],
13212 force_reg (SImode, GEN_INT (63)), scratch));
13213 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13214
13215 DONE;
13216 }")
13217
13218 (define_insn "byterev"
13219 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13220 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13221 (parallel [(const_int 7) (const_int 6) (const_int 5)
13222 (const_int 4) (const_int 3) (const_int 2)
13223 (const_int 1) (const_int 0)])))]
13224 "TARGET_SHMEDIA"
13225 "byterev %1, %0"
13226 [(set_attr "type" "arith_media")])
13227
13228 (define_insn "*prefetch_media"
13229 [(prefetch (match_operand:QI 0 "address_operand" "p")
13230 (match_operand:SI 1 "const_int_operand" "n")
13231 (match_operand:SI 2 "const_int_operand" "n"))]
13232 "TARGET_SHMEDIA"
13233 "*
13234 {
13235 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13236 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13237 return \"\";
13238 }"
13239 [(set_attr "type" "other")])
13240
13241 (define_insn "*prefetch_i4"
13242 [(prefetch (match_operand:SI 0 "register_operand" "r")
13243 (match_operand:SI 1 "const_int_operand" "n")
13244 (match_operand:SI 2 "const_int_operand" "n"))]
13245 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13246 "*
13247 {
13248 return \"pref @%0\";
13249 }"
13250 [(set_attr "type" "other")])
13251
13252 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13253 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13254 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13255 (define_expand "prefetch"
13256 [(prefetch (match_operand 0 "address_operand" "p")
13257 (match_operand:SI 1 "const_int_operand" "n")
13258 (match_operand:SI 2 "const_int_operand" "n"))]
13259 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13260 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13261 "
13262 {
13263 if (GET_MODE (operands[0]) != Pmode
13264 || !CONST_INT_P (operands[1])
13265 || !CONST_INT_P (operands[2]))
13266 FAIL;
13267 if (! TARGET_SHMEDIA)
13268 operands[0] = force_reg (Pmode, operands[0]);
13269 }")
13270
13271 (define_insn "prefetch_m2a"
13272 [(prefetch (match_operand:SI 0 "register_operand" "r")
13273 (match_operand:SI 1 "const_int_operand" "n")
13274 (match_operand:SI 2 "const_int_operand" "n"))]
13275 "TARGET_SH2A"
13276 "pref\\t@%0"
13277 [(set_attr "type" "other")])
13278
13279 (define_insn "alloco_i"
13280 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13281 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13282 "TARGET_SHMEDIA32"
13283 "*
13284 {
13285 rtx xops[2];
13286
13287 if (GET_CODE (operands[0]) == PLUS)
13288 {
13289 xops[0] = XEXP (operands[0], 0);
13290 xops[1] = XEXP (operands[0], 1);
13291 }
13292 else
13293 {
13294 xops[0] = operands[0];
13295 xops[1] = const0_rtx;
13296 }
13297 output_asm_insn (\"alloco %0, %1\", xops);
13298 return \"\";
13299 }"
13300 [(set_attr "type" "other")])
13301
13302 (define_split
13303 [(set (match_operand 0 "any_register_operand" "")
13304 (match_operand 1 "" ""))]
13305 "TARGET_SHMEDIA && reload_completed"
13306 [(set (match_dup 0) (match_dup 1))]
13307 "
13308 {
13309 int n_changes = 0;
13310
13311 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13312 if (!n_changes)
13313 FAIL;
13314 }")
13315
13316 ; Stack Protector Patterns
13317
13318 (define_expand "stack_protect_set"
13319 [(set (match_operand 0 "memory_operand" "")
13320 (match_operand 1 "memory_operand" ""))]
13321 ""
13322 {
13323 if (TARGET_SHMEDIA)
13324 {
13325 if (TARGET_SHMEDIA64)
13326 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13327 else
13328 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13329 }
13330 else
13331 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13332
13333 DONE;
13334 })
13335
13336 (define_insn "stack_protect_set_si"
13337 [(set (match_operand:SI 0 "memory_operand" "=m")
13338 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13339 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13340 "!TARGET_SHMEDIA"
13341 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13342 [(set_attr "type" "other")
13343 (set_attr "length" "6")])
13344
13345 (define_insn "stack_protect_set_si_media"
13346 [(set (match_operand:SI 0 "memory_operand" "=m")
13347 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13348 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13349 "TARGET_SHMEDIA"
13350 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13351 [(set_attr "type" "other")
13352 (set_attr "length" "12")])
13353
13354 (define_insn "stack_protect_set_di_media"
13355 [(set (match_operand:DI 0 "memory_operand" "=m")
13356 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13357 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13358 "TARGET_SHMEDIA64"
13359 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13360 [(set_attr "type" "other")
13361 (set_attr "length" "12")])
13362
13363 (define_expand "stack_protect_test"
13364 [(match_operand 0 "memory_operand" "")
13365 (match_operand 1 "memory_operand" "")
13366 (match_operand 2 "" "")]
13367 ""
13368 {
13369 if (TARGET_SHMEDIA)
13370 {
13371 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13372 rtx test;
13373
13374 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13375 if (TARGET_SHMEDIA64)
13376 {
13377 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13378 operands[1]));
13379 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13380 }
13381 else
13382 {
13383 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13384 operands[1]));
13385 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13386 }
13387 }
13388 else
13389 {
13390 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13391 emit_jump_insn (gen_branch_true (operands[2]));
13392 }
13393
13394 DONE;
13395 })
13396
13397 (define_insn "stack_protect_test_si"
13398 [(set (reg:SI T_REG)
13399 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13400 (match_operand:SI 1 "memory_operand" "m")]
13401 UNSPEC_SP_TEST))
13402 (set (match_scratch:SI 2 "=&r") (const_int 0))
13403 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13404 "!TARGET_SHMEDIA"
13405 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13406 [(set_attr "type" "other")
13407 (set_attr "length" "10")])
13408
13409 (define_insn "stack_protect_test_si_media"
13410 [(set (match_operand:SI 0 "register_operand" "=&r")
13411 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13412 (match_operand:SI 2 "memory_operand" "m")]
13413 UNSPEC_SP_TEST))
13414 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13415 "TARGET_SHMEDIA"
13416 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13417 [(set_attr "type" "other")
13418 (set_attr "length" "16")])
13419
13420 (define_insn "stack_protect_test_di_media"
13421 [(set (match_operand:DI 0 "register_operand" "=&r")
13422 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13423 (match_operand:DI 2 "memory_operand" "m")]
13424 UNSPEC_SP_TEST))
13425 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13426 "TARGET_SHMEDIA64"
13427 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13428 [(set_attr "type" "other")
13429 (set_attr "length" "16")])