]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/sh.md
builtins.c: Rename movstr*, except for movstrict*, to movmem* and clrstr* to clrmem*.
[thirdparty/gcc.git] / gcc / config / sh / sh.md
CommitLineData
c8f0269d 1;;- Machine description for Renesas / SuperH SH.
68d2b0bb
R
2;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3;; 2003, 2004 Free Software Foundation, Inc.
51aea58d
JW
4;; Contributed by Steve Chamberlain (sac@cygnus.com).
5;; Improved by Jim Wilson (wilson@cygnus.com).
bc45ade3 6
7ec022b2 7;; This file is part of GCC.
bc45ade3 8
7ec022b2 9;; GCC is free software; you can redistribute it and/or modify
bc45ade3
SC
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
7ec022b2 14;; GCC is distributed in the hope that it will be useful,
bc45ade3
SC
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
7ec022b2 20;; along with GCC; see the file COPYING. If not, write to
3f63df56
RK
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
bc45ade3 23
bc45ade3 24
d0aae509
RK
25;; ??? Should prepend a * to all pattern names which are not used.
26;; This will make the compiler smaller, and rebuilds after changes faster.
27
ffae286a
JW
28;; ??? Should be enhanced to include support for many more GNU superoptimizer
29;; sequences. Especially the sequences for arithmetic right shifts.
30
31;; ??? Should check all DImode patterns for consistency and usefulness.
32
51bd623f
JW
33;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34;; way to generate them.
35
ffae286a
JW
36;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37;; for a str* inline function.
38
4ed4cb9a
JR
39;; BSR is not generated by the compiler proper, but when relaxing, it
40;; generates .uses pseudo-ops that allow linker relaxation to create
41;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42
0d7e008e
SC
43;; Special constraints for SH machine description:
44;;
07a45e5c
JW
45;; t -- T
46;; x -- mac
47;; l -- pr
0d7e008e
SC
48;; z -- r0
49;;
50;; Special formats used for outputting SH instructions:
51;;
52;; %. -- print a .s if insn needs delay slot
51aea58d 53;; %@ -- print rte/rts if is/isn't an interrupt function
0d7e008e 54;; %# -- output a nop if there is nothing to put in the delay slot
0d7e008e 55;; %O -- print a constant without the #
51aea58d
JW
56;; %R -- print the lsw reg of a double
57;; %S -- print the msw reg of a double
58;; %T -- print next word of a double REG or MEM
0d7e008e
SC
59;;
60;; Special predicates:
61;;
62;; arith_operand -- operand is valid source for arithmetic op
63;; arith_reg_operand -- operand is valid register for arithmetic op
0d7e008e
SC
64;; general_movdst_operand -- operand is valid move destination
65;; general_movsrc_operand -- operand is valid move source
66;; logical_operand -- operand is valid source for logical op
4773afa4
AO
67
68;; -------------------------------------------------------------------------
69;; Constants
70;; -------------------------------------------------------------------------
71
72(define_constants [
fa5322fa
AO
73 (AP_REG 145)
74 (PR_REG 146)
75 (T_REG 147)
76 (GBR_REG 144)
77 (MACH_REG 148)
78 (MACL_REG 149)
79 (FPUL_REG 150)
80 (RAP_REG 152)
4773afa4 81
fa5322fa 82 (FPSCR_REG 151)
4773afa4
AO
83
84 (PIC_REG 12)
85 (FP_REG 14)
86 (SP_REG 15)
87
fa5322fa
AO
88 (PR_MEDIA_REG 18)
89 (T_MEDIA_REG 19)
90
4773afa4
AO
91 (R0_REG 0)
92 (R1_REG 1)
93 (R2_REG 2)
94 (R3_REG 3)
95 (R4_REG 4)
96 (R5_REG 5)
97 (R6_REG 6)
fa5322fa
AO
98 (R7_REG 7)
99 (R8_REG 8)
100 (R9_REG 9)
101 (R10_REG 10)
9e96203d
R
102 (R20_REG 20)
103 (R21_REG 21)
104 (R22_REG 22)
105 (R23_REG 23)
fa5322fa
AO
106
107 (DR0_REG 64)
108 (DR2_REG 66)
109 (DR4_REG 68)
9e96203d 110 (FR23_REG 87)
4773afa4 111
fa5322fa
AO
112 (TR0_REG 128)
113 (TR1_REG 129)
114 (TR2_REG 130)
4773afa4 115
fa5322fa 116 (XD0_REG 136)
4773afa4
AO
117
118 ;; These are used with unspec.
fa5322fa 119 (UNSPEC_COMPACT_ARGS 0)
4773afa4
AO
120 (UNSPEC_MOVA 1)
121 (UNSPEC_CASESI 2)
fa5322fa 122 (UNSPEC_DATALABEL 3)
4773afa4
AO
123 (UNSPEC_BBR 4)
124 (UNSPEC_SFUNC 5)
125 (UNSPEC_PIC 6)
126 (UNSPEC_GOT 7)
127 (UNSPEC_GOTOFF 8)
128 (UNSPEC_PLT 9)
2d01e445 129 (UNSPEC_CALLER 10)
fa5322fa 130 (UNSPEC_GOTPLT 11)
4773afa4 131 (UNSPEC_ICACHE 12)
c1b92d09
R
132 (UNSPEC_INIT_TRAMP 13)
133 (UNSPEC_FCOSA 14)
134 (UNSPEC_FSRRA 15)
135 (UNSPEC_FSINA 16)
136 (UNSPEC_NSB 17)
137 (UNSPEC_ALLOCO 18)
4977bab6 138 (UNSPEC_EH_RETURN 19)
463f02cd
KK
139 (UNSPEC_TLSGD 20)
140 (UNSPEC_TLSLDM 21)
141 (UNSPEC_TLSIE 22)
142 (UNSPEC_DTPOFF 23)
143 (UNSPEC_GOTTPOFF 24)
144 (UNSPEC_TPOFF 25)
7d73a2ba 145 (UNSPEC_RA 26)
4773afa4
AO
146
147 ;; These are used with unspec_volatile.
148 (UNSPECV_BLOCKAGE 0)
b927e8c7 149 (UNSPECV_ALIGN 1)
4773afa4
AO
150 (UNSPECV_CONST2 2)
151 (UNSPECV_CONST4 4)
152 (UNSPECV_CONST8 6)
b91455de 153 (UNSPECV_WINDOW_END 10)
4773afa4 154 (UNSPECV_CONST_END 11)
73774972 155])
4773afa4 156
bc45ade3
SC
157;; -------------------------------------------------------------------------
158;; Attributes
159;; -------------------------------------------------------------------------
160
eeb531d5 161;; Target CPU.
b9654711 162
1245df60 163(define_attr "cpu"
3a8699c7 164 "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
07a45e5c 165 (const (symbol_ref "sh_cpu_attr")))
961c4780 166
1245df60
R
167(define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
170
d64264ff
R
171;; Indicate if the default fpu mode is single precision.
172(define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
175
225e4f43
R
176(define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
2ad65b0e
SC
179;; pipeline model
180(define_attr "pipe_model" "sh1,sh4,sh5media"
181 (const
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
225e4f43 185
0d7e008e
SC
186;; cbranch conditional branch instructions
187;; jump unconditional jumps
188;; arith ordinary arithmetic
956d6950 189;; arith3 a compound insn that behaves similarly to a sequence of
1245df60
R
190;; three insns of type arith
191;; arith3b like above, but might end with a redirected branch
0d7e008e 192;; load from memory
1245df60 193;; load_si Likewise, SImode variant for general register.
c49439f1 194;; fload Likewise, but load to fp register.
0d7e008e 195;; store to memory
c49439f1
R
196;; move general purpose register to register
197;; mt_group other sh4 mt instructions
1245df60 198;; fmove register to register, floating point
51bd623f
JW
199;; smpy word precision integer multiply
200;; dmpy longword or doublelongword precision integer multiply
0d7e008e 201;; return rts
ffae286a 202;; pload load of pr reg, which can't be put into delay slot of rts
99e87c10 203;; prset copy register to pr reg, ditto
ffae286a 204;; pstore store of pr reg, which can't be put into delay slot of jsr
99e87c10 205;; prget copy pr to register, ditto
22e1ebf1 206;; pcload pc relative load of constant value
c49439f1 207;; pcfload Likewise, but load to fp register.
1245df60 208;; pcload_si Likewise, SImode variant for general register.
0d7e008e
SC
209;; rte return from exception
210;; sfunc special function call with known used registers
ffae286a 211;; call function call
c1aef54d
ILT
212;; fp floating point
213;; fdiv floating point divide (or square root)
c49439f1
R
214;; gp_fpul move from general purpose register to fpul
215;; fpul_gp move from fpul to general purpose register
216;; mac_gp move from mac[lh] to general purpose register
225e4f43 217;; dfp_arith, dfp_cmp,dfp_conv
c49439f1 218;; ftrc_s fix_truncsfsi2_i4
225e4f43 219;; dfdiv double precision floating point divide (or square root)
c49439f1 220;; cwb ic_invalidate_line_i
73774972 221;; tls_load load TLS related address
2ad65b0e
SC
222;; arith_media SHmedia arithmetic, logical, and shift instructions
223;; cbranch_media SHmedia conditional branch instructions
224;; cmp_media SHmedia compare instructions
225;; dfdiv_media SHmedia double precision divide and square root
226;; dfmul_media SHmedia double precision multiply instruction
227;; dfparith_media SHmedia double precision floating point arithmetic
228;; dfpconv_media SHmedia double precision floating point conversions
229;; dmpy_media SHmedia longword multiply
230;; fcmp_media SHmedia floating point compare instructions
231;; fdiv_media SHmedia single precision divide and square root
232;; fload_media SHmedia floating point register load instructions
233;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
234;; fparith_media SHmedia single precision floating point arithmetic
235;; fpconv_media SHmedia single precision floating point conversions
236;; fstore_media SHmedia floating point register store instructions
237;; gettr_media SHmedia gettr instruction
825db093 238;; invalidate_line_media SHmedia invalidate_line sequence
2ad65b0e
SC
239;; jump_media SHmedia unconditional branch instructions
240;; load_media SHmedia general register load instructions
241;; pt_media SHmedia pt instruction (expanded by assembler)
242;; ptabs_media SHmedia ptabs instruction
243;; store_media SHmedia general register store instructions
244;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
245;; mac_media SHmedia mac-style fixed point operations
246;; d2mpy_media SHmedia: two 32 bit integer multiplies
825db093 247;; atrans SHmedia approximate transcendental functions
2ad65b0e 248;; ustore_media SHmedia unaligned stores
4dff12bf 249;; nil no-op move, will be deleted.
0d7e008e 250
07a45e5c 251(define_attr "type"
463f02cd 252 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
bc45ade3
SC
253 (const_string "other"))
254
fae15c93 255;; We define a new attribute namely "insn_class".We use
c49439f1 256;; this for the DFA based pipeline description.
fae15c93
VM
257;;
258;; mt_group SH4 "mt" group instructions.
259;;
c49439f1
R
260;; ex_group SH4 "ex" group instructions.
261;;
262;; ls_group SH4 "ls" group instructions.
fae15c93 263;;
fae15c93
VM
264
265(define_attr "insn_class"
c49439f1
R
266 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270 (eq_attr "type" "cbranch,jump") (const_string "br_group")
271 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272 (const_string "fe_group")
273 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
274 (const_string "none")))
275;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276;; so these do not belong in an insn group, although they are modeled
277;; with their own define_insn_reservations.
fae15c93 278
d64264ff
R
279;; Indicate what precision must be selected in fpscr for this insn, if any.
280
281(define_attr "fp_mode" "single,double,none" (const_string "none"))
282
73774972
EC
283;; Indicate if the fpu mode is set by this instruction
284;; "unknown" must have the value as "none" in fp_mode, and means
285;; that the instruction/abi has left the processor in an unknown
286;; state.
287;; "none" means that nothing has changed and no mode is set.
288;; This attribute is only used for the Renesas ABI.
289(define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
290
07a45e5c 291; If a conditional branch destination is within -252..258 bytes away
bc45ade3 292; from the instruction it can be 2 bytes long. Something in the
22e1ebf1 293; range -4090..4100 bytes can be 6 bytes long. All other conditional
1245df60
R
294; branches are initially assumed to be 16 bytes long.
295; In machine_dependent_reorg, we split all branches that are longer than
296; 2 bytes.
bc45ade3 297
536fe39c 298;; The maximum range used for SImode constant pool entries is 1018. A final
33f7f353
JR
299;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
301;; instruction around the pool table, 2 bytes of alignment before the table,
302;; and 30 bytes of alignment after the table. That gives a maximum total
303;; pool size of 1058 bytes.
304;; Worst case code/pool content size ratio is 1:2 (using asms).
305;; Thus, in the worst case, there is one instruction in front of a maximum
306;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
308;; If we have a forward branch, the initial table will be put after the
309;; unconditional branch.
310;;
311;; ??? We could do much better by keeping track of the actual pcloads within
312;; the branch range and in the pcload range in front of the branch range.
313
314;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
315;; inside an le.
316(define_attr "short_cbranch_p" "no,yes"
317 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
318 (const_string "no")
319 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
320 (const_string "yes")
321 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
322 (const_string "no")
323 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
324 (const_string "yes")
325 ] (const_string "no")))
326
327(define_attr "med_branch_p" "no,yes"
328 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
329 (const_int 1988))
330 (const_string "yes")
331 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
332 (const_string "no")
333 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
334 (const_int 8186))
335 (const_string "yes")
336 ] (const_string "no")))
337
338(define_attr "med_cbranch_p" "no,yes"
339 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
340 (const_int 1986))
341 (const_string "yes")
342 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343 (const_string "no")
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
345 (const_int 8184))
346 (const_string "yes")
347 ] (const_string "no")))
348
349(define_attr "braf_branch_p" "no,yes"
350 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
351 (const_string "no")
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
353 (const_int 20660))
354 (const_string "yes")
355 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356 (const_string "no")
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
358 (const_int 65530))
359 (const_string "yes")
360 ] (const_string "no")))
361
362(define_attr "braf_cbranch_p" "no,yes"
363 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364 (const_string "no")
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
366 (const_int 20658))
367 (const_string "yes")
368 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369 (const_string "no")
370 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
371 (const_int 65528))
372 (const_string "yes")
373 ] (const_string "no")))
374
22e1ebf1 375; An unconditional jump in the range -4092..4098 can be 2 bytes long.
1245df60
R
376; For wider ranges, we need a combination of a code and a data part.
377; If we can get a scratch register for a long range jump, the code
378; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379; If the jump is in the range -32764..32770, the data part can be 2 bytes
380; long; otherwise, it must be 6 bytes long.
bc45ade3
SC
381
382; All other instructions are two bytes long by default.
383
33f7f353
JR
384;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385;; but getattrtab doesn't understand this.
07a45e5c 386(define_attr "length" ""
bc45ade3 387 (cond [(eq_attr "type" "cbranch")
33f7f353 388 (cond [(eq_attr "short_cbranch_p" "yes")
1245df60 389 (const_int 2)
33f7f353 390 (eq_attr "med_cbranch_p" "yes")
1245df60 391 (const_int 6)
33f7f353 392 (eq_attr "braf_cbranch_p" "yes")
1245df60 393 (const_int 12)
33f7f353
JR
394;; ??? using pc is not computed transitively.
395 (ne (match_dup 0) (match_dup 0))
396 (const_int 14)
e6dfd05f
AO
397 (ne (symbol_ref ("flag_pic")) (const_int 0))
398 (const_int 24)
1245df60 399 ] (const_int 16))
bc45ade3 400 (eq_attr "type" "jump")
33f7f353 401 (cond [(eq_attr "med_branch_p" "yes")
1245df60 402 (const_int 2)
10f4f635 403 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
1245df60 404 (symbol_ref "INSN"))
10f4f635 405 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
1245df60 406 (symbol_ref "code_for_indirect_jump_scratch")))
33f7f353 407 (if_then_else (eq_attr "braf_branch_p" "yes")
1245df60
R
408 (const_int 6)
409 (const_int 10))
33f7f353 410 (eq_attr "braf_branch_p" "yes")
1245df60 411 (const_int 10)
33f7f353
JR
412;; ??? using pc is not computed transitively.
413 (ne (match_dup 0) (match_dup 0))
1245df60 414 (const_int 12)
e6dfd05f
AO
415 (ne (symbol_ref ("flag_pic")) (const_int 0))
416 (const_int 22)
1245df60 417 ] (const_int 14))
2ad65b0e 418 (eq_attr "type" "pt_media")
fa5322fa
AO
419 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420 (const_int 20) (const_int 12))
421 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
422 (const_int 4)
423 (const_int 2))))
b9654711 424
c1aef54d
ILT
425;; Load and store instructions save a cycle if they are aligned on a
426;; four byte boundary. Using a function unit for stores encourages
427;; gcc to separate load and store instructions by one instruction,
428;; which makes it more likely that the linker will be able to word
429;; align them when relaxing.
1245df60 430
52c27e16
SB
431;; SH-1 scheduling
432
433(define_automaton "sh1")
434(define_cpu_unit "sh1memory,sh1int,sh1mpy,sh1fp" "sh1")
435
1245df60 436;; Loads have a latency of two.
deeef0ac 437;; However, call insns can have a delay slot, so that we want one more
1245df60
R
438;; insn to be scheduled between the load of the function address and the call.
439;; This is equivalent to a latency of three.
1245df60
R
440;; ADJUST_COST can only properly handle reductions of the cost, so we
441;; use a latency of three here.
956d6950 442;; We only do this for SImode loads of general registers, to make the work
1245df60 443;; for ADJUST_COST easier.
52c27e16 444(define_insn_reservation "sh1_load_si" 3
2ad65b0e 445 (and (eq_attr "pipe_model" "sh1")
225e4f43 446 (eq_attr "type" "load_si,pcload_si"))
52c27e16
SB
447 "sh1memory*2")
448
449(define_insn_reservation "sh1_load_store" 2
2ad65b0e 450 (and (eq_attr "pipe_model" "sh1")
225e4f43 451 (eq_attr "type" "load,pcload,pload,store,pstore"))
52c27e16 452 "sh1memory*2")
1245df60 453
52c27e16
SB
454(define_insn_reservation "sh1_arith3" 3
455 (and (eq_attr "pipe_model" "sh1")
456 (eq_attr "type" "arith3,arith3b"))
457 "sh1int*3")
1245df60 458
52c27e16
SB
459(define_insn_reservation "sh1_dyn_shift" 2
460 (and (eq_attr "pipe_model" "sh1")
461 (eq_attr "type" "dyn_shift"))
462 "sh1int*2")
1245df60 463
52c27e16
SB
464(define_insn_reservation "sh1_int" 1
465 (and (eq_attr "pipe_model" "sh1")
466 (eq_attr "type" "!arith3,arith3b,dyn_shift"))
467 "sh1int")
c1aef54d
ILT
468
469;; ??? These are approximations.
52c27e16
SB
470(define_insn_reservation "sh1_smpy" 2
471 (and (eq_attr "pipe_model" "sh1")
472 (eq_attr "type" "smpy"))
473 "sh1mpy*2")
225e4f43 474
52c27e16
SB
475(define_insn_reservation "sh1_dmpy" 3
476 (and (eq_attr "pipe_model" "sh1")
477 (eq_attr "type" "dmpy"))
478 "sh1mpy*3")
225e4f43 479
52c27e16
SB
480(define_insn_reservation "sh1_fp" 2
481 (and (eq_attr "pipe_model" "sh1")
482 (eq_attr "type" "fp,fmove"))
483 "sh1fp")
484
485(define_insn_reservation "sh1_fdiv" 13
486 (and (eq_attr "pipe_model" "sh1")
487 (eq_attr "type" "fdiv"))
488 "sh1fp*12")
225e4f43 489
2ad65b0e
SC
490;; SH-5 SHmedia scheduling
491;; When executing SHmedia code, the SH-5 is a fairly straightforward
492;; single-issue machine. It has four pipelines, the branch unit (br),
493;; the integer and multimedia unit (imu), the load/store unit (lsu), and
494;; the floating point unit (fpu).
52c27e16
SB
495;;
496;; (define_function_unit {name} {num-units} {n-users} {test}
497;; {ready-delay} {issue-delay} [{conflict-list}])
2ad65b0e
SC
498
499;; Every instruction on SH-5 occupies the issue resource for at least one
500;; cycle.
501(define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
504
52c27e16
SB
505;; Here model the instructions with a latency greater than one cycle.
506
2ad65b0e
SC
507;; Specify the various types of instruction which have latency > 1
508(define_function_unit "sh5issue" 1 0
509 (and (eq_attr "pipe_model" "sh5media")
510 (eq_attr "type" "mcmp_media")) 2 1)
511
512(define_function_unit "sh5issue" 1 0
513 (and (eq_attr "pipe_model" "sh5media")
514 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
515;; but see sh_adjust_cost for mac_media exception.
516
517(define_function_unit "sh5issue" 1 0
518 (and (eq_attr "pipe_model" "sh5media")
519 (eq_attr "type" "fload_media,fmove_media")) 4 1)
520
521(define_function_unit "sh5issue" 1 0
522 (and (eq_attr "pipe_model" "sh5media")
523 (eq_attr "type" "d2mpy_media")) 4 2)
524
525(define_function_unit "sh5issue" 1 0
526 (and (eq_attr "pipe_model" "sh5media")
527 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
528
529(define_function_unit "sh5issue" 1 0
530 (and (eq_attr "pipe_model" "sh5media")
531 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
532
533(define_function_unit "sh5issue" 1 0
534 (and (eq_attr "pipe_model" "sh5media")
535 (eq_attr "type" "invalidate_line_media")) 7 7)
536
537(define_function_unit "sh5issue" 1 0
538 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
539
540(define_function_unit "sh5issue" 1 0
541 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
542
543;; Floating-point divide and square-root occupy an additional resource,
544;; which is not internally pipelined. However, other instructions
545;; can continue to issue.
546(define_function_unit "sh5fds" 1 0
547 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
548
549(define_function_unit "sh5fds" 1 0
550 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
fa5322fa 551
51bd623f 552; Definitions for filling branch delay slots.
bc45ade3 553
51bd623f
JW
554(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
555
225e4f43
R
556;; ??? This should be (nil) instead of (const_int 0)
557(define_attr "hit_stack" "yes,no"
4773afa4
AO
558 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
559 (const_int 0))
225e4f43
R
560 (const_string "no")]
561 (const_string "yes")))
51bd623f
JW
562
563(define_attr "interrupt_function" "no,yes"
552ecbd9 564 (const (symbol_ref "current_function_interrupt")))
51bd623f 565
07a45e5c 566(define_attr "in_delay_slot" "yes,no"
51bd623f 567 (cond [(eq_attr "type" "cbranch") (const_string "no")
1245df60 568 (eq_attr "type" "pcload,pcload_si") (const_string "no")
51bd623f
JW
569 (eq_attr "needs_delay_slot" "yes") (const_string "no")
570 (eq_attr "length" "2") (const_string "yes")
571 ] (const_string "no")))
572
c608a684
R
573(define_attr "cond_delay_slot" "yes,no"
574 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
575 ] (const_string "no")))
576
0603a39d
R
577(define_attr "is_sfunc" ""
578 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
579
2ad65b0e
SC
580(define_attr "is_mac_media" ""
581 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
582
c49439f1
R
583(define_attr "branch_zero" "yes,no"
584 (cond [(eq_attr "type" "!cbranch") (const_string "no")
585 (ne (symbol_ref "(next_active_insn (insn)\
586 == (prev_active_insn\
587 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
588 && get_attr_length (next_active_insn (insn)) == 2")
589 (const_int 0))
590 (const_string "yes")]
591 (const_string "no")))
592
593;; SH4 Double-precision computation with double-precision result -
594;; the two halves are ready at different times.
595(define_attr "dfp_comp" "yes,no"
596 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
597 (const_string "no")))
598
599;; Insns for which the latency of a preceding fp insn is decreased by one.
600(define_attr "late_fp_use" "yes,no" (const_string "no"))
601;; And feeding insns for which this relevant.
602(define_attr "any_fp_comp" "yes,no"
603 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
604 (const_string "yes")]
605 (const_string "no")))
606
607(define_attr "any_int_load" "yes,no"
608 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
609 (const_string "yes")]
610 (const_string "no")))
611
51bd623f 612(define_delay
0d7e008e 613 (eq_attr "needs_delay_slot" "yes")
b9654711
SC
614 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
615
51aea58d
JW
616;; On the SH and SH2, the rte instruction reads the return pc from the stack,
617;; and thus we can't put a pop instruction in its delay slot.
6b005b88
JW
618;; ??? On the SH3, the rte instruction does not use the stack, so a pop
619;; instruction can go in the delay slot.
51aea58d 620
ffae286a
JW
621;; Since a normal return (rts) implicitly uses the PR register,
622;; we can't allow PR register loads in an rts delay slot.
623
07a45e5c 624(define_delay
961c4780 625 (eq_attr "type" "return")
07a45e5c 626 [(and (eq_attr "in_delay_slot" "yes")
ffae286a 627 (ior (and (eq_attr "interrupt_function" "no")
99e87c10 628 (eq_attr "type" "!pload,prset"))
ffae286a 629 (and (eq_attr "interrupt_function" "yes")
552ecbd9
AH
630 (ior
631 (ne (symbol_ref "TARGET_SH3") (const_int 0))
632 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
ffae286a
JW
633
634;; Since a call implicitly uses the PR register, we can't allow
635;; a PR register store in a jsr delay slot.
636
637(define_delay
638 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
639 [(and (eq_attr "in_delay_slot" "yes")
99e87c10 640 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
ffae286a
JW
641
642;; Say that we have annulled true branches, since this gives smaller and
643;; faster code when branches are predicted as not taken.
644
07a45e5c
JW
645(define_delay
646 (and (eq_attr "type" "cbranch")
1245df60 647 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
3a8699c7
AO
648 ;; SH2e has a hardware bug that pretty much prohibits the use of
649 ;; annuled delay slots.
650 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
651 (not (eq_attr "cpu" "sh2e"))) (nil)])
bc45ade3
SC
652\f
653;; -------------------------------------------------------------------------
654;; SImode signed integer comparisons
655;; -------------------------------------------------------------------------
656
51bd623f 657(define_insn ""
4773afa4 658 [(set (reg:SI T_REG)
51bd623f 659 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
735cb76e 660 (match_operand:SI 1 "arith_operand" "K08,r"))
51bd623f 661 (const_int 0)))]
fa5322fa 662 "TARGET_SH1"
fae15c93 663 "tst %1,%0"
c49439f1 664 [(set_attr "type" "mt_group")])
0d7e008e 665
07a45e5c
JW
666;; ??? Perhaps should only accept reg/constant if the register is reg 0.
667;; That would still allow reload to create cmpi instructions, but would
668;; perhaps allow forcing the constant into a register when that is better.
ffae286a
JW
669;; Probably should use r0 for mem/imm compares, but force constant into a
670;; register for pseudo/imm compares.
07a45e5c 671
0d7e008e 672(define_insn "cmpeqsi_t"
4773afa4
AO
673 [(set (reg:SI T_REG)
674 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
735cb76e 675 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
fa5322fa 676 "TARGET_SH1"
0d7e008e 677 "@
51bd623f 678 tst %0,%0
0d7e008e 679 cmp/eq %1,%0
fae15c93 680 cmp/eq %1,%0"
c49439f1 681 [(set_attr "type" "mt_group")])
bc45ade3
SC
682
683(define_insn "cmpgtsi_t"
4773afa4
AO
684 [(set (reg:SI T_REG)
685 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
686 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 687 "TARGET_SH1"
0d7e008e 688 "@
22e1ebf1 689 cmp/gt %1,%0
fae15c93 690 cmp/pl %0"
c49439f1 691 [(set_attr "type" "mt_group")])
bc45ade3
SC
692
693(define_insn "cmpgesi_t"
4773afa4
AO
694 [(set (reg:SI T_REG)
695 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
696 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 697 "TARGET_SH1"
0d7e008e 698 "@
22e1ebf1 699 cmp/ge %1,%0
fae15c93 700 cmp/pz %0"
c49439f1 701 [(set_attr "type" "mt_group")])
fae15c93 702
bc45ade3
SC
703;; -------------------------------------------------------------------------
704;; SImode unsigned integer comparisons
705;; -------------------------------------------------------------------------
706
707(define_insn "cmpgeusi_t"
4773afa4
AO
708 [(set (reg:SI T_REG)
709 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
710 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 711 "TARGET_SH1"
fae15c93 712 "cmp/hs %1,%0"
c49439f1 713 [(set_attr "type" "mt_group")])
bc45ade3
SC
714
715(define_insn "cmpgtusi_t"
4773afa4
AO
716 [(set (reg:SI T_REG)
717 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
718 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 719 "TARGET_SH1"
fae15c93 720 "cmp/hi %1,%0"
c49439f1 721 [(set_attr "type" "mt_group")])
bc45ade3
SC
722
723;; We save the compare operands in the cmpxx patterns and use them when
724;; we generate the branch.
725
726(define_expand "cmpsi"
4773afa4 727 [(set (reg:SI T_REG)
3db1b434 728 (compare (match_operand:SI 0 "cmpsi_operand" "")
4773afa4 729 (match_operand:SI 1 "arith_operand" "")))]
fa5322fa 730 "TARGET_SH1"
bc45ade3 731 "
0d7e008e 732{
3db1b434
R
733 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
734 && GET_CODE (operands[1]) != CONST_INT)
735 operands[0] = copy_to_mode_reg (SImode, operands[0]);
0d7e008e 736 sh_compare_op0 = operands[0];
bc45ade3
SC
737 sh_compare_op1 = operands[1];
738 DONE;
739}")
bc45ade3
SC
740\f
741;; -------------------------------------------------------------------------
1245df60
R
742;; DImode signed integer comparisons
743;; -------------------------------------------------------------------------
744
745;; ??? Could get better scheduling by splitting the initial test from the
746;; rest of the insn after reload. However, the gain would hardly justify
747;; the sh.md size increase necessary to do that.
748
749(define_insn ""
4773afa4 750 [(set (reg:SI T_REG)
1245df60
R
751 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
752 (match_operand:DI 1 "arith_operand" "r"))
753 (const_int 0)))]
fa5322fa 754 "TARGET_SH1"
1245df60
R
755 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
756 insn, operands);"
757 [(set_attr "length" "6")
758 (set_attr "type" "arith3b")])
759
760(define_insn "cmpeqdi_t"
4773afa4
AO
761 [(set (reg:SI T_REG)
762 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
763 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
fa5322fa 764 "TARGET_SH1"
712646d0 765 "@
4c0d0505
JR
766 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
767 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
1245df60
R
768 [(set_attr "length" "6")
769 (set_attr "type" "arith3b")])
770
1987b7bc 771(define_split
4773afa4 772 [(set (reg:SI T_REG)
e69d1422
R
773 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
774 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
712646d0
R
775;; If we applied this split when not optimizing, it would only be
776;; applied during the machine-dependent reorg, when no new basic blocks
777;; may be created.
fa5322fa 778 "TARGET_SH1 && reload_completed && optimize"
4773afa4
AO
779 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
780 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
712646d0
R
781 (label_ref (match_dup 6))
782 (pc)))
4773afa4 783 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
712646d0 784 (match_dup 6)]
1987b7bc
R
785 "
786{
787 operands[2]
788 = gen_rtx_REG (SImode,
789 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
790 operands[3]
791 = (operands[1] == const0_rtx
792 ? const0_rtx
793 : gen_rtx_REG (SImode,
794 true_regnum (operands[1])
795 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
796 operands[4] = gen_lowpart (SImode, operands[0]);
797 operands[5] = gen_lowpart (SImode, operands[1]);
712646d0 798 operands[6] = gen_label_rtx ();
1987b7bc
R
799}")
800
1245df60 801(define_insn "cmpgtdi_t"
4773afa4
AO
802 [(set (reg:SI T_REG)
803 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
804 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
805 "TARGET_SH2"
806 "@
807 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
808 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
809 [(set_attr "length" "8")
810 (set_attr "type" "arith3")])
811
812(define_insn "cmpgedi_t"
4773afa4
AO
813 [(set (reg:SI T_REG)
814 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
815 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
816 "TARGET_SH2"
817 "@
818 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
819 cmp/pz\\t%S0"
820 [(set_attr "length" "8,2")
c49439f1 821 (set_attr "type" "arith3,mt_group")])
1245df60
R
822\f
823;; -------------------------------------------------------------------------
824;; DImode unsigned integer comparisons
825;; -------------------------------------------------------------------------
826
827(define_insn "cmpgeudi_t"
4773afa4
AO
828 [(set (reg:SI T_REG)
829 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
830 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
831 "TARGET_SH2"
832 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
833 [(set_attr "length" "8")
834 (set_attr "type" "arith3")])
835
836(define_insn "cmpgtudi_t"
4773afa4
AO
837 [(set (reg:SI T_REG)
838 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
839 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
840 "TARGET_SH2"
841 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
842 [(set_attr "length" "8")
843 (set_attr "type" "arith3")])
844
fa5322fa 845(define_insn "cmpeqdi_media"
b6d33983
R
846 [(set (match_operand:DI 0 "register_operand" "=r")
847 (eq:DI (match_operand:DI 1 "register_operand" "%r")
848 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
fa5322fa 849 "TARGET_SHMEDIA"
b6d33983
R
850 "cmpeq %1, %N2, %0"
851 [(set_attr "type" "cmp_media")])
fa5322fa
AO
852
853(define_insn "cmpgtdi_media"
b6d33983
R
854 [(set (match_operand:DI 0 "register_operand" "=r")
855 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
856 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 857 "TARGET_SHMEDIA"
b6d33983
R
858 "cmpgt %N1, %N2, %0"
859 [(set_attr "type" "cmp_media")])
fa5322fa
AO
860
861(define_insn "cmpgtudi_media"
b6d33983
R
862 [(set (match_operand:DI 0 "register_operand" "=r")
863 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
864 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 865 "TARGET_SHMEDIA"
68cef009 866 "cmpgtu %N1, %N2, %0"
b6d33983 867 [(set_attr "type" "cmp_media")])
fa5322fa 868
1245df60
R
869;; We save the compare operands in the cmpxx patterns and use them when
870;; we generate the branch.
871
872(define_expand "cmpdi"
4773afa4
AO
873 [(set (reg:SI T_REG)
874 (compare (match_operand:DI 0 "arith_operand" "")
875 (match_operand:DI 1 "arith_operand" "")))]
fa5322fa 876 "TARGET_SH2 || TARGET_SHMEDIA"
1245df60
R
877 "
878{
879 sh_compare_op0 = operands[0];
880 sh_compare_op1 = operands[1];
881 DONE;
882}")
fa5322fa
AO
883;; -------------------------------------------------------------------------
884;; Conditional move instructions
885;; -------------------------------------------------------------------------
886
887;; The insn names may seem reversed, but note that cmveq performs the move
888;; if op1 == 0, and cmvne does it if op1 != 0.
889
890(define_insn "movdicc_false"
b6d33983
R
891 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
892 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 893 (const_int 0))
b6d33983
R
894 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
895 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 896 "TARGET_SHMEDIA"
b6d33983
R
897 "cmveq %1, %N2, %0"
898 [(set_attr "type" "arith_media")])
fa5322fa
AO
899
900(define_insn "movdicc_true"
b6d33983
R
901 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
902 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 903 (const_int 0))
b6d33983
R
904 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
905 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 906 "TARGET_SHMEDIA"
b6d33983
R
907 "cmvne %1, %N2, %0"
908 [(set_attr "type" "arith_media")])
fa5322fa
AO
909
910(define_expand "movdicc"
911 [(set (match_operand:DI 0 "register_operand" "")
912 (if_then_else:DI (match_operand 1 "comparison_operator" "")
913 (match_operand:DI 2 "register_operand" "")
914 (match_operand:DI 3 "register_operand" "")))]
915 "TARGET_SHMEDIA"
916 "
917{
918 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
919 && GET_MODE (sh_compare_op0) == DImode
920 && sh_compare_op1 == const0_rtx)
1c563bed 921 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
0f4c242b 922 sh_compare_op0, sh_compare_op1);
fa5322fa
AO
923 else
924 {
925 rtx tmp;
926
927 if (no_new_pseudos)
928 FAIL;
929
930 tmp = gen_reg_rtx (DImode);
931
932 switch (GET_CODE (operands[1]))
933 {
934 case EQ:
935 emit_insn (gen_seq (tmp));
c0d4e710 936 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
937 break;
938
939 case NE:
940 emit_insn (gen_seq (tmp));
c0d4e710 941 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
942 break;
943
944 case GT:
945 emit_insn (gen_sgt (tmp));
c0d4e710 946 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
947 break;
948
949 case LT:
950 emit_insn (gen_slt (tmp));
c0d4e710 951 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
952 break;
953
954 case GE:
955 emit_insn (gen_slt (tmp));
c0d4e710 956 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
957 break;
958
959 case LE:
960 emit_insn (gen_sgt (tmp));
c0d4e710 961 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
962 break;
963
964 case GTU:
965 emit_insn (gen_sgtu (tmp));
c0d4e710 966 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
967 break;
968
969 case LTU:
970 emit_insn (gen_sltu (tmp));
c0d4e710 971 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
972 break;
973
974 case GEU:
975 emit_insn (gen_sltu (tmp));
c0d4e710 976 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
977 break;
978
979 case LEU:
980 emit_insn (gen_sgtu (tmp));
c0d4e710 981 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
982 break;
983
984 case UNORDERED:
985 emit_insn (gen_sunordered (tmp));
c0d4e710 986 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
987 break;
988
989 case ORDERED:
990 emit_insn (gen_sunordered (tmp));
c0d4e710 991 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
992 break;
993
994 case UNEQ:
995 case UNGE:
996 case UNGT:
997 case UNLE:
998 case UNLT:
999 case LTGT:
1000 FAIL;
1001
1002 default:
1003 abort ();
1004 }
1005 }
1006}")
1245df60
R
1007\f
1008;; -------------------------------------------------------------------------
bc45ade3
SC
1009;; Addition instructions
1010;; -------------------------------------------------------------------------
1011
fa5322fa
AO
1012(define_expand "adddi3"
1013 [(set (match_operand:DI 0 "arith_reg_operand" "")
1014 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1015 (match_operand:DI 2 "arith_operand" "")))]
1016 ""
1017 "
1018{
1019 if (TARGET_SH1)
1020 {
1021 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1022 FAIL;
1023 operands[2] = force_reg (DImode, operands[2]);
1024 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1025 DONE;
1026 }
1027}")
0d7e008e 1028
fa5322fa
AO
1029(define_insn "*adddi3_media"
1030 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1031 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 1032 (match_operand:DI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1033 "TARGET_SHMEDIA"
1034 "@
1035 add %1, %2, %0
2ad65b0e
SC
1036 addi %1, %2, %0"
1037 [(set_attr "type" "arith_media")])
fa5322fa 1038
b6d33983
R
1039(define_insn "adddi3z_media"
1040 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
fa5322fa 1041 (zero_extend:DI
b6d33983
R
1042 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1043 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
fa5322fa 1044 "TARGET_SHMEDIA"
b6d33983
R
1045 "addz.l %1, %N2, %0"
1046 [(set_attr "type" "arith_media")])
52702ae1 1047
fa5322fa 1048(define_insn "adddi3_compact"
38b3ef8b 1049 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
07a45e5c
JW
1050 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1051 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1052 (clobber (reg:SI T_REG))]
fa5322fa 1053 "TARGET_SH1"
1245df60 1054 "#"
4fdd1f85 1055 [(set_attr "length" "6")])
961c4780 1056
1245df60 1057(define_split
e69d1422
R
1058 [(set (match_operand:DI 0 "arith_reg_operand" "")
1059 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1060 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1061 (clobber (reg:SI T_REG))]
fa5322fa 1062 "TARGET_SH1 && reload_completed"
1245df60
R
1063 [(const_int 0)]
1064 "
1065{
1066 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1067 high0 = gen_rtx_REG (SImode,
1068 true_regnum (operands[0])
1069 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1070 high2 = gen_rtx_REG (SImode,
1071 true_regnum (operands[2])
1072 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1073 emit_insn (gen_clrt ());
1074 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1075 emit_insn (gen_addc1 (high0, high0, high2));
1076 DONE;
1077}")
1078
1079(define_insn "addc"
1080 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1081 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1082 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1083 (reg:SI T_REG)))
1084 (set (reg:SI T_REG)
1245df60 1085 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1086 "TARGET_SH1"
1245df60 1087 "addc %2,%0"
c49439f1 1088 [(set_attr "type" "arith")])
1245df60
R
1089
1090(define_insn "addc1"
1091 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1092 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1093 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1094 (reg:SI T_REG)))
1095 (clobber (reg:SI T_REG))]
fa5322fa 1096 "TARGET_SH1"
1245df60 1097 "addc %2,%0"
c49439f1 1098 [(set_attr "type" "arith")])
1245df60 1099
fa5322fa
AO
1100(define_expand "addsi3"
1101 [(set (match_operand:SI 0 "arith_reg_operand" "")
1102 (plus:SI (match_operand:SI 1 "arith_operand" "")
1103 (match_operand:SI 2 "arith_operand" "")))]
1104 ""
1105 "
1106{
1107 if (TARGET_SHMEDIA)
1108 operands[1] = force_reg (SImode, operands[1]);
1109}")
1110
1111(define_insn "addsi3_media"
1112 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 1113 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
735cb76e 1114 (match_operand:SI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1115 "TARGET_SHMEDIA"
1116 "@
1117 add.l %1, %2, %0
b6d33983
R
1118 addi.l %1, %2, %0"
1119 [(set_attr "type" "arith_media")])
52702ae1 1120
fa5322fa 1121(define_insn "*addsi3_compact"
aa684c94 1122 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f 1123 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
735cb76e 1124 (match_operand:SI 2 "arith_operand" "rI08")))]
fa5322fa 1125 "TARGET_SH1"
bc45ade3 1126 "add %2,%0"
c49439f1 1127 [(set_attr "type" "arith")])
fae15c93 1128
bc45ade3
SC
1129;; -------------------------------------------------------------------------
1130;; Subtraction instructions
1131;; -------------------------------------------------------------------------
1132
fa5322fa
AO
1133(define_expand "subdi3"
1134 [(set (match_operand:DI 0 "arith_reg_operand" "")
52702ae1 1135 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
fa5322fa
AO
1136 (match_operand:DI 2 "arith_reg_operand" "")))]
1137 ""
1138 "
1139{
1140 if (TARGET_SH1)
1141 {
52702ae1 1142 operands[1] = force_reg (DImode, operands[1]);
fa5322fa
AO
1143 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1144 DONE;
1145 }
1146}")
52702ae1 1147
fa5322fa
AO
1148(define_insn "*subdi3_media"
1149 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
52702ae1 1150 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
fa5322fa
AO
1151 (match_operand:DI 2 "arith_reg_operand" "r")))]
1152 "TARGET_SHMEDIA"
2ad65b0e
SC
1153 "sub %N1, %2, %0"
1154 [(set_attr "type" "arith_media")])
52702ae1 1155
fa5322fa 1156(define_insn "subdi3_compact"
38b3ef8b 1157 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
07a45e5c
JW
1158 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1159 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1160 (clobber (reg:SI T_REG))]
fa5322fa 1161 "TARGET_SH1"
1245df60 1162 "#"
4fdd1f85 1163 [(set_attr "length" "6")])
bc45ade3 1164
1245df60 1165(define_split
e69d1422
R
1166 [(set (match_operand:DI 0 "arith_reg_operand" "")
1167 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1168 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1169 (clobber (reg:SI T_REG))]
fa5322fa 1170 "TARGET_SH1 && reload_completed"
1245df60
R
1171 [(const_int 0)]
1172 "
1173{
1174 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1175 high0 = gen_rtx_REG (SImode,
1176 true_regnum (operands[0])
1177 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1178 high2 = gen_rtx_REG (SImode,
1179 true_regnum (operands[2])
1180 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1181 emit_insn (gen_clrt ());
1182 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1183 emit_insn (gen_subc1 (high0, high0, high2));
1184 DONE;
1185}")
1186
1187(define_insn "subc"
1188 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1189 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1190 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1191 (reg:SI T_REG)))
1192 (set (reg:SI T_REG)
3db1b434
R
1193 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1194 (reg:SI T_REG))
1195 (match_dup 1)))]
fa5322fa 1196 "TARGET_SH1"
1245df60 1197 "subc %2,%0"
c49439f1 1198 [(set_attr "type" "arith")])
1245df60
R
1199
1200(define_insn "subc1"
1201 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1202 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1203 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1204 (reg:SI T_REG)))
1205 (clobber (reg:SI T_REG))]
fa5322fa 1206 "TARGET_SH1"
1245df60 1207 "subc %2,%0"
c49439f1 1208 [(set_attr "type" "arith")])
1245df60 1209
caca3c8a 1210(define_insn "*subsi3_internal"
0d7e008e
SC
1211 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1212 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1213 (match_operand:SI 2 "arith_reg_operand" "r")))]
fa5322fa 1214 "TARGET_SH1"
0d7e008e 1215 "sub %2,%0"
c49439f1 1216 [(set_attr "type" "arith")])
caca3c8a 1217
fa5322fa
AO
1218(define_insn "*subsi3_media"
1219 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
b6d33983
R
1220 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1221 (match_operand:SI 2 "extend_reg_operand" "r")))]
fa5322fa 1222 "TARGET_SHMEDIA"
b6d33983
R
1223 "sub.l %N1, %2, %0"
1224 [(set_attr "type" "arith_media")])
fa5322fa 1225
caca3c8a
JW
1226;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1227;; will sometimes save one instruction. Otherwise we might get
1228;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1229;; are the same.
1230
1231(define_expand "subsi3"
1232 [(set (match_operand:SI 0 "arith_reg_operand" "")
1233 (minus:SI (match_operand:SI 1 "arith_operand" "")
1234 (match_operand:SI 2 "arith_reg_operand" "")))]
1235 ""
1236 "
1237{
fa5322fa 1238 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
caca3c8a
JW
1239 {
1240 emit_insn (gen_negsi2 (operands[0], operands[2]));
1241 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1242 DONE;
1243 }
fa5322fa
AO
1244 if (TARGET_SHMEDIA)
1245 {
b6d33983 1246 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
fa5322fa 1247 FAIL;
b6d33983
R
1248 if (operands[1] != const0_rtx)
1249 operands[1] = force_reg (SImode, operands[1]);
fa5322fa 1250 }
caca3c8a 1251}")
bc45ade3
SC
1252\f
1253;; -------------------------------------------------------------------------
0d7e008e 1254;; Division instructions
bc45ade3
SC
1255;; -------------------------------------------------------------------------
1256
ffae286a 1257;; We take advantage of the library routines which don't clobber as many
0d7e008e
SC
1258;; registers as a normal function call would.
1259
1245df60 1260;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
956d6950 1261;; also has an effect on the register that holds the address of the sfunc.
e69d1422 1262;; To make this work, we have an extra dummy insn that shows the use
1245df60
R
1263;; of this register for reorg.
1264
1265(define_insn "use_sfunc_addr"
4773afa4 1266 [(set (reg:SI PR_REG)
e69d1422 1267 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
07d7d2f4 1268 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1245df60
R
1269 ""
1270 [(set_attr "length" "0")])
1271
ddd5a7c1 1272;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
e96a50cc
JW
1273;; hard register 0. If we used hard register 0, then the next instruction
1274;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1275;; gets allocated to a stack slot that needs its address reloaded, then
1276;; there is nothing to prevent reload from using r0 to reload the address.
1277;; This reload would clobber the value in r0 we are trying to store.
1278;; If we let reload allocate r0, then this problem can never happen.
0d7e008e 1279
a512fa97 1280(define_insn "udivsi3_i1"
1245df60 1281 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1282 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1283 (clobber (reg:SI T_REG))
1284 (clobber (reg:SI PR_REG))
1285 (clobber (reg:SI R4_REG))
1245df60 1286 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1287 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1288 "jsr @%1%#"
1289 [(set_attr "type" "sfunc")
1290 (set_attr "needs_delay_slot" "yes")])
1291
9e96203d
R
1292; Since shmedia-nofpu code could be linked against shcompact code, and
1293; the udivsi3 libcall has the same name, we must consider all registers
1294; clobbered that are in the union of the registers clobbered by the
1295; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1296; implementation actually used shcompact code, we'd need to clobber
9e96203d 1297; also r23 and fr23.
fa5322fa
AO
1298(define_insn "udivsi3_i1_media"
1299 [(set (match_operand:SI 0 "register_operand" "=z")
1300 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1301 (clobber (reg:SI T_MEDIA_REG))
1302 (clobber (reg:SI PR_MEDIA_REG))
9e96203d
R
1303 (clobber (reg:SI R20_REG))
1304 (clobber (reg:SI R21_REG))
1305 (clobber (reg:SI R22_REG))
fa5322fa
AO
1306 (clobber (reg:DI TR0_REG))
1307 (clobber (reg:DI TR1_REG))
1308 (clobber (reg:DI TR2_REG))
1309 (use (match_operand:DI 1 "target_operand" "b"))]
1310 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1311 "blink %1, r18"
1312 [(set_attr "type" "sfunc")
1313 (set_attr "needs_delay_slot" "yes")])
1314
1315(define_expand "udivsi3_i4_media"
b6d33983
R
1316 [(set (match_dup 3)
1317 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1318 (set (match_dup 4)
1319 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
fa5322fa 1320 (set (match_dup 5) (float:DF (match_dup 3)))
b6d33983
R
1321 (set (match_dup 6) (float:DF (match_dup 4)))
1322 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1323 (set (match_dup 8) (fix:DI (match_dup 7)))
0ac78517
R
1324 (set (match_operand:SI 0 "register_operand" "")
1325 (truncate:SI (match_dup 8)))]
fa5322fa
AO
1326 "TARGET_SHMEDIA_FPU"
1327 "
1328{
fa5322fa 1329 operands[3] = gen_reg_rtx (DImode);
b6d33983 1330 operands[4] = gen_reg_rtx (DImode);
fa5322fa
AO
1331 operands[5] = gen_reg_rtx (DFmode);
1332 operands[6] = gen_reg_rtx (DFmode);
b6d33983
R
1333 operands[7] = gen_reg_rtx (DFmode);
1334 operands[8] = gen_reg_rtx (DImode);
fa5322fa
AO
1335}")
1336
225e4f43
R
1337(define_insn "udivsi3_i4"
1338 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1339 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1340 (clobber (reg:SI T_REG))
4773afa4
AO
1341 (clobber (reg:SI PR_REG))
1342 (clobber (reg:DF DR0_REG))
1343 (clobber (reg:DF DR2_REG))
1344 (clobber (reg:DF DR4_REG))
1345 (clobber (reg:SI R0_REG))
1346 (clobber (reg:SI R1_REG))
1347 (clobber (reg:SI R4_REG))
1348 (clobber (reg:SI R5_REG))
1349 (use (reg:PSI FPSCR_REG))
225e4f43
R
1350 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1351 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1352 "jsr @%1%#"
1353 [(set_attr "type" "sfunc")
d64264ff 1354 (set_attr "fp_mode" "double")
225e4f43
R
1355 (set_attr "needs_delay_slot" "yes")])
1356
1357(define_insn "udivsi3_i4_single"
1358 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1359 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1360 (clobber (reg:SI T_REG))
4773afa4
AO
1361 (clobber (reg:SI PR_REG))
1362 (clobber (reg:DF DR0_REG))
1363 (clobber (reg:DF DR2_REG))
1364 (clobber (reg:DF DR4_REG))
1365 (clobber (reg:SI R0_REG))
1366 (clobber (reg:SI R1_REG))
1367 (clobber (reg:SI R4_REG))
1368 (clobber (reg:SI R5_REG))
225e4f43 1369 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1370 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1371 "jsr @%1%#"
0d7e008e 1372 [(set_attr "type" "sfunc")
0d7e008e
SC
1373 (set_attr "needs_delay_slot" "yes")])
1374
1375(define_expand "udivsi3"
a512fa97 1376 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
4773afa4
AO
1377 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1378 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1379 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1380 (udiv:SI (reg:SI R4_REG)
1381 (reg:SI R5_REG)))
1382 (clobber (reg:SI T_REG))
1383 (clobber (reg:SI PR_REG))
1384 (clobber (reg:SI R4_REG))
ffae286a 1385 (use (match_dup 3))])]
0d7e008e 1386 ""
225e4f43
R
1387 "
1388{
4392ebd3 1389 rtx first, last;
a512fa97 1390
fa5322fa 1391 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1392 /* Emit the move of the address to a pseudo outside of the libcall. */
3a8699c7 1393 if (TARGET_HARD_SH4 && TARGET_SH2E)
225e4f43 1394 {
90534361 1395 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
225e4f43 1396 if (TARGET_FPU_SINGLE)
a512fa97 1397 last = gen_udivsi3_i4_single (operands[0], operands[3]);
225e4f43 1398 else
a512fa97 1399 last = gen_udivsi3_i4 (operands[0], operands[3]);
225e4f43 1400 }
fa5322fa 1401 else if (TARGET_SHMEDIA_FPU)
b6d33983
R
1402 {
1403 operands[1] = force_reg (SImode, operands[1]);
1404 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1405 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1406 DONE;
b6d33983 1407 }
fa5322fa
AO
1408 else if (TARGET_SH5)
1409 {
1410 emit_move_insn (operands[3],
90534361
R
1411 function_symbol (TARGET_FPU_ANY
1412 ? \"__udivsi3_i4\"
1413 : \"__udivsi3\"));
fa5322fa
AO
1414
1415 if (TARGET_SHMEDIA)
1416 last = gen_udivsi3_i1_media (operands[0],
1417 Pmode == DImode
1418 ? operands[3]
1419 : gen_rtx_SUBREG (DImode, operands[3],
1420 0));
1421 else if (TARGET_FPU_ANY)
1422 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1423 else
1424 last = gen_udivsi3_i1 (operands[0], operands[3]);
1425 }
a512fa97
R
1426 else
1427 {
90534361 1428 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
a512fa97
R
1429 last = gen_udivsi3_i1 (operands[0], operands[3]);
1430 }
4392ebd3
RS
1431 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1432 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1433 last = emit_insn (last);
1434 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1435 invariant code motion can move it. */
1436 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1437 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1438 DONE;
225e4f43 1439}")
0d7e008e 1440
a512fa97 1441(define_insn "divsi3_i1"
1245df60 1442 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1443 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1444 (clobber (reg:SI T_REG))
1445 (clobber (reg:SI PR_REG))
1446 (clobber (reg:SI R1_REG))
1447 (clobber (reg:SI R2_REG))
1448 (clobber (reg:SI R3_REG))
1245df60 1449 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1450 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1451 "jsr @%1%#"
1452 [(set_attr "type" "sfunc")
1453 (set_attr "needs_delay_slot" "yes")])
1454
9e96203d 1455; Since shmedia-nofpu code could be linked against shcompact code, and
b6d33983 1456; the sdivsi3 libcall has the same name, we must consider all registers
9e96203d
R
1457; clobbered that are in the union of the registers clobbered by the
1458; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1459; implementation actually used shcompact code, we'd need to clobber
9e96203d 1460; also r22, r23 and fr23.
fa5322fa
AO
1461(define_insn "divsi3_i1_media"
1462 [(set (match_operand:SI 0 "register_operand" "=z")
1463 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1464 (clobber (reg:SI T_MEDIA_REG))
1465 (clobber (reg:SI PR_MEDIA_REG))
1466 (clobber (reg:SI R1_REG))
1467 (clobber (reg:SI R2_REG))
1468 (clobber (reg:SI R3_REG))
9e96203d
R
1469 (clobber (reg:SI R20_REG))
1470 (clobber (reg:SI R21_REG))
fa5322fa
AO
1471 (clobber (reg:DI TR0_REG))
1472 (clobber (reg:DI TR1_REG))
1473 (clobber (reg:DI TR2_REG))
1474 (use (match_operand:DI 1 "target_operand" "b"))]
1475 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
2ad65b0e
SC
1476 "blink %1, r18"
1477 [(set_attr "type" "sfunc")])
fa5322fa
AO
1478
1479(define_expand "divsi3_i4_media"
51214775
R
1480 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1481 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1482 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
fa5322fa 1483 (set (match_operand:SI 0 "register_operand" "=r")
51214775 1484 (fix:SI (match_dup 5)))]
fa5322fa
AO
1485 "TARGET_SHMEDIA_FPU"
1486 "
1487{
51214775 1488 operands[3] = gen_reg_rtx (DFmode);
fa5322fa
AO
1489 operands[4] = gen_reg_rtx (DFmode);
1490 operands[5] = gen_reg_rtx (DFmode);
fa5322fa
AO
1491}")
1492
225e4f43
R
1493(define_insn "divsi3_i4"
1494 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1495 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1496 (clobber (reg:SI PR_REG))
1497 (clobber (reg:DF DR0_REG))
1498 (clobber (reg:DF DR2_REG))
1499 (use (reg:PSI FPSCR_REG))
225e4f43
R
1500 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1501 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1502 "jsr @%1%#"
1503 [(set_attr "type" "sfunc")
d64264ff 1504 (set_attr "fp_mode" "double")
225e4f43
R
1505 (set_attr "needs_delay_slot" "yes")])
1506
1507(define_insn "divsi3_i4_single"
1508 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1509 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1510 (clobber (reg:SI PR_REG))
1511 (clobber (reg:DF DR0_REG))
1512 (clobber (reg:DF DR2_REG))
1513 (clobber (reg:SI R2_REG))
225e4f43 1514 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1515 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1516 "jsr @%1%#"
0d7e008e 1517 [(set_attr "type" "sfunc")
0d7e008e
SC
1518 (set_attr "needs_delay_slot" "yes")])
1519
1520(define_expand "divsi3"
a512fa97 1521 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
4773afa4
AO
1522 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1523 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1524 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1525 (div:SI (reg:SI R4_REG)
1526 (reg:SI R5_REG)))
1527 (clobber (reg:SI T_REG))
1528 (clobber (reg:SI PR_REG))
1529 (clobber (reg:SI R1_REG))
1530 (clobber (reg:SI R2_REG))
1531 (clobber (reg:SI R3_REG))
ffae286a 1532 (use (match_dup 3))])]
0d7e008e 1533 ""
225e4f43
R
1534 "
1535{
4392ebd3 1536 rtx first, last;
a512fa97 1537
fa5322fa 1538 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1539 /* Emit the move of the address to a pseudo outside of the libcall. */
3a8699c7 1540 if (TARGET_HARD_SH4 && TARGET_SH2E)
225e4f43 1541 {
90534361 1542 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
225e4f43 1543 if (TARGET_FPU_SINGLE)
a512fa97 1544 last = gen_divsi3_i4_single (operands[0], operands[3]);
225e4f43 1545 else
a512fa97 1546 last = gen_divsi3_i4 (operands[0], operands[3]);
225e4f43 1547 }
fa5322fa 1548 else if (TARGET_SHMEDIA_FPU)
51214775
R
1549 {
1550 operands[1] = force_reg (SImode, operands[1]);
1551 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1552 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1553 DONE;
51214775 1554 }
fa5322fa
AO
1555 else if (TARGET_SH5)
1556 {
1557 emit_move_insn (operands[3],
90534361
R
1558 function_symbol (TARGET_FPU_ANY
1559 ? \"__sdivsi3_i4\"
1560 : \"__sdivsi3\"));
fa5322fa
AO
1561
1562 if (TARGET_SHMEDIA)
52702ae1 1563 last = gen_divsi3_i1_media (operands[0],
fa5322fa
AO
1564 Pmode == DImode
1565 ? operands[3]
1566 : gen_rtx_SUBREG (DImode, operands[3],
1567 0));
1568 else if (TARGET_FPU_ANY)
1569 last = gen_divsi3_i4_single (operands[0], operands[3]);
1570 else
1571 last = gen_divsi3_i1 (operands[0], operands[3]);
1572 }
a512fa97
R
1573 else
1574 {
90534361 1575 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
a512fa97
R
1576 last = gen_divsi3_i1 (operands[0], operands[3]);
1577 }
4392ebd3
RS
1578 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1579 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1580 last = emit_insn (last);
1581 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1582 invariant code motion can move it. */
1583 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1584 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1585 DONE;
225e4f43 1586}")
0d7e008e
SC
1587\f
1588;; -------------------------------------------------------------------------
1589;; Multiplication instructions
1590;; -------------------------------------------------------------------------
1591
a512fa97 1592(define_insn "umulhisi3_i"
4773afa4
AO
1593 [(set (reg:SI MACL_REG)
1594 (mult:SI (zero_extend:SI
1595 (match_operand:HI 0 "arith_reg_operand" "r"))
1596 (zero_extend:SI
1597 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1598 "TARGET_SH1"
e9a9e960 1599 "mulu.w %1,%0"
b9654711 1600 [(set_attr "type" "smpy")])
bc45ade3 1601
a512fa97 1602(define_insn "mulhisi3_i"
4773afa4 1603 [(set (reg:SI MACL_REG)
bc45ade3 1604 (mult:SI (sign_extend:SI
af55dae3 1605 (match_operand:HI 0 "arith_reg_operand" "r"))
bc45ade3 1606 (sign_extend:SI
af55dae3 1607 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1608 "TARGET_SH1"
e9a9e960 1609 "muls.w %1,%0"
b9654711 1610 [(set_attr "type" "smpy")])
bc45ade3
SC
1611
1612(define_expand "mulhisi3"
4773afa4 1613 [(set (reg:SI MACL_REG)
bc45ade3 1614 (mult:SI (sign_extend:SI
51aea58d 1615 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1616 (sign_extend:SI
51aea58d
JW
1617 (match_operand:HI 2 "arith_reg_operand" ""))))
1618 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1619 (reg:SI MACL_REG))]
fa5322fa 1620 "TARGET_SH1"
a512fa97
R
1621 "
1622{
1623 rtx first, last;
1624
1625 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
4773afa4 1626 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1627 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1628 invariant code motion can move it. */
1629 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1630 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1631 /* expand_binop can't find a suitable code in umul_widen_optab to
1632 make a REG_EQUAL note from, so make one here.
1633 See also smulsi3_highpart.
1634 ??? Alternatively, we could put this at the calling site of expand_binop,
1635 i.e. expand_expr. */
1636 REG_NOTES (last)
1637 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1638 REG_NOTES (last));
a512fa97
R
1639 DONE;
1640}")
bc45ade3
SC
1641
1642(define_expand "umulhisi3"
4773afa4 1643 [(set (reg:SI MACL_REG)
bc45ade3 1644 (mult:SI (zero_extend:SI
51aea58d 1645 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1646 (zero_extend:SI
51aea58d
JW
1647 (match_operand:HI 2 "arith_reg_operand" ""))))
1648 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1649 (reg:SI MACL_REG))]
fa5322fa 1650 "TARGET_SH1"
a512fa97
R
1651 "
1652{
1653 rtx first, last;
1654
1655 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
4773afa4 1656 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1657 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1658 invariant code motion can move it. */
1659 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1660 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1661 /* expand_binop can't find a suitable code in umul_widen_optab to
1662 make a REG_EQUAL note from, so make one here.
1663 See also smulsi3_highpart.
1664 ??? Alternatively, we could put this at the calling site of expand_binop,
1665 i.e. expand_expr. */
1666 REG_NOTES (last)
1667 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1668 REG_NOTES (last));
a512fa97
R
1669 DONE;
1670}")
bc45ade3 1671
0d7e008e
SC
1672;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1673;; a call to a routine which clobbers known registers.
1674
1675(define_insn ""
e96a50cc 1676 [(set (match_operand:SI 1 "register_operand" "=z")
4773afa4
AO
1677 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1678 (clobber (reg:SI MACL_REG))
1679 (clobber (reg:SI T_REG))
1680 (clobber (reg:SI PR_REG))
1681 (clobber (reg:SI R3_REG))
1682 (clobber (reg:SI R2_REG))
1683 (clobber (reg:SI R1_REG))
07a45e5c 1684 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 1685 "TARGET_SH1"
0d7e008e
SC
1686 "jsr @%0%#"
1687 [(set_attr "type" "sfunc")
0d7e008e
SC
1688 (set_attr "needs_delay_slot" "yes")])
1689
1690(define_expand "mulsi3_call"
4773afa4
AO
1691 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1692 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
51aea58d 1693 (parallel[(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1694 (mult:SI (reg:SI R4_REG)
1695 (reg:SI R5_REG)))
1696 (clobber (reg:SI MACL_REG))
1697 (clobber (reg:SI T_REG))
1698 (clobber (reg:SI PR_REG))
1699 (clobber (reg:SI R3_REG))
1700 (clobber (reg:SI R2_REG))
1701 (clobber (reg:SI R1_REG))
225e4f43 1702 (use (match_operand:SI 3 "register_operand" ""))])]
fa5322fa 1703 "TARGET_SH1"
225e4f43 1704 "")
07a45e5c 1705
0d7e008e 1706(define_insn "mul_l"
4773afa4 1707 [(set (reg:SI MACL_REG)
0d7e008e
SC
1708 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1709 (match_operand:SI 1 "arith_reg_operand" "r")))]
1710 "TARGET_SH2"
1711 "mul.l %1,%0"
51bd623f 1712 [(set_attr "type" "dmpy")])
0d7e008e
SC
1713
1714(define_expand "mulsi3"
4773afa4 1715 [(set (reg:SI MACL_REG)
51aea58d
JW
1716 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1717 (match_operand:SI 2 "arith_reg_operand" "")))
1718 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1719 (reg:SI MACL_REG))]
fa5322fa 1720 "TARGET_SH1"
51bd623f
JW
1721 "
1722{
225e4f43
R
1723 rtx first, last;
1724
51bd623f
JW
1725 if (!TARGET_SH2)
1726 {
225e4f43
R
1727 /* The address must be set outside the libcall,
1728 since it goes into a pseudo. */
90534361 1729 rtx sym = function_symbol (\"__mulsi3\");
a6f463a0
AO
1730 rtx addr = force_reg (SImode, sym);
1731 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1732 operands[2], addr);
fa60f36d
R
1733 first = insns;
1734 last = emit_insn (insns);
51bd623f 1735 }
225e4f43
R
1736 else
1737 {
1738 rtx macl = gen_rtx_REG (SImode, MACL_REG);
aa4778b6 1739
225e4f43 1740 first = emit_insn (gen_mul_l (operands[1], operands[2]));
aa4778b6
R
1741 /* consec_sets_giv can only recognize the first insn that sets a
1742 giv as the giv insn. So we must tag this also with a REG_EQUAL
1743 note. */
78d114ef 1744 last = emit_insn (gen_movsi_i ((operands[0]), macl));
225e4f43
R
1745 }
1746 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1747 invariant code motion can move it. */
1748 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1749 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1750 DONE;
51bd623f 1751}")
00f8ff66 1752
af55dae3 1753(define_insn "mulsidi3_i"
4773afa4 1754 [(set (reg:SI MACH_REG)
a512fa97 1755 (truncate:SI
4773afa4
AO
1756 (lshiftrt:DI
1757 (mult:DI
1758 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1759 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1760 (const_int 32))))
1761 (set (reg:SI MACL_REG)
a512fa97
R
1762 (mult:SI (match_dup 0)
1763 (match_dup 1)))]
06e1bace 1764 "TARGET_SH2"
af55dae3 1765 "dmuls.l %1,%0"
0d7e008e
SC
1766 [(set_attr "type" "dmpy")])
1767
fa5322fa
AO
1768(define_expand "mulsidi3"
1769 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1770 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1771 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1772 "TARGET_SH2 || TARGET_SHMEDIA"
1773 "
1774{
1775 if (TARGET_SH2)
1776 {
1777 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1778 operands[2]));
1779 DONE;
1780 }
1781}")
1782
1783(define_insn "mulsidi3_media"
1784 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1785 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1786 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1787 "TARGET_SHMEDIA"
b6d33983
R
1788 "muls.l %1, %2, %0"
1789 [(set_attr "type" "dmpy_media")])
52702ae1 1790
fa5322fa 1791(define_insn "mulsidi3_compact"
a512fa97 1792 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1793 (mult:DI
1794 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1795 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1796 (clobber (reg:SI MACH_REG))
1797 (clobber (reg:SI MACL_REG))]
a512fa97
R
1798 "TARGET_SH2"
1799 "#")
1800
1801(define_split
1802 [(set (match_operand:DI 0 "arith_reg_operand" "")
4773afa4
AO
1803 (mult:DI
1804 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1805 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1806 (clobber (reg:SI MACH_REG))
1807 (clobber (reg:SI MACL_REG))]
06e1bace 1808 "TARGET_SH2"
a512fa97 1809 [(const_int 0)]
af55dae3
JW
1810 "
1811{
a512fa97
R
1812 rtx low_dst = gen_lowpart (SImode, operands[0]);
1813 rtx high_dst = gen_highpart (SImode, operands[0]);
0d7e008e 1814
a512fa97 1815 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
af55dae3 1816
4773afa4
AO
1817 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1818 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1819 /* We need something to tag the possible REG_EQUAL notes on to. */
1820 emit_move_insn (operands[0], operands[0]);
1821 DONE;
af55dae3
JW
1822}")
1823
1824(define_insn "umulsidi3_i"
4773afa4 1825 [(set (reg:SI MACH_REG)
a512fa97 1826 (truncate:SI
4773afa4
AO
1827 (lshiftrt:DI
1828 (mult:DI
1829 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1830 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1831 (const_int 32))))
1832 (set (reg:SI MACL_REG)
a512fa97
R
1833 (mult:SI (match_dup 0)
1834 (match_dup 1)))]
06e1bace 1835 "TARGET_SH2"
af55dae3 1836 "dmulu.l %1,%0"
0d7e008e
SC
1837 [(set_attr "type" "dmpy")])
1838
fa5322fa
AO
1839(define_expand "umulsidi3"
1840 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1841 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1842 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1843 "TARGET_SH2 || TARGET_SHMEDIA"
1844 "
1845{
1846 if (TARGET_SH2)
1847 {
1848 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1849 operands[2]));
1850 DONE;
1851 }
1852}")
1853
1854(define_insn "umulsidi3_media"
1855 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1856 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1857 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1858 "TARGET_SHMEDIA"
b6d33983
R
1859 "mulu.l %1, %2, %0"
1860 [(set_attr "type" "dmpy_media")])
52702ae1 1861
fa5322fa 1862(define_insn "umulsidi3_compact"
a512fa97 1863 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1864 (mult:DI
1865 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1866 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1867 (clobber (reg:SI MACH_REG))
1868 (clobber (reg:SI MACL_REG))]
a512fa97
R
1869 "TARGET_SH2"
1870 "#")
1871
1872(define_split
1873 [(set (match_operand:DI 0 "arith_reg_operand" "")
51aea58d
JW
1874 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1875 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1876 (clobber (reg:SI MACH_REG))
1877 (clobber (reg:SI MACL_REG))]
06e1bace 1878 "TARGET_SH2"
a512fa97 1879 [(const_int 0)]
af55dae3
JW
1880 "
1881{
a512fa97
R
1882 rtx low_dst = gen_lowpart (SImode, operands[0]);
1883 rtx high_dst = gen_highpart (SImode, operands[0]);
af55dae3 1884
a512fa97 1885 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
af55dae3 1886
4773afa4
AO
1887 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1888 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1889 /* We need something to tag the possible REG_EQUAL notes on to. */
1890 emit_move_insn (operands[0], operands[0]);
1891 DONE;
af55dae3 1892}")
06e1bace 1893
a512fa97 1894(define_insn "smulsi3_highpart_i"
4773afa4 1895 [(set (reg:SI MACH_REG)
06e1bace 1896 (truncate:SI
4773afa4
AO
1897 (lshiftrt:DI
1898 (mult:DI
1899 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1900 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1901 (const_int 32))))
1902 (clobber (reg:SI MACL_REG))]
06e1bace 1903 "TARGET_SH2"
af55dae3 1904 "dmuls.l %1,%0"
06e1bace
RK
1905 [(set_attr "type" "dmpy")])
1906
1907(define_expand "smulsi3_highpart"
4773afa4
AO
1908 [(parallel
1909 [(set (reg:SI MACH_REG)
1910 (truncate:SI
1911 (lshiftrt:DI
1912 (mult:DI
1913 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1914 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1915 (const_int 32))))
1916 (clobber (reg:SI MACL_REG))])
06e1bace 1917 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1918 (reg:SI MACH_REG))]
06e1bace 1919 "TARGET_SH2"
a512fa97
R
1920 "
1921{
1922 rtx first, last;
06e1bace 1923
a512fa97 1924 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1925 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1926 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1927 invariant code motion can move it. */
1928 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1929 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
22d05f60
R
1930 /* expand_binop can't find a suitable code in mul_highpart_optab to
1931 make a REG_EQUAL note from, so make one here.
c49439f1 1932 See also {,u}mulhisi.
22d05f60
R
1933 ??? Alternatively, we could put this at the calling site of expand_binop,
1934 i.e. expand_mult_highpart. */
1935 REG_NOTES (last)
1936 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1937 REG_NOTES (last));
a512fa97
R
1938 DONE;
1939}")
1940
1941(define_insn "umulsi3_highpart_i"
4773afa4 1942 [(set (reg:SI MACH_REG)
06e1bace 1943 (truncate:SI
4773afa4
AO
1944 (lshiftrt:DI
1945 (mult:DI
1946 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1947 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1948 (const_int 32))))
1949 (clobber (reg:SI MACL_REG))]
06e1bace 1950 "TARGET_SH2"
af55dae3 1951 "dmulu.l %1,%0"
06e1bace
RK
1952 [(set_attr "type" "dmpy")])
1953
1954(define_expand "umulsi3_highpart"
4773afa4
AO
1955 [(parallel
1956 [(set (reg:SI MACH_REG)
1957 (truncate:SI
1958 (lshiftrt:DI
1959 (mult:DI
1960 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1961 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1962 (const_int 32))))
1963 (clobber (reg:SI MACL_REG))])
06e1bace 1964 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1965 (reg:SI MACH_REG))]
06e1bace 1966 "TARGET_SH2"
a512fa97
R
1967 "
1968{
1969 rtx first, last;
1970
1971 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1972 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1973 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1974 invariant code motion can move it. */
1975 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1976 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1977 DONE;
1978}")
bc45ade3
SC
1979\f
1980;; -------------------------------------------------------------------------
1981;; Logical operations
1982;; -------------------------------------------------------------------------
1983
b6d33983 1984(define_insn "*andsi3_compact"
aa684c94
SC
1985 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1986 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 1987 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 1988 "TARGET_SH1"
bc45ade3 1989 "and %2,%0"
c49439f1 1990 [(set_attr "type" "arith")])
bc45ade3 1991
43aa4e05 1992;; If the constant is 255, then emit an extu.b instruction instead of an
51bd623f
JW
1993;; and, since that will give better code.
1994
0d7e008e
SC
1995(define_expand "andsi3"
1996 [(set (match_operand:SI 0 "arith_reg_operand" "")
1997 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1998 (match_operand:SI 2 "logical_operand" "")))]
fa5322fa 1999 "TARGET_SH1"
51bd623f
JW
2000 "
2001{
2002 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
2003 {
2004 emit_insn (gen_zero_extendqisi2 (operands[0],
2005 gen_lowpart (QImode, operands[1])));
2006 DONE;
2007 }
2008}")
0d7e008e 2009
c1b92d09
R
2010(define_insn_and_split "anddi3"
2011 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
2012 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
735cb76e 2013 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
fa5322fa
AO
2014 "TARGET_SHMEDIA"
2015 "@
2016 and %1, %2, %0
c1b92d09
R
2017 andi %1, %2, %0
2018 #"
2019 "reload_completed
2020 && ! logical_operand (operands[2], DImode)"
2021 [(const_int 0)]
2022 "
2023{
2024 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2025 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2026 else
2027 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2028 DONE;
2ad65b0e
SC
2029}"
2030 [(set_attr "type" "arith_media")])
fa5322fa 2031
b6d33983 2032(define_insn "andcdi3"
fa5322fa
AO
2033 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2034 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2035 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2036 "TARGET_SHMEDIA"
2ad65b0e
SC
2037 "andc %1,%2,%0"
2038 [(set_attr "type" "arith_media")])
fa5322fa 2039
bc45ade3 2040(define_insn "iorsi3"
aa684c94
SC
2041 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2042 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 2043 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 2044 "TARGET_SH1"
1245df60 2045 "or %2,%0"
c49439f1 2046 [(set_attr "type" "arith")])
bc45ade3 2047
fa5322fa
AO
2048(define_insn "iordi3"
2049 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2050 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 2051 (match_operand:DI 2 "logical_operand" "r,I10")))]
fa5322fa
AO
2052 "TARGET_SHMEDIA"
2053 "@
2054 or %1, %2, %0
2ad65b0e
SC
2055 ori %1, %2, %0"
2056 [(set_attr "type" "arith_media")])
fa5322fa 2057
bc45ade3 2058(define_insn "xorsi3"
0d7e008e 2059 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
aa684c94 2060 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 2061 (match_operand:SI 2 "logical_operand" "K08,r")))]
fa5322fa 2062 "TARGET_SH1"
bc45ade3 2063 "xor %2,%0"
c49439f1 2064 [(set_attr "type" "arith")])
fa5322fa
AO
2065
2066(define_insn "xordi3"
2067 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2068 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 2069 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
fa5322fa
AO
2070 "TARGET_SHMEDIA"
2071 "@
2072 xor %1, %2, %0
2ad65b0e
SC
2073 xori %1, %2, %0"
2074 [(set_attr "type" "arith_media")])
ff881d52
R
2075
2076;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2077;; converts 2 * sign extend -> logical op into logical op -> sign extend
2078(define_split
2079 [(set (match_operand:DI 0 "arith_reg_operand" "")
2080 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2081 [(match_operand 1 "any_register_operand" "")
2082 (match_operand 2 "any_register_operand" "")])))]
2083 "TARGET_SHMEDIA"
2084 [(set (match_dup 5) (match_dup 4))
2085 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2086"
2087{
2088 enum machine_mode inmode = GET_MODE (operands[1]);
fada1961 2089 int offset = 0;
ff881d52
R
2090
2091 if (GET_CODE (operands[0]) == SUBREG)
2092 {
2093 offset = SUBREG_BYTE (operands[0]);
2094 operands[0] = SUBREG_REG (operands[0]);
2095 }
2096 if (GET_CODE (operands[0]) != REG)
2097 abort ();
2098 if (! TARGET_LITTLE_ENDIAN)
2099 offset += 8 - GET_MODE_SIZE (inmode);
2100 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2101}")
bc45ade3
SC
2102\f
2103;; -------------------------------------------------------------------------
2104;; Shifts and rotates
2105;; -------------------------------------------------------------------------
2106
b6d33983
R
2107(define_expand "rotldi3"
2108 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2109 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2110 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2111 "TARGET_SHMEDIA"
2112 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2113
2114(define_insn "rotldi3_mextr"
2115 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2116 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2117 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2118 "TARGET_SHMEDIA"
2119 "*
2120{
2121 static char templ[16];
2122
2123 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2124 8 - (int) (INTVAL (operands[2]) >> 3));
2125 return templ;
2126}"
2127 [(set_attr "type" "arith_media")])
2128
2129(define_expand "rotrdi3"
2130 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2131 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2132 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2133 "TARGET_SHMEDIA"
2134 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2135
2136(define_insn "rotrdi3_mextr"
2137 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2138 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2139 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2140 "TARGET_SHMEDIA"
2141 "*
2142{
2143 static char templ[16];
2144
2145 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2146 return templ;
2147}"
2148 [(set_attr "type" "arith_media")])
2149
51bd623f 2150(define_insn "rotlsi3_1"
b9654711
SC
2151 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2152 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2153 (const_int 1)))
4773afa4 2154 (set (reg:SI T_REG)
51aea58d 2155 (lshiftrt:SI (match_dup 1) (const_int 31)))]
fa5322fa 2156 "TARGET_SH1"
1245df60 2157 "rotl %0"
c49439f1 2158 [(set_attr "type" "arith")])
b9654711 2159
51bd623f 2160(define_insn "rotlsi3_31"
b9654711 2161 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f
JW
2162 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2163 (const_int 31)))
4773afa4 2164 (clobber (reg:SI T_REG))]
fa5322fa 2165 "TARGET_SH1"
1245df60 2166 "rotr %0"
c49439f1 2167 [(set_attr "type" "arith")])
b9654711 2168
1245df60 2169(define_insn "rotlsi3_16"
51bd623f
JW
2170 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2171 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2172 (const_int 16)))]
fa5322fa 2173 "TARGET_SH1"
1245df60 2174 "swap.w %1,%0"
c49439f1 2175 [(set_attr "type" "arith")])
b9654711 2176
51bd623f
JW
2177(define_expand "rotlsi3"
2178 [(set (match_operand:SI 0 "arith_reg_operand" "")
2179 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2180 (match_operand:SI 2 "immediate_operand" "")))]
fa5322fa 2181 "TARGET_SH1"
51bd623f
JW
2182 "
2183{
0139adca 2184 static const char rot_tab[] = {
1245df60
R
2185 000, 000, 000, 000, 000, 000, 010, 001,
2186 001, 001, 011, 013, 003, 003, 003, 003,
2187 003, 003, 003, 003, 003, 013, 012, 002,
2188 002, 002, 010, 000, 000, 000, 000, 000,
2189 };
2190
2191 int count, choice;
2192
51bd623f
JW
2193 if (GET_CODE (operands[2]) != CONST_INT)
2194 FAIL;
1245df60
R
2195 count = INTVAL (operands[2]);
2196 choice = rot_tab[count];
2197 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2198 FAIL;
2199 choice &= 7;
2200 switch (choice)
51bd623f 2201 {
1245df60
R
2202 case 0:
2203 emit_move_insn (operands[0], operands[1]);
2204 count -= (count & 16) * 2;
2205 break;
2206 case 3:
2207 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2208 count -= 16;
2209 break;
2210 case 1:
2211 case 2:
2212 {
2213 rtx parts[2];
2214 parts[0] = gen_reg_rtx (SImode);
2215 parts[1] = gen_reg_rtx (SImode);
2216 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
4fbf3498 2217 emit_move_insn (parts[choice-1], operands[1]);
1245df60
R
2218 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2219 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2220 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2221 count = (count & ~16) - 8;
2222 }
51bd623f 2223 }
1245df60
R
2224
2225 for (; count > 0; count--)
2226 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2227 for (; count < 0; count++)
2228 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2229
2230 DONE;
51bd623f
JW
2231}")
2232
1245df60 2233(define_insn "*rotlhi3_8"
51bd623f
JW
2234 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2235 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2236 (const_int 8)))]
fa5322fa 2237 "TARGET_SH1"
1245df60 2238 "swap.b %1,%0"
c49439f1 2239 [(set_attr "type" "arith")])
51bd623f
JW
2240
2241(define_expand "rotlhi3"
2242 [(set (match_operand:HI 0 "arith_reg_operand" "")
2243 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2244 (match_operand:HI 2 "immediate_operand" "")))]
fa5322fa 2245 "TARGET_SH1"
51bd623f
JW
2246 "
2247{
2248 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2249 FAIL;
2250}")
0d7e008e
SC
2251
2252;;
2253;; shift left
2254
7e2fda6e
BS
2255;; This pattern is used by init_expmed for computing the costs of shift
2256;; insns.
2257
2258(define_insn_and_split "ashlsi3_std"
2259 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2260 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
735cb76e 2261 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
7e2fda6e
BS
2262 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2263 "TARGET_SH3
fa5322fa 2264 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
735cb76e 2265 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
0d7e008e 2266 "@
7e2fda6e
BS
2267 shld %2,%0
2268 add %0,%0
2269 shll%O2 %0
2270 #"
2271 "TARGET_SH3
615cd49b 2272 && reload_completed
7e2fda6e 2273 && GET_CODE (operands[2]) == CONST_INT
735cb76e 2274 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
7e2fda6e
BS
2275 [(set (match_dup 3) (match_dup 2))
2276 (parallel
2277 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2278 (clobber (match_dup 4))])]
2279 "operands[4] = gen_rtx_SCRATCH (SImode);"
2280 [(set_attr "length" "*,*,*,4")
c49439f1 2281 (set_attr "type" "dyn_shift,arith,arith,arith")])
0d7e008e 2282
98e819b9
JW
2283(define_insn "ashlhi3_k"
2284 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2285 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
735cb76e
R
2286 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2287 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
98e819b9
JW
2288 "@
2289 add %0,%0
1245df60 2290 shll%O2 %0"
c49439f1 2291 [(set_attr "type" "arith")])
98e819b9 2292
0d7e008e
SC
2293(define_insn "ashlsi3_n"
2294 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2295 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2296 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2297 (clobber (reg:SI T_REG))]
fa5322fa 2298 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2299 "#"
2300 [(set (attr "length")
2301 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2302 (const_string "2")
2303 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2304 (const_string "4")
2305 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2306 (const_string "6")]
2307 (const_string "8")))
c49439f1 2308 (set_attr "type" "arith")])
bc45ade3 2309
07a45e5c
JW
2310(define_split
2311 [(set (match_operand:SI 0 "arith_reg_operand" "")
2312 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2313 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2314 (clobber (reg:SI T_REG))]
fa5322fa 2315 "TARGET_SH1 && reload_completed"
4773afa4 2316 [(use (reg:SI R0_REG))]
07a45e5c
JW
2317 "
2318{
2319 gen_shifty_op (ASHIFT, operands);
2320 DONE;
2321}")
2322
fa5322fa
AO
2323(define_insn "ashlsi3_media"
2324 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2325 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2326 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2327 "TARGET_SHMEDIA"
2328 "@
2329 shlld.l %1, %2, %0
b6d33983
R
2330 shlli.l %1, %2, %0"
2331 [(set_attr "type" "arith_media")])
fa5322fa 2332
bc45ade3 2333(define_expand "ashlsi3"
ffae286a
JW
2334 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2335 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2336 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2337 (clobber (reg:SI T_REG))])]
bc45ade3 2338 ""
d2f09a2f
JW
2339 "
2340{
fa5322fa
AO
2341 if (TARGET_SHMEDIA)
2342 {
2343 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2344 DONE;
2345 }
1245df60
R
2346 if (GET_CODE (operands[2]) == CONST_INT
2347 && sh_dynamicalize_shift_p (operands[2]))
2348 operands[2] = force_reg (SImode, operands[2]);
7e2fda6e 2349 if (TARGET_SH3)
6b005b88 2350 {
7e2fda6e 2351 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
6b005b88
JW
2352 DONE;
2353 }
d2f09a2f
JW
2354 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2355 FAIL;
2356}")
0d7e008e 2357
98e819b9
JW
2358(define_insn "ashlhi3"
2359 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2360 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2361 (match_operand:HI 2 "const_int_operand" "n")))
4773afa4 2362 (clobber (reg:SI T_REG))]
fa5322fa 2363 "TARGET_SH1"
98e819b9
JW
2364 "#"
2365 [(set (attr "length")
2366 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2367 (const_string "2")
2368 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2369 (const_string "4")]
2370 (const_string "6")))
2371 (set_attr "type" "arith")])
2372
2373(define_split
2374 [(set (match_operand:HI 0 "arith_reg_operand" "")
2375 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
e69d1422 2376 (match_operand:HI 2 "const_int_operand" "")))
4773afa4 2377 (clobber (reg:SI T_REG))]
fa5322fa 2378 "TARGET_SH1 && reload_completed"
4773afa4 2379 [(use (reg:SI R0_REG))]
98e819b9
JW
2380 "
2381{
2382 gen_shifty_hi_op (ASHIFT, operands);
2383 DONE;
2384}")
2385
0d7e008e
SC
2386;
2387; arithmetic shift right
2388;
bc45ade3
SC
2389
2390(define_insn "ashrsi3_k"
aa684c94
SC
2391 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2392 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2393 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2394 (clobber (reg:SI T_REG))]
fa5322fa 2395 "TARGET_SH1 && INTVAL (operands[2]) == 1"
bc45ade3 2396 "shar %0"
c49439f1 2397 [(set_attr "type" "arith")])
bc45ade3 2398
d0c42859
R
2399;; We can't do HImode right shifts correctly unless we start out with an
2400;; explicit zero / sign extension; doing that would result in worse overall
2401;; code, so just let the machine independent code widen the mode.
2402;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2403
98e819b9 2404
ffae286a
JW
2405;; ??? This should be a define expand.
2406
00f8ff66 2407(define_insn "ashrsi2_16"
07a45e5c
JW
2408 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2409 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3e8bd1ce 2410 (const_int 16)))]
fa5322fa 2411 "TARGET_SH1"
1245df60 2412 "#"
00f8ff66
SC
2413 [(set_attr "length" "4")])
2414
1245df60 2415(define_split
e69d1422
R
2416 [(set (match_operand:SI 0 "arith_reg_operand" "")
2417 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2418 (const_int 16)))]
fa5322fa 2419 "TARGET_SH1"
1245df60
R
2420 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2421 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2422 "operands[2] = gen_lowpart (HImode, operands[0]);")
2423
ffae286a
JW
2424;; ??? This should be a define expand.
2425
00f8ff66 2426(define_insn "ashrsi2_31"
6b005b88 2427 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1245df60
R
2428 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2429 (const_int 31)))
4773afa4 2430 (clobber (reg:SI T_REG))]
fa5322fa 2431 "TARGET_SH1"
1245df60 2432 "#"
6b005b88 2433 [(set_attr "length" "4")])
3e8bd1ce 2434
1245df60 2435(define_split
e69d1422
R
2436 [(set (match_operand:SI 0 "arith_reg_operand" "")
2437 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2438 (const_int 31)))
4773afa4 2439 (clobber (reg:SI T_REG))]
fa5322fa 2440 "TARGET_SH1"
1245df60
R
2441 [(const_int 0)]
2442 "
2443{
5bac82c5 2444 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
1245df60
R
2445 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2446 DONE;
2447}")
2448
2449(define_insn "ashlsi_c"
2450 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2451 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4773afa4
AO
2452 (set (reg:SI T_REG)
2453 (lt:SI (match_dup 1) (const_int 0)))]
fa5322fa 2454 "TARGET_SH1"
1245df60 2455 "shll %0"
c49439f1 2456 [(set_attr "type" "arith")])
1245df60 2457
6b005b88
JW
2458(define_insn "ashrsi3_d"
2459 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2460 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2461 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2462 "TARGET_SH3"
1245df60 2463 "shad %2,%0"
c49439f1 2464 [(set_attr "type" "dyn_shift")])
51aea58d 2465
0d7e008e 2466(define_insn "ashrsi3_n"
4773afa4
AO
2467 [(set (reg:SI R4_REG)
2468 (ashiftrt:SI (reg:SI R4_REG)
ffae286a 2469 (match_operand:SI 0 "const_int_operand" "i")))
4773afa4
AO
2470 (clobber (reg:SI T_REG))
2471 (clobber (reg:SI PR_REG))
0d7e008e 2472 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 2473 "TARGET_SH1"
0d7e008e
SC
2474 "jsr @%1%#"
2475 [(set_attr "type" "sfunc")
0d7e008e
SC
2476 (set_attr "needs_delay_slot" "yes")])
2477
fa5322fa
AO
2478(define_insn "ashrsi3_media"
2479 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2480 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2481 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2482 "TARGET_SHMEDIA"
2483 "@
2484 shard.l %1, %2, %0
b6d33983
R
2485 shari.l %1, %2, %0"
2486 [(set_attr "type" "arith_media")])
fa5322fa 2487
bc45ade3 2488(define_expand "ashrsi3"
ffae286a
JW
2489 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2490 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2491 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2492 (clobber (reg:SI T_REG))])]
bc45ade3 2493 ""
fa5322fa
AO
2494 "
2495{
2496 if (TARGET_SHMEDIA)
2497 {
2498 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2499 DONE;
2500 }
2501 if (expand_ashiftrt (operands))
2502 DONE;
2503 else
2504 FAIL;
2505}")
0d7e008e 2506
07a45e5c 2507;; logical shift right
bc45ade3 2508
6b005b88
JW
2509(define_insn "lshrsi3_d"
2510 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2511 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2512 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2513 "TARGET_SH3"
1245df60 2514 "shld %2,%0"
c49439f1 2515 [(set_attr "type" "dyn_shift")])
00f8ff66 2516
ffae286a 2517;; Only the single bit shift clobbers the T bit.
07a45e5c
JW
2518
2519(define_insn "lshrsi3_m"
2520 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2521 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2522 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2523 (clobber (reg:SI T_REG))]
fa5322fa 2524 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2525 "shlr %0"
c49439f1 2526 [(set_attr "type" "arith")])
0d7e008e 2527
07a45e5c
JW
2528(define_insn "lshrsi3_k"
2529 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2530 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
735cb76e
R
2531 (match_operand:SI 2 "const_int_operand" "P27")))]
2532 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
07a45e5c 2533 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2534 "shlr%O2 %0"
c49439f1 2535 [(set_attr "type" "arith")])
0d7e008e
SC
2536
2537(define_insn "lshrsi3_n"
2538 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2539 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2540 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2541 (clobber (reg:SI T_REG))]
fa5322fa 2542 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2543 "#"
2544 [(set (attr "length")
2545 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2546 (const_string "2")
2547 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2548 (const_string "4")
2549 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2550 (const_string "6")]
2551 (const_string "8")))
bc45ade3
SC
2552 (set_attr "type" "arith")])
2553
07a45e5c
JW
2554(define_split
2555 [(set (match_operand:SI 0 "arith_reg_operand" "")
2556 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2557 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2558 (clobber (reg:SI T_REG))]
fa5322fa 2559 "TARGET_SH1 && reload_completed"
4773afa4 2560 [(use (reg:SI R0_REG))]
07a45e5c
JW
2561 "
2562{
2563 gen_shifty_op (LSHIFTRT, operands);
2564 DONE;
2565}")
2566
fa5322fa
AO
2567(define_insn "lshrsi3_media"
2568 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2569 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2570 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2571 "TARGET_SHMEDIA"
2572 "@
2573 shlrd.l %1, %2, %0
b6d33983
R
2574 shlri.l %1, %2, %0"
2575 [(set_attr "type" "arith_media")])
fa5322fa 2576
bc45ade3 2577(define_expand "lshrsi3"
ffae286a
JW
2578 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2579 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2580 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2581 (clobber (reg:SI T_REG))])]
bc45ade3 2582 ""
d2f09a2f
JW
2583 "
2584{
fa5322fa
AO
2585 if (TARGET_SHMEDIA)
2586 {
2587 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2588 DONE;
2589 }
1245df60
R
2590 if (GET_CODE (operands[2]) == CONST_INT
2591 && sh_dynamicalize_shift_p (operands[2]))
2592 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
2593 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2594 {
2595 rtx count = copy_to_mode_reg (SImode, operands[2]);
2596 emit_insn (gen_negsi2 (count, count));
7b7499bf 2597 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
6b005b88
JW
2598 DONE;
2599 }
d2f09a2f
JW
2600 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2601 FAIL;
2602}")
bc45ade3 2603
ffae286a
JW
2604;; ??? This should be a define expand.
2605
bc45ade3 2606(define_insn "ashldi3_k"
aa684c94
SC
2607 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2608 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2609 (const_int 1)))
4773afa4 2610 (clobber (reg:SI T_REG))]
fa5322fa 2611 "TARGET_SH1"
00f8ff66 2612 "shll %R0\;rotcl %S0"
1245df60 2613 [(set_attr "length" "4")
c49439f1 2614 (set_attr "type" "arith")])
bc45ade3 2615
fa5322fa
AO
2616(define_insn "ashldi3_media"
2617 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2618 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2619 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2620 "TARGET_SHMEDIA"
2621 "@
2622 shlld %1, %2, %0
2ad65b0e
SC
2623 shlli %1, %2, %0"
2624 [(set_attr "type" "arith_media")])
fa5322fa 2625
bc45ade3 2626(define_expand "ashldi3"
ffae286a
JW
2627 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2628 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2629 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2630 (clobber (reg:SI T_REG))])]
bc45ade3 2631 ""
fa5322fa
AO
2632 "
2633{
2634 if (TARGET_SHMEDIA)
2635 {
2636 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2637 DONE;
2638 }
2639 if (GET_CODE (operands[2]) != CONST_INT
2640 || INTVAL (operands[2]) != 1)
2641 FAIL;
2642}")
ffae286a
JW
2643
2644;; ??? This should be a define expand.
bc45ade3
SC
2645
2646(define_insn "lshrdi3_k"
aa684c94 2647 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b9654711 2648 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2649 (const_int 1)))
4773afa4 2650 (clobber (reg:SI T_REG))]
fa5322fa 2651 "TARGET_SH1"
00f8ff66 2652 "shlr %S0\;rotcr %R0"
1245df60 2653 [(set_attr "length" "4")
c49439f1 2654 (set_attr "type" "arith")])
bc45ade3 2655
fa5322fa
AO
2656(define_insn "lshrdi3_media"
2657 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2658 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2659 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2660 "TARGET_SHMEDIA"
2661 "@
2662 shlrd %1, %2, %0
2ad65b0e
SC
2663 shlri %1, %2, %0"
2664 [(set_attr "type" "arith_media")])
fa5322fa 2665
bc45ade3 2666(define_expand "lshrdi3"
ffae286a
JW
2667 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2668 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
bc45ade3 2669 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2670 (clobber (reg:SI T_REG))])]
bc45ade3 2671 ""
fa5322fa
AO
2672 "
2673{
2674 if (TARGET_SHMEDIA)
2675 {
2676 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2677 DONE;
2678 }
2679 if (GET_CODE (operands[2]) != CONST_INT
2680 || INTVAL (operands[2]) != 1)
2681 FAIL;
2682}")
ffae286a
JW
2683
2684;; ??? This should be a define expand.
bc45ade3
SC
2685
2686(define_insn "ashrdi3_k"
aa684c94
SC
2687 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2688 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2689 (const_int 1)))
4773afa4 2690 (clobber (reg:SI T_REG))]
fa5322fa 2691 "TARGET_SH1"
00f8ff66 2692 "shar %S0\;rotcr %R0"
1245df60 2693 [(set_attr "length" "4")
c49439f1 2694 (set_attr "type" "arith")])
bc45ade3 2695
fa5322fa
AO
2696(define_insn "ashrdi3_media"
2697 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2698 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2699 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2700 "TARGET_SHMEDIA"
2701 "@
2702 shard %1, %2, %0
2ad65b0e
SC
2703 shari %1, %2, %0"
2704 [(set_attr "type" "arith_media")])
fa5322fa 2705
bc45ade3 2706(define_expand "ashrdi3"
ffae286a
JW
2707 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2708 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2709 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2710 (clobber (reg:SI T_REG))])]
bc45ade3 2711 ""
fa5322fa
AO
2712 "
2713{
2714 if (TARGET_SHMEDIA)
2715 {
2716 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2717 DONE;
2718 }
2719 if (GET_CODE (operands[2]) != CONST_INT
2720 || INTVAL (operands[2]) != 1)
2721 FAIL;
2722}")
98e819b9
JW
2723
2724;; combined left/right shift
2725
2726(define_split
2727 [(set (match_operand:SI 0 "register_operand" "")
2728 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2729 (match_operand:SI 2 "const_int_operand" ""))
2730 (match_operand:SI 3 "const_int_operand" "")))]
85af47b9 2731 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2732 [(use (reg:SI R0_REG))]
98e819b9
JW
2733 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2734 DONE;")
2735
2736(define_split
2737 [(set (match_operand:SI 0 "register_operand" "")
2738 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2739 (match_operand:SI 2 "const_int_operand" ""))
2740 (match_operand:SI 3 "const_int_operand" "")))
4773afa4 2741 (clobber (reg:SI T_REG))]
85af47b9 2742 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2743 [(use (reg:SI R0_REG))]
98e819b9
JW
2744 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2745 DONE;")
2746
2747(define_insn ""
2748 [(set (match_operand:SI 0 "register_operand" "=r")
2749 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2750 (match_operand:SI 2 "const_int_operand" "n"))
2751 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2752 (clobber (reg:SI T_REG))]
fa5322fa 2753 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
98e819b9
JW
2754 "#"
2755 [(set (attr "length")
2756 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2757 (const_string "4")
2758 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2759 (const_string "6")
2760 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2761 (const_string "8")
2762 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2763 (const_string "10")
2764 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2765 (const_string "12")
2766 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2767 (const_string "14")
2768 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2769 (const_string "16")]
2770 (const_string "18")))
2771 (set_attr "type" "arith")])
2772
2773(define_insn ""
2774 [(set (match_operand:SI 0 "register_operand" "=z")
2775 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2776 (match_operand:SI 2 "const_int_operand" "n"))
2777 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2778 (clobber (reg:SI T_REG))]
fa5322fa 2779 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
98e819b9
JW
2780 "#"
2781 [(set (attr "length")
2782 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2783 (const_string "4")
2784 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2785 (const_string "6")
2786 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2787 (const_string "8")]
2788 (const_string "10")))
2789 (set_attr "type" "arith")])
2790
2791;; shift left / and combination with a scratch register: The combine pass
2792;; does not accept the individual instructions, even though they are
2793;; cheap. But it needs a precise description so that it is usable after
2794;; reload.
2795(define_insn "and_shl_scratch"
2796 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4773afa4
AO
2797 (lshiftrt:SI
2798 (ashift:SI
2799 (and:SI
2800 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2801 (match_operand:SI 2 "const_int_operand" "N,n"))
2802 (match_operand:SI 3 "" "0,r"))
2803 (match_operand:SI 4 "const_int_operand" "n,n"))
2804 (match_operand:SI 5 "const_int_operand" "n,n")))
2805 (clobber (reg:SI T_REG))]
fa5322fa 2806 "TARGET_SH1"
98e819b9
JW
2807 "#"
2808 [(set (attr "length")
2809 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2810 (const_string "4")
2811 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2812 (const_string "6")
2813 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
9788ff4d 2814 (const_string "8")
98e819b9
JW
2815 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2816 (const_string "10")]
2817 (const_string "12")))
2818 (set_attr "type" "arith")])
2819
2820(define_split
e69d1422 2821 [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
2822 (lshiftrt:SI
2823 (ashift:SI
2824 (and:SI
e69d1422
R
2825 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2826 (match_operand:SI 2 "const_int_operand" ""))
2827 (match_operand:SI 3 "register_operand" ""))
2828 (match_operand:SI 4 "const_int_operand" ""))
2829 (match_operand:SI 5 "const_int_operand" "")))
4773afa4 2830 (clobber (reg:SI T_REG))]
fa5322fa 2831 "TARGET_SH1"
4773afa4 2832 [(use (reg:SI R0_REG))]
98e819b9
JW
2833 "
2834{
fc2380b9 2835 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
98e819b9
JW
2836
2837 if (INTVAL (operands[2]))
2838 {
2839 gen_shifty_op (LSHIFTRT, operands);
98e819b9
JW
2840 }
2841 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2842 operands[2] = operands[4];
2843 gen_shifty_op (ASHIFT, operands);
2844 if (INTVAL (operands[5]))
2845 {
2846 operands[2] = operands[5];
2847 gen_shifty_op (LSHIFTRT, operands);
2848 }
2849 DONE;
2850}")
2851
2852;; signed left/right shift combination.
2853(define_split
e69d1422 2854 [(set (match_operand:SI 0 "register_operand" "")
4773afa4 2855 (sign_extract:SI
e69d1422
R
2856 (ashift:SI (match_operand:SI 1 "register_operand" "")
2857 (match_operand:SI 2 "const_int_operand" ""))
2858 (match_operand:SI 3 "const_int_operand" "")
4773afa4
AO
2859 (const_int 0)))
2860 (clobber (reg:SI T_REG))]
fa5322fa 2861 "TARGET_SH1"
4773afa4 2862 [(use (reg:SI R0_REG))]
98e819b9
JW
2863 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2864 DONE;")
2865
2866(define_insn "shl_sext_ext"
2867 [(set (match_operand:SI 0 "register_operand" "=r")
4773afa4
AO
2868 (sign_extract:SI
2869 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2870 (match_operand:SI 2 "const_int_operand" "n"))
2871 (match_operand:SI 3 "const_int_operand" "n")
2872 (const_int 0)))
2873 (clobber (reg:SI T_REG))]
fa5322fa 2874 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
98e819b9
JW
2875 "#"
2876 [(set (attr "length")
2877 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2878 (const_string "2")
2879 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2880 (const_string "4")
2881 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2882 (const_string "6")
2883 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2884 (const_string "8")
2885 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2886 (const_string "10")
2887 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2888 (const_string "12")
2889 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2890 (const_string "14")
2891 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2892 (const_string "16")]
2893 (const_string "18")))
2894 (set_attr "type" "arith")])
2895
2896(define_insn "shl_sext_sub"
2897 [(set (match_operand:SI 0 "register_operand" "=z")
e11cddec
AO
2898 (sign_extract:SI
2899 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2900 (match_operand:SI 2 "const_int_operand" "n"))
2901 (match_operand:SI 3 "const_int_operand" "n")
2902 (const_int 0)))
4773afa4 2903 (clobber (reg:SI T_REG))]
fa5322fa 2904 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
98e819b9
JW
2905 "#"
2906 [(set (attr "length")
2907 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2908 (const_string "6")
2909 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2910 (const_string "8")
2911 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2912 (const_string "10")
2913 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2914 (const_string "12")]
2915 (const_string "14")))
2916 (set_attr "type" "arith")])
2917
977eef43
JW
2918;; These patterns are found in expansions of DImode shifts by 16, and
2919;; allow the xtrct instruction to be generated from C source.
2920
2921(define_insn "xtrct_left"
2922 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2923 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2924 (const_int 16))
2925 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2926 (const_int 16))))]
fa5322fa 2927 "TARGET_SH1"
1245df60 2928 "xtrct %1,%0"
c49439f1 2929 [(set_attr "type" "arith")])
977eef43
JW
2930
2931(define_insn "xtrct_right"
2932 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2933 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2934 (const_int 16))
2935 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2936 (const_int 16))))]
fa5322fa 2937 "TARGET_SH1"
1245df60 2938 "xtrct %2,%0"
c49439f1 2939 [(set_attr "type" "arith")])
fae15c93 2940
bc45ade3
SC
2941;; -------------------------------------------------------------------------
2942;; Unary arithmetic
2943;; -------------------------------------------------------------------------
2944
8e87e161
SC
2945(define_insn "negc"
2946 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 2947 (neg:SI (plus:SI (reg:SI T_REG)
51bd623f 2948 (match_operand:SI 1 "arith_reg_operand" "r"))))
4773afa4
AO
2949 (set (reg:SI T_REG)
2950 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
51bd623f 2951 (const_int 0)))]
fa5322fa 2952 "TARGET_SH1"
8e87e161 2953 "negc %1,%0"
c49439f1 2954 [(set_attr "type" "arith")])
bc45ade3 2955
fa5322fa
AO
2956(define_insn "*negdi_media"
2957 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2958 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2959 "TARGET_SHMEDIA"
2ad65b0e
SC
2960 "sub r63, %1, %0"
2961 [(set_attr "type" "arith_media")])
fa5322fa 2962
8e87e161 2963(define_expand "negdi2"
51aea58d 2964 [(set (match_operand:DI 0 "arith_reg_operand" "")
b6d33983 2965 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
8e87e161 2966 ""
ffae286a
JW
2967 "
2968{
fa5322fa
AO
2969 if (TARGET_SH1)
2970 {
2971 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2972 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
8e87e161 2973
fa5322fa
AO
2974 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2975 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
0a0b733a 2976
fa5322fa
AO
2977 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2978 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
8e87e161 2979
fa5322fa
AO
2980 emit_insn (gen_clrt ());
2981 emit_insn (gen_negc (low_dst, low_src));
2982 emit_insn (gen_negc (high_dst, high_src));
2983 DONE;
2984 }
ffae286a 2985}")
8e87e161 2986
bc45ade3 2987(define_insn "negsi2"
aa684c94
SC
2988 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2989 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2990 "TARGET_SH1"
bc45ade3 2991 "neg %1,%0"
c49439f1 2992 [(set_attr "type" "arith")])
bc45ade3
SC
2993
2994(define_insn "one_cmplsi2"
aa684c94
SC
2995 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2996 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2997 "TARGET_SH1"
bc45ade3 2998 "not %1,%0"
c49439f1 2999 [(set_attr "type" "arith")])
fa5322fa
AO
3000
3001(define_expand "one_cmpldi2"
3002 [(set (match_operand:DI 0 "arith_reg_operand" "")
3003 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
3004 (const_int -1)))]
3005 "TARGET_SHMEDIA" "")
bc45ade3
SC
3006\f
3007;; -------------------------------------------------------------------------
3008;; Zero extension instructions
3009;; -------------------------------------------------------------------------
3010
fa5322fa
AO
3011(define_insn "zero_extendsidi2"
3012 [(set (match_operand:DI 0 "register_operand" "=r")
b6d33983 3013 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
fa5322fa 3014 "TARGET_SHMEDIA"
b6d33983
R
3015 "addz.l %1, r63, %0"
3016 [(set_attr "type" "arith_media")])
fa5322fa
AO
3017
3018(define_insn "zero_extendhidi2"
3019 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3020 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3021 "TARGET_SHMEDIA"
3022 "@
3023 #
b6d33983
R
3024 ld%M1.uw %m1, %0"
3025 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3026
3027(define_split
e69d1422
R
3028 [(set (match_operand:DI 0 "register_operand" "")
3029 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3030 "TARGET_SHMEDIA && reload_completed"
3031 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
3032 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3033 "
3034{
3035 if (GET_CODE (operands[1]) == TRUNCATE)
3036 operands[1] = XEXP (operands[1], 0);
3037}")
3038
fae778eb
KH
3039;; ??? when a truncated input to a zero_extend is reloaded, reload will
3040;; reload the entire truncate expression.
b6d33983 3041(define_insn_and_split "*loaddi_trunc"
e69d1422 3042 [(set (match_operand 0 "int_gpr_dest" "=r")
b6d33983
R
3043 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3044 "TARGET_SHMEDIA && reload_completed"
3045 "#"
3046 "TARGET_SHMEDIA && reload_completed"
3047 [(set (match_dup 0) (match_dup 1))]
3048 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
fa5322fa
AO
3049
3050(define_insn "zero_extendqidi2"
3051 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3052 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3053 "TARGET_SHMEDIA"
3054 "@
3055 andi %1, 255, %0
b6d33983
R
3056 ld%M1.ub %m1, %0"
3057 [(set_attr "type" "arith_media,load_media")])
3058
3059(define_expand "zero_extendhisi2"
3060 [(set (match_operand:SI 0 "arith_reg_operand" "")
3061 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3062 ""
3063 "
3064{
3065 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3066 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3067}")
fa5322fa 3068
b6d33983 3069(define_insn "*zero_extendhisi2_compact"
aa684c94
SC
3070 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3071 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
fa5322fa 3072 "TARGET_SH1"
bc45ade3 3073 "extu.w %1,%0"
c49439f1 3074 [(set_attr "type" "arith")])
bc45ade3 3075
b6d33983
R
3076(define_insn "*zero_extendhisi2_media"
3077 [(set (match_operand:SI 0 "register_operand" "=r,r")
3078 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3079 "TARGET_SHMEDIA"
3080 "@
3081 #
3082 ld%M1.uw %m1, %0"
3083 [(set_attr "type" "arith_media,load_media")])
3084
3085(define_split
e69d1422
R
3086 [(set (match_operand:SI 0 "register_operand" "")
3087 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3088 "TARGET_SHMEDIA && reload_completed"
3089 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3090 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3091 "
3092{
3093 if (GET_CODE (operands[1]) == TRUNCATE)
3094 operands[1] = XEXP (operands[1], 0);
3095}")
3096
3097(define_expand "zero_extendqisi2"
3098 [(set (match_operand:SI 0 "arith_reg_operand" "")
3099 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3100 ""
3101 "
3102{
3103 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3104 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3105}")
3106
3107(define_insn "*zero_extendqisi2_compact"
aa684c94
SC
3108 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3109 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3110 "TARGET_SH1"
bc45ade3 3111 "extu.b %1,%0"
c49439f1 3112 [(set_attr "type" "arith")])
bc45ade3 3113
b6d33983
R
3114(define_insn "*zero_extendqisi2_media"
3115 [(set (match_operand:SI 0 "register_operand" "=r,r")
3116 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3117 "TARGET_SHMEDIA"
3118 "@
3119 andi %1, 255, %0
3120 ld%M1.ub %m1, %0"
3121 [(set_attr "type" "arith_media,load_media")])
3122
bc45ade3 3123(define_insn "zero_extendqihi2"
aa684c94
SC
3124 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3125 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3126 "TARGET_SH1"
bc45ade3 3127 "extu.b %1,%0"
c49439f1 3128 [(set_attr "type" "arith")])
fae15c93 3129
bc45ade3
SC
3130;; -------------------------------------------------------------------------
3131;; Sign extension instructions
3132;; -------------------------------------------------------------------------
3133
ffae286a
JW
3134;; ??? This should be a define expand.
3135;; ??? Or perhaps it should be dropped?
3136
fa5322fa
AO
3137;; convert_move generates good code for SH[1-4].
3138(define_insn "extendsidi2"
3139 [(set (match_operand:DI 0 "register_operand" "=r,r")
3140 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3141 "TARGET_SHMEDIA"
3142 "@
3143 add.l %1, r63, %0
2ad65b0e
SC
3144 ld%M1.l %m1, %0"
3145 [(set_attr "type" "arith_media,load_media")])
fa5322fa
AO
3146
3147(define_insn "extendhidi2"
3148 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3149 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3150 "TARGET_SHMEDIA"
3151 "@
3152 #
b6d33983
R
3153 ld%M1.w %m1, %0"
3154 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3155
3156(define_split
e69d1422
R
3157 [(set (match_operand:DI 0 "register_operand" "")
3158 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3159 "TARGET_SHMEDIA && reload_completed"
3160 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
3161 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3162 "
3163{
3164 if (GET_CODE (operands[1]) == TRUNCATE)
3165 operands[1] = XEXP (operands[1], 0);
3166}")
fa5322fa
AO
3167
3168(define_insn "extendqidi2"
3169 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3170 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3171 "TARGET_SHMEDIA"
3172 "@
3173 #
b6d33983
R
3174 ld%M1.b %m1, %0"
3175 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3176
3177(define_split
e69d1422
R
3178 [(set (match_operand:DI 0 "register_operand" "")
3179 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3180 "TARGET_SHMEDIA && reload_completed"
3181 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
b6d33983
R
3182 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3183 "
3184{
3185 if (GET_CODE (operands[1]) == TRUNCATE)
3186 operands[1] = XEXP (operands[1], 0);
3187}")
3188
3189(define_expand "extendhisi2"
3190 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
40779a72 3191 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
b6d33983
R
3192 ""
3193 "")
bc45ade3 3194
b6d33983 3195(define_insn "*extendhisi2_compact"
51bd623f
JW
3196 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3197 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3198 "TARGET_SH1"
0d7e008e
SC
3199 "@
3200 exts.w %1,%0
40779a72 3201 mov.w %1,%0"
c49439f1 3202 [(set_attr "type" "arith,load")])
bc45ade3 3203
b6d33983
R
3204(define_insn "*extendhisi2_media"
3205 [(set (match_operand:SI 0 "register_operand" "=r,r")
3206 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3207 "TARGET_SHMEDIA"
3208 "@
3209 #
3210 ld%M1.w %m1, %0"
3211 [(set_attr "type" "arith_media,load_media")])
3212
3213(define_split
e69d1422
R
3214 [(set (match_operand:SI 0 "register_operand" "")
3215 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3216 "TARGET_SHMEDIA && reload_completed"
3217 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3218 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3219 "
3220{
3221 if (GET_CODE (operands[1]) == TRUNCATE)
3222 operands[1] = XEXP (operands[1], 0);
3223}")
3224
3225(define_expand "extendqisi2"
3226 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3227 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3228 ""
3229 "")
3230
3231(define_insn "*extendqisi2_compact"
51bd623f
JW
3232 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3233 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3234 "TARGET_SH1"
0d7e008e
SC
3235 "@
3236 exts.b %1,%0
51bd623f 3237 mov.b %1,%0"
c49439f1 3238 [(set_attr "type" "arith,load")])
bc45ade3 3239
b6d33983
R
3240(define_insn "*extendqisi2_media"
3241 [(set (match_operand:SI 0 "register_operand" "=r,r")
3242 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3243 "TARGET_SHMEDIA"
3244 "@
3245 #
3246 ld%M1.b %m1, %0"
3247 [(set_attr "type" "arith_media,load_media")])
3248
3249(define_split
e69d1422
R
3250 [(set (match_operand:SI 0 "register_operand" "")
3251 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
b6d33983
R
3252 "TARGET_SHMEDIA && reload_completed"
3253 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3254 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3255 "
3256{
3257 if (GET_CODE (operands[1]) == TRUNCATE)
3258 operands[1] = XEXP (operands[1], 0);
3259}")
3260
bc45ade3 3261(define_insn "extendqihi2"
51bd623f
JW
3262 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3263 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3264 "TARGET_SH1"
0d7e008e
SC
3265 "@
3266 exts.b %1,%0
51bd623f 3267 mov.b %1,%0"
c49439f1 3268 [(set_attr "type" "arith,load")])
fae15c93 3269
b6d33983
R
3270/* It would seem useful to combine the truncXi patterns into the movXi
3271 patterns, but unary operators are ignored when matching constraints,
3272 so we need separate patterns. */
3273(define_insn "truncdisi2"
0ac78517 3274 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
b6d33983
R
3275 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3276 "TARGET_SHMEDIA"
3277 "@
3278 add.l %1, r63, %0
3279 st%M0.l %m0, %1
3280 fst%M0.s %m0, %T1
3281 fmov.ls %1, %0
3282 fmov.sl %T1, %0
3283 fmov.s %T1, %0"
3284 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3285
3286
3287(define_insn "truncdihi2"
0ac78517 3288 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
b6d33983
R
3289 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3290 "TARGET_SHMEDIA"
3291 "@
3292 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3293 st%M0.w %m0, %1"
3294 [(set_attr "type" "arith_media,store_media")
3295 (set_attr "length" "8,4")])
3296
59324685
R
3297; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3298; Because we use zero extension, we can't provide signed QImode compares
3299; using a simple compare or conditional banch insn.
b6d33983
R
3300(define_insn "truncdiqi2"
3301 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3302 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3303 "TARGET_SHMEDIA"
3304 "@
40779a72 3305 andi %1, 255, %0
b6d33983
R
3306 st%M0.b %m0, %1"
3307 [(set_attr "type" "arith_media,store")])
3308
bc45ade3
SC
3309;; -------------------------------------------------------------------------
3310;; Move instructions
3311;; -------------------------------------------------------------------------
3312
0d7e008e 3313;; define push and pop so it is easy for sh.c
fa5322fa
AO
3314;; We can't use push and pop on SHcompact because the stack must always
3315;; be 8-byte aligned.
b9654711 3316
225e4f43 3317(define_expand "push"
4773afa4 3318 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
ffae286a 3319 (match_operand:SI 0 "register_operand" "r,l,x"))]
fa5322fa 3320 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3321 "")
b9654711 3322
225e4f43 3323(define_expand "pop"
51bd623f 3324 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4773afa4 3325 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
fa5322fa 3326 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3327 "")
3328
3329(define_expand "push_e"
4773afa4 3330 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
225e4f43 3331 (match_operand:SF 0 "" ""))
4773afa4 3332 (use (reg:PSI FPSCR_REG))
225e4f43 3333 (clobber (scratch:SI))])]
fa5322fa 3334 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3335 "")
b9654711 3336
225e4f43 3337(define_insn "push_fpul"
4773afa4 3338 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3a8699c7 3339 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 3340 "sts.l fpul,@-r15"
45348d9e 3341 [(set_attr "type" "store")
c49439f1 3342 (set_attr "late_fp_use" "yes")
45348d9e
JW
3343 (set_attr "hit_stack" "yes")])
3344
225e4f43
R
3345;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3346;; so use that.
3347(define_expand "push_4"
4773afa4
AO
3348 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3349 (match_operand:DF 0 "" ""))
3350 (use (reg:PSI FPSCR_REG))
225e4f43 3351 (clobber (scratch:SI))])]
fa5322fa 3352 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3353 "")
3354
3355(define_expand "pop_e"
3356 [(parallel [(set (match_operand:SF 0 "" "")
4773afa4
AO
3357 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3358 (use (reg:PSI FPSCR_REG))
225e4f43 3359 (clobber (scratch:SI))])]
fa5322fa 3360 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3361 "")
3362
3363(define_insn "pop_fpul"
4773afa4 3364 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3a8699c7 3365 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 3366 "lds.l @r15+,fpul"
45348d9e
JW
3367 [(set_attr "type" "load")
3368 (set_attr "hit_stack" "yes")])
3369
225e4f43
R
3370(define_expand "pop_4"
3371 [(parallel [(set (match_operand:DF 0 "" "")
4773afa4
AO
3372 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3373 (use (reg:PSI FPSCR_REG))
225e4f43 3374 (clobber (scratch:SI))])]
fa5322fa 3375 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3376 "")
3377
7144b2d8
DD
3378(define_expand "push_fpscr"
3379 [(const_int 0)]
603ff6b5 3380 "TARGET_SH2E"
7144b2d8
DD
3381 "
3382{
c0d4e710
KH
3383 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3384 gen_rtx_PRE_DEC (Pmode,
7144b2d8
DD
3385 stack_pointer_rtx)),
3386 get_fpscr_rtx ()));
c0d4e710 3387 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
7144b2d8
DD
3388 DONE;
3389}")
3390
3391(define_expand "pop_fpscr"
3392 [(const_int 0)]
603ff6b5 3393 "TARGET_SH2E"
7144b2d8
DD
3394 "
3395{
3396 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
c0d4e710
KH
3397 gen_rtx_MEM (PSImode,
3398 gen_rtx_POST_INC (Pmode,
7144b2d8 3399 stack_pointer_rtx))));
c0d4e710 3400 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
7144b2d8
DD
3401 DONE;
3402}")
3403
e3391510
JW
3404;; These two patterns can happen as the result of optimization, when
3405;; comparisons get simplified to a move of zero or 1 into the T reg.
3406;; They don't disappear completely, because the T reg is a fixed hard reg.
ffae286a 3407
0d7e008e 3408(define_insn "clrt"
4773afa4 3409 [(set (reg:SI T_REG) (const_int 0))]
fa5322fa 3410 "TARGET_SH1"
0d7e008e 3411 "clrt")
bc45ade3 3412
e3391510 3413(define_insn "sett"
4773afa4 3414 [(set (reg:SI T_REG) (const_int 1))]
fa5322fa 3415 "TARGET_SH1"
e3391510
JW
3416 "sett")
3417
3ca0a524 3418;; t/r must come after r/r, lest reload will try to reload stuff like
4773afa4 3419;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
e11cddec 3420;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
0d7e008e 3421(define_insn "movsi_i"
735cb76e
R
3422 [(set (match_operand:SI 0 "general_movdst_operand"
3423 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3424 (match_operand:SI 1 "general_movsrc_operand"
3425 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
fa5322fa 3426 "TARGET_SH1
3a8699c7 3427 && ! TARGET_SH2E
1245df60
R
3428 && (register_operand (operands[0], SImode)
3429 || register_operand (operands[1], SImode))"
8e87e161
SC
3430 "@
3431 mov.l %1,%0
3432 mov %1,%0
3ca0a524 3433 cmp/pl %1
8e87e161
SC
3434 mov.l %1,%0
3435 sts %1,%0
99e87c10 3436 sts %1,%0
8e87e161
SC
3437 movt %0
3438 mov.l %1,%0
3439 sts.l %1,%0
1245df60 3440 sts.l %1,%0
8e87e161 3441 lds %1,%0
99e87c10 3442 lds %1,%0
8e87e161 3443 lds.l %1,%0
1245df60 3444 lds.l %1,%0
51bd623f 3445 fake %1,%0"
c49439f1 3446 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
99e87c10 3447 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
07a45e5c 3448
1245df60 3449;; t/r must come after r/r, lest reload will try to reload stuff like
e11cddec 3450;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
45348d9e
JW
3451;; ??? This allows moves from macl to fpul to be recognized, but these moves
3452;; will require a reload.
ec555f32
R
3453;; ??? We can't include f/f because we need the proper FPSCR setting when
3454;; TARGET_FMOVD is in effect, and mode switching is done before reload.
45348d9e 3455(define_insn "movsi_ie"
735cb76e
R
3456 [(set (match_operand:SI 0 "general_movdst_operand"
3457 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3458 (match_operand:SI 1 "general_movsrc_operand"
3459 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3a8699c7 3460 "TARGET_SH2E
45348d9e
JW
3461 && (register_operand (operands[0], SImode)
3462 || register_operand (operands[1], SImode))"
3463 "@
45348d9e
JW
3464 mov.l %1,%0
3465 mov %1,%0
1245df60 3466 cmp/pl %1
45348d9e
JW
3467 mov.l %1,%0
3468 sts %1,%0
99e87c10 3469 sts %1,%0
45348d9e
JW
3470 movt %0
3471 mov.l %1,%0
3472 sts.l %1,%0
1245df60 3473 sts.l %1,%0
45348d9e 3474 lds %1,%0
99e87c10 3475 lds %1,%0
45348d9e 3476 lds.l %1,%0
1245df60 3477 lds.l %1,%0
225e4f43 3478 lds.l %1,%0
a92facbb 3479 sts.l %1,%0
45348d9e
JW
3480 fake %1,%0
3481 lds %1,%0
1245df60 3482 sts %1,%0
ec555f32
R
3483 fsts fpul,%0
3484 flds %1,fpul
3485 fmov %1,%0
1245df60 3486 ! move optimized away"
ec555f32
R
3487 [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3488 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3489 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
1245df60
R
3490
3491(define_insn "movsi_i_lowpart"
99e87c10 3492 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
735cb76e 3493 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
fa5322fa
AO
3494 "TARGET_SH1
3495 && (register_operand (operands[0], SImode)
3496 || register_operand (operands[1], SImode))"
1245df60
R
3497 "@
3498 mov.l %1,%0
3499 mov %1,%0
3500 mov.l %1,%0
3501 sts %1,%0
99e87c10 3502 sts %1,%0
1245df60
R
3503 movt %0
3504 mov.l %1,%0
3505 fake %1,%0"
99e87c10 3506 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
a6f463a0 3507
7d73a2ba 3508(define_insn_and_split "load_ra"
b869f904 3509 [(set (match_operand:SI 0 "general_movdst_operand" "")
7d73a2ba 3510 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
dce20bbc 3511 "TARGET_SH1"
7d73a2ba
R
3512 "#"
3513 "&& ! rtx_equal_function_value_matters"
b869f904 3514 [(set (match_dup 0) (match_dup 1))]
7d73a2ba
R
3515 "
3516{
dce20bbc 3517 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
7d73a2ba
R
3518 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3519}")
b869f904 3520
fa5322fa 3521(define_insn "*movsi_media"
735cb76e
R
3522 [(set (match_operand:SI 0 "general_movdst_operand"
3523 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3524 (match_operand:SI 1 "general_movsrc_operand"
3525 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
fa5322fa
AO
3526 "TARGET_SHMEDIA_FPU
3527 && (register_operand (operands[0], SImode)
d9da94a1 3528 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3529 "@
3530 add.l %1, r63, %0
3531 movi %1, %0
3532 #
3533 ld%M1.l %m1, %0
d9da94a1 3534 st%M0.l %m0, %N1
fa5322fa
AO
3535 fld%M1.s %m1, %0
3536 fst%M0.s %m0, %1
0ac78517 3537 fmov.ls %N1, %0
fa5322fa
AO
3538 fmov.sl %1, %0
3539 fmov.s %1, %0
3540 ptabs %1, %0
3541 gettr %1, %0
3542 pt %1, %0"
2ad65b0e 3543 [(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")
fa5322fa
AO
3544 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3545
3546(define_insn "*movsi_media_nofpu"
735cb76e
R
3547 [(set (match_operand:SI 0 "general_movdst_operand"
3548 "=r,r,r,r,m,*b,r,b")
3549 (match_operand:SI 1 "general_movsrc_operand"
3550 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
fa5322fa
AO
3551 "TARGET_SHMEDIA
3552 && (register_operand (operands[0], SImode)
d9da94a1 3553 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3554 "@
3555 add.l %1, r63, %0
3556 movi %1, %0
3557 #
3558 ld%M1.l %m1, %0
d9da94a1 3559 st%M0.l %m0, %N1
fa5322fa
AO
3560 ptabs %1, %0
3561 gettr %1, %0
3562 pt %1, %0"
2ad65b0e 3563 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3564 (set_attr "length" "4,4,8,4,4,4,4,12")])
3565
3566(define_split
e69d1422
R
3567 [(set (match_operand:SI 0 "arith_reg_operand" "")
3568 (match_operand:SI 1 "immediate_operand" ""))]
fa5322fa
AO
3569 "TARGET_SHMEDIA && reload_completed
3570 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3571 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3572 "
3573{
3574 operands[2] = shallow_copy_rtx (operands[1]);
3575 PUT_MODE (operands[2], DImode);
3576}")
3577
3578(define_split
e69d1422
R
3579 [(set (match_operand:SI 0 "register_operand" "")
3580 (match_operand:SI 1 "immediate_operand" ""))]
b6d33983 3581 "TARGET_SHMEDIA && reload_completed
fa5322fa 3582 && ((GET_CODE (operands[1]) == CONST_INT
735cb76e 3583 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
fa5322fa
AO
3584 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3585 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3586
bc45ade3 3587(define_expand "movsi"
0d7e008e
SC
3588 [(set (match_operand:SI 0 "general_movdst_operand" "")
3589 (match_operand:SI 1 "general_movsrc_operand" ""))]
bc45ade3 3590 ""
ffae286a 3591 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
961c4780 3592
225e4f43
R
3593(define_expand "ic_invalidate_line"
3594 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4773afa4 3595 (match_dup 1)] UNSPEC_ICACHE)
225e4f43 3596 (clobber (scratch:SI))])]
fa5322fa 3597 "TARGET_HARD_SH4 || TARGET_SH5"
225e4f43
R
3598 "
3599{
fa5322fa
AO
3600 if (TARGET_SHMEDIA)
3601 {
3602 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3603 DONE;
3604 }
3605 else if (TARGET_SHCOMPACT)
3606 {
90534361 3607 operands[1] = function_symbol (\"__ic_invalidate\");
fa5322fa
AO
3608 operands[1] = force_reg (Pmode, operands[1]);
3609 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3610 DONE;
3611 }
225e4f43 3612 operands[0] = force_reg (Pmode, operands[0]);
90e65b70
AO
3613 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3614 Pmode)));
225e4f43
R
3615}")
3616
3617;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
0aa54da2
R
3618;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3619;; the requirement *1*00 for associative address writes. The alignment of
225e4f43
R
3620;; %0 implies that its least significant bit is cleared,
3621;; thus we clear the V bit of a matching entry if there is one.
3622(define_insn "ic_invalidate_line_i"
0aa54da2 3623 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
4773afa4
AO
3624 (match_operand:SI 1 "register_operand" "r")]
3625 UNSPEC_ICACHE)
0aa54da2 3626 (clobber (match_scratch:SI 2 "=&r"))]
225e4f43 3627 "TARGET_HARD_SH4"
0aa54da2 3628 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
fae15c93 3629 [(set_attr "length" "8")
c49439f1 3630 (set_attr "type" "cwb")])
225e4f43 3631
ca903bba
R
3632;; ??? could make arg 0 an offsettable memory operand to allow to save
3633;; an add in the code that calculates the address.
fa5322fa
AO
3634(define_insn "ic_invalidate_line_media"
3635 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3636 UNSPEC_ICACHE)]
3637 "TARGET_SHMEDIA"
b6d33983
R
3638 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3639 [(set_attr "length" "16")
3640 (set_attr "type" "invalidate_line_media")])
fa5322fa
AO
3641
3642(define_insn "ic_invalidate_line_compact"
3643 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3644 (match_operand:SI 1 "register_operand" "r")]
3645 UNSPEC_ICACHE)
3646 (clobber (reg:SI PR_REG))]
3647 "TARGET_SHCOMPACT"
3648 "jsr @%1%#"
3649 [(set_attr "type" "sfunc")
3650 (set_attr "needs_delay_slot" "yes")])
3651
ca903bba
R
3652(define_expand "initialize_trampoline"
3653 [(match_operand:SI 0 "" "")
3654 (match_operand:SI 1 "" "")
3655 (match_operand:SI 2 "" "")]
3656 "TARGET_SHCOMPACT"
3657 "
3658{
3659 rtx sfun, tramp;
3660
e300c78c 3661 tramp = force_reg (Pmode, operands[0]);
90534361 3662 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
ca903bba
R
3663 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3664 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3665
3666 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3667 DONE;
3668}")
3669
3670(define_insn "initialize_trampoline_compact"
3671 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3672 (match_operand:SI 1 "register_operand" "r")
3673 (reg:SI R2_REG) (reg:SI R3_REG)]
3674 UNSPEC_INIT_TRAMP)
3675
3676 (clobber (reg:SI PR_REG))]
3677 "TARGET_SHCOMPACT"
3678 "jsr @%1%#"
3679 [(set_attr "type" "sfunc")
3680 (set_attr "needs_delay_slot" "yes")])
3681
bc45ade3 3682(define_insn "movqi_i"
07a45e5c
JW
3683 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3684 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
fa5322fa
AO
3685 "TARGET_SH1
3686 && (arith_reg_operand (operands[0], QImode)
3687 || arith_reg_operand (operands[1], QImode))"
bc45ade3
SC
3688 "@
3689 mov %1,%0
0d7e008e
SC
3690 mov.b %1,%0
3691 mov.b %1,%0
3692 movt %0
bc45ade3 3693 sts %1,%0
0d7e008e 3694 lds %1,%0"
22e1ebf1 3695 [(set_attr "type" "move,load,store,move,move,move")])
bc45ade3 3696
fa5322fa
AO
3697(define_insn "*movqi_media"
3698 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 3699 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
fa5322fa
AO
3700 "TARGET_SHMEDIA
3701 && (arith_reg_operand (operands[0], QImode)
d9da94a1 3702 || arith_reg_or_0_operand (operands[1], QImode))"
fa5322fa
AO
3703 "@
3704 add.l %1, r63, %0
3705 movi %1, %0
59324685 3706 ld%M1.ub %m1, %0
d9da94a1 3707 st%M0.b %m0, %N1"
2ad65b0e 3708 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
fa5322fa 3709
bc45ade3
SC
3710(define_expand "movqi"
3711 [(set (match_operand:QI 0 "general_operand" "")
3712 (match_operand:QI 1 "general_operand" ""))]
3713 ""
ffae286a 3714 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
bc45ade3 3715
b6d33983
R
3716(define_expand "reload_inqi"
3717 [(set (match_operand:SI 2 "" "=&r")
3718 (match_operand:QI 1 "inqhi_operand" ""))
3719 (set (match_operand:QI 0 "arith_reg_operand" "=r")
ea45c4b0 3720 (truncate:QI (match_dup 3)))]
b6d33983
R
3721 "TARGET_SHMEDIA"
3722 "
3723{
3724 rtx inner = XEXP (operands[1], 0);
3725 int regno = REGNO (inner);
3726
3727 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3728 operands[1] = gen_rtx_REG (SImode, regno);
3729 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3730}")
3731
266a2732 3732/* When storing r0, we have to avoid reg+reg addressing. */
bc45ade3 3733(define_insn "movhi_i"
735cb76e
R
3734 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3735 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
fa5322fa
AO
3736 "TARGET_SH1
3737 && (arith_reg_operand (operands[0], HImode)
266a2732
R
3738 || arith_reg_operand (operands[1], HImode))
3739 && (GET_CODE (operands[0]) != MEM
3740 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3741 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3742 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
8e87e161
SC
3743 "@
3744 mov.w %1,%0
3745 mov %1,%0
3746 mov.w %1,%0
3747 movt %0
3748 mov.w %1,%0
8e87e161 3749 sts %1,%0
51bd623f
JW
3750 lds %1,%0
3751 fake %1,%0"
27232d28 3752 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
bc45ade3 3753
fa5322fa 3754(define_insn "*movhi_media"
735cb76e
R
3755 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3756 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
fa5322fa
AO
3757 "TARGET_SHMEDIA
3758 && (arith_reg_operand (operands[0], HImode)
d9da94a1 3759 || arith_reg_or_0_operand (operands[1], HImode))"
fa5322fa
AO
3760 "@
3761 add.l %1, r63, %0
3762 movi %1, %0
3763 #
3764 ld%M1.w %m1, %0
d9da94a1 3765 st%M0.w %m0, %N1"
2ad65b0e 3766 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
fa5322fa
AO
3767
3768(define_split
e69d1422
R
3769 [(set (match_operand:HI 0 "register_operand" "")
3770 (match_operand:HI 1 "immediate_operand" ""))]
b6d33983 3771 "TARGET_SHMEDIA && reload_completed
735cb76e 3772 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa
AO
3773 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3774
bc45ade3 3775(define_expand "movhi"
0d7e008e
SC
3776 [(set (match_operand:HI 0 "general_movdst_operand" "")
3777 (match_operand:HI 1 "general_movsrc_operand" ""))]
bc45ade3 3778 ""
ffae286a
JW
3779 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3780
b6d33983
R
3781(define_expand "reload_inhi"
3782 [(set (match_operand:SI 2 "" "=&r")
3783 (match_operand:HI 1 "inqhi_operand" ""))
3784 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3785 (truncate:HI (match_dup 3)))]
3786 "TARGET_SHMEDIA"
3787 "
3788{
3789 rtx inner = XEXP (operands[1], 0);
3790 int regno = REGNO (inner);
3791
3792 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3793 operands[1] = gen_rtx_REG (SImode, regno);
3794 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3795}")
3796
1245df60
R
3797;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3798;; compiled with -m2 -ml -O3 -funroll-loops
0113c3c0 3799(define_insn "*movdi_i"
1245df60 3800 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
735cb76e 3801 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
fa5322fa
AO
3802 "TARGET_SH1
3803 && (arith_reg_operand (operands[0], DImode)
3804 || arith_reg_operand (operands[1], DImode))"
0d7e008e 3805 "* return output_movedouble (insn, operands, DImode);"
22e1ebf1 3806 [(set_attr "length" "4")
1245df60 3807 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
bc45ade3 3808
d0aae509 3809;; If the output is a register and the input is memory or a register, we have
52702ae1 3810;; to be careful and see which word needs to be loaded first.
b9b7c1c9 3811
8e87e161
SC
3812(define_split
3813 [(set (match_operand:DI 0 "general_movdst_operand" "")
3814 (match_operand:DI 1 "general_movsrc_operand" ""))]
fa5322fa 3815 "TARGET_SH1 && reload_completed"
8e87e161
SC
3816 [(set (match_dup 2) (match_dup 3))
3817 (set (match_dup 4) (match_dup 5))]
3818 "
d0aae509
RK
3819{
3820 int regno;
3821
3822 if ((GET_CODE (operands[0]) == MEM
3823 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3824 || (GET_CODE (operands[1]) == MEM
3825 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3826 FAIL;
3827
3828 if (GET_CODE (operands[0]) == REG)
3829 regno = REGNO (operands[0]);
3830 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 3831 regno = subreg_regno (operands[0]);
d0aae509
RK
3832 else if (GET_CODE (operands[0]) == MEM)
3833 regno = -1;
533f5e0f
KG
3834 else
3835 abort ();
d0aae509
RK
3836
3837 if (regno == -1
3838 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
3839 {
3840 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3841 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3842 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3843 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3844 }
3845 else
3846 {
3847 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3848 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3849 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3850 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3851 }
3852
3853 if (operands[2] == 0 || operands[3] == 0
3854 || operands[4] == 0 || operands[5] == 0)
3855 FAIL;
3856}")
961c4780 3857
fa5322fa 3858(define_insn "*movdi_media"
735cb76e
R
3859 [(set (match_operand:DI 0 "general_movdst_operand"
3860 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3861 (match_operand:DI 1 "general_movsrc_operand"
3862 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
fa5322fa
AO
3863 "TARGET_SHMEDIA_FPU
3864 && (register_operand (operands[0], DImode)
d9da94a1 3865 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3866 "@
3867 add %1, r63, %0
3868 movi %1, %0
3869 #
3870 ld%M1.q %m1, %0
d9da94a1 3871 st%M0.q %m0, %N1
fa5322fa
AO
3872 fld%M1.d %m1, %0
3873 fst%M0.d %m0, %1
0ac78517 3874 fmov.qd %N1, %0
fa5322fa
AO
3875 fmov.dq %1, %0
3876 fmov.d %1, %0
3877 ptabs %1, %0
3878 gettr %1, %0
3879 pt %1, %0"
2ad65b0e 3880 [(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")
fa5322fa
AO
3881 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3882
3883(define_insn "*movdi_media_nofpu"
b6d33983 3884 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
735cb76e 3885 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
fa5322fa
AO
3886 "TARGET_SHMEDIA
3887 && (register_operand (operands[0], DImode)
d9da94a1 3888 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3889 "@
3890 add %1, r63, %0
3891 movi %1, %0
3892 #
3893 ld%M1.q %m1, %0
d9da94a1 3894 st%M0.q %m0, %N1
fa5322fa
AO
3895 ptabs %1, %0
3896 gettr %1, %0
3897 pt %1, %0"
2ad65b0e 3898 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3899 (set_attr "length" "4,4,16,4,4,4,4,*")])
3900
3901(define_split
e69d1422
R
3902 [(set (match_operand:DI 0 "arith_reg_operand" "")
3903 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3904 "TARGET_SHMEDIA && reload_completed
3905 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3906 [(set (match_dup 0) (match_dup 1))]
3907 "
3908{
3909 rtx insn;
3910
3911 if (TARGET_SHMEDIA64)
3912 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3913 else
3914 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3915
3916 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3917 REG_NOTES (insn));
3918
3919 DONE;
3920}")
3921
3922(define_expand "movdi_const"
3923 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3924 (const:DI (sign_extend:DI
3925 (truncate:HI
3926 (ashiftrt:DI
3927 (match_operand:DI 1 "immediate_operand" "s")
3928 (const_int 48))))))
3929 (set (match_dup 0)
3930 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3931 (zero_extend:DI
3932 (truncate:HI
3933 (const:DI
3934 (sign_extend:DI
3935 (truncate:HI
3936 (ashiftrt:SI
3937 (match_dup 1)
3938 (const_int 32)))))))))
3939 (set (match_dup 0)
3940 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3941 (zero_extend:DI
3942 (truncate:HI
3943 (const:DI
3944 (sign_extend:DI
3945 (truncate:HI
3946 (ashiftrt:SI
3947 (match_dup 1)
3948 (const_int 16)))))))))
3949 (set (match_dup 0)
3950 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3951 (zero_extend:DI
3952 (truncate:HI
3953 (const:DI
3954 (sign_extend:DI
3955 (truncate:HI
3956 (match_dup 1))))))))]
3957 "TARGET_SHMEDIA64 && reload_completed
3958 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3959 "
3960{
ea4210ef 3961 sh_mark_label (operands[1], 4);
fa5322fa
AO
3962}")
3963
3964(define_expand "movdi_const_32bit"
3965 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3966 (const:DI (sign_extend:DI
3967 (truncate:HI
3968 (ashiftrt:DI
3969 (match_operand:DI 1 "immediate_operand" "s")
3970 (const_int 16))))))
3971 (set (match_dup 0)
3972 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3973 (zero_extend:DI
3974 (truncate:HI
3975 (const:DI
3976 (sign_extend:DI
3977 (truncate:HI
3978 (match_dup 1))))))))]
3979 "TARGET_SHMEDIA32 && reload_completed
3980 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3981 "
3982{
ea4210ef 3983 sh_mark_label (operands[1], 2);
fa5322fa
AO
3984}")
3985
3986(define_expand "movdi_const_16bit"
3987 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3988 (const:DI (sign_extend:DI
3989 (truncate:HI
3990 (match_operand:DI 1 "immediate_operand" "s")))))]
3991 "TARGET_SHMEDIA && flag_pic && reload_completed
3992 && GET_CODE (operands[1]) == SYMBOL_REF"
3993 "")
3994
3995(define_split
e69d1422
R
3996 [(set (match_operand:DI 0 "arith_reg_operand" "")
3997 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3998 "TARGET_SHMEDIA && reload_completed
3999 && GET_CODE (operands[1]) == CONST_INT
735cb76e 4000 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa 4001 [(set (match_dup 0) (match_dup 2))
c1b92d09 4002 (match_dup 1)]
fa5322fa
AO
4003 "
4004{
c1b92d09
R
4005 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4006 unsigned HOST_WIDE_INT low = val;
4007 unsigned HOST_WIDE_INT high = val;
fa5322fa 4008 unsigned HOST_WIDE_INT sign;
c1b92d09 4009 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
fa5322fa
AO
4010
4011 /* Sign-extend the 16 least-significant bits. */
c1b92d09
R
4012 low &= 0xffff;
4013 low ^= 0x8000;
4014 low -= 0x8000;
fa5322fa
AO
4015
4016 /* Arithmetic shift right the word by 16 bits. */
c1b92d09 4017 high >>= 16;
fa5322fa
AO
4018 sign = 1;
4019 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
c1b92d09
R
4020 high ^= sign;
4021 high -= sign;
4022 do
4023 {
4024 /* If we can't generate the constant with a two-insn movi / shori
4025 sequence, try some other strategies. */
735cb76e 4026 if (! CONST_OK_FOR_I16 (high))
c1b92d09
R
4027 {
4028 /* Try constant load / left shift. We know VAL != 0. */
4029 val2 = val ^ (val-1);
4030 if (val2 > 0x1ffff)
4031 {
4032 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4033
735cb76e
R
4034 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4035 || (! CONST_OK_FOR_I16 (high >> 16)
4036 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
c1b92d09
R
4037 {
4038 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4039 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4040 GEN_INT (trailing_zeroes));
4041 break;
4042 }
4043 }
4044 /* Try constant load / right shift. */
4045 val2 = (val >> 15) + 1;
4046 if (val2 == (val2 & -val2))
4047 {
4048 int shift = 49 - exact_log2 (val2);
4049
4050 val2 = trunc_int_for_mode (val << shift, DImode);
735cb76e 4051 if (CONST_OK_FOR_I16 (val2))
c1b92d09
R
4052 {
4053 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4054 GEN_INT (shift));
4055 break;
4056 }
4057 }
4058 /* Try mperm.w . */
4059 val2 = val & 0xffff;
4060 if ((val >> 16 & 0xffff) == val2
4061 && (val >> 32 & 0xffff) == val2
4062 && (val >> 48 & 0xffff) == val2)
4063 {
4064 val2 = (HOST_WIDE_INT) val >> 48;
4065 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4066 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4067 break;
4068 }
4069 /* Try movi / mshflo.l */
4070 val2 = (HOST_WIDE_INT) val >> 32;
4071 if (val2 == trunc_int_for_mode (val, SImode))
4072 {
4073 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4074 operands[0]);
4075 break;
4076 }
4077 /* Try movi / mshflo.l w/ r63. */
4078 val2 = val + ((HOST_WIDE_INT) -1 << 32);
735cb76e 4079 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
c1b92d09
R
4080 {
4081 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
a556fd39 4082 const0_rtx);
c1b92d09
R
4083 break;
4084 }
4085 }
4086 val2 = high;
4087 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4088 }
4089 while (0);
4090 operands[2] = GEN_INT (val2);
fa5322fa
AO
4091}")
4092
4093(define_split
e69d1422
R
4094 [(set (match_operand:DI 0 "arith_reg_operand" "")
4095 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
4096 "TARGET_SHMEDIA && reload_completed
4097 && GET_CODE (operands[1]) == CONST_DOUBLE"
4098 [(set (match_dup 0) (match_dup 2))
4099 (set (match_dup 0)
4100 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4101 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4102 "
4103{
4104 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4105 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4106 unsigned HOST_WIDE_INT val = low;
4107 unsigned HOST_WIDE_INT sign;
4108
4109 /* Sign-extend the 16 least-significant bits. */
4110 val &= 0xffff;
4111 val ^= 0x8000;
4112 val -= 0x8000;
4113 operands[1] = GEN_INT (val);
4114
4115 /* Arithmetic shift right the double-word by 16 bits. */
4116 low >>= 16;
4117 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4118 high >>= 16;
4119 sign = 1;
4120 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4121 high ^= sign;
4122 high -= sign;
4123
4124 /* This will only be true if high is a sign-extension of low, i.e.,
4125 it must be either 0 or (unsigned)-1, and be zero iff the
4126 most-significant bit of low is set. */
4127 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4128 operands[2] = GEN_INT (low);
4129 else
4130 operands[2] = immed_double_const (low, high, DImode);
4131}")
4132
c1b92d09 4133(define_insn "shori_media"
fa5322fa
AO
4134 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4135 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4136 (const_int 16))
4137 (zero_extend:DI
4138 (truncate:HI
735cb76e 4139 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
fa5322fa
AO
4140 "TARGET_SHMEDIA"
4141 "@
4142 shori %u2, %0
2ad65b0e
SC
4143 #"
4144 [(set_attr "type" "arith_media,*")])
fa5322fa 4145
bc45ade3 4146(define_expand "movdi"
961c4780
SC
4147 [(set (match_operand:DI 0 "general_movdst_operand" "")
4148 (match_operand:DI 1 "general_movsrc_operand" ""))]
bc45ade3 4149 ""
a6f463a0 4150 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
ffae286a 4151
fa5322fa
AO
4152(define_insn "movdf_media"
4153 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 4154 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
4155 "TARGET_SHMEDIA_FPU
4156 && (register_operand (operands[0], DFmode)
d9da94a1 4157 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4158 "@
4159 fmov.d %1, %0
0ac78517 4160 fmov.qd %N1, %0
fa5322fa
AO
4161 fmov.dq %1, %0
4162 add %1, r63, %0
4163 #
4164 fld%M1.d %m1, %0
4165 fst%M0.d %m0, %1
4166 ld%M1.q %m1, %0
d9da94a1 4167 st%M0.q %m0, %N1"
2ad65b0e 4168 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4169
4170(define_insn "movdf_media_nofpu"
4171 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 4172 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
4173 "TARGET_SHMEDIA
4174 && (register_operand (operands[0], DFmode)
d9da94a1 4175 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4176 "@
4177 add %1, r63, %0
4178 #
4179 ld%M1.q %m1, %0
d9da94a1 4180 st%M0.q %m0, %N1"
2ad65b0e 4181 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4182
4183(define_split
4184 [(set (match_operand:DF 0 "arith_reg_operand" "")
4185 (match_operand:DF 1 "immediate_operand" ""))]
4186 "TARGET_SHMEDIA && reload_completed"
4187 [(set (match_dup 3) (match_dup 2))]
4188 "
4189{
4190 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4191 long values[2];
4192 REAL_VALUE_TYPE value;
4193
4194 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4195 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4196
4197 if (HOST_BITS_PER_WIDE_INT >= 64)
4198 operands[2] = immed_double_const ((unsigned long) values[endian]
4199 | ((HOST_WIDE_INT) values[1 - endian]
4200 << 32), 0, DImode);
4201 else if (HOST_BITS_PER_WIDE_INT == 32)
4202 operands[2] = immed_double_const (values[endian], values[1 - endian],
4203 DImode);
4204 else
4205 abort ();
4206
4207 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4208}")
4209
ffae286a 4210;; ??? This should be a define expand.
bc45ade3 4211
bc45ade3 4212(define_insn "movdf_k"
3e943b59
JR
4213 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4214 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
fa5322fa
AO
4215 "TARGET_SH1
4216 && (! TARGET_SH4 || reload_completed
4217 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4218 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4219 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
225e4f43
R
4220 && (arith_reg_operand (operands[0], DFmode)
4221 || arith_reg_operand (operands[1], DFmode))"
0d7e008e 4222 "* return output_movedouble (insn, operands, DFmode);"
b9654711 4223 [(set_attr "length" "4")
3e943b59 4224 (set_attr "type" "move,pcload,load,store")])
bc45ade3 4225
225e4f43
R
4226;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4227;; However, the d/F/c/z alternative cannot be split directly; it is converted
4228;; with special code in machine_dependent_reorg into a load of the R0_REG and
4229;; the d/m/c/X alternative, which is split later into single-precision
4230;; instructions. And when not optimizing, no splits are done before fixing
4231;; up pcloads, so we need usable length information for that.
4232(define_insn "movdf_i4"
4233 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4234 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4235 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4236 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4237 "TARGET_SH4
4238 && (arith_reg_operand (operands[0], DFmode)
4239 || arith_reg_operand (operands[1], DFmode))"
4240 "@
4241 fmov %1,%0
4242 #
4243 #
4244 fmov.d %1,%0
4245 fmov.d %1,%0
4246 #
4247 #
4248 #
4249 #
4250 #"
4251 [(set_attr_alternative "length"
4252 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4253 (const_int 4)
4254 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4255 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4256 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4257 (const_int 4)
4258 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
fa5322fa
AO
4259 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4260 ;; increment or decrement r15 explicitly.
4261 (if_then_else
4262 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4263 (const_int 10) (const_int 8))
4264 (if_then_else
4265 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4266 (const_int 10) (const_int 8))])
c49439f1
R
4267 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4268 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
d64264ff
R
4269 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4270 (const_string "double")
4271 (const_string "none")))])
225e4f43
R
4272
4273;; Moving DFmode between fp/general registers through memory
4274;; (the top of the stack) is faster than moving through fpul even for
4275;; little endian. Because the type of an instruction is important for its
4276;; scheduling, it is beneficial to split these operations, rather than
4277;; emitting them in one single chunk, even if this will expose a stack
4278;; use that will prevent scheduling of other stack accesses beyond this
4279;; instruction.
4280(define_split
4281 [(set (match_operand:DF 0 "register_operand" "")
4282 (match_operand:DF 1 "register_operand" ""))
e69d1422 4283 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43
R
4284 (clobber (match_scratch:SI 3 "=X"))]
4285 "TARGET_SH4 && reload_completed
4286 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4287 [(const_int 0)]
4288 "
4289{
4290 rtx insn, tos;
4291
fa5322fa
AO
4292 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4293 {
4294 emit_move_insn (stack_pointer_rtx,
4295 plus_constant (stack_pointer_rtx, -8));
4296 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4297 }
4298 else
c0d4e710 4299 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
225e4f43 4300 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
fa5322fa 4301 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
c0d4e710 4302 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
fa5322fa
AO
4303 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4304 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4305 else
c0d4e710 4306 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
225e4f43 4307 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
fa5322fa
AO
4308 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4309 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4310 else
c0d4e710 4311 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
225e4f43
R
4312 DONE;
4313}")
4314
4315;; local-alloc sometimes allocates scratch registers even when not required,
4316;; so we must be prepared to handle these.
4317
4318;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4319(define_split
4320 [(set (match_operand:DF 0 "general_movdst_operand" "")
4321 (match_operand:DF 1 "general_movsrc_operand" ""))
e69d1422
R
4322 (use (match_operand:PSI 2 "fpscr_operand" ""))
4323 (clobber (match_scratch:SI 3 ""))]
225e4f43
R
4324 "TARGET_SH4
4325 && reload_completed
4326 && true_regnum (operands[0]) < 16
4327 && true_regnum (operands[1]) < 16"
4328 [(set (match_dup 0) (match_dup 1))]
4329 "
4330{
4331 /* If this was a reg <-> mem operation with base + index reg addressing,
4332 we have to handle this in a special way. */
4333 rtx mem = operands[0];
4334 int store_p = 1;
4335 if (! memory_operand (mem, DFmode))
4336 {
4337 mem = operands[1];
4338 store_p = 0;
4339 }
ddef6bc7 4340 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
225e4f43
R
4341 mem = SUBREG_REG (mem);
4342 if (GET_CODE (mem) == MEM)
4343 {
4344 rtx addr = XEXP (mem, 0);
4345 if (GET_CODE (addr) == PLUS
4346 && GET_CODE (XEXP (addr, 0)) == REG
4347 && GET_CODE (XEXP (addr, 1)) == REG)
4348 {
4349 int offset;
c0d4e710 4350 rtx reg0 = gen_rtx_REG (Pmode, 0);
225e4f43
R
4351 rtx regop = operands[store_p], word0 ,word1;
4352
4353 if (GET_CODE (regop) == SUBREG)
4dd8c093 4354 alter_subreg (&regop);
225e4f43
R
4355 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4356 offset = 2;
4357 else
4358 offset = 4;
4359 mem = copy_rtx (mem);
4360 PUT_MODE (mem, SImode);
c0d4e710 4361 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4dd8c093 4362 alter_subreg (&word0);
c0d4e710 4363 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4dd8c093 4364 alter_subreg (&word1);
18a7c2a7
AO
4365 if (store_p || ! refers_to_regno_p (REGNO (word0),
4366 REGNO (word0) + 1, addr, 0))
4367 {
4368 emit_insn (store_p
4369 ? gen_movsi_ie (mem, word0)
4370 : gen_movsi_ie (word0, mem));
4371 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4372 mem = copy_rtx (mem);
4373 emit_insn (store_p
4374 ? gen_movsi_ie (mem, word1)
4375 : gen_movsi_ie (word1, mem));
4376 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4377 }
4378 else
4379 {
4380 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4381 emit_insn (gen_movsi_ie (word1, mem));
4382 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4383 mem = copy_rtx (mem);
4384 emit_insn (gen_movsi_ie (word0, mem));
4385 }
225e4f43
R
4386 DONE;
4387 }
4388 }
4389}")
4390
4391;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4392(define_split
4393 [(set (match_operand:DF 0 "register_operand" "")
4394 (match_operand:DF 1 "memory_operand" ""))
e69d1422 4395 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4396 (clobber (reg:SI R0_REG))]
225e4f43
R
4397 "TARGET_SH4 && reload_completed"
4398 [(parallel [(set (match_dup 0) (match_dup 1))
4399 (use (match_dup 2))
4400 (clobber (scratch:SI))])]
4401 "")
4402
4403(define_expand "reload_indf"
4404 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4405 (match_operand:DF 1 "immediate_operand" "FQ"))
4773afa4 4406 (use (reg:PSI FPSCR_REG))
225e4f43 4407 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4408 "TARGET_SH1"
225e4f43
R
4409 "")
4410
4411(define_expand "reload_outdf"
4412 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4413 (match_operand:DF 1 "register_operand" "af,r"))
4414 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
fa5322fa 4415 "TARGET_SH1"
225e4f43
R
4416 "")
4417
4418;; Simplify no-op moves.
4419(define_split
4420 [(set (match_operand:SF 0 "register_operand" "")
4421 (match_operand:SF 1 "register_operand" ""))
4422 (use (match_operand:PSI 2 "fpscr_operand" ""))
40779a72 4423 (clobber (match_scratch:SI 3 ""))]
3a8699c7 4424 "TARGET_SH2E && reload_completed
225e4f43
R
4425 && true_regnum (operands[0]) == true_regnum (operands[1])"
4426 [(set (match_dup 0) (match_dup 0))]
4427 "")
4428
4429;; fmovd substitute post-reload splits
4430(define_split
4431 [(set (match_operand:DF 0 "register_operand" "")
4432 (match_operand:DF 1 "register_operand" ""))
e69d1422 4433 (use (match_operand:PSI 2 "fpscr_operand" ""))
40779a72 4434 (clobber (match_scratch:SI 3 ""))]
225e4f43 4435 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b
AO
4436 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4437 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4438 [(const_int 0)]
4439 "
4440{
4441 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
c0d4e710
KH
4442 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4443 gen_rtx_REG (SFmode, src), operands[2]));
4444 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4445 gen_rtx_REG (SFmode, src + 1), operands[2]));
225e4f43
R
4446 DONE;
4447}")
4448
4449(define_split
4450 [(set (match_operand:DF 0 "register_operand" "")
4451 (mem:DF (match_operand:SI 1 "register_operand" "")))
e69d1422
R
4452 (use (match_operand:PSI 2 "fpscr_operand" ""))
4453 (clobber (match_scratch:SI 3 ""))]
225e4f43 4454 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
b6c02328 4455 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
225e4f43
R
4456 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4457 [(const_int 0)]
4458 "
4459{
4460 int regno = true_regnum (operands[0]);
4461 rtx insn;
c0d4e710 4462 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
225e4f43 4463
c0d4e710 4464 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
225e4f43
R
4465 regno + !! TARGET_LITTLE_ENDIAN),
4466 mem2, operands[2]));
c0d4e710
KH
4467 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4468 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
225e4f43 4469 regno + ! TARGET_LITTLE_ENDIAN),
c0d4e710 4470 gen_rtx_MEM (SFmode, operands[1]),
225e4f43
R
4471 operands[2]));
4472 DONE;
4473}")
4474
4475(define_split
4476 [(set (match_operand:DF 0 "register_operand" "")
4477 (match_operand:DF 1 "memory_operand" ""))
e69d1422
R
4478 (use (match_operand:PSI 2 "fpscr_operand" ""))
4479 (clobber (match_scratch:SI 3 ""))]
225e4f43 4480 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4481 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
225e4f43
R
4482 [(const_int 0)]
4483 "
4484{
4485 int regno = true_regnum (operands[0]);
4486 rtx addr, insn, adjust = NULL_RTX;
4487 rtx mem2 = copy_rtx (operands[1]);
4488 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4489 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4490
4491 PUT_MODE (mem2, SFmode);
4492 operands[1] = copy_rtx (mem2);
4493 addr = XEXP (mem2, 0);
4494 if (GET_CODE (addr) != POST_INC)
4495 {
4496 /* If we have to modify the stack pointer, the value that we have
4497 read with post-increment might be modified by an interrupt,
4498 so write it back. */
4499 if (REGNO (addr) == STACK_POINTER_REGNUM)
4500 adjust = gen_push_e (reg0);
4501 else
4502 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4503 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4504 }
4505 addr = XEXP (addr, 0);
4506 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4507 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4508 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4509 if (adjust)
4510 emit_insn (adjust);
4511 else
4512 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4513 DONE;
4514}")
4515
4516(define_split
4517 [(set (match_operand:DF 0 "memory_operand" "")
4518 (match_operand:DF 1 "register_operand" ""))
e69d1422
R
4519 (use (match_operand:PSI 2 "fpscr_operand" ""))
4520 (clobber (match_scratch:SI 3 ""))]
225e4f43 4521 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4522 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4523 [(const_int 0)]
4524 "
4525{
4526 int regno = true_regnum (operands[1]);
4527 rtx insn, addr, adjust = NULL_RTX;
4528
4529 operands[0] = copy_rtx (operands[0]);
4530 PUT_MODE (operands[0], SFmode);
4531 insn = emit_insn (gen_movsf_ie (operands[0],
c0d4e710 4532 gen_rtx_REG (SFmode,
225e4f43
R
4533 regno + ! TARGET_LITTLE_ENDIAN),
4534 operands[2]));
4535 operands[0] = copy_rtx (operands[0]);
4536 addr = XEXP (operands[0], 0);
4537 if (GET_CODE (addr) != PRE_DEC)
4538 {
4539 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4540 emit_insn_before (adjust, insn);
c0d4e710 4541 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
225e4f43
R
4542 }
4543 addr = XEXP (addr, 0);
4544 if (! adjust)
c0d4e710 4545 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
225e4f43 4546 insn = emit_insn (gen_movsf_ie (operands[0],
c0d4e710 4547 gen_rtx_REG (SFmode,
225e4f43
R
4548 regno + !! TARGET_LITTLE_ENDIAN),
4549 operands[2]));
c0d4e710 4550 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
225e4f43
R
4551 DONE;
4552}")
4553
d0aae509 4554;; If the output is a register and the input is memory or a register, we have
52702ae1 4555;; to be careful and see which word needs to be loaded first.
07a45e5c 4556
8e87e161
SC
4557(define_split
4558 [(set (match_operand:DF 0 "general_movdst_operand" "")
4559 (match_operand:DF 1 "general_movsrc_operand" ""))]
fa5322fa 4560 "TARGET_SH1 && reload_completed"
8e87e161
SC
4561 [(set (match_dup 2) (match_dup 3))
4562 (set (match_dup 4) (match_dup 5))]
4563 "
d0aae509
RK
4564{
4565 int regno;
4566
4567 if ((GET_CODE (operands[0]) == MEM
4568 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4569 || (GET_CODE (operands[1]) == MEM
4570 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4571 FAIL;
4572
4573 if (GET_CODE (operands[0]) == REG)
4574 regno = REGNO (operands[0]);
4575 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 4576 regno = subreg_regno (operands[0]);
d0aae509
RK
4577 else if (GET_CODE (operands[0]) == MEM)
4578 regno = -1;
533f5e0f
KG
4579 else
4580 abort ();
d0aae509
RK
4581
4582 if (regno == -1
4583 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
4584 {
4585 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4586 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4587 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4588 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4589 }
4590 else
4591 {
4592 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4593 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4594 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4595 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4596 }
4597
4598 if (operands[2] == 0 || operands[3] == 0
4599 || operands[4] == 0 || operands[5] == 0)
4600 FAIL;
4601}")
4602
653bd7a6
JW
4603;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4604;; used only once, let combine add in the index again.
4605
4606(define_split
4607 [(set (match_operand:SI 0 "register_operand" "")
4608 (match_operand:SI 1 "" ""))
4609 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4610 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4611 [(use (reg:SI R0_REG))]
653bd7a6
JW
4612 "
4613{
4614 rtx addr, reg, const_int;
4615
4616 if (GET_CODE (operands[1]) != MEM)
4617 FAIL;
4618 addr = XEXP (operands[1], 0);
4619 if (GET_CODE (addr) != PLUS)
4620 FAIL;
4621 reg = XEXP (addr, 0);
4622 const_int = XEXP (addr, 1);
f295bdb5
AH
4623 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4624 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4625 FAIL;
4626 emit_move_insn (operands[2], const_int);
4627 emit_move_insn (operands[0],
4628 change_address (operands[1], VOIDmode,
c5c76735 4629 gen_rtx_PLUS (SImode, reg, operands[2])));
653bd7a6
JW
4630 DONE;
4631}")
4632
4633(define_split
4634 [(set (match_operand:SI 1 "" "")
4635 (match_operand:SI 0 "register_operand" ""))
4636 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4637 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4638 [(use (reg:SI R0_REG))]
653bd7a6
JW
4639 "
4640{
4641 rtx addr, reg, const_int;
4642
4643 if (GET_CODE (operands[1]) != MEM)
4644 FAIL;
4645 addr = XEXP (operands[1], 0);
4646 if (GET_CODE (addr) != PLUS)
4647 FAIL;
4648 reg = XEXP (addr, 0);
4649 const_int = XEXP (addr, 1);
f295bdb5
AH
4650 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4651 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4652 FAIL;
4653 emit_move_insn (operands[2], const_int);
4654 emit_move_insn (change_address (operands[1], VOIDmode,
c5c76735 4655 gen_rtx_PLUS (SImode, reg, operands[2])),
653bd7a6
JW
4656 operands[0]);
4657 DONE;
4658}")
4659
bc45ade3 4660(define_expand "movdf"
0d7e008e
SC
4661 [(set (match_operand:DF 0 "general_movdst_operand" "")
4662 (match_operand:DF 1 "general_movsrc_operand" ""))]
bc45ade3 4663 ""
1245df60
R
4664 "
4665{
4666 if (prepare_move_operands (operands, DFmode)) DONE;
fa5322fa
AO
4667 if (TARGET_SHMEDIA)
4668 {
4669 if (TARGET_SHMEDIA_FPU)
4670 emit_insn (gen_movdf_media (operands[0], operands[1]));
4671 else
4672 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4673 DONE;
4674 }
225e4f43
R
4675 if (TARGET_SH4)
4676 {
4677 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
4678 DONE;
4679 }
1245df60
R
4680}")
4681
0ac78517
R
4682;;This is incompatible with the way gcc uses subregs.
4683;;(define_insn "movv2sf_i"
4684;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4685;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4686;; "TARGET_SHMEDIA_FPU
4687;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4688;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4689;; "@
4690;; #
4691;; fld%M1.p %m1, %0
4692;; fst%M0.p %m0, %1"
4693;; [(set_attr "type" "*,fload_media,fstore_media")])
4694
4695(define_insn_and_split "movv2sf_i"
4696 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
735cb76e 4697 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
0ac78517
R
4698 "TARGET_SHMEDIA_FPU"
4699 "#"
4700 "TARGET_SHMEDIA_FPU && reload_completed"
4701 [(set (match_dup 0) (match_dup 1))]
4702 "
4703{
4704 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4705 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4706}")
fa5322fa
AO
4707
4708(define_expand "movv2sf"
0ac78517
R
4709 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4710 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
fa5322fa
AO
4711 "TARGET_SHMEDIA_FPU"
4712 "
4713{
4714 if (prepare_move_operands (operands, V2SFmode))
4715 DONE;
4716}")
4717
0ac78517
R
4718(define_expand "addv2sf3"
4719 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4720 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4721 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4722 "TARGET_SHMEDIA_FPU"
4723 "
4724{
4725 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4726 DONE;
4727}")
4728
4729(define_expand "subv2sf3"
4730 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4731 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4732 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4733 "TARGET_SHMEDIA_FPU"
4734 "
4735{
4736 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4737 DONE;
4738}")
4739
4740(define_expand "mulv2sf3"
4741 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4742 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4743 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4744 "TARGET_SHMEDIA_FPU"
4745 "
4746{
4747 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4748 DONE;
4749}")
4750
4751(define_expand "divv2sf3"
4752 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4753 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4754 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4755 "TARGET_SHMEDIA_FPU"
4756 "
4757{
4758 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4759 DONE;
4760}")
4761
fa5322fa
AO
4762(define_insn_and_split "*movv4sf_i"
4763 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
735cb76e 4764 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
fa5322fa
AO
4765 "TARGET_SHMEDIA_FPU"
4766 "#"
4767 "&& reload_completed"
4768 [(const_int 0)]
4769 "
4770{
4771 int i;
4772
4773 for (i = 0; i < 4/2; i++)
4774 {
4775 rtx x, y;
4776
4777 if (GET_CODE (operands[0]) == MEM)
4778 x = gen_rtx_MEM (V2SFmode,
4779 plus_constant (XEXP (operands[0], 0),
4780 i * GET_MODE_SIZE (V2SFmode)));
4781 else
0ac78517 4782 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
fa5322fa
AO
4783
4784 if (GET_CODE (operands[1]) == MEM)
4785 y = gen_rtx_MEM (V2SFmode,
4786 plus_constant (XEXP (operands[1], 0),
4787 i * GET_MODE_SIZE (V2SFmode)));
4788 else
0ac78517 4789 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
fa5322fa
AO
4790
4791 emit_insn (gen_movv2sf_i (x, y));
4792 }
4793
4794 DONE;
4795}"
4796 [(set_attr "length" "8")])
52702ae1 4797
fa5322fa 4798(define_expand "movv4sf"
0ac78517
R
4799 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4800 (match_operand:V4SF 1 "general_operand" ""))]
fa5322fa
AO
4801 "TARGET_SHMEDIA_FPU"
4802 "
4803{
4804 if (prepare_move_operands (operands, V4SFmode))
4805 DONE;
4806}")
4807
4808(define_insn_and_split "*movv16sf_i"
4809 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4810 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4811 "TARGET_SHMEDIA_FPU"
4812 "#"
4813 "&& reload_completed"
4814 [(const_int 0)]
4815 "
4816{
4817 int i;
4818
4819 for (i = 0; i < 16/2; i++)
4820 {
4821 rtx x,y;
4822
4823 if (GET_CODE (operands[0]) == MEM)
4824 x = gen_rtx_MEM (V2SFmode,
4825 plus_constant (XEXP (operands[0], 0),
4826 i * GET_MODE_SIZE (V2SFmode)));
4827 else
4828 {
40779a72 4829 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
fa5322fa
AO
4830 alter_subreg (&x);
4831 }
4832
4833 if (GET_CODE (operands[1]) == MEM)
4834 y = gen_rtx_MEM (V2SFmode,
4835 plus_constant (XEXP (operands[1], 0),
4836 i * GET_MODE_SIZE (V2SFmode)));
4837 else
4838 {
40779a72 4839 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
fa5322fa
AO
4840 alter_subreg (&y);
4841 }
4842
4843 emit_insn (gen_movv2sf_i (x, y));
4844 }
4845
4846 DONE;
4847}"
4848 [(set_attr "length" "32")])
52702ae1 4849
fa5322fa
AO
4850(define_expand "movv16sf"
4851 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4852 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4853 "TARGET_SHMEDIA_FPU"
4854 "
4855{
4856 if (prepare_move_operands (operands, V16SFmode))
4857 DONE;
4858}")
4859
4860(define_insn "movsf_media"
4861 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 4862 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
4863 "TARGET_SHMEDIA_FPU
4864 && (register_operand (operands[0], SFmode)
d9da94a1 4865 || sh_register_operand (operands[1], SFmode))"
fa5322fa
AO
4866 "@
4867 fmov.s %1, %0
0ac78517 4868 fmov.ls %N1, %0
fa5322fa 4869 fmov.sl %1, %0
b6d33983 4870 add.l %1, r63, %0
fa5322fa
AO
4871 #
4872 fld%M1.s %m1, %0
4873 fst%M0.s %m0, %1
4874 ld%M1.l %m1, %0
d9da94a1 4875 st%M0.l %m0, %N1"
b6d33983 4876 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4877
4878(define_insn "movsf_media_nofpu"
4879 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 4880 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
4881 "TARGET_SHMEDIA
4882 && (register_operand (operands[0], SFmode)
d9da94a1 4883 || sh_register_operand (operands[1], SFmode))"
fa5322fa 4884 "@
b6d33983 4885 add.l %1, r63, %0
fa5322fa
AO
4886 #
4887 ld%M1.l %m1, %0
d9da94a1 4888 st%M0.l %m0, %N1"
b6d33983 4889 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4890
4891(define_split
4892 [(set (match_operand:SF 0 "arith_reg_operand" "")
4893 (match_operand:SF 1 "immediate_operand" ""))]
0ac78517
R
4894 "TARGET_SHMEDIA && reload_completed
4895 && ! FP_REGISTER_P (true_regnum (operands[0]))"
fa5322fa
AO
4896 [(set (match_dup 3) (match_dup 2))]
4897 "
4898{
4899 long values;
4900 REAL_VALUE_TYPE value;
4901
4902 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4903 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4904 operands[2] = GEN_INT (values);
52702ae1 4905
fa5322fa
AO
4906 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4907}")
bc45ade3 4908
bc45ade3 4909(define_insn "movsf_i"
3e943b59 4910 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
735cb76e 4911 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
fa5322fa 4912 "TARGET_SH1
3a8699c7 4913 && (! TARGET_SH2E
fa5322fa
AO
4914 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4915 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4916 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
1245df60
R
4917 && (arith_reg_operand (operands[0], SFmode)
4918 || arith_reg_operand (operands[1], SFmode))"
bc45ade3
SC
4919 "@
4920 mov %1,%0
735cb76e 4921 mov #0,%0
bc45ade3
SC
4922 mov.l %1,%0
4923 mov.l %1,%0
3e943b59 4924 mov.l %1,%0
b9654711 4925 lds %1,%0
0d7e008e 4926 sts %1,%0"
3e943b59 4927 [(set_attr "type" "move,move,pcload,load,store,move,move")])
bc45ade3 4928
4dff12bf
R
4929;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4930;; update_flow_info would not know where to put REG_EQUAL notes
4931;; when the destination changes mode.
45348d9e 4932(define_insn "movsf_ie"
7f74cc8d 4933 [(set (match_operand:SF 0 "general_movdst_operand"
a92facbb 4934 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
7f74cc8d 4935 (match_operand:SF 1 "general_movsrc_operand"
a92facbb
AO
4936 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4937 (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"))
735cb76e 4938 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
7f74cc8d 4939
3a8699c7 4940 "TARGET_SH2E
45348d9e 4941 && (arith_reg_operand (operands[0], SFmode)
c2d10707
AO
4942 || arith_reg_operand (operands[1], SFmode)
4943 || arith_reg_operand (operands[3], SImode)
4944 || (fpul_operand (operands[0], SFmode)
4945 && memory_operand (operands[1], SFmode)
4946 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4947 || (fpul_operand (operands[1], SFmode)
4948 && memory_operand (operands[0], SFmode)
4949 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
45348d9e
JW
4950 "@
4951 fmov %1,%0
4952 mov %1,%0
4953 fldi0 %0
4954 fldi1 %0
7f74cc8d 4955 #
45348d9e
JW
4956 fmov.s %1,%0
4957 fmov.s %1,%0
4958 mov.l %1,%0
4959 mov.l %1,%0
3e943b59 4960 mov.l %1,%0
1245df60
R
4961 fsts fpul,%0
4962 flds %1,fpul
4963 lds.l %1,%0
4964 #
4dff12bf
R
4965 sts %1,%0
4966 lds %1,%0
a92facbb
AO
4967 sts.l %1,%0
4968 lds.l %1,%0
4dff12bf 4969 ! move optimized away"
c49439f1
R
4970 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4971 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
a92facbb 4972 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
d64264ff
R
4973 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4974 (const_string "single")
4975 (const_string "none")))])
79664856 4976
1245df60
R
4977(define_split
4978 [(set (match_operand:SF 0 "register_operand" "")
4979 (match_operand:SF 1 "register_operand" ""))
e69d1422 4980 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4981 (clobber (reg:SI FPUL_REG))]
fa5322fa 4982 "TARGET_SH1"
4773afa4 4983 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
225e4f43 4984 (use (match_dup 2))
1245df60 4985 (clobber (scratch:SI))])
4773afa4 4986 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
225e4f43 4987 (use (match_dup 2))
1245df60
R
4988 (clobber (scratch:SI))])]
4989 "")
4990
bc45ade3 4991(define_expand "movsf"
0d7e008e 4992 [(set (match_operand:SF 0 "general_movdst_operand" "")
3e943b59 4993 (match_operand:SF 1 "general_movsrc_operand" ""))]
bc45ade3 4994 ""
3e943b59
JR
4995 "
4996{
4997 if (prepare_move_operands (operands, SFmode))
4998 DONE;
fa5322fa
AO
4999 if (TARGET_SHMEDIA)
5000 {
5001 if (TARGET_SHMEDIA_FPU)
5002 emit_insn (gen_movsf_media (operands[0], operands[1]));
5003 else
5004 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
5005 DONE;
5006 }
3a8699c7 5007 if (TARGET_SH2E)
3e943b59 5008 {
225e4f43 5009 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
3e943b59
JR
5010 DONE;
5011 }
5012}")
7f74cc8d 5013
225e4f43 5014(define_insn "mov_nop"
e69d1422 5015 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
3a8699c7 5016 "TARGET_SH2E"
225e4f43
R
5017 ""
5018 [(set_attr "length" "0")
5019 (set_attr "type" "nil")])
5020
7f74cc8d 5021(define_expand "reload_insf"
c2d10707 5022 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
7f74cc8d 5023 (match_operand:SF 1 "immediate_operand" "FQ"))
4773afa4 5024 (use (reg:PSI FPSCR_REG))
7f74cc8d 5025 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 5026 "TARGET_SH1"
7f74cc8d 5027 "")
225e4f43
R
5028
5029(define_expand "reload_insi"
5030 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5031 (match_operand:SF 1 "immediate_operand" "FQ"))
5032 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 5033 "TARGET_SH1"
225e4f43
R
5034 "")
5035
5036(define_insn "*movsi_y"
5037 [(set (match_operand:SI 0 "register_operand" "=y,y")
735cb76e 5038 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
c77e04ae 5039 (clobber (match_scratch:SI 2 "=&z,r"))]
3a8699c7 5040 "TARGET_SH2E
225e4f43
R
5041 && (reload_in_progress || reload_completed)"
5042 "#"
5043 [(set_attr "length" "4")
5044 (set_attr "type" "pcload,move")])
5045
5046(define_split
997718c7
RH
5047 [(set (match_operand:SI 0 "register_operand" "")
5048 (match_operand:SI 1 "immediate_operand" ""))
5049 (clobber (match_operand:SI 2 "register_operand" ""))]
fa5322fa 5050 "TARGET_SH1"
225e4f43
R
5051 [(set (match_dup 2) (match_dup 1))
5052 (set (match_dup 0) (match_dup 2))]
5053 "")
5054
5055(define_split
997718c7
RH
5056 [(set (match_operand:SI 0 "register_operand" "")
5057 (match_operand:SI 1 "memory_operand" ""))
4773afa4 5058 (clobber (reg:SI R0_REG))]
fa5322fa 5059 "TARGET_SH1"
225e4f43
R
5060 [(set (match_dup 0) (match_dup 1))]
5061 "")
bc45ade3
SC
5062\f
5063;; ------------------------------------------------------------------------
5064;; Define the real conditional branch instructions.
5065;; ------------------------------------------------------------------------
5066
5067(define_insn "branch_true"
4773afa4 5068 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5069 (label_ref (match_operand 0 "" ""))
5070 (pc)))]
fa5322fa 5071 "TARGET_SH1"
51aea58d 5072 "* return output_branch (1, insn, operands);"
bc45ade3
SC
5073 [(set_attr "type" "cbranch")])
5074
5075(define_insn "branch_false"
4773afa4 5076 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5077 (label_ref (match_operand 0 "" ""))
5078 (pc)))]
fa5322fa 5079 "TARGET_SH1"
51aea58d 5080 "* return output_branch (0, insn, operands);"
bc45ade3
SC
5081 [(set_attr "type" "cbranch")])
5082
1245df60
R
5083;; Patterns to prevent reorg from re-combining a condbranch with a branch
5084;; which destination is too far away.
5085;; The const_int_operand is distinct for each branch target; it avoids
5086;; unwanted matches with redundant_insn.
5087(define_insn "block_branch_redirect"
e11cddec 5088 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
fa5322fa 5089 "TARGET_SH1"
1245df60
R
5090 ""
5091 [(set_attr "length" "0")])
bc45ade3 5092
1245df60
R
5093;; This one has the additional purpose to record a possible scratch register
5094;; for the following branch.
10f4f635
R
5095;; ??? Unfortunately, just setting the scratch register is not good enough,
5096;; because the insn then might be deemed dead and deleted. And we can't
5097;; make the use in the jump insn explicit because that would disable
5098;; delay slot scheduling from the target.
1245df60 5099(define_insn "indirect_jump_scratch"
e69d1422 5100 [(set (match_operand:SI 0 "register_operand" "=r")
73774972 5101 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
10f4f635 5102 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
fa5322fa 5103 "TARGET_SH1"
1245df60
R
5104 ""
5105 [(set_attr "length" "0")])
c608a684
R
5106
5107;; This one is used to preemt an insn from beyond the bra / braf / jmp
5108;; being pulled into the delay slot of a condbranch that has been made to
5109;; jump around the unconditional jump because it was out of range.
5110(define_insn "stuff_delay_slot"
5111 [(set (pc)
5112 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5113 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5114 "TARGET_SH1"
5115 ""
5116 [(set_attr "length" "0")
5117 (set_attr "cond_delay_slot" "yes")])
bc45ade3
SC
5118\f
5119;; Conditional branch insns
5120
fa5322fa 5121(define_expand "beq_media"
1245df60 5122 [(set (pc)
fa5322fa 5123 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5124 (match_operand:DI 2 "arith_operand" "r,I06"))
fa5322fa 5125 (label_ref:DI (match_operand 0 "" ""))
bc45ade3 5126 (pc)))]
fa5322fa
AO
5127 "TARGET_SHMEDIA"
5128 "")
bc45ade3 5129
c8cc4417 5130(define_insn "*beq_media_i"
1245df60 5131 [(set (pc)
c8cc4417
R
5132 (if_then_else (match_operator 3 "equality_comparison_operator"
5133 [(match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5134 (match_operand:DI 2 "arith_operand" "r,I06")])
fa5322fa 5135 (match_operand:DI 0 "target_operand" "b,b")
1245df60 5136 (pc)))]
fa5322fa
AO
5137 "TARGET_SHMEDIA"
5138 "@
c8cc4417
R
5139 b%o3%' %1, %2, %0
5140 b%o3i%' %1, %2, %0"
5141 [(set_attr "type" "cbranch_media")])
bc45ade3 5142
fa5322fa 5143(define_expand "bne_media"
1245df60 5144 [(set (pc)
fa5322fa 5145 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5146 (match_operand:DI 2 "arith_operand" "r,I06"))
fa5322fa 5147 (label_ref:DI (match_operand 0 "" ""))
ffae286a 5148 (pc)))]
fa5322fa
AO
5149 "TARGET_SHMEDIA"
5150 "")
bc45ade3 5151
fa5322fa 5152(define_expand "bgt_media"
1245df60 5153 [(set (pc)
b6d33983
R
5154 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5155 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa 5156 (label_ref:DI (match_operand 0 "" ""))
1245df60 5157 (pc)))]
fa5322fa
AO
5158 "TARGET_SHMEDIA"
5159 "")
5160
fa5322fa
AO
5161(define_expand "bge_media"
5162 [(set (pc)
b6d33983
R
5163 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5164 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5165 (label_ref:DI (match_operand 0 "" ""))
5166 (pc)))]
5167 "TARGET_SHMEDIA"
5168 "")
5169
fa5322fa
AO
5170(define_expand "bgtu_media"
5171 [(set (pc)
b6d33983
R
5172 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5173 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5174 (label_ref:DI (match_operand 0 "" ""))
5175 (pc)))]
5176 "TARGET_SHMEDIA"
5177 "")
5178
fa5322fa
AO
5179(define_expand "bgeu_media"
5180 [(set (pc)
b6d33983
R
5181 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5182 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5183 (label_ref:DI (match_operand 0 "" ""))
5184 (pc)))]
5185 "TARGET_SHMEDIA"
5186 "")
5187
c8cc4417 5188(define_insn "*bgt_media_i"
fa5322fa 5189 [(set (pc)
c8cc4417
R
5190 (if_then_else (match_operator 3 "greater_comparison_operator"
5191 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5192 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5193 (match_operand:DI 0 "target_operand" "b")
5194 (pc)))]
5195 "TARGET_SHMEDIA"
c8cc4417
R
5196 "b%o3%' %N1, %N2, %0"
5197 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5198
5199;; These are only needed to make invert_jump() happy.
b6d33983 5200(define_insn "*blt_media_i"
fa5322fa 5201 [(set (pc)
c8cc4417 5202 (if_then_else (match_operator 3 "less_comparison_operator"
b6d33983
R
5203 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5204 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5205 (match_operand:DI 0 "target_operand" "b")
5206 (pc)))]
5207 "TARGET_SHMEDIA"
c8cc4417
R
5208 "b%o3%' %N2, %N1, %0"
5209 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5210
5211(define_expand "beq"
5212 [(set (pc)
5213 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5214 (label_ref (match_operand 0 "" ""))
5215 (pc)))]
5216 ""
5217 "
5218{
5219 if (TARGET_SHMEDIA)
5220 {
5221 if (GET_MODE (sh_compare_op0) != DImode)
5222 {
5223 rtx tmp = gen_reg_rtx (DImode);
5224
5225 emit_insn (gen_seq (tmp));
5226 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5227 DONE;
5228 }
5229
5230 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5231 emit_jump_insn (gen_beq_media (operands[0],
5232 sh_compare_op0, sh_compare_op1));
5233 DONE;
5234 }
5235
5236 from_compare (operands, EQ);
5237}")
5238
5239(define_expand "bne"
5240 [(set (pc)
5241 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5242 (label_ref (match_operand 0 "" ""))
5243 (pc)))]
5244 ""
5245 "
5246{
5247 if (TARGET_SHMEDIA)
5248 {
5249 if (GET_MODE (sh_compare_op0) != DImode)
5250 {
5251 rtx tmp = gen_reg_rtx (DImode);
5252
5253 emit_insn (gen_seq (tmp));
5254 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5255 DONE;
5256 }
5257
5258 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5259 emit_jump_insn (gen_bne_media (operands[0],
5260 sh_compare_op0, sh_compare_op1));
5261 DONE;
5262 }
5263
5264 from_compare (operands, EQ);
5265}")
5266
5267(define_expand "bgt"
5268 [(set (pc)
5269 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5270 (label_ref (match_operand 0 "" ""))
5271 (pc)))]
5272 ""
5273 "
5274{
5275 if (TARGET_SHMEDIA)
5276 {
5277 if (GET_MODE (sh_compare_op0) != DImode)
5278 {
5279 rtx tmp = gen_reg_rtx (DImode);
5280
5281 emit_insn (gen_sgt (tmp));
5282 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5283 DONE;
5284 }
5285
c8cc4417
R
5286 if (sh_compare_op0 != const0_rtx)
5287 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5288 if (sh_compare_op1 != const0_rtx)
5289 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5290 emit_jump_insn (gen_bgt_media (operands[0],
5291 sh_compare_op0, sh_compare_op1));
5292 DONE;
5293 }
5294
5295 from_compare (operands, GT);
5296}")
5297
5298(define_expand "blt"
5299 [(set (pc)
5300 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5301 (label_ref (match_operand 0 "" ""))
5302 (pc)))]
5303 ""
5304 "
5305{
5306 if (TARGET_SHMEDIA)
5307 {
5308 if (GET_MODE (sh_compare_op0) != DImode)
5309 {
5310 rtx tmp = gen_reg_rtx (DImode);
5311
5312 emit_insn (gen_slt (tmp));
5313 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5314 DONE;
5315 }
5316
c8cc4417
R
5317 if (sh_compare_op0 != const0_rtx)
5318 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5319 if (sh_compare_op1 != const0_rtx)
5320 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5321 emit_jump_insn (gen_bgt_media (operands[0],
5322 sh_compare_op1, sh_compare_op0));
5323 DONE;
5324 }
5325
5326 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5327 {
5328 rtx tmp = sh_compare_op0;
5329 sh_compare_op0 = sh_compare_op1;
5330 sh_compare_op1 = tmp;
5331 emit_insn (gen_bgt (operands[0]));
5332 DONE;
5333 }
5334 from_compare (operands, GE);
5335}")
5336
5337(define_expand "ble"
5338 [(set (pc)
5339 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5340 (label_ref (match_operand 0 "" ""))
5341 (pc)))]
5342 ""
5343 "
5344{
5345 if (TARGET_SHMEDIA)
5346 {
5347 if (GET_MODE (sh_compare_op0) != DImode)
5348 {
5349 rtx tmp = gen_reg_rtx (DImode);
5350
5351 emit_insn (gen_sle (tmp));
5352 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5353 DONE;
5354 }
5355
c8cc4417
R
5356 if (sh_compare_op0 != const0_rtx)
5357 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5358 if (sh_compare_op1 != const0_rtx)
5359 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5360 emit_jump_insn (gen_bge_media (operands[0],
5361 sh_compare_op1, sh_compare_op0));
5362 DONE;
5363 }
5364
3a8699c7 5365 if (TARGET_SH2E
fa5322fa 5366 && TARGET_IEEE
1245df60
R
5367 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5368 {
5369 rtx tmp = sh_compare_op0;
5370 sh_compare_op0 = sh_compare_op1;
5371 sh_compare_op1 = tmp;
5372 emit_insn (gen_bge (operands[0]));
5373 DONE;
5374 }
5375 from_compare (operands, GT);
5376}")
bc45ade3
SC
5377
5378(define_expand "bge"
1245df60 5379 [(set (pc)
4773afa4 5380 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5381 (label_ref (match_operand 0 "" ""))
ffae286a 5382 (pc)))]
bc45ade3 5383 ""
45348d9e
JW
5384 "
5385{
fa5322fa
AO
5386 if (TARGET_SHMEDIA)
5387 {
5388 if (GET_MODE (sh_compare_op0) != DImode)
5389 {
5390 rtx tmp = gen_reg_rtx (DImode);
5391
5392 emit_insn (gen_sge (tmp));
5393 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5394 DONE;
5395 }
5396
c8cc4417
R
5397 if (sh_compare_op0 != const0_rtx)
5398 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5399 if (sh_compare_op1 != const0_rtx)
5400 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5401 emit_jump_insn (gen_bge_media (operands[0],
5402 sh_compare_op0, sh_compare_op1));
5403 DONE;
5404 }
5405
3a8699c7 5406 if (TARGET_SH2E
1245df60
R
5407 && ! TARGET_IEEE
5408 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e
JW
5409 {
5410 rtx tmp = sh_compare_op0;
5411 sh_compare_op0 = sh_compare_op1;
5412 sh_compare_op1 = tmp;
5413 emit_insn (gen_ble (operands[0]));
5414 DONE;
5415 }
5416 from_compare (operands, GE);
5417}")
bc45ade3
SC
5418
5419(define_expand "bgtu"
1245df60 5420 [(set (pc)
4773afa4 5421 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5422 (label_ref (match_operand 0 "" ""))
5423 (pc)))]
5424 ""
fa5322fa
AO
5425 "
5426{
5427 if (TARGET_SHMEDIA)
5428 {
c8cc4417
R
5429 if (sh_compare_op0 != const0_rtx)
5430 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5431 if (sh_compare_op1 != const0_rtx)
5432 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5433 emit_jump_insn (gen_bgtu_media (operands[0],
5434 sh_compare_op0, sh_compare_op1));
5435 DONE;
5436 }
5437
5438 from_compare (operands, GTU);
5439}")
bc45ade3
SC
5440
5441(define_expand "bltu"
1245df60 5442 [(set (pc)
4773afa4
AO
5443 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5444 (label_ref (match_operand 0 "" ""))
5445 (pc)))]
bc45ade3 5446 ""
fa5322fa
AO
5447 "
5448{
5449 if (TARGET_SHMEDIA)
5450 {
c8cc4417
R
5451 if (sh_compare_op0 != const0_rtx)
5452 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5453 if (sh_compare_op1 != const0_rtx)
5454 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5455 emit_jump_insn (gen_bgtu_media (operands[0],
5456 sh_compare_op1, sh_compare_op0));
5457 DONE;
5458 }
5459
5460 from_compare (operands, GEU);
5461}")
bc45ade3
SC
5462
5463(define_expand "bgeu"
1245df60 5464 [(set (pc)
4773afa4 5465 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5466 (label_ref (match_operand 0 "" ""))
ffae286a 5467 (pc)))]
bc45ade3 5468 ""
fa5322fa
AO
5469 "
5470{
5471 if (TARGET_SHMEDIA)
5472 {
c8cc4417
R
5473 if (sh_compare_op0 != const0_rtx)
5474 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5475 if (sh_compare_op1 != const0_rtx)
5476 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5477 emit_jump_insn (gen_bgeu_media (operands[0],
5478 sh_compare_op0, sh_compare_op1));
5479 DONE;
5480 }
5481
5482 from_compare (operands, GEU);
5483}")
bc45ade3
SC
5484
5485(define_expand "bleu"
1245df60 5486 [(set (pc)
4773afa4 5487 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1245df60
R
5488 (label_ref (match_operand 0 "" ""))
5489 (pc)))]
bc45ade3 5490 ""
fa5322fa
AO
5491 "
5492{
5493 if (TARGET_SHMEDIA)
5494 {
c8cc4417
R
5495 if (sh_compare_op0 != const0_rtx)
5496 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5497 if (sh_compare_op1 != const0_rtx)
5498 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5499 emit_jump_insn (gen_bgeu_media (operands[0],
5500 sh_compare_op1, sh_compare_op0));
5501 DONE;
5502 }
5503
5504 from_compare (operands, GTU);
5505}")
5506
5507(define_expand "bunordered"
5508 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5509 (set (pc)
5510 (if_then_else (ne (match_dup 1) (const_int 0))
5511 (label_ref:DI (match_operand 0 "" ""))
5512 (pc)))]
5513 "TARGET_SHMEDIA"
5514 "
5515{
5516 operands[1] = gen_reg_rtx (DImode);
5517 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5518 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5519}")
bc45ade3
SC
5520\f
5521;; ------------------------------------------------------------------------
5522;; Jump and linkage insns
5523;; ------------------------------------------------------------------------
5524
fa5322fa 5525(define_insn "jump_compact"
bc45ade3
SC
5526 [(set (pc)
5527 (label_ref (match_operand 0 "" "")))]
fa5322fa 5528 "TARGET_SH1"
bc45ade3
SC
5529 "*
5530{
22e1ebf1 5531 /* The length is 16 if the delay slot is unfilled. */
1245df60 5532 if (get_attr_length(insn) > 4)
51aea58d 5533 return output_far_jump(insn, operands[0]);
bc45ade3 5534 else
51aea58d 5535 return \"bra %l0%#\";
bc45ade3
SC
5536}"
5537 [(set_attr "type" "jump")
5538 (set_attr "needs_delay_slot" "yes")])
5539
10f4f635
R
5540;; ??? It would be much saner to explicitly use the scratch register
5541;; in the jump insn, and have indirect_jump_scratch only set it,
5542;; but fill_simple_delay_slots would refuse to do delay slot filling
5543;; from the target then, as it uses simplejump_p.
5544;;(define_insn "jump_compact_far"
5545;; [(set (pc)
5546;; (label_ref (match_operand 0 "" "")))
5547;; (use (match_operand 1 "register_operand" "r")]
5548;; "TARGET_SH1"
5549;; "* return output_far_jump(insn, operands[0], operands[1]);"
5550;; [(set_attr "type" "jump")
5551;; (set_attr "needs_delay_slot" "yes")])
5552
fa5322fa
AO
5553(define_insn "jump_media"
5554 [(set (pc)
5555 (match_operand:DI 0 "target_operand" "b"))]
5556 "TARGET_SHMEDIA"
2ad65b0e
SC
5557 "blink %0, r63"
5558 [(set_attr "type" "jump_media")])
fa5322fa
AO
5559
5560(define_expand "jump"
5561 [(set (pc)
5562 (label_ref (match_operand 0 "" "")))]
5563 ""
5564 "
5565{
5566 if (TARGET_SH1)
8e831557 5567 emit_jump_insn (gen_jump_compact (operands[0]));
fa5322fa
AO
5568 else if (TARGET_SHMEDIA)
5569 {
5570 if (reload_in_progress || reload_completed)
5571 FAIL;
8e831557
KK
5572 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5573 operands[0])));
fa5322fa
AO
5574 }
5575 DONE;
5576}")
5577
5578(define_insn "force_mode_for_call"
5579 [(use (reg:PSI FPSCR_REG))]
5580 "TARGET_SHCOMPACT"
5581 ""
5582 [(set_attr "length" "0")
5583 (set (attr "fp_mode")
5584 (if_then_else (eq_attr "fpu_single" "yes")
5585 (const_string "single") (const_string "double")))])
5586
bc45ade3 5587(define_insn "calli"
aa684c94 5588 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
bc45ade3 5589 (match_operand 1 "" ""))
5d00b10a 5590 (use (reg:PSI FPSCR_REG))
4773afa4 5591 (clobber (reg:SI PR_REG))]
fa5322fa 5592 "TARGET_SH1"
bc45ade3 5593 "jsr @%0%#"
ffae286a 5594 [(set_attr "type" "call")
d64264ff
R
5595 (set (attr "fp_mode")
5596 (if_then_else (eq_attr "fpu_single" "yes")
5597 (const_string "single") (const_string "double")))
73774972
EC
5598 (set_attr "needs_delay_slot" "yes")
5599 (set_attr "fp_set" "unknown")])
961c4780 5600
1a66cd67
AO
5601;; This is a pc-rel call, using bsrf, for use with PIC.
5602
5603(define_insn "calli_pcrel"
5604 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5605 (match_operand 1 "" ""))
5d00b10a 5606 (use (reg:PSI FPSCR_REG))
2d01e445 5607 (use (reg:SI PIC_REG))
1a66cd67 5608 (use (match_operand 2 "" ""))
4773afa4 5609 (clobber (reg:SI PR_REG))]
eb69f95c 5610 "TARGET_SH2"
1a66cd67
AO
5611 "bsrf %0\\n%O2:%#"
5612 [(set_attr "type" "call")
5613 (set (attr "fp_mode")
5614 (if_then_else (eq_attr "fpu_single" "yes")
5615 (const_string "single") (const_string "double")))
73774972
EC
5616 (set_attr "needs_delay_slot" "yes")
5617 (set_attr "fp_set" "unknown")])
1a66cd67 5618
2d01e445
AO
5619(define_insn_and_split "call_pcrel"
5620 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5621 (match_operand 1 "" ""))
5622 (use (reg:PSI FPSCR_REG))
5623 (use (reg:SI PIC_REG))
5624 (clobber (reg:SI PR_REG))
5625 (clobber (match_scratch:SI 2 "=r"))]
cb51ecd2 5626 "TARGET_SH2"
2d01e445
AO
5627 "#"
5628 "reload_completed"
5629 [(const_int 0)]
5630 "
5631{
8e831557 5632 rtx lab = PATTERN (gen_call_site ());
2d01e445 5633
675ff4c7 5634 if (SYMBOL_REF_LOCAL_P (operands[0]))
2d01e445
AO
5635 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5636 else
5637 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5638 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5639 DONE;
5640}"
5641 [(set_attr "type" "call")
5642 (set (attr "fp_mode")
5643 (if_then_else (eq_attr "fpu_single" "yes")
5644 (const_string "single") (const_string "double")))
73774972
EC
5645 (set_attr "needs_delay_slot" "yes")
5646 (set_attr "fp_set" "unknown")])
2d01e445 5647
fa5322fa
AO
5648(define_insn "call_compact"
5649 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5650 (match_operand 1 "" ""))
5651 (match_operand 2 "immediate_operand" "n")
5652 (use (reg:SI R0_REG))
5653 (use (reg:SI R1_REG))
5654 (use (reg:PSI FPSCR_REG))
5655 (clobber (reg:SI PR_REG))]
5656 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5657 "jsr @%0%#"
5658 [(set_attr "type" "call")
5659 (set (attr "fp_mode")
5660 (if_then_else (eq_attr "fpu_single" "yes")
5661 (const_string "single") (const_string "double")))
5662 (set_attr "needs_delay_slot" "yes")])
5663
5664(define_insn "call_compact_rettramp"
5665 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5666 (match_operand 1 "" ""))
5667 (match_operand 2 "immediate_operand" "n")
5668 (use (reg:SI R0_REG))
5669 (use (reg:SI R1_REG))
5670 (use (reg:PSI FPSCR_REG))
5671 (clobber (reg:SI R10_REG))
5672 (clobber (reg:SI PR_REG))]
5673 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5674 "jsr @%0%#"
5675 [(set_attr "type" "call")
5676 (set (attr "fp_mode")
5677 (if_then_else (eq_attr "fpu_single" "yes")
5678 (const_string "single") (const_string "double")))
5679 (set_attr "needs_delay_slot" "yes")])
5680
5681(define_insn "call_media"
5682 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5683 (match_operand 1 "" ""))
5684 (clobber (reg:DI PR_MEDIA_REG))]
5685 "TARGET_SHMEDIA"
2ad65b0e
SC
5686 "blink %0, r18"
5687 [(set_attr "type" "jump_media")])
fa5322fa 5688
bc45ade3
SC
5689(define_insn "call_valuei"
5690 [(set (match_operand 0 "" "=rf")
aa684c94 5691 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
bc45ade3 5692 (match_operand 2 "" "")))
5d00b10a 5693 (use (reg:PSI FPSCR_REG))
4773afa4 5694 (clobber (reg:SI PR_REG))]
fa5322fa 5695 "TARGET_SH1"
bc45ade3 5696 "jsr @%1%#"
ffae286a 5697 [(set_attr "type" "call")
d64264ff
R
5698 (set (attr "fp_mode")
5699 (if_then_else (eq_attr "fpu_single" "yes")
5700 (const_string "single") (const_string "double")))
73774972
EC
5701 (set_attr "needs_delay_slot" "yes")
5702 (set_attr "fp_set" "unknown")])
bc45ade3 5703
1a66cd67
AO
5704(define_insn "call_valuei_pcrel"
5705 [(set (match_operand 0 "" "=rf")
5706 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5707 (match_operand 2 "" "")))
5d00b10a 5708 (use (reg:PSI FPSCR_REG))
2d01e445 5709 (use (reg:SI PIC_REG))
1a66cd67 5710 (use (match_operand 3 "" ""))
4773afa4 5711 (clobber (reg:SI PR_REG))]
eb69f95c 5712 "TARGET_SH2"
1a66cd67
AO
5713 "bsrf %1\\n%O3:%#"
5714 [(set_attr "type" "call")
5715 (set (attr "fp_mode")
5716 (if_then_else (eq_attr "fpu_single" "yes")
5717 (const_string "single") (const_string "double")))
73774972
EC
5718 (set_attr "needs_delay_slot" "yes")
5719 (set_attr "fp_set" "unknown")])
1a66cd67 5720
2d01e445
AO
5721(define_insn_and_split "call_value_pcrel"
5722 [(set (match_operand 0 "" "=rf")
5723 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5724 (match_operand 2 "" "")))
5725 (use (reg:PSI FPSCR_REG))
5726 (use (reg:SI PIC_REG))
5727 (clobber (reg:SI PR_REG))
5728 (clobber (match_scratch:SI 3 "=r"))]
cb51ecd2 5729 "TARGET_SH2"
2d01e445
AO
5730 "#"
5731 "reload_completed"
5732 [(const_int 0)]
5733 "
5734{
8e831557 5735 rtx lab = PATTERN (gen_call_site ());
2d01e445 5736
675ff4c7 5737 if (SYMBOL_REF_LOCAL_P (operands[1]))
2d01e445
AO
5738 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5739 else
5740 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5741 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5742 operands[2], lab));
5743 DONE;
5744}"
5745 [(set_attr "type" "call")
5746 (set (attr "fp_mode")
5747 (if_then_else (eq_attr "fpu_single" "yes")
5748 (const_string "single") (const_string "double")))
73774972
EC
5749 (set_attr "needs_delay_slot" "yes")
5750 (set_attr "fp_set" "unknown")])
2d01e445 5751
fa5322fa
AO
5752(define_insn "call_value_compact"
5753 [(set (match_operand 0 "" "=rf")
5754 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5755 (match_operand 2 "" "")))
5756 (match_operand 3 "immediate_operand" "n")
5757 (use (reg:SI R0_REG))
5758 (use (reg:SI R1_REG))
5759 (use (reg:PSI FPSCR_REG))
5760 (clobber (reg:SI PR_REG))]
5761 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5762 "jsr @%1%#"
5763 [(set_attr "type" "call")
5764 (set (attr "fp_mode")
5765 (if_then_else (eq_attr "fpu_single" "yes")
5766 (const_string "single") (const_string "double")))
5767 (set_attr "needs_delay_slot" "yes")])
5768
5769(define_insn "call_value_compact_rettramp"
5770 [(set (match_operand 0 "" "=rf")
5771 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5772 (match_operand 2 "" "")))
5773 (match_operand 3 "immediate_operand" "n")
5774 (use (reg:SI R0_REG))
5775 (use (reg:SI R1_REG))
5776 (use (reg:PSI FPSCR_REG))
5777 (clobber (reg:SI R10_REG))
5778 (clobber (reg:SI PR_REG))]
5779 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5780 "jsr @%1%#"
5781 [(set_attr "type" "call")
5782 (set (attr "fp_mode")
5783 (if_then_else (eq_attr "fpu_single" "yes")
5784 (const_string "single") (const_string "double")))
5785 (set_attr "needs_delay_slot" "yes")])
5786
5787(define_insn "call_value_media"
5788 [(set (match_operand 0 "" "=rf")
5789 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5790 (match_operand 2 "" "")))
5791 (clobber (reg:DI PR_MEDIA_REG))]
5792 "TARGET_SHMEDIA"
2ad65b0e
SC
5793 "blink %1, r18"
5794 [(set_attr "type" "jump_media")])
fa5322fa 5795
bc45ade3 5796(define_expand "call"
51aea58d
JW
5797 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5798 (match_operand 1 "" ""))
fa5322fa 5799 (match_operand 2 "" "")
5d00b10a 5800 (use (reg:PSI FPSCR_REG))
4773afa4 5801 (clobber (reg:SI PR_REG))])]
bc45ade3 5802 ""
1a66cd67 5803 "
827bdee4 5804{
fa5322fa
AO
5805 if (TARGET_SHMEDIA)
5806 {
5807 operands[0] = XEXP (operands[0], 0);
5808 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5809 {
675ff4c7 5810 if (! SYMBOL_REF_LOCAL_P (operands[0]))
fa5322fa
AO
5811 {
5812 rtx reg = gen_reg_rtx (Pmode);
52702ae1 5813
fa5322fa
AO
5814 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5815 operands[0] = reg;
5816 }
5817 else
5818 {
5819 operands[0] = gen_sym2PIC (operands[0]);
5820 PUT_MODE (operands[0], Pmode);
5821 }
5822 }
5823 if (GET_MODE (operands[0]) == SImode)
5824 {
5825 if (GET_CODE (operands[0]) == REG)
5826 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5827 else if (GET_CODE (operands[0]) == SUBREG)
5828 {
5829 operands[0] = SUBREG_REG (operands[0]);
5830 if (GET_MODE (operands[0]) != DImode)
5831 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5832 }
5833 else
5834 {
5835 operands[0] = shallow_copy_rtx (operands[0]);
5836 PUT_MODE (operands[0], DImode);
5837 }
5838 }
5839 if (! target_reg_operand (operands[0], DImode))
5840 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5841 emit_call_insn (gen_call_media (operands[0], operands[1]));
5842 DONE;
5843 }
5844 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5845 {
5846 rtx cookie_rtx = operands[2];
5847 long cookie = INTVAL (cookie_rtx);
5848 rtx func = XEXP (operands[0], 0);
5849 rtx r0, r1;
5850
5851 if (flag_pic)
5852 {
675ff4c7 5853 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
5854 {
5855 rtx reg = gen_reg_rtx (Pmode);
5856
5857 emit_insn (gen_symGOTPLT2reg (reg, func));
5858 func = reg;
5859 }
5860 else
5861 func = legitimize_pic_address (func, Pmode, 0);
5862 }
5863
5864 r0 = gen_rtx_REG (SImode, R0_REG);
5865 r1 = gen_rtx_REG (SImode, R1_REG);
5866
5867 /* Since such a call function may use all call-clobbered
5868 registers, we force a mode switch earlier, so that we don't
5869 run out of registers when adjusting fpscr for the call. */
5870 emit_insn (gen_force_mode_for_call ());
5871
90534361 5872 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
5873 if (flag_pic)
5874 {
5875 rtx reg = gen_reg_rtx (Pmode);
5876
5877 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5878 operands[0] = reg;
5879 }
5880 operands[0] = force_reg (SImode, operands[0]);
5881
5882 emit_move_insn (r0, func);
5883 emit_move_insn (r1, cookie_rtx);
5884
5885 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5886 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5887 operands[2]));
5888 else
5889 emit_call_insn (gen_call_compact (operands[0], operands[1],
5890 operands[2]));
5891
5892 DONE;
5893 }
5894 else if (TARGET_SHCOMPACT && flag_pic
5895 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 5896 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
5897 {
5898 rtx reg = gen_reg_rtx (Pmode);
5899
5900 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5901 XEXP (operands[0], 0) = reg;
5902 }
cb51ecd2 5903 if (flag_pic && TARGET_SH2
827bdee4
AO
5904 && GET_CODE (operands[0]) == MEM
5905 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5906 {
2d01e445 5907 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
827bdee4
AO
5908 DONE;
5909 }
5910 else
61f71b34 5911 {
827bdee4 5912 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
61f71b34
DD
5913 operands[1] = operands[2];
5914 }
fa5322fa
AO
5915
5916 emit_call_insn (gen_calli (operands[0], operands[1]));
5917 DONE;
5918}")
5919
5920(define_insn "call_pop_compact"
5921 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5922 (match_operand 1 "" ""))
5923 (match_operand 2 "immediate_operand" "n")
5924 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5925 (match_operand 3 "immediate_operand" "n")))
5926 (use (reg:SI R0_REG))
5927 (use (reg:SI R1_REG))
5928 (use (reg:PSI FPSCR_REG))
5929 (clobber (reg:SI PR_REG))]
5930 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5931 "jsr @%0%#"
5932 [(set_attr "type" "call")
5933 (set (attr "fp_mode")
5934 (if_then_else (eq_attr "fpu_single" "yes")
5935 (const_string "single") (const_string "double")))
5936 (set_attr "needs_delay_slot" "yes")])
5937
5938(define_insn "call_pop_compact_rettramp"
5939 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5940 (match_operand 1 "" ""))
5941 (match_operand 2 "immediate_operand" "n")
5942 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5943 (match_operand 3 "immediate_operand" "n")))
5944 (use (reg:SI R0_REG))
5945 (use (reg:SI R1_REG))
5946 (use (reg:PSI FPSCR_REG))
5947 (clobber (reg:SI R10_REG))
5948 (clobber (reg:SI PR_REG))]
5949 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5950 "jsr @%0%#"
5951 [(set_attr "type" "call")
5952 (set (attr "fp_mode")
5953 (if_then_else (eq_attr "fpu_single" "yes")
5954 (const_string "single") (const_string "double")))
5955 (set_attr "needs_delay_slot" "yes")])
5956
5957(define_expand "call_pop"
5958 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5959 (match_operand 1 "" ""))
5960 (match_operand 2 "" "")
5961 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5962 (match_operand 3 "" "")))])]
5963 "TARGET_SHCOMPACT"
5964 "
5965{
5966 if (operands[2] && INTVAL (operands[2]))
5967 {
5968 rtx cookie_rtx = operands[2];
5969 long cookie = INTVAL (cookie_rtx);
5970 rtx func = XEXP (operands[0], 0);
5971 rtx r0, r1;
5972
5973 if (flag_pic)
5974 {
675ff4c7 5975 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
5976 {
5977 rtx reg = gen_reg_rtx (Pmode);
5978
5979 emit_insn (gen_symGOTPLT2reg (reg, func));
5980 func = reg;
5981 }
5982 else
5983 func = legitimize_pic_address (func, Pmode, 0);
5984 }
5985
5986 r0 = gen_rtx_REG (SImode, R0_REG);
5987 r1 = gen_rtx_REG (SImode, R1_REG);
5988
5989 /* Since such a call function may use all call-clobbered
5990 registers, we force a mode switch earlier, so that we don't
5991 run out of registers when adjusting fpscr for the call. */
5992 emit_insn (gen_force_mode_for_call ());
5993
90534361 5994 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
5995 if (flag_pic)
5996 {
5997 rtx reg = gen_reg_rtx (Pmode);
5998
5999 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
6000 operands[0] = reg;
6001 }
6002 operands[0] = force_reg (SImode, operands[0]);
6003
6004 emit_move_insn (r0, func);
6005 emit_move_insn (r1, cookie_rtx);
6006
6007 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6008 emit_call_insn (gen_call_pop_compact_rettramp
6009 (operands[0], operands[1], operands[2], operands[3]));
6010 else
6011 emit_call_insn (gen_call_pop_compact
6012 (operands[0], operands[1], operands[2], operands[3]));
6013
6014 DONE;
6015 }
6016
6017 abort ();
827bdee4 6018}")
bc45ade3
SC
6019
6020(define_expand "call_value"
51aea58d
JW
6021 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6022 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6023 (match_operand 2 "" "")))
fa5322fa 6024 (match_operand 3 "" "")
5d00b10a 6025 (use (reg:PSI FPSCR_REG))
4773afa4 6026 (clobber (reg:SI PR_REG))])]
bc45ade3 6027 ""
1a66cd67 6028 "
827bdee4 6029{
fa5322fa
AO
6030 if (TARGET_SHMEDIA)
6031 {
6032 operands[1] = XEXP (operands[1], 0);
6033 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6034 {
675ff4c7 6035 if (! SYMBOL_REF_LOCAL_P (operands[1]))
fa5322fa
AO
6036 {
6037 rtx reg = gen_reg_rtx (Pmode);
52702ae1 6038
fa5322fa
AO
6039 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6040 operands[1] = reg;
6041 }
6042 else
6043 {
6044 operands[1] = gen_sym2PIC (operands[1]);
6045 PUT_MODE (operands[1], Pmode);
6046 }
6047 }
6048 if (GET_MODE (operands[1]) == SImode)
6049 {
6050 if (GET_CODE (operands[1]) == REG)
6051 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6052 else if (GET_CODE (operands[1]) == SUBREG)
6053 {
6054 operands[1] = SUBREG_REG (operands[1]);
6055 if (GET_MODE (operands[1]) != DImode)
6056 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6057 }
6058 else
6059 {
6060 operands[1] = shallow_copy_rtx (operands[1]);
6061 PUT_MODE (operands[1], DImode);
6062 }
6063 }
6064 if (! target_reg_operand (operands[1], DImode))
6065 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6066 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6067 operands[2]));
6068 DONE;
6069 }
6070 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6071 {
6072 rtx cookie_rtx = operands[3];
6073 long cookie = INTVAL (cookie_rtx);
6074 rtx func = XEXP (operands[1], 0);
6075 rtx r0, r1;
6076
6077 if (flag_pic)
6078 {
675ff4c7 6079 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6080 {
6081 rtx reg = gen_reg_rtx (Pmode);
6082
6083 emit_insn (gen_symGOTPLT2reg (reg, func));
6084 func = reg;
6085 }
6086 else
6087 func = legitimize_pic_address (func, Pmode, 0);
6088 }
6089
6090 r0 = gen_rtx_REG (SImode, R0_REG);
6091 r1 = gen_rtx_REG (SImode, R1_REG);
6092
6093 /* Since such a call function may use all call-clobbered
6094 registers, we force a mode switch earlier, so that we don't
6095 run out of registers when adjusting fpscr for the call. */
6096 emit_insn (gen_force_mode_for_call ());
6097
90534361 6098 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6099 if (flag_pic)
6100 {
6101 rtx reg = gen_reg_rtx (Pmode);
6102
6103 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6104 operands[1] = reg;
6105 }
6106 operands[1] = force_reg (SImode, operands[1]);
6107
6108 emit_move_insn (r0, func);
6109 emit_move_insn (r1, cookie_rtx);
6110
6111 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6112 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6113 operands[1],
6114 operands[2],
6115 operands[3]));
6116 else
6117 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6118 operands[2], operands[3]));
6119
6120 DONE;
6121 }
6122 else if (TARGET_SHCOMPACT && flag_pic
6123 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
675ff4c7 6124 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
fa5322fa
AO
6125 {
6126 rtx reg = gen_reg_rtx (Pmode);
6127
6128 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6129 XEXP (operands[1], 0) = reg;
6130 }
cb51ecd2 6131 if (flag_pic && TARGET_SH2
827bdee4
AO
6132 && GET_CODE (operands[1]) == MEM
6133 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6134 {
2d01e445
AO
6135 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6136 operands[2]));
827bdee4
AO
6137 DONE;
6138 }
6139 else
6140 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
fa5322fa
AO
6141
6142 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6143 DONE;
827bdee4 6144}")
bc45ade3 6145
5db5a888 6146(define_insn "sibcalli"
cb51ecd2 6147 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5db5a888
AO
6148 (match_operand 1 "" ""))
6149 (use (reg:PSI FPSCR_REG))
6150 (return)]
fa5322fa 6151 "TARGET_SH1"
5db5a888
AO
6152 "jmp @%0%#"
6153 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6154 (set (attr "fp_mode")
6155 (if_then_else (eq_attr "fpu_single" "yes")
6156 (const_string "single") (const_string "double")))
5db5a888
AO
6157 (set_attr "type" "jump_ind")])
6158
6159(define_insn "sibcalli_pcrel"
cb51ecd2 6160 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5db5a888
AO
6161 (match_operand 1 "" ""))
6162 (use (match_operand 2 "" ""))
6163 (use (reg:PSI FPSCR_REG))
6164 (return)]
6165 "TARGET_SH2"
6166 "braf %0\\n%O2:%#"
6167 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6168 (set (attr "fp_mode")
6169 (if_then_else (eq_attr "fpu_single" "yes")
6170 (const_string "single") (const_string "double")))
5db5a888
AO
6171 (set_attr "type" "jump_ind")])
6172
6173(define_insn_and_split "sibcall_pcrel"
6174 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6175 (match_operand 1 "" ""))
6176 (use (reg:PSI FPSCR_REG))
cb51ecd2 6177 (clobber (match_scratch:SI 2 "=k"))
5db5a888 6178 (return)]
cb51ecd2 6179 "TARGET_SH2"
5db5a888
AO
6180 "#"
6181 "reload_completed"
6182 [(const_int 0)]
6183 "
6184{
8e831557 6185 rtx lab = PATTERN (gen_call_site ());
5db5a888
AO
6186 rtx call_insn;
6187
fa5322fa
AO
6188 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6189 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6190 lab));
6191 SIBLING_CALL_P (call_insn) = 1;
6192 DONE;
6193}"
6194 [(set_attr "needs_delay_slot" "yes")
6195 (set (attr "fp_mode")
6196 (if_then_else (eq_attr "fpu_single" "yes")
6197 (const_string "single") (const_string "double")))
6198 (set_attr "type" "jump_ind")])
6199
6200(define_insn "sibcall_compact"
6201 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6202 (match_operand 1 "" ""))
6203 (return)
e69d1422 6204 (use (match_operand:SI 2 "register_operand" "z,x"))
fa5322fa
AO
6205 (use (reg:SI R1_REG))
6206 (use (reg:PSI FPSCR_REG))
6207 ;; We want to make sure the `x' above will only match MACH_REG
6208 ;; because sibcall_epilogue may clobber MACL_REG.
6209 (clobber (reg:SI MACL_REG))]
6210 "TARGET_SHCOMPACT"
6211 "@
6212 jmp @%0%#
6213 jmp @%0\\n sts %2, r0"
6214 [(set_attr "needs_delay_slot" "yes,no")
6215 (set_attr "length" "2,4")
6216 (set (attr "fp_mode") (const_string "single"))
6217 (set_attr "type" "jump_ind")])
6218
6219(define_insn "sibcall_media"
6220 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6221 (match_operand 1 "" ""))
7d73a2ba 6222 (use (reg:SI PR_MEDIA_REG))
fa5322fa
AO
6223 (return)]
6224 "TARGET_SHMEDIA"
2ad65b0e
SC
6225 "blink %0, r63"
6226 [(set_attr "type" "jump_media")])
fa5322fa
AO
6227
6228(define_expand "sibcall"
6229 [(parallel
6230 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6231 (match_operand 1 "" ""))
6232 (match_operand 2 "" "")
6233 (use (reg:PSI FPSCR_REG))
6234 (return)])]
6235 ""
6236 "
6237{
6238 if (TARGET_SHMEDIA)
6239 {
6240 operands[0] = XEXP (operands[0], 0);
6241 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6242 {
675ff4c7 6243 if (! SYMBOL_REF_LOCAL_P (operands[0]))
fa5322fa
AO
6244 {
6245 rtx reg = gen_reg_rtx (Pmode);
52702ae1 6246
fa5322fa
AO
6247 /* We must not use GOTPLT for sibcalls, because PIC_REG
6248 must be restored before the PLT code gets to run. */
6249 emit_insn (gen_symGOT2reg (reg, operands[0]));
6250 operands[0] = reg;
6251 }
6252 else
6253 {
6254 operands[0] = gen_sym2PIC (operands[0]);
6255 PUT_MODE (operands[0], Pmode);
6256 }
6257 }
6258 if (GET_MODE (operands[0]) == SImode)
6259 {
6260 if (GET_CODE (operands[0]) == REG)
6261 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6262 else if (GET_CODE (operands[0]) == SUBREG)
6263 {
6264 operands[0] = SUBREG_REG (operands[0]);
6265 if (GET_MODE (operands[0]) != DImode)
6266 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6267 }
6268 else
6269 {
6270 operands[0] = shallow_copy_rtx (operands[0]);
6271 PUT_MODE (operands[0], DImode);
6272 }
6273 }
6274 if (! target_reg_operand (operands[0], DImode))
6275 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6276 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6277 DONE;
6278 }
6279 else if (TARGET_SHCOMPACT && operands[2]
6280 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6281 {
6282 rtx cookie_rtx = operands[2];
6283 long cookie = INTVAL (cookie_rtx);
6284 rtx func = XEXP (operands[0], 0);
6285 rtx mach, r1;
6286
6287 if (flag_pic)
6288 {
675ff4c7 6289 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6290 {
6291 rtx reg = gen_reg_rtx (Pmode);
6292
6293 emit_insn (gen_symGOT2reg (reg, func));
6294 func = reg;
6295 }
6296 else
6297 func = legitimize_pic_address (func, Pmode, 0);
6298 }
5db5a888 6299
fa5322fa
AO
6300 /* FIXME: if we could tell whether all argument registers are
6301 already taken, we could decide whether to force the use of
6302 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6303 simple way to tell. We could use the CALL_COOKIE, but we
6304 can't currently tell a register used for regular argument
6305 passing from one that is unused. If we leave it up to reload
6306 to decide which register to use, it seems to always choose
6307 R0_REG, which leaves no available registers in SIBCALL_REGS
6308 to hold the address of the trampoline. */
6309 mach = gen_rtx_REG (SImode, MACH_REG);
6310 r1 = gen_rtx_REG (SImode, R1_REG);
6311
6312 /* Since such a call function may use all call-clobbered
6313 registers, we force a mode switch earlier, so that we don't
6314 run out of registers when adjusting fpscr for the call. */
6315 emit_insn (gen_force_mode_for_call ());
6316
90534361 6317 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6318 if (flag_pic)
6319 {
6320 rtx reg = gen_reg_rtx (Pmode);
6321
6322 emit_insn (gen_symGOT2reg (reg, operands[0]));
6323 operands[0] = reg;
6324 }
6325 operands[0] = force_reg (SImode, operands[0]);
6326
6327 /* We don't need a return trampoline, since the callee will
6328 return directly to the upper caller. */
6329 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6330 {
6331 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6332 cookie_rtx = GEN_INT (cookie);
6333 }
6334
6335 emit_move_insn (mach, func);
6336 emit_move_insn (r1, cookie_rtx);
6337
6338 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6339 DONE;
6340 }
6341 else if (TARGET_SHCOMPACT && flag_pic
6342 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 6343 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
6344 {
6345 rtx reg = gen_reg_rtx (Pmode);
6346
6347 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6348 XEXP (operands[0], 0) = reg;
6349 }
cb51ecd2 6350 if (flag_pic && TARGET_SH2
5db5a888
AO
6351 && GET_CODE (operands[0]) == MEM
6352 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6353 /* The PLT needs the PIC register, but the epilogue would have
6354 to restore it, so we can only use PC-relative PIC calls for
6355 static functions. */
675ff4c7 6356 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5db5a888
AO
6357 {
6358 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6359 DONE;
6360 }
6361 else
6362 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
fa5322fa
AO
6363
6364 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6365 DONE;
5db5a888
AO
6366}")
6367
6368(define_expand "sibcall_value"
6369 [(set (match_operand 0 "" "")
6370 (call (match_operand 1 "" "")
fa5322fa
AO
6371 (match_operand 2 "" "")))
6372 (match_operand 3 "" "")]
5db5a888
AO
6373 ""
6374 "
6375{
fa5322fa 6376 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5db5a888
AO
6377 DONE;
6378}")
6379
fa5322fa
AO
6380(define_insn "call_value_pop_compact"
6381 [(set (match_operand 0 "" "=rf")
6382 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6383 (match_operand 2 "" "")))
6384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6385 (match_operand 4 "immediate_operand" "n")))
6386 (match_operand 3 "immediate_operand" "n")
6387 (use (reg:SI R0_REG))
6388 (use (reg:SI R1_REG))
6389 (use (reg:PSI FPSCR_REG))
6390 (clobber (reg:SI PR_REG))]
6391 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6392 "jsr @%1%#"
6393 [(set_attr "type" "call")
6394 (set (attr "fp_mode")
6395 (if_then_else (eq_attr "fpu_single" "yes")
6396 (const_string "single") (const_string "double")))
6397 (set_attr "needs_delay_slot" "yes")])
6398
6399(define_insn "call_value_pop_compact_rettramp"
6400 [(set (match_operand 0 "" "=rf")
6401 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6402 (match_operand 2 "" "")))
6403 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6404 (match_operand 4 "immediate_operand" "n")))
6405 (match_operand 3 "immediate_operand" "n")
6406 (use (reg:SI R0_REG))
6407 (use (reg:SI R1_REG))
6408 (use (reg:PSI FPSCR_REG))
6409 (clobber (reg:SI R10_REG))
6410 (clobber (reg:SI PR_REG))]
6411 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6412 "jsr @%1%#"
6413 [(set_attr "type" "call")
6414 (set (attr "fp_mode")
6415 (if_then_else (eq_attr "fpu_single" "yes")
6416 (const_string "single") (const_string "double")))
6417 (set_attr "needs_delay_slot" "yes")])
6418
6419(define_expand "call_value_pop"
6420 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6421 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6422 (match_operand 2 "" "")))
6423 (match_operand 3 "" "")
6424 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6425 (match_operand 4 "" "")))])]
6426 "TARGET_SHCOMPACT"
6427 "
6428{
6429 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6430 {
6431 rtx cookie_rtx = operands[3];
6432 long cookie = INTVAL (cookie_rtx);
6433 rtx func = XEXP (operands[1], 0);
6434 rtx r0, r1;
6435
6436 if (flag_pic)
6437 {
675ff4c7 6438 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6439 {
6440 rtx reg = gen_reg_rtx (Pmode);
6441
6442 emit_insn (gen_symGOTPLT2reg (reg, func));
6443 func = reg;
6444 }
6445 else
6446 func = legitimize_pic_address (func, Pmode, 0);
6447 }
6448
6449 r0 = gen_rtx_REG (SImode, R0_REG);
6450 r1 = gen_rtx_REG (SImode, R1_REG);
6451
6452 /* Since such a call function may use all call-clobbered
6453 registers, we force a mode switch earlier, so that we don't
6454 run out of registers when adjusting fpscr for the call. */
6455 emit_insn (gen_force_mode_for_call ());
6456
90534361 6457 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6458 if (flag_pic)
6459 {
6460 rtx reg = gen_reg_rtx (Pmode);
6461
6462 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6463 operands[1] = reg;
6464 }
6465 operands[1] = force_reg (SImode, operands[1]);
6466
6467 emit_move_insn (r0, func);
6468 emit_move_insn (r1, cookie_rtx);
6469
6470 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6471 emit_call_insn (gen_call_value_pop_compact_rettramp
6472 (operands[0], operands[1], operands[2],
6473 operands[3], operands[4]));
6474 else
6475 emit_call_insn (gen_call_value_pop_compact
6476 (operands[0], operands[1], operands[2],
6477 operands[3], operands[4]));
6478
6479 DONE;
6480 }
6481
6482 abort ();
6483}")
6484
5db5a888
AO
6485(define_expand "sibcall_epilogue"
6486 [(return)]
6487 ""
6488 "
6489{
726d4cb7 6490 sh_expand_epilogue (1);
fa5322fa
AO
6491 if (TARGET_SHCOMPACT)
6492 {
6493 rtx insn, set;
6494
6495 /* If epilogue clobbers r0, preserve it in macl. */
6496 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6497 if ((set = single_set (insn))
6498 && GET_CODE (SET_DEST (set)) == REG
6499 && REGNO (SET_DEST (set)) == R0_REG)
6500 {
6501 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6502 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6503 rtx i;
6504
6505 /* We can't tell at this point whether the sibcall is a
6506 sibcall_compact and, if it is, whether it uses r0 or
6507 mach as operand 2, so let the instructions that
6508 preserve r0 be optimized away if r0 turns out to be
6509 dead. */
6510 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6511 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6512 REG_NOTES (i));
6513 i = emit_move_insn (r0, tmp);
6514 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6515 REG_NOTES (i));
6516 break;
6517 }
6518 }
5db5a888
AO
6519 DONE;
6520}")
6521
fa5322fa 6522(define_insn "indirect_jump_compact"
bc45ade3 6523 [(set (pc)
aa684c94 6524 (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 6525 "TARGET_SH1"
b9654711 6526 "jmp @%0%#"
1245df60
R
6527 [(set_attr "needs_delay_slot" "yes")
6528 (set_attr "type" "jump_ind")])
a1a0806a 6529
fa5322fa
AO
6530(define_expand "indirect_jump"
6531 [(set (pc)
6532 (match_operand 0 "register_operand" ""))]
6533 ""
6534 "
6535{
6536 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6537 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6538}")
6539
1245df60 6540;; The use of operand 1 / 2 helps us distinguish case table jumps
f1ffca1c
JW
6541;; which can be present in structured code from indirect jumps which can not
6542;; be present in structured code. This allows -fprofile-arcs to work.
6543
1245df60
R
6544;; For SH1 processors.
6545(define_insn "casesi_jump_1"
f1ffca1c 6546 [(set (pc)
1245df60 6547 (match_operand:SI 0 "register_operand" "r"))
f1ffca1c 6548 (use (label_ref (match_operand 1 "" "")))]
fa5322fa 6549 "TARGET_SH1"
1245df60
R
6550 "jmp @%0%#"
6551 [(set_attr "needs_delay_slot" "yes")
6552 (set_attr "type" "jump_ind")])
6553
6554;; For all later processors.
6555(define_insn "casesi_jump_2"
6556 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
eb3881bf 6557 (label_ref (match_operand 1 "" ""))))
1245df60 6558 (use (label_ref (match_operand 2 "" "")))]
e6dfd05f
AO
6559 "TARGET_SH2
6560 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
1245df60
R
6561 "braf %0%#"
6562 [(set_attr "needs_delay_slot" "yes")
6563 (set_attr "type" "jump_ind")])
6564
fa5322fa
AO
6565(define_insn "casesi_jump_media"
6566 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6567 (use (label_ref (match_operand 1 "" "")))]
6568 "TARGET_SHMEDIA"
2ad65b0e
SC
6569 "blink %0, r63"
6570 [(set_attr "type" "jump_media")])
52702ae1 6571
a1a0806a
JW
6572;; Call subroutine returning any type.
6573;; ??? This probably doesn't work.
6574
6575(define_expand "untyped_call"
6576 [(parallel [(call (match_operand 0 "" "")
6577 (const_int 0))
6578 (match_operand 1 "" "")
6579 (match_operand 2 "" "")])]
3a8699c7 6580 "TARGET_SH2E || TARGET_SHMEDIA"
a1a0806a
JW
6581 "
6582{
6583 int i;
6584
fa5322fa 6585 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
a1a0806a
JW
6586
6587 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6588 {
6589 rtx set = XVECEXP (operands[2], 0, i);
6590 emit_move_insn (SET_DEST (set), SET_SRC (set));
6591 }
6592
6593 /* The optimizer does not know that the call sets the function value
6594 registers we stored in the result block. We avoid problems by
6595 claiming that all hard registers are used and clobbered at this
6596 point. */
6597 emit_insn (gen_blockage ());
6598
6599 DONE;
6600}")
bc45ade3
SC
6601\f
6602;; ------------------------------------------------------------------------
6603;; Misc insns
6604;; ------------------------------------------------------------------------
6605
51bd623f 6606(define_insn "dect"
4773afa4 6607 [(set (reg:SI T_REG)
aff48e32
JR
6608 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6609 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
51bd623f 6610 "TARGET_SH2"
1245df60
R
6611 "dt %0"
6612 [(set_attr "type" "arith")])
bc45ade3
SC
6613
6614(define_insn "nop"
6615 [(const_int 0)]
6616 ""
51bd623f 6617 "nop")
0d7e008e 6618
1245df60
R
6619;; Load address of a label. This is only generated by the casesi expand,
6620;; and by machine_dependent_reorg (fixing up fp moves).
6621;; This must use unspec, because this only works for labels that are
6622;; within range,
0d7e008e
SC
6623
6624(define_insn "mova"
4773afa4 6625 [(set (reg:SI R0_REG)
e69d1422 6626 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
fa5322fa 6627 "TARGET_SH1"
0d7e008e 6628 "mova %O0,r0"
1245df60
R
6629 [(set_attr "in_delay_slot" "no")
6630 (set_attr "type" "arith")])
0d7e008e 6631
18dbd950 6632;; machine_dependent_reorg will make this a `mova'.
43c05634
AO
6633(define_insn "mova_const"
6634 [(set (reg:SI R0_REG)
e69d1422 6635 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
fa5322fa 6636 "TARGET_SH1"
43c05634
AO
6637 "#"
6638 [(set_attr "in_delay_slot" "no")
6639 (set_attr "type" "arith")])
6640
1a66cd67 6641(define_expand "GOTaddr2picreg"
4773afa4 6642 [(set (reg:SI R0_REG)
e69d1422
R
6643 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6644 UNSPEC_MOVA))
615cd49b 6645 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
4773afa4 6646 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
1a66cd67
AO
6647 "" "
6648{
fa5322fa 6649 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
1a66cd67 6650 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
fa5322fa
AO
6651
6652 if (TARGET_SH5)
6653 operands[1] = gen_datalabel_ref (operands[1]);
6654
6655 if (TARGET_SHMEDIA)
6656 {
6657 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6658 rtx dipic = operands[0];
8e831557 6659 rtx lab = PATTERN (gen_call_site ());
fa5322fa
AO
6660 rtx insn, equiv;
6661
6662 equiv = operands[1];
6663 operands[1] = gen_rtx_MINUS (DImode,
6664 operands[1],
6665 gen_rtx_CONST
6666 (DImode,
6667 gen_rtx_MINUS (DImode,
6668 gen_rtx_CONST (DImode,
6669 lab),
6670 pc_rtx)));
6671 operands[1] = gen_sym2PIC (operands[1]);
6672 PUT_MODE (operands[1], DImode);
6673
6674 if (GET_MODE (dipic) != DImode)
6675 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6676
6677 if (TARGET_SHMEDIA64)
6678 emit_insn (gen_movdi_const (dipic, operands[1]));
6679 else
6680 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6681
6682 emit_insn (gen_ptrel (tr, dipic, lab));
6683
6684 if (GET_MODE (operands[0]) != GET_MODE (tr))
90534361 6685 tr = gen_lowpart (GET_MODE (operands[0]), tr);
fa5322fa
AO
6686
6687 insn = emit_move_insn (operands[0], tr);
52702ae1 6688
fa5322fa
AO
6689 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6690 REG_NOTES (insn));
6691
6692 DONE;
6693 }
1a66cd67
AO
6694}
6695")
6696
fa5322fa 6697(define_insn "*ptb"
b6d33983 6698 [(set (match_operand:DI 0 "target_reg_operand" "=b")
735cb76e 6699 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
fa5322fa
AO
6700 UNSPEC_DATALABEL)))]
6701 "TARGET_SHMEDIA && flag_pic
735cb76e 6702 && EXTRA_CONSTRAINT_Csy (operands[1])"
fa5322fa 6703 "ptb/u datalabel %1, %0"
2ad65b0e 6704 [(set_attr "type" "pt_media")
fa5322fa
AO
6705 (set_attr "length" "*")])
6706
6707(define_insn "ptrel"
e69d1422
R
6708 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6709 (plus:DI (match_operand:DI 1 "register_operand" "r")
fa5322fa
AO
6710 (pc)))
6711 (match_operand:DI 2 "" "")]
6712 "TARGET_SHMEDIA"
6713 "%O2: ptrel/u %1, %0"
2ad65b0e 6714 [(set_attr "type" "ptabs_media")])
fa5322fa 6715
001643af
KK
6716(define_expand "builtin_setjmp_receiver"
6717 [(match_operand 0 "" "")]
6718 "flag_pic"
6719 "
6720{
6721 emit_insn (gen_GOTaddr2picreg ());
6722 DONE;
6723}")
6724
2d01e445
AO
6725(define_expand "call_site"
6726 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
fa5322fa 6727 "TARGET_SH1"
2d01e445
AO
6728 "
6729{
6730 static HOST_WIDE_INT i = 0;
6731 operands[0] = GEN_INT (i);
6732 i++;
6733}")
6734
1a66cd67
AO
6735(define_expand "sym_label2reg"
6736 [(set (match_operand:SI 0 "" "")
a4f76ef9
AO
6737 (const:SI (minus:SI
6738 (const:SI
6739 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6740 (const:SI
6741 (plus:SI
6742 (match_operand:SI 2 "" "")
6743 (const_int 2))))))]
fa5322fa 6744 "TARGET_SH1" "")
1a66cd67 6745
e1d71275
AO
6746(define_expand "symGOT_load"
6747 [(set (match_dup 2) (match_operand 1 "" ""))
6748 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6749 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6750 ""
6751 "
6752{
6753 rtx insn;
6754
6755 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6756 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6757
fa5322fa
AO
6758 if (TARGET_SHMEDIA)
6759 {
6760 rtx reg = operands[2];
52702ae1 6761
fa5322fa
AO
6762 if (GET_MODE (reg) != DImode)
6763 reg = gen_rtx_SUBREG (DImode, reg, 0);
52702ae1 6764
fa5322fa
AO
6765 if (flag_pic > 1)
6766 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6767 else
6768 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6769 }
6770 else
6771 emit_move_insn (operands[2], operands[1]);
e1d71275
AO
6772
6773 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6774 operands[2],
6775 gen_rtx_REG (Pmode, PIC_REG)));
6776
6777 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6778
6779 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6780 0), 0, 0),
6781 REG_NOTES (insn));
52702ae1 6782
e1d71275
AO
6783 DONE;
6784}")
6785
6786(define_expand "sym2GOT"
6787 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6788 ""
6789 "")
6790
1a66cd67 6791(define_expand "symGOT2reg"
e1d71275 6792 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6793 ""
6794 "
6795{
e1d71275
AO
6796 rtx gotsym, insn;
6797
6798 gotsym = gen_sym2GOT (operands[1]);
6799 PUT_MODE (gotsym, Pmode);
6800 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6801
6802 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6803
6804 DONE;
1a66cd67
AO
6805}")
6806
fa5322fa
AO
6807(define_expand "sym2GOTPLT"
6808 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6809 ""
6810 "")
6811
6812(define_expand "symGOTPLT2reg"
6813 [(match_operand 0 "" "") (match_operand 1 "" "")]
6814 ""
6815 "
6816{
6817 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6818 DONE;
6819}")
6820
e1d71275
AO
6821(define_expand "sym2GOTOFF"
6822 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6823 ""
6824 "")
6825
1a66cd67 6826(define_expand "symGOTOFF2reg"
e1d71275 6827 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6828 ""
6829 "
6830{
e1d71275
AO
6831 rtx gotoffsym, insn;
6832 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6833
6834 gotoffsym = gen_sym2GOTOFF (operands[1]);
6835 PUT_MODE (gotoffsym, Pmode);
6836 emit_move_insn (t, gotoffsym);
6837 insn = emit_move_insn (operands[0],
6838 gen_rtx_PLUS (Pmode, t,
6839 gen_rtx_REG (Pmode, PIC_REG)));
6840
6841 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6842 REG_NOTES (insn));
6843
6844 DONE;
1a66cd67
AO
6845}")
6846
6847(define_expand "symPLT_label2reg"
6848 [(set (match_operand:SI 0 "" "")
e1d71275
AO
6849 (const:SI (minus:SI
6850 (const:SI
6851 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6852 (const:SI
6853 (minus:SI
6854 (const:SI (plus:SI
6855 (match_operand:SI 2 "" "")
6856 (const_int 2)))
6857 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6915629f
AO
6858 ;; Even though the PIC register is not really used by the call
6859 ;; sequence in which this is expanded, the PLT code assumes the PIC
6860 ;; register is set, so we must not skip its initialization. Since
6861 ;; we only use this expand as part of calling sequences, and never
6862 ;; to take the address of a function, this is the best point to
6863 ;; insert the (use). Using the PLT to take the address of a
6864 ;; function would be wrong, not only because the PLT entry could
6865 ;; then be called from a function that doesn't initialize the PIC
6866 ;; register to the proper GOT, but also because pointers to the
6867 ;; same function might not compare equal, should they be set by
6868 ;; different shared libraries.
6869 (use (reg:SI PIC_REG))]
fa5322fa
AO
6870 "TARGET_SH1"
6871 "")
6872
6873(define_expand "sym2PIC"
6874 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6915629f
AO
6875 ""
6876 "")
1a66cd67 6877
463f02cd
KK
6878;; TLS code generation.
6879;; ??? this should be a define_insn_and_split
6880;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6881;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6882;; for details.
6883
6884(define_insn "tls_global_dynamic"
6885 [(set (match_operand:SI 0 "register_operand" "=&z")
13ecc9e0
KK
6886 (call (unspec:SI [(match_operand:SI 1 "" "")]
6887 UNSPEC_TLSGD)
6888 (const_int 0)))
463f02cd
KK
6889 (use (reg:PSI FPSCR_REG))
6890 (use (reg:SI PIC_REG))
6891 (clobber (reg:SI PR_REG))
6892 (clobber (scratch:SI))]
6893 "TARGET_SH1"
6894 "*
6895{
6896 return \"\\
6897mov.l\\t1f,r4\\n\\
6898\\tmova\\t2f,r0\\n\\
6899\\tmov.l\\t2f,r1\\n\\
6900\\tadd\\tr0,r1\\n\\
6901\\tjsr\\t@r1\\n\\
6902\\tadd\\tr12,r4\\n\\
6903\\tbra\\t3f\\n\\
6904\\tnop\\n\\
6905\\t.align\\t2\\n\\
69061:\\t.long\\t%a1@TLSGD\\n\\
69072:\\t.long\\t__tls_get_addr@PLT\\n\\
69083:\";
6909}"
6910 [(set_attr "type" "tls_load")
6911 (set_attr "length" "26")])
6912
6913(define_insn "tls_local_dynamic"
6914 [(set (match_operand:SI 0 "register_operand" "=&z")
13ecc9e0
KK
6915 (call (unspec:SI [(match_operand:SI 1 "" "")]
6916 UNSPEC_TLSLDM)
6917 (const_int 0)))
463f02cd
KK
6918 (use (reg:PSI FPSCR_REG))
6919 (use (reg:SI PIC_REG))
6920 (clobber (reg:SI PR_REG))
6921 (clobber (scratch:SI))]
6922 "TARGET_SH1"
6923 "*
6924{
6925 return \"\\
6926mov.l\\t1f,r4\\n\\
6927\\tmova\\t2f,r0\\n\\
6928\\tmov.l\\t2f,r1\\n\\
6929\\tadd\\tr0,r1\\n\\
6930\\tjsr\\t@r1\\n\\
6931\\tadd\\tr12,r4\\n\\
6932\\tbra\\t3f\\n\\
6933\\tnop\\n\\
6934\\t.align\\t2\\n\\
69351:\\t.long\\t%a1@TLSLDM\\n\\
69362:\\t.long\\t__tls_get_addr@PLT\\n\\
69373:\";
6938}"
6939 [(set_attr "type" "tls_load")
6940 (set_attr "length" "26")])
6941
6942(define_expand "sym2DTPOFF"
6943 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6944 ""
6945 "")
6946
6947(define_expand "symDTPOFF2reg"
6948 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6949 ""
6950 "
6951{
6952 rtx dtpoffsym, insn;
6953 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6954
6955 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6956 PUT_MODE (dtpoffsym, Pmode);
6957 emit_move_insn (t, dtpoffsym);
6958 insn = emit_move_insn (operands[0],
6959 gen_rtx_PLUS (Pmode, t, operands[2]));
6960 DONE;
6961}")
6962
6963(define_expand "sym2GOTTPOFF"
6964 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6965 ""
6966 "")
6967
6968(define_insn "tls_initial_exec"
6969 [(set (match_operand:SI 0 "register_operand" "=&r")
6970 (unspec:SI [(match_operand:SI 1 "" "")]
6971 UNSPEC_TLSIE))
6972 (use (reg:SI GBR_REG))
6973 (use (reg:SI PIC_REG))
6974 (clobber (reg:SI R0_REG))]
6975 ""
6976 "*
6977{
6978 return \"\\
6979mov.l\\t1f,r0\\n\\
6980\\tstc\\tgbr,%0\\n\\
6981\\tmov.l\\t@(r0,r12),r0\\n\\
6982\\tbra\\t2f\\n\\
6983\\tadd\\tr0,%0\\n\\
6984\\t.align\\t2\\n\\
69851:\\t.long\\t%a1\\n\\
69862:\";
6987}"
6988 [(set_attr "type" "tls_load")
6989 (set_attr "length" "16")])
6990
6991(define_expand "sym2TPOFF"
6992 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6993 ""
6994 "")
6995
6996(define_expand "symTPOFF2reg"
6997 [(match_operand 0 "" "") (match_operand 1 "" "")]
6998 ""
6999 "
7000{
7001 rtx tpoffsym, insn;
7002
7003 tpoffsym = gen_sym2TPOFF (operands[1]);
7004 PUT_MODE (tpoffsym, Pmode);
7005 insn = emit_move_insn (operands[0], tpoffsym);
7006 DONE;
7007}")
7008
7009(define_insn "load_gbr"
7010 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
7011 (use (reg:SI GBR_REG))]
7012 ""
7013 "stc gbr,%0"
7014 [(set_attr "type" "tls_load")])
7015
0d7e008e
SC
7016;; case instruction for switch statements.
7017
7018;; Operand 0 is index
7019;; operand 1 is the minimum bound
7020;; operand 2 is the maximum bound - minimum bound + 1
7021;; operand 3 is CODE_LABEL for the table;
7022;; operand 4 is the CODE_LABEL to go to if index out of range.
7023
7024(define_expand "casesi"
1245df60
R
7025 [(match_operand:SI 0 "arith_reg_operand" "")
7026 (match_operand:SI 1 "arith_reg_operand" "")
7027 (match_operand:SI 2 "arith_reg_operand" "")
7028 (match_operand 3 "" "") (match_operand 4 "" "")]
7029 ""
7030 "
7031{
7032 rtx reg = gen_reg_rtx (SImode);
7033 rtx reg2 = gen_reg_rtx (SImode);
fa5322fa
AO
7034 if (TARGET_SHMEDIA)
7035 {
7036 rtx reg = gen_reg_rtx (DImode);
7037 rtx reg2 = gen_reg_rtx (DImode);
7038 rtx reg3 = gen_reg_rtx (DImode);
7039 rtx reg4 = gen_reg_rtx (DImode);
7040 rtx reg5 = gen_reg_rtx (DImode);
7041
7042 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7043 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7044 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7045
7046 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7047 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7048 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7049 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7050 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7051 (DImode, operands[3])));
7052 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7053 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7054 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7055 emit_barrier ();
7056 DONE;
7057 }
1245df60
R
7058 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7059 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7060 /* If optimizing, casesi_worker depends on the mode of the instruction
7061 before label it 'uses' - operands[3]. */
7062 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7063 reg));
7064 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7065 if (TARGET_SH2)
eb3881bf 7066 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
1245df60 7067 else
eb3881bf 7068 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
1245df60
R
7069 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7070 operands[3], but to lab. We will fix this up in
7071 machine_dependent_reorg. */
7072 emit_barrier ();
7073 DONE;
7074}")
7075
7076(define_expand "casesi_0"
7077 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7078 (set (match_dup 4) (minus:SI (match_dup 4)
0d7e008e 7079 (match_operand:SI 1 "arith_operand" "")))
4773afa4 7080 (set (reg:SI T_REG)
1245df60 7081 (gtu:SI (match_dup 4)
22e1ebf1 7082 (match_operand:SI 2 "arith_reg_operand" "")))
0d7e008e 7083 (set (pc)
4773afa4 7084 (if_then_else (ne (reg:SI T_REG)
7c225e88 7085 (const_int 0))
1245df60
R
7086 (label_ref (match_operand 3 "" ""))
7087 (pc)))]
fa5322fa 7088 "TARGET_SH1"
1245df60 7089 "")
0d7e008e 7090
1245df60
R
7091;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7092;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7093;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7094
7095(define_insn "casesi_worker_0"
7096 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422 7097 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
4773afa4 7098 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7099 (clobber (match_scratch:SI 3 "=X,1"))
7100 (clobber (match_scratch:SI 4 "=&z,z"))]
fa5322fa 7101 "TARGET_SH1"
1245df60
R
7102 "#")
7103
7104(define_split
7105 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
7106 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7107 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7108 (clobber (match_scratch:SI 3 ""))
7109 (clobber (match_scratch:SI 4 ""))]
fa5322fa 7110 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
e69d1422 7111 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 7112 (parallel [(set (match_dup 0)
e69d1422
R
7113 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7114 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 7115 (clobber (match_dup 3))])
4773afa4 7116 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
b6d33983 7117 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
7118
7119(define_split
7120 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
7121 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7122 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7123 (clobber (match_scratch:SI 3 ""))
7124 (clobber (match_scratch:SI 4 ""))]
7125 "TARGET_SH2 && reload_completed"
e69d1422 7126 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 7127 (parallel [(set (match_dup 0)
615cd49b 7128 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
e69d1422 7129 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 7130 (clobber (match_dup 3))])]
b6d33983 7131 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60 7132
078c8b08 7133(define_insn "casesi_worker_1"
1245df60 7134 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422
R
7135 (unspec:SI [(reg:SI R0_REG)
7136 (match_operand:SI 1 "register_operand" "0,r")
7137 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60 7138 (clobber (match_scratch:SI 3 "=X,1"))]
fa5322fa 7139 "TARGET_SH1"
4fdd1f85 7140 "*
ffae286a 7141{
33f7f353
JR
7142 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7143
7144 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7145 abort ();
7146
7147 switch (GET_MODE (diff_vec))
1245df60
R
7148 {
7149 case SImode:
7150 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7151 case HImode:
7152 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7153 case QImode:
33f7f353 7154 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
1245df60 7155 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
33f7f353 7156 return \"mov.b @(r0,%1),%0\";
1245df60
R
7157 default:
7158 abort ();
7159 }
ffae286a 7160}"
51bd623f 7161 [(set_attr "length" "4")])
0d7e008e 7162
078c8b08
R
7163(define_insn "casesi_worker_2"
7164 [(set (match_operand:SI 0 "register_operand" "=r,r")
7165 (unspec:SI [(reg:SI R0_REG)
7166 (match_operand:SI 1 "register_operand" "0,r")
7167 (label_ref (match_operand 2 "" ""))
7168 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7169 (clobber (match_operand:SI 4 "" "=X,1"))]
7170 "TARGET_SH2 && reload_completed && flag_pic"
7171 "*
7172{
7173 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7174 char *load;
7175
7176 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7177 abort ();
7178
7179 switch (GET_MODE (diff_vec))
7180 {
7181 case SImode:
7182 output_asm_insn (\"shll2 %1\", operands);
7183 load = \"mov.l @(r0,%1),%0\"; break;
7184 case HImode:
7185 output_asm_insn (\"add %1,%1\", operands);
7186 load = \"mov.w @(r0,%1),%0\"; break;
7187 case QImode:
7188 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7189 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7190 else
7191 load = \"mov.b @(r0,%1),%0\";
7192 break;
7193 default:
7194 abort ();
7195 }
7196 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7197 return load;
7198}"
7199 [(set_attr "length" "8")])
7200
fa5322fa 7201(define_insn "casesi_shift_media"
51214775
R
7202 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7203 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7204 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7205 UNSPEC_CASESI)))]
fa5322fa
AO
7206 "TARGET_SHMEDIA"
7207 "*
7208{
7209 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7210
7211 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7212 abort ();
7213
7214 switch (GET_MODE (diff_vec))
7215 {
7216 case SImode:
7217 return \"shlli %1, 2, %0\";
7218 case HImode:
7219 return \"shlli %1, 1, %0\";
7220 case QImode:
7221 if (rtx_equal_p (operands[0], operands[1]))
7222 return \"\";
7223 return \"add %1, r63, %0\";
7224 default:
7225 abort ();
7226 }
2ad65b0e
SC
7227}"
7228 [(set_attr "type" "arith_media")])
fa5322fa
AO
7229
7230(define_insn "casesi_load_media"
7231 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7232 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7233 (match_operand 2 "arith_reg_operand" "r")
7234 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7235 "TARGET_SHMEDIA"
7236 "*
7237{
7238 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7239
7240 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7241 abort ();
7242
7243 switch (GET_MODE (diff_vec))
7244 {
7245 case SImode:
7246 return \"ldx.l %1, %2, %0\";
7247 case HImode:
7248#if 0
7249 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7250 return \"ldx.uw %1, %2, %0\";
7251#endif
7252 return \"ldx.w %1, %2, %0\";
7253 case QImode:
7254 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7255 return \"ldx.ub %1, %2, %0\";
7256 return \"ldx.b %1, %2, %0\";
7257 default:
7258 abort ();
7259 }
2ad65b0e
SC
7260}"
7261 [(set_attr "type" "load_media")])
fa5322fa 7262
afbc2905
R
7263(define_expand "return"
7264 [(return)]
7265 "reload_completed && ! sh_need_epilogue ()"
fa5322fa
AO
7266 "
7267{
7268 if (TARGET_SHMEDIA)
7269 {
7270 emit_jump_insn (gen_return_media ());
7271 DONE;
7272 }
7273
7274 if (TARGET_SHCOMPACT
7275 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7276 {
7277 emit_jump_insn (gen_shcompact_return_tramp ());
7278 DONE;
7279 }
7280}")
afbc2905
R
7281
7282(define_insn "*return_i"
0d7e008e 7283 [(return)]
fa5322fa
AO
7284 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7285 && (current_function_args_info.call_cookie
7286 & CALL_COOKIE_RET_TRAMP (1)))
7287 && reload_completed"
961c4780 7288 "%@ %#"
51bd623f
JW
7289 [(set_attr "type" "return")
7290 (set_attr "needs_delay_slot" "yes")])
b9654711 7291
fa5322fa
AO
7292(define_expand "shcompact_return_tramp"
7293 [(return)]
7294 "TARGET_SHCOMPACT
7295 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7296 "
7297{
7298 rtx reg = gen_rtx_REG (Pmode, R0_REG);
90534361 7299 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
fa5322fa
AO
7300
7301 if (flag_pic)
7302 emit_insn (gen_symGOTPLT2reg (reg, sym));
7303 else
7304 emit_move_insn (reg, sym);
7305
7306 emit_jump_insn (gen_shcompact_return_tramp_i ());
7307 DONE;
7308}")
7309
7310(define_insn "shcompact_return_tramp_i"
7311 [(parallel [(return) (use (reg:SI R0_REG))])]
7312 "TARGET_SHCOMPACT
7313 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7314 "jmp @r0%#"
7315 [(set_attr "type" "jump_ind")
7316 (set_attr "needs_delay_slot" "yes")])
7317
7318(define_insn "return_media_i"
7319 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7320 "TARGET_SHMEDIA && reload_completed"
2ad65b0e
SC
7321 "blink %0, r63"
7322 [(set_attr "type" "jump_media")])
fa5322fa 7323
1bf93c14
R
7324(define_insn "return_media_rte"
7325 [(return)]
7326 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7327 "rte"
7328 [(set_attr "type" "jump_media")])
7329
fa5322fa
AO
7330(define_expand "return_media"
7331 [(return)]
7332 "TARGET_SHMEDIA && reload_completed"
7333 "
7334{
7335 int tr_regno = sh_media_register_for_return ();
7336 rtx tr;
7337
1bf93c14
R
7338 if (current_function_interrupt)
7339 {
7340 emit_jump_insn (gen_return_media_rte ());
7341 DONE;
7342 }
fa5322fa
AO
7343 if (tr_regno < 0)
7344 {
7345 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7346
fada1961
R
7347 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7348 abort ();
fa5322fa
AO
7349 tr_regno = TR0_REG;
7350 tr = gen_rtx_REG (DImode, tr_regno);
7351 emit_move_insn (tr, r18);
7352 }
7353 else
7354 tr = gen_rtx_REG (DImode, tr_regno);
7355
7356 emit_jump_insn (gen_return_media_i (tr));
7357 DONE;
7358}")
7359
7360(define_insn "shcompact_preserve_incoming_args"
e69d1422
R
7361 [(set (match_operand:SI 0 "register_operand" "+r")
7362 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
fa5322fa
AO
7363 "TARGET_SHCOMPACT"
7364 ""
7365 [(set_attr "length" "0")])
7366
7367(define_insn "shcompact_incoming_args"
e69d1422
R
7368 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7369 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7370 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7371 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7372 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7373 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7374 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7375 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa 7376 (set (mem:BLK (reg:SI MACL_REG))
e69d1422 7377 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa
AO
7378 (use (reg:SI R0_REG))
7379 (clobber (reg:SI R0_REG))
7380 (clobber (reg:SI MACL_REG))
7381 (clobber (reg:SI MACH_REG))
7382 (clobber (reg:SI PR_REG))]
7383 "TARGET_SHCOMPACT"
7384 "jsr @r0%#"
7385 [(set_attr "needs_delay_slot" "yes")])
7386
7387(define_insn "shmedia_save_restore_regs_compact"
7388 [(set (reg:SI SP_REG)
7389 (plus:SI (reg:SI SP_REG)
7390 (match_operand:SI 0 "immediate_operand" "i")))
7391 (use (reg:SI R0_REG))
7392 (clobber (reg:SI PR_REG))]
7393 "TARGET_SHCOMPACT
7394 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7395 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7396 "jsr @r0%#"
7397 [(set_attr "needs_delay_slot" "yes")])
7398
b9654711
SC
7399(define_expand "prologue"
7400 [(const_int 0)]
7401 ""
7402 "sh_expand_prologue (); DONE;")
7403
7404(define_expand "epilogue"
7405 [(return)]
7406 ""
fa5322fa
AO
7407 "
7408{
726d4cb7 7409 sh_expand_epilogue (0);
fa5322fa
AO
7410 emit_jump_insn (gen_return ());
7411 DONE;
7412}")
b9654711 7413
4977bab6 7414(define_expand "eh_return"
34dc173c 7415 [(use (match_operand 0 "register_operand" ""))]
4977bab6
ZW
7416 ""
7417{
34dc173c 7418 rtx tmp, ra = operands[0];
4977bab6
ZW
7419
7420 if (TARGET_SHMEDIA64)
7421 emit_insn (gen_eh_set_ra_di (ra));
7422 else
7423 emit_insn (gen_eh_set_ra_si (ra));
7424
4977bab6
ZW
7425 DONE;
7426})
7427
7428;; Clobber the return address on the stack. We can't expand this
7429;; until we know where it will be put in the stack frame.
7430
7431(define_insn "eh_set_ra_si"
7432 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7433 (clobber (match_scratch:SI 1 "=&r"))]
7434 "! TARGET_SHMEDIA64"
7435 "#")
7436
7437(define_insn "eh_set_ra_di"
7438 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7439 (clobber (match_scratch:DI 1 "=&r"))]
7440 "TARGET_SHMEDIA64"
7441 "#")
7442
7443(define_split
7444 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7445 (clobber (match_scratch 1 ""))]
7446 "reload_completed"
7447 [(const_int 0)]
7448 "
7449{
7450 sh_set_return_address (operands[0], operands[1]);
7451 DONE;
7452}")
7453
b9654711 7454(define_insn "blockage"
4773afa4 7455 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
b9654711
SC
7456 ""
7457 ""
7458 [(set_attr "length" "0")])
bc45ade3
SC
7459\f
7460;; ------------------------------------------------------------------------
7461;; Scc instructions
7462;; ------------------------------------------------------------------------
7463
0d7e008e 7464(define_insn "movt"
aa684c94 7465 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 7466 (eq:SI (reg:SI T_REG) (const_int 1)))]
fa5322fa 7467 "TARGET_SH1"
1245df60
R
7468 "movt %0"
7469 [(set_attr "type" "arith")])
bc45ade3
SC
7470
7471(define_expand "seq"
aa684c94 7472 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7473 (match_dup 1))]
7474 ""
fa5322fa
AO
7475 "
7476{
7477 if (TARGET_SHMEDIA)
7478 {
7479 if (GET_MODE (operands[0]) != DImode)
7480 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7481 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7482 if (sh_compare_op1 != const0_rtx)
7483 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7484 ? GET_MODE (sh_compare_op0)
7485 : GET_MODE (sh_compare_op1),
7486 sh_compare_op1);
7487
7488 switch (GET_MODE (sh_compare_op0))
7489 {
7490 case DImode:
7491 emit_insn (gen_cmpeqdi_media (operands[0],
7492 sh_compare_op0, sh_compare_op1));
7493 break;
7494
7495 case SFmode:
7496 if (! TARGET_SHMEDIA_FPU)
7497 FAIL;
7498 emit_insn (gen_cmpeqsf_media (operands[0],
7499 sh_compare_op0, sh_compare_op1));
7500 break;
7501
7502 case DFmode:
7503 if (! TARGET_SHMEDIA_FPU)
7504 FAIL;
7505 emit_insn (gen_cmpeqdf_media (operands[0],
7506 sh_compare_op0, sh_compare_op1));
7507 break;
7508
7509 default:
7510 FAIL;
7511 }
7512 DONE;
7513 }
3db1b434
R
7514 if (sh_expand_t_scc (EQ, operands[0]))
7515 DONE;
7516 if (! rtx_equal_function_value_matters)
7517 FAIL;
fa5322fa
AO
7518 operands[1] = prepare_scc_operands (EQ);
7519}")
bc45ade3
SC
7520
7521(define_expand "slt"
aa684c94 7522 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7523 (match_dup 1))]
7524 ""
fa5322fa
AO
7525 "
7526{
7527 if (TARGET_SHMEDIA)
7528 {
7529 if (GET_MODE (operands[0]) != DImode)
7530 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7531 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7532 if (sh_compare_op1 != const0_rtx)
7533 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7534 ? GET_MODE (sh_compare_op0)
7535 : GET_MODE (sh_compare_op1),
7536 sh_compare_op1);
7537
7538 switch (GET_MODE (sh_compare_op0))
7539 {
7540 case DImode:
7541 emit_insn (gen_cmpgtdi_media (operands[0],
7542 sh_compare_op1, sh_compare_op0));
7543 break;
7544
7545 case SFmode:
7546 if (! TARGET_SHMEDIA_FPU)
7547 FAIL;
7548 emit_insn (gen_cmpgtsf_media (operands[0],
7549 sh_compare_op1, sh_compare_op0));
7550 break;
7551
7552 case DFmode:
7553 if (! TARGET_SHMEDIA_FPU)
7554 FAIL;
7555 emit_insn (gen_cmpgtdf_media (operands[0],
7556 sh_compare_op1, sh_compare_op0));
7557 break;
7558
7559 default:
7560 FAIL;
7561 }
7562 DONE;
7563 }
3db1b434
R
7564 if (! rtx_equal_function_value_matters)
7565 FAIL;
fa5322fa
AO
7566 operands[1] = prepare_scc_operands (LT);
7567}")
bc45ade3
SC
7568
7569(define_expand "sle"
1245df60 7570 [(match_operand:SI 0 "arith_reg_operand" "")]
bc45ade3 7571 ""
45348d9e
JW
7572 "
7573{
1245df60 7574 rtx tmp = sh_compare_op0;
fa5322fa
AO
7575
7576 if (TARGET_SHMEDIA)
7577 {
7578 if (GET_MODE (operands[0]) != DImode)
7579 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7580 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7581 if (sh_compare_op1 != const0_rtx)
7582 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7583 ? GET_MODE (sh_compare_op0)
7584 : GET_MODE (sh_compare_op1),
7585 sh_compare_op1);
7586
7587 switch (GET_MODE (sh_compare_op0))
7588 {
7589 case DImode:
7590 {
7591 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7592
7593 emit_insn (gen_cmpgtdi_media (tmp,
7594 sh_compare_op0, sh_compare_op1));
7595 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7596 break;
7597 }
7598
7599 case SFmode:
7600 if (! TARGET_SHMEDIA_FPU)
7601 FAIL;
7602 emit_insn (gen_cmpgesf_media (operands[0],
7603 sh_compare_op1, sh_compare_op0));
7604 break;
7605
7606 case DFmode:
7607 if (! TARGET_SHMEDIA_FPU)
7608 FAIL;
7609 emit_insn (gen_cmpgedf_media (operands[0],
7610 sh_compare_op1, sh_compare_op0));
7611 break;
7612
7613 default:
7614 FAIL;
7615 }
7616 DONE;
7617 }
7618
1245df60
R
7619 sh_compare_op0 = sh_compare_op1;
7620 sh_compare_op1 = tmp;
7621 emit_insn (gen_sge (operands[0]));
7622 DONE;
45348d9e 7623}")
bc45ade3
SC
7624
7625(define_expand "sgt"
aa684c94 7626 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7627 (match_dup 1))]
7628 ""
fa5322fa
AO
7629 "
7630{
7631 if (TARGET_SHMEDIA)
7632 {
7633 if (GET_MODE (operands[0]) != DImode)
7634 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7635 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7636 if (sh_compare_op1 != const0_rtx)
7637 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7638 ? GET_MODE (sh_compare_op0)
7639 : GET_MODE (sh_compare_op1),
7640 sh_compare_op1);
7641
7642 switch (GET_MODE (sh_compare_op0))
7643 {
7644 case DImode:
7645 emit_insn (gen_cmpgtdi_media (operands[0],
7646 sh_compare_op0, sh_compare_op1));
7647 break;
7648
7649 case SFmode:
7650 if (! TARGET_SHMEDIA_FPU)
7651 FAIL;
7652 emit_insn (gen_cmpgtsf_media (operands[0],
7653 sh_compare_op0, sh_compare_op1));
7654 break;
7655
7656 case DFmode:
7657 if (! TARGET_SHMEDIA_FPU)
7658 FAIL;
7659 emit_insn (gen_cmpgtdf_media (operands[0],
7660 sh_compare_op0, sh_compare_op1));
7661 break;
7662
7663 default:
7664 FAIL;
7665 }
7666 DONE;
7667 }
3db1b434
R
7668 if (! rtx_equal_function_value_matters)
7669 FAIL;
fa5322fa
AO
7670 operands[1] = prepare_scc_operands (GT);
7671}")
bc45ade3
SC
7672
7673(define_expand "sge"
aa684c94 7674 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7675 (match_dup 1))]
7676 ""
45348d9e
JW
7677 "
7678{
fa5322fa
AO
7679 if (TARGET_SHMEDIA)
7680 {
7681 if (GET_MODE (operands[0]) != DImode)
7682 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7683 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7684 if (sh_compare_op1 != const0_rtx)
7685 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7686 ? GET_MODE (sh_compare_op0)
7687 : GET_MODE (sh_compare_op1),
7688 sh_compare_op1);
7689
7690 switch (GET_MODE (sh_compare_op0))
7691 {
7692 case DImode:
7693 {
7694 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7695
7696 emit_insn (gen_cmpgtdi_media (tmp,
7697 sh_compare_op1, sh_compare_op0));
7698 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7699 break;
7700 }
7701
7702 case SFmode:
7703 if (! TARGET_SHMEDIA_FPU)
7704 FAIL;
7705 emit_insn (gen_cmpgesf_media (operands[0],
7706 sh_compare_op0, sh_compare_op1));
7707 break;
7708
7709 case DFmode:
7710 if (! TARGET_SHMEDIA_FPU)
7711 FAIL;
7712 emit_insn (gen_cmpgedf_media (operands[0],
7713 sh_compare_op0, sh_compare_op1));
7714 break;
7715
7716 default:
7717 FAIL;
7718 }
7719 DONE;
7720 }
7721
3db1b434
R
7722 if (! rtx_equal_function_value_matters)
7723 FAIL;
225e4f43 7724 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e 7725 {
1245df60
R
7726 if (TARGET_IEEE)
7727 {
1245df60 7728 rtx lab = gen_label_rtx ();
225e4f43 7729 prepare_scc_operands (EQ);
1245df60 7730 emit_jump_insn (gen_branch_true (lab));
225e4f43 7731 prepare_scc_operands (GT);
1245df60
R
7732 emit_label (lab);
7733 emit_insn (gen_movt (operands[0]));
7734 }
7735 else
7736 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
45348d9e
JW
7737 DONE;
7738 }
7739 operands[1] = prepare_scc_operands (GE);
7740}")
bc45ade3
SC
7741
7742(define_expand "sgtu"
aa684c94 7743 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7744 (match_dup 1))]
7745 ""
fa5322fa
AO
7746 "
7747{
7748 if (TARGET_SHMEDIA)
7749 {
7750 if (GET_MODE (operands[0]) != DImode)
7751 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7752 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7753 if (sh_compare_op1 != const0_rtx)
7754 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7755 ? GET_MODE (sh_compare_op0)
7756 : GET_MODE (sh_compare_op1),
7757 sh_compare_op1);
7758
7759 emit_insn (gen_cmpgtudi_media (operands[0],
7760 sh_compare_op0, sh_compare_op1));
7761 DONE;
7762 }
3db1b434
R
7763 if (! rtx_equal_function_value_matters)
7764 FAIL;
fa5322fa
AO
7765 operands[1] = prepare_scc_operands (GTU);
7766}")
bc45ade3
SC
7767
7768(define_expand "sltu"
aa684c94 7769 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7770 (match_dup 1))]
7771 ""
fa5322fa
AO
7772 "
7773{
7774 if (TARGET_SHMEDIA)
7775 {
7776 if (GET_MODE (operands[0]) != DImode)
7777 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7778 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7779 if (sh_compare_op1 != const0_rtx)
7780 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7781 ? GET_MODE (sh_compare_op0)
7782 : GET_MODE (sh_compare_op1),
7783 sh_compare_op1);
7784
7785 emit_insn (gen_cmpgtudi_media (operands[0],
7786 sh_compare_op1, sh_compare_op0));
7787 DONE;
7788 }
3db1b434
R
7789 if (! rtx_equal_function_value_matters)
7790 FAIL;
fa5322fa
AO
7791 operands[1] = prepare_scc_operands (LTU);
7792}")
bc45ade3
SC
7793
7794(define_expand "sleu"
aa684c94 7795 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7796 (match_dup 1))]
7797 ""
fa5322fa
AO
7798 "
7799{
7800 if (TARGET_SHMEDIA)
7801 {
7802 rtx tmp;
7803
7804 if (GET_MODE (operands[0]) != DImode)
7805 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7806 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7807 if (sh_compare_op1 != const0_rtx)
7808 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7809 ? GET_MODE (sh_compare_op0)
7810 : GET_MODE (sh_compare_op1),
7811 sh_compare_op1);
7812
7813 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7814
7815 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7816 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7817
7818 DONE;
7819 }
3db1b434
R
7820 if (! rtx_equal_function_value_matters)
7821 FAIL;
fa5322fa
AO
7822 operands[1] = prepare_scc_operands (LEU);
7823}")
bc45ade3
SC
7824
7825(define_expand "sgeu"
aa684c94 7826 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7827 (match_dup 1))]
7828 ""
fa5322fa
AO
7829 "
7830{
7831 if (TARGET_SHMEDIA)
7832 {
7833 rtx tmp;
7834
7835 if (GET_MODE (operands[0]) != DImode)
7836 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7837 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7838 if (sh_compare_op1 != const0_rtx)
7839 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7840 ? GET_MODE (sh_compare_op0)
7841 : GET_MODE (sh_compare_op1),
7842 sh_compare_op1);
7843
7844 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7845
7846 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7847 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7848
7849 DONE;
7850 }
7851
3db1b434
R
7852 if (! rtx_equal_function_value_matters)
7853 FAIL;
fa5322fa
AO
7854 operands[1] = prepare_scc_operands (GEU);
7855}")
bc45ade3 7856
8bca10f4
JW
7857;; sne moves the complement of the T reg to DEST like this:
7858;; cmp/eq ...
7859;; mov #-1,temp
7860;; negc temp,dest
7861;; This is better than xoring compare result with 1 because it does
7862;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7863;; loop.
7864
bc45ade3 7865(define_expand "sne"
8bca10f4
JW
7866 [(set (match_dup 2) (const_int -1))
7867 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7868 (neg:SI (plus:SI (match_dup 1)
7869 (match_dup 2))))
4773afa4 7870 (set (reg:SI T_REG)
8bca10f4 7871 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
52702ae1 7872 (const_int 0)))])]
8bca10f4
JW
7873 ""
7874 "
7875{
fa5322fa
AO
7876 if (TARGET_SHMEDIA)
7877 {
7878 rtx tmp;
7879
7880 if (GET_MODE (operands[0]) != DImode)
7881 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7882
7883 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7884 FAIL;
7885
7886 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7887 if (sh_compare_op1 != const0_rtx)
7888 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7889 ? GET_MODE (sh_compare_op0)
7890 : GET_MODE (sh_compare_op1),
7891 sh_compare_op1);
7892
7893 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7894
7895 emit_insn (gen_seq (tmp));
7896 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7897
7898 DONE;
7899 }
7900
3db1b434
R
7901 if (sh_expand_t_scc (NE, operands[0]))
7902 DONE;
7903 if (! rtx_equal_function_value_matters)
7904 FAIL;
7905 operands[1] = prepare_scc_operands (EQ);
7906 operands[2] = gen_reg_rtx (SImode);
8bca10f4
JW
7907}")
7908
fa5322fa
AO
7909(define_expand "sunordered"
7910 [(set (match_operand:DI 0 "arith_reg_operand" "")
7911 (unordered:DI (match_dup 1) (match_dup 2)))]
7912 "TARGET_SHMEDIA_FPU"
7913 "
7914{
7915 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7916 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7917}")
7918
1245df60
R
7919;; Use the same trick for FP sle / sge
7920(define_expand "movnegt"
7921 [(set (match_dup 2) (const_int -1))
7922 (parallel [(set (match_operand 0 "" "")
7923 (neg:SI (plus:SI (match_dup 1)
7924 (match_dup 2))))
4773afa4 7925 (set (reg:SI T_REG)
1245df60 7926 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
52702ae1 7927 (const_int 0)))])]
fa5322fa 7928 "TARGET_SH1"
1245df60
R
7929 "operands[2] = gen_reg_rtx (SImode);")
7930
8bca10f4 7931;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
956d6950 7932;; This prevents a regression that occurred when we switched from xor to
8bca10f4
JW
7933;; mov/neg for sne.
7934
7935(define_split
aa684c94 7936 [(set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 7937 (plus:SI (reg:SI T_REG)
8bca10f4 7938 (const_int -1)))]
fa5322fa 7939 "TARGET_SH1"
4773afa4 7940 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
8bca10f4
JW
7941 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7942 "")
bc45ade3 7943
0d7e008e
SC
7944;; -------------------------------------------------------------------------
7945;; Instructions to cope with inline literal tables
7946;; -------------------------------------------------------------------------
7947
7948; 2 byte integer in line
b9654711 7949
0d7e008e 7950(define_insn "consttable_2"
b91455de
KK
7951 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7952 (match_operand 1 "" "")]
4773afa4 7953 UNSPECV_CONST2)]
0d7e008e
SC
7954 ""
7955 "*
7956{
b91455de 7957 if (operands[1] != const0_rtx)
c8af3574 7958 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
0d7e008e
SC
7959 return \"\";
7960}"
7961 [(set_attr "length" "2")
7962 (set_attr "in_delay_slot" "no")])
7963
7964; 4 byte integer in line
7965
7966(define_insn "consttable_4"
b91455de
KK
7967 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7968 (match_operand 1 "" "")]
4773afa4 7969 UNSPECV_CONST4)]
0d7e008e
SC
7970 ""
7971 "*
7972{
b91455de 7973 if (operands[1] != const0_rtx)
c8af3574 7974 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
0d7e008e
SC
7975 return \"\";
7976}"
7977 [(set_attr "length" "4")
7978 (set_attr "in_delay_slot" "no")])
7979
7980; 8 byte integer in line
7981
7982(define_insn "consttable_8"
b91455de
KK
7983 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7984 (match_operand 1 "" "")]
4773afa4 7985 UNSPECV_CONST8)]
0d7e008e
SC
7986 ""
7987 "*
7988{
b91455de 7989 if (operands[1] != const0_rtx)
c8af3574 7990 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
0d7e008e
SC
7991 return \"\";
7992}"
7993 [(set_attr "length" "8")
7994 (set_attr "in_delay_slot" "no")])
7995
3e943b59
JR
7996; 4 byte floating point
7997
7998(define_insn "consttable_sf"
b91455de
KK
7999 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
8000 (match_operand 1 "" "")]
4773afa4 8001 UNSPECV_CONST4)]
3e943b59
JR
8002 ""
8003 "*
8004{
b91455de
KK
8005 if (operands[1] != const0_rtx)
8006 {
85654444
ZW
8007 REAL_VALUE_TYPE d;
8008 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8009 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
b91455de 8010 }
3e943b59
JR
8011 return \"\";
8012}"
8013 [(set_attr "length" "4")
8014 (set_attr "in_delay_slot" "no")])
8015
8016; 8 byte floating point
8017
8018(define_insn "consttable_df"
b91455de
KK
8019 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
8020 (match_operand 1 "" "")]
4773afa4 8021 UNSPECV_CONST8)]
3e943b59
JR
8022 ""
8023 "*
8024{
b91455de
KK
8025 if (operands[1] != const0_rtx)
8026 {
85654444
ZW
8027 REAL_VALUE_TYPE d;
8028 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8029 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
b91455de 8030 }
3e943b59
JR
8031 return \"\";
8032}"
8033 [(set_attr "length" "8")
8034 (set_attr "in_delay_slot" "no")])
8035
1245df60
R
8036;; Alignment is needed for some constant tables; it may also be added for
8037;; Instructions at the start of loops, or after unconditional branches.
8038;; ??? We would get more accurate lengths if we did instruction
8039;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8040;; here is too conservative.
8041
0d7e008e
SC
8042; align to a two byte boundary
8043
33f7f353 8044(define_expand "align_2"
4773afa4 8045 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
0d7e008e 8046 ""
33f7f353 8047 "")
0d7e008e
SC
8048
8049; align to a four byte boundary
1245df60
R
8050;; align_4 and align_log are instructions for the starts of loops, or
8051;; after unconditional branches, which may take up extra room.
8052
8053(define_expand "align_4"
4773afa4 8054 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
1245df60
R
8055 ""
8056 "")
8057
8058; align to a cache line boundary
0d7e008e 8059
1245df60 8060(define_insn "align_log"
4773afa4 8061 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
0d7e008e 8062 ""
33f7f353
JR
8063 ""
8064 [(set_attr "length" "0")
1245df60 8065 (set_attr "in_delay_slot" "no")])
0d7e008e
SC
8066
8067; emitted at the end of the literal table, used to emit the
8068; 32bit branch labels if needed.
8069
8070(define_insn "consttable_end"
4773afa4 8071 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
0d7e008e
SC
8072 ""
8073 "* return output_jump_label_table ();"
8074 [(set_attr "in_delay_slot" "no")])
8075
b91455de
KK
8076; emitted at the end of the window in the literal table.
8077
8078(define_insn "consttable_window_end"
8079 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8080 ""
8081 ""
8082 [(set_attr "length" "0")
8083 (set_attr "in_delay_slot" "no")])
8084
0d7e008e
SC
8085;; -------------------------------------------------------------------------
8086;; Misc
8087;; -------------------------------------------------------------------------
8088
07a45e5c 8089;; String/block move insn.
0d7e008e 8090
70128ad9 8091(define_expand "movmemsi"
0d7e008e
SC
8092 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8093 (mem:BLK (match_operand:BLK 1 "" "")))
8094 (use (match_operand:SI 2 "nonmemory_operand" ""))
8095 (use (match_operand:SI 3 "immediate_operand" ""))
4773afa4
AO
8096 (clobber (reg:SI PR_REG))
8097 (clobber (reg:SI R4_REG))
8098 (clobber (reg:SI R5_REG))
8099 (clobber (reg:SI R0_REG))])]
fa5322fa 8100 "TARGET_SH1 && ! TARGET_SH5"
0d7e008e
SC
8101 "
8102{
8103 if(expand_block_move (operands))
8104 DONE;
8105 else FAIL;
8106}")
8107
8108(define_insn "block_move_real"
4773afa4
AO
8109 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8110 (mem:BLK (reg:SI R5_REG)))
0d7e008e 8111 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8112 (clobber (reg:SI PR_REG))
8113 (clobber (reg:SI R0_REG))])]
fa5322fa 8114 "TARGET_SH1 && ! TARGET_HARD_SH4"
0d7e008e 8115 "jsr @%0%#"
22e1ebf1 8116 [(set_attr "type" "sfunc")
0d7e008e
SC
8117 (set_attr "needs_delay_slot" "yes")])
8118
8119(define_insn "block_lump_real"
4773afa4
AO
8120 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8121 (mem:BLK (reg:SI R5_REG)))
0d7e008e 8122 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8123 (use (reg:SI R6_REG))
8124 (clobber (reg:SI PR_REG))
8125 (clobber (reg:SI T_REG))
8126 (clobber (reg:SI R4_REG))
8127 (clobber (reg:SI R5_REG))
8128 (clobber (reg:SI R6_REG))
8129 (clobber (reg:SI R0_REG))])]
fa5322fa 8130 "TARGET_SH1 && ! TARGET_HARD_SH4"
225e4f43
R
8131 "jsr @%0%#"
8132 [(set_attr "type" "sfunc")
8133 (set_attr "needs_delay_slot" "yes")])
8134
8135(define_insn "block_move_real_i4"
4773afa4
AO
8136 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8137 (mem:BLK (reg:SI R5_REG)))
225e4f43 8138 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8139 (clobber (reg:SI PR_REG))
8140 (clobber (reg:SI R0_REG))
8141 (clobber (reg:SI R1_REG))
8142 (clobber (reg:SI R2_REG))])]
225e4f43
R
8143 "TARGET_HARD_SH4"
8144 "jsr @%0%#"
8145 [(set_attr "type" "sfunc")
8146 (set_attr "needs_delay_slot" "yes")])
8147
8148(define_insn "block_lump_real_i4"
4773afa4
AO
8149 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8150 (mem:BLK (reg:SI R5_REG)))
225e4f43 8151 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8152 (use (reg:SI R6_REG))
8153 (clobber (reg:SI PR_REG))
8154 (clobber (reg:SI T_REG))
8155 (clobber (reg:SI R4_REG))
8156 (clobber (reg:SI R5_REG))
8157 (clobber (reg:SI R6_REG))
8158 (clobber (reg:SI R0_REG))
8159 (clobber (reg:SI R1_REG))
8160 (clobber (reg:SI R2_REG))
8161 (clobber (reg:SI R3_REG))])]
225e4f43 8162 "TARGET_HARD_SH4"
0d7e008e 8163 "jsr @%0%#"
22e1ebf1 8164 [(set_attr "type" "sfunc")
0d7e008e 8165 (set_attr "needs_delay_slot" "yes")])
45348d9e
JW
8166\f
8167;; -------------------------------------------------------------------------
8168;; Floating point instructions.
8169;; -------------------------------------------------------------------------
8170
8171;; ??? All patterns should have a type attribute.
8172
225e4f43 8173(define_expand "fpu_switch0"
8845e874
AO
8174 [(set (match_operand:SI 0 "" "") (match_dup 2))
8175 (set (match_dup 1) (mem:PSI (match_dup 0)))]
ecfdeaeb 8176 "TARGET_SH4"
225e4f43
R
8177 "
8178{
8845e874
AO
8179 operands[1] = get_fpscr_rtx ();
8180 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
8181 if (flag_pic)
8182 operands[2] = legitimize_pic_address (operands[2], SImode,
8183 no_new_pseudos ? operands[0] : 0);
225e4f43
R
8184}")
8185
8186(define_expand "fpu_switch1"
8845e874
AO
8187 [(set (match_operand:SI 0 "" "") (match_dup 2))
8188 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8189 (set (match_dup 1) (mem:PSI (match_dup 3)))]
ecfdeaeb 8190 "TARGET_SH4"
225e4f43
R
8191 "
8192{
8845e874
AO
8193 operands[1] = get_fpscr_rtx ();
8194 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
8195 if (flag_pic)
8196 operands[2] = legitimize_pic_address (operands[2], SImode,
8197 no_new_pseudos ? operands[0] : 0);
8845e874 8198 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
225e4f43
R
8199}")
8200
8201(define_expand "movpsi"
8202 [(set (match_operand:PSI 0 "register_operand" "")
8203 (match_operand:PSI 1 "general_movsrc_operand" ""))]
ecfdeaeb 8204 "TARGET_SH4"
225e4f43
R
8205 "")
8206
8207;; The c / m alternative is a fake to guide reload to load directly into
8208;; fpscr, since reload doesn't know how to use post-increment.
8209;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8210;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8211;; predicate after reload.
c49439f1
R
8212;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8213;; like a mac -> gpr move.
225e4f43 8214(define_insn "fpu_switch"
7144b2d8
DD
8215 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8216 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
603ff6b5 8217 "TARGET_SH2E
ecfdeaeb
AO
8218 && (! reload_completed
8219 || true_regnum (operands[0]) != FPSCR_REG
8220 || GET_CODE (operands[1]) != MEM
8221 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
225e4f43
R
8222 "@
8223 ! precision stays the same
8224 lds.l %1,fpscr
8225 mov.l %1,%0
8226 #
8227 lds %1,fpscr
8228 mov %1,%0
8229 mov.l %1,%0
7144b2d8
DD
8230 sts fpscr,%0
8231 sts.l fpscr,%0"
8232 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8233 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
225e4f43
R
8234
8235(define_split
4773afa4 8236 [(set (reg:PSI FPSCR_REG)
c1b92d09 8237 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 8238 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
225e4f43
R
8239 [(set (match_dup 0) (match_dup 0))]
8240 "
8241{
8242 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
c0d4e710
KH
8243 gen_rtx_MEM (PSImode,
8244 gen_rtx_POST_INC (Pmode,
225e4f43 8245 operands[0]))));
c0d4e710 8246 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
225e4f43
R
8247}")
8248
8249(define_split
4773afa4 8250 [(set (reg:PSI FPSCR_REG)
c1b92d09 8251 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 8252 "TARGET_SH4"
225e4f43
R
8253 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8254 "
8255{
8256 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
c0d4e710
KH
8257 gen_rtx_MEM (PSImode,
8258 gen_rtx_POST_INC (Pmode,
225e4f43 8259 operands[0]))));
c0d4e710 8260 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
225e4f43
R
8261}")
8262
8263;; ??? This uses the fp unit, but has no type indicating that.
8264;; If we did that, this would either give a bogus latency or introduce
8265;; a bogus FIFO constraint.
8266;; Since this insn is currently only used for prologues/epilogues,
8267;; it is probably best to claim no function unit, which matches the
8268;; current setting.
8269(define_insn "toggle_sz"
4773afa4
AO
8270 [(set (reg:PSI FPSCR_REG)
8271 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
225e4f43 8272 "TARGET_SH4"
73774972
EC
8273 "fschg"
8274 [(set_attr "fp_set" "unknown")])
225e4f43
R
8275
8276(define_expand "addsf3"
fa5322fa
AO
8277 [(set (match_operand:SF 0 "arith_reg_operand" "")
8278 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8279 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 8280 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8281 "
8282{
3a8699c7 8283 if (TARGET_SH2E)
fa5322fa
AO
8284 {
8285 expand_sf_binop (&gen_addsf3_i, operands);
8286 DONE;
8287 }
8288}")
8289
8290(define_insn "*addsf3_media"
8291 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8292 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8293 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8294 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8295 "fadd.s %1, %2, %0"
8296 [(set_attr "type" "fparith_media")])
225e4f43 8297
0ac78517
R
8298(define_insn_and_split "unary_sf_op"
8299 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8300 (vec_select:V2SF
8301 (vec_concat:V2SF
8302 (vec_select:SF
8303 (match_dup 0)
8304 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8305 (match_operator:SF 2 "unary_float_operator"
8306 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8307 (parallel [(match_operand 4
8308 "const_int_operand" "n")]))]))
8309 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8310 "TARGET_SHMEDIA_FPU"
8311 "#"
8312 "TARGET_SHMEDIA_FPU && reload_completed"
8313 [(set (match_dup 5) (match_dup 6))]
8314 "
8315{
8316 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8317 rtx op1 = gen_rtx_REG (SFmode,
8318 (true_regnum (operands[1])
8319 + (INTVAL (operands[4]) ^ endian)));
8320
8321 operands[7] = gen_rtx_REG (SFmode,
8322 (true_regnum (operands[0])
8323 + (INTVAL (operands[3]) ^ endian)));
1c563bed 8324 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
0ac78517
R
8325}"
8326 [(set_attr "type" "fparith_media")])
8327
8328(define_insn_and_split "binary_sf_op"
8329 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8330 (vec_select:V2SF
8331 (vec_concat:V2SF
8332 (vec_select:SF
8333 (match_dup 0)
a93d1ba2 8334 (parallel [(match_operand 7 "const_int_operand" "n")]))
0ac78517
R
8335 (match_operator:SF 3 "binary_float_operator"
8336 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8337 (parallel [(match_operand 5
8338 "const_int_operand" "n")]))
8339 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8340 (parallel [(match_operand 6
8341 "const_int_operand" "n")]))]))
a93d1ba2
R
8342 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8343 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
0ac78517 8344 "#"
a93d1ba2
R
8345 "&& reload_completed"
8346 [(set (match_dup 8) (match_dup 9))]
0ac78517
R
8347 "
8348{
8349 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8350 rtx op1 = gen_rtx_REG (SFmode,
8351 (true_regnum (operands[1])
8352 + (INTVAL (operands[5]) ^ endian)));
8353 rtx op2 = gen_rtx_REG (SFmode,
8354 (true_regnum (operands[2])
8355 + (INTVAL (operands[6]) ^ endian)));
8356
a93d1ba2 8357 operands[8] = gen_rtx_REG (SFmode,
0ac78517
R
8358 (true_regnum (operands[0])
8359 + (INTVAL (operands[4]) ^ endian)));
1c563bed 8360 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
0ac78517
R
8361}"
8362 [(set_attr "type" "fparith_media")])
8363
225e4f43 8364(define_insn "addsf3_i"
45348d9e
JW
8365 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8366 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
225e4f43
R
8367 (match_operand:SF 2 "arith_reg_operand" "f")))
8368 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8369 "TARGET_SH2E"
c1aef54d 8370 "fadd %2,%0"
d64264ff
R
8371 [(set_attr "type" "fp")
8372 (set_attr "fp_mode" "single")])
45348d9e 8373
225e4f43 8374(define_expand "subsf3"
fa5322fa
AO
8375 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8376 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8377 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 8378 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8379 "
8380{
3a8699c7 8381 if (TARGET_SH2E)
fa5322fa
AO
8382 {
8383 expand_sf_binop (&gen_subsf3_i, operands);
8384 DONE;
8385 }
8386}")
8387
8388(define_insn "*subsf3_media"
8389 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8390 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8391 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8392 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8393 "fsub.s %1, %2, %0"
8394 [(set_attr "type" "fparith_media")])
225e4f43
R
8395
8396(define_insn "subsf3_i"
66c0b347
R
8397 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8398 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8399 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8400 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8401 "TARGET_SH2E"
c1aef54d 8402 "fsub %2,%0"
d64264ff
R
8403 [(set_attr "type" "fp")
8404 (set_attr "fp_mode" "single")])
45348d9e 8405
225e4f43
R
8406;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8407;; register in feeding fp instructions. Thus, we cannot generate fmac for
8408;; mixed-precision SH4 targets. To allow it to be still generated for the
8409;; SH3E, we use a separate insn for SH3E mulsf3.
8410
8411(define_expand "mulsf3"
fa5322fa
AO
8412 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8413 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8414 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 8415 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8416 "
8417{
8418 if (TARGET_SH4)
8419 expand_sf_binop (&gen_mulsf3_i4, operands);
3a8699c7 8420 else if (TARGET_SH2E)
225e4f43 8421 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
fa5322fa
AO
8422 if (! TARGET_SHMEDIA)
8423 DONE;
225e4f43
R
8424}")
8425
fa5322fa
AO
8426(define_insn "*mulsf3_media"
8427 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8429 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8430 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8431 "fmul.s %1, %2, %0"
8432 [(set_attr "type" "fparith_media")])
fa5322fa 8433
225e4f43 8434(define_insn "mulsf3_i4"
4b9580a5
R
8435 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8436 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8437 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8438 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8439 "TARGET_SH2E"
c1aef54d 8440 "fmul %2,%0"
d64264ff
R
8441 [(set_attr "type" "fp")
8442 (set_attr "fp_mode" "single")])
45348d9e 8443
225e4f43 8444(define_insn "mulsf3_ie"
4b9580a5
R
8445 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8446 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8447 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
3a8699c7 8448 "TARGET_SH2E && ! TARGET_SH4"
225e4f43
R
8449 "fmul %2,%0"
8450 [(set_attr "type" "fp")])
8451
fa5322fa
AO
8452(define_insn "*mac_media"
8453 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8454 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8455 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8456 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8457 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8458 "fmac.s %1, %2, %0"
8459 [(set_attr "type" "fparith_media")])
fa5322fa 8460
45348d9e 8461(define_insn "*macsf3"
4b9580a5
R
8462 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8463 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8464 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
225e4f43
R
8465 (match_operand:SF 3 "arith_reg_operand" "0")))
8466 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
3a8699c7 8467 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8468 "fmac fr0,%2,%0"
d64264ff
R
8469 [(set_attr "type" "fp")
8470 (set_attr "fp_mode" "single")])
45348d9e 8471
225e4f43 8472(define_expand "divsf3"
fa5322fa
AO
8473 [(set (match_operand:SF 0 "arith_reg_operand" "")
8474 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8475 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 8476 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8477 "
8478{
3a8699c7 8479 if (TARGET_SH2E)
fa5322fa
AO
8480 {
8481 expand_sf_binop (&gen_divsf3_i, operands);
8482 DONE;
8483 }
8484}")
8485
8486(define_insn "*divsf3_media"
8487 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8488 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8489 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8490 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8491 "fdiv.s %1, %2, %0"
8492 [(set_attr "type" "fdiv_media")])
225e4f43
R
8493
8494(define_insn "divsf3_i"
45348d9e
JW
8495 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8496 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
225e4f43
R
8497 (match_operand:SF 2 "arith_reg_operand" "f")))
8498 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8499 "TARGET_SH2E"
c1aef54d 8500 "fdiv %2,%0"
d64264ff
R
8501 [(set_attr "type" "fdiv")
8502 (set_attr "fp_mode" "single")])
45348d9e 8503
fa5322fa
AO
8504(define_insn "floatdisf2"
8505 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8506 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8507 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8508 "float.qs %1, %0"
8509 [(set_attr "type" "fpconv_media")])
fa5322fa 8510
1245df60 8511(define_expand "floatsisf2"
4b9580a5
R
8512 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8513 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
3a8699c7 8514 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8515 "
8516{
8517 if (TARGET_SH4)
8518 {
0c4c9b16 8519 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8520 DONE;
8521 }
225e4f43
R
8522}")
8523
fa5322fa
AO
8524(define_insn "*floatsisf2_media"
8525 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8526 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8527 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8528 "float.ls %1, %0"
8529 [(set_attr "type" "fpconv_media")])
fa5322fa 8530
225e4f43 8531(define_insn "floatsisf2_i4"
4b9580a5
R
8532 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8533 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8534 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
0f805606 8535 "TARGET_SH4"
0c4c9b16 8536 "float %1,%0"
d64264ff
R
8537 [(set_attr "type" "fp")
8538 (set_attr "fp_mode" "single")])
45348d9e 8539
0f805606 8540(define_insn "*floatsisf2_ie"
4b9580a5
R
8541 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8542 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
3a8699c7 8543 "TARGET_SH2E && ! TARGET_SH4"
0f805606
BS
8544 "float %1,%0"
8545 [(set_attr "type" "fp")])
45348d9e 8546
fa5322fa
AO
8547(define_insn "fix_truncsfdi2"
8548 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8549 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8550 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8551 "ftrc.sq %1, %0"
8552 [(set_attr "type" "fpconv_media")])
fa5322fa 8553
1245df60 8554(define_expand "fix_truncsfsi2"
4b9580a5
R
8555 [(set (match_operand:SI 0 "fpul_operand" "=y")
8556 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8557 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8558 "
8559{
8560 if (TARGET_SH4)
8561 {
0c4c9b16 8562 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8563 DONE;
8564 }
8565}")
8566
fa5322fa
AO
8567(define_insn "*fix_truncsfsi2_media"
8568 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8569 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8570 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8571 "ftrc.sl %1, %0"
8572 [(set_attr "type" "fpconv_media")])
fa5322fa 8573
225e4f43 8574(define_insn "fix_truncsfsi2_i4"
4b9580a5
R
8575 [(set (match_operand:SI 0 "fpul_operand" "=y")
8576 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8577 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8578 "TARGET_SH4"
0c4c9b16 8579 "ftrc %1,%0"
c49439f1 8580 [(set_attr "type" "ftrc_s")
d64264ff 8581 (set_attr "fp_mode" "single")])
225e4f43 8582
0c4c9b16
BS
8583;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8584;; fix_truncsfsi2_i4.
8585;; (define_insn "fix_truncsfsi2_i4_2"
8586;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8587;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
5d00b10a 8588;; (use (reg:PSI FPSCR_REG))
4773afa4 8589;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8590;; "TARGET_SH4"
8591;; "#"
8592;; [(set_attr "length" "4")
8593;; (set_attr "fp_mode" "single")])
8594
8595;;(define_split
8596;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8597;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8598;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8599;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8600;; "TARGET_SH4"
4773afa4 8601;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8602;; (use (match_dup 2))])
4773afa4 8603;; (set (match_dup 0) (reg:SI FPUL_REG))])
45348d9e 8604
1245df60 8605(define_insn "*fixsfsi"
4b9580a5
R
8606 [(set (match_operand:SI 0 "fpul_operand" "=y")
8607 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8608 "TARGET_SH2E && ! TARGET_SH4"
0c4c9b16 8609 "ftrc %1,%0"
1245df60 8610 [(set_attr "type" "fp")])
45348d9e 8611
1245df60 8612(define_insn "cmpgtsf_t"
4773afa4
AO
8613 [(set (reg:SI T_REG)
8614 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8615 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8616 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8617 "fcmp/gt %1,%0"
d64264ff
R
8618 [(set_attr "type" "fp")
8619 (set_attr "fp_mode" "single")])
45348d9e 8620
1245df60 8621(define_insn "cmpeqsf_t"
4773afa4
AO
8622 [(set (reg:SI T_REG)
8623 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8624 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8625 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8626 "fcmp/eq %1,%0"
d64264ff
R
8627 [(set_attr "type" "fp")
8628 (set_attr "fp_mode" "single")])
45348d9e 8629
1245df60 8630(define_insn "ieee_ccmpeqsf_t"
4773afa4
AO
8631 [(set (reg:SI T_REG)
8632 (ior:SI (reg:SI T_REG)
4b9580a5
R
8633 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8634 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
3a8699c7 8635 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
1245df60
R
8636 "* return output_ieee_ccmpeq (insn, operands);"
8637 [(set_attr "length" "4")])
8638
8639
225e4f43 8640(define_insn "cmpgtsf_t_i4"
4773afa4
AO
8641 [(set (reg:SI T_REG)
8642 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8643 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8644 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8645 "TARGET_SH4"
8646 "fcmp/gt %1,%0"
d64264ff
R
8647 [(set_attr "type" "fp")
8648 (set_attr "fp_mode" "single")])
225e4f43
R
8649
8650(define_insn "cmpeqsf_t_i4"
4773afa4
AO
8651 [(set (reg:SI T_REG)
8652 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8653 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8654 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8655 "TARGET_SH4"
8656 "fcmp/eq %1,%0"
d64264ff
R
8657 [(set_attr "type" "fp")
8658 (set_attr "fp_mode" "single")])
225e4f43
R
8659
8660(define_insn "*ieee_ccmpeqsf_t_4"
4773afa4
AO
8661 [(set (reg:SI T_REG)
8662 (ior:SI (reg:SI T_REG)
4b9580a5
R
8663 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8664 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
225e4f43
R
8665 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8666 "TARGET_IEEE && TARGET_SH4"
8667 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8668 [(set_attr "length" "4")
8669 (set_attr "fp_mode" "single")])
225e4f43 8670
fa5322fa
AO
8671(define_insn "cmpeqsf_media"
8672 [(set (match_operand:DI 0 "register_operand" "=r")
8673 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8674 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8675 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8676 "fcmpeq.s %1, %2, %0"
8677 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8678
8679(define_insn "cmpgtsf_media"
8680 [(set (match_operand:DI 0 "register_operand" "=r")
8681 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8682 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8683 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8684 "fcmpgt.s %1, %2, %0"
8685 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8686
8687(define_insn "cmpgesf_media"
8688 [(set (match_operand:DI 0 "register_operand" "=r")
8689 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8690 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8691 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8692 "fcmpge.s %1, %2, %0"
8693 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8694
8695(define_insn "cmpunsf_media"
8696 [(set (match_operand:DI 0 "register_operand" "=r")
8697 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8698 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8699 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8700 "fcmpun.s %1, %2, %0"
8701 [(set_attr "type" "fcmp_media")])
fa5322fa 8702
45348d9e 8703(define_expand "cmpsf"
4773afa4
AO
8704 [(set (reg:SI T_REG)
8705 (compare (match_operand:SF 0 "arith_operand" "")
8706 (match_operand:SF 1 "arith_operand" "")))]
3a8699c7 8707 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
45348d9e
JW
8708 "
8709{
8710 sh_compare_op0 = operands[0];
8711 sh_compare_op1 = operands[1];
8712 DONE;
8713}")
b9654711 8714
225e4f43 8715(define_expand "negsf2"
fa5322fa
AO
8716 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8717 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 8718 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8719 "
8720{
3a8699c7 8721 if (TARGET_SH2E)
fa5322fa
AO
8722 {
8723 expand_sf_unop (&gen_negsf2_i, operands);
8724 DONE;
8725 }
8726}")
8727
8728(define_insn "*negsf2_media"
8729 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8730 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8731 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8732 "fneg.s %1, %0"
8733 [(set_attr "type" "fmove_media")])
225e4f43
R
8734
8735(define_insn "negsf2_i"
4b9580a5
R
8736 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8737 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8738 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 8739 "TARGET_SH2E"
c1aef54d 8740 "fneg %0"
d64264ff
R
8741 [(set_attr "type" "fmove")
8742 (set_attr "fp_mode" "single")])
45348d9e 8743
225e4f43 8744(define_expand "sqrtsf2"
fa5322fa
AO
8745 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8746 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8747 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8748 "
8749{
8750 if (TARGET_SH3E)
8751 {
8752 expand_sf_unop (&gen_sqrtsf2_i, operands);
8753 DONE;
8754 }
8755}")
8756
8757(define_insn "*sqrtsf2_media"
8758 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8759 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8760 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8761 "fsqrt.s %1, %0"
8762 [(set_attr "type" "fdiv_media")])
225e4f43
R
8763
8764(define_insn "sqrtsf2_i"
4b9580a5
R
8765 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8766 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8767 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 8768 "TARGET_SH3E"
c1aef54d 8769 "fsqrt %0"
d64264ff
R
8770 [(set_attr "type" "fdiv")
8771 (set_attr "fp_mode" "single")])
45348d9e 8772
225e4f43 8773(define_expand "abssf2"
fa5322fa
AO
8774 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8775 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 8776 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8777 "
8778{
3a8699c7 8779 if (TARGET_SH2E)
fa5322fa
AO
8780 {
8781 expand_sf_unop (&gen_abssf2_i, operands);
8782 DONE;
8783 }
8784}")
8785
8786(define_insn "*abssf2_media"
8787 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8788 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8789 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8790 "fabs.s %1, %0"
8791 [(set_attr "type" "fmove_media")])
225e4f43
R
8792
8793(define_insn "abssf2_i"
4b9580a5
R
8794 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8795 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8796 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 8797 "TARGET_SH2E"
c1aef54d 8798 "fabs %0"
d64264ff
R
8799 [(set_attr "type" "fmove")
8800 (set_attr "fp_mode" "single")])
225e4f43
R
8801
8802(define_expand "adddf3"
fa5322fa
AO
8803 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8804 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8805 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8806 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8807 "
8808{
8809 if (TARGET_SH4)
8810 {
8811 expand_df_binop (&gen_adddf3_i, operands);
8812 DONE;
8813 }
8814}")
8815
8816(define_insn "*adddf3_media"
8817 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8818 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8819 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8820 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8821 "fadd.d %1, %2, %0"
8822 [(set_attr "type" "dfparith_media")])
225e4f43
R
8823
8824(define_insn "adddf3_i"
4b9580a5
R
8825 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8826 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8827 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8828 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8829 "TARGET_SH4"
8830 "fadd %2,%0"
d64264ff
R
8831 [(set_attr "type" "dfp_arith")
8832 (set_attr "fp_mode" "double")])
225e4f43
R
8833
8834(define_expand "subdf3"
fa5322fa
AO
8835 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8836 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8837 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8838 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8839 "
8840{
8841 if (TARGET_SH4)
8842 {
8843 expand_df_binop (&gen_subdf3_i, operands);
8844 DONE;
8845 }
8846}")
8847
8848(define_insn "*subdf3_media"
8849 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8850 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8851 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8852 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8853 "fsub.d %1, %2, %0"
8854 [(set_attr "type" "dfparith_media")])
225e4f43
R
8855
8856(define_insn "subdf3_i"
4b9580a5
R
8857 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8858 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8859 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8860 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8861 "TARGET_SH4"
8862 "fsub %2,%0"
d64264ff
R
8863 [(set_attr "type" "dfp_arith")
8864 (set_attr "fp_mode" "double")])
225e4f43
R
8865
8866(define_expand "muldf3"
fa5322fa
AO
8867 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8868 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8869 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8870 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8871 "
8872{
8873 if (TARGET_SH4)
8874 {
8875 expand_df_binop (&gen_muldf3_i, operands);
8876 DONE;
8877 }
8878}")
8879
8880(define_insn "*muldf3_media"
8881 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8882 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8883 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8884 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8885 "fmul.d %1, %2, %0"
8886 [(set_attr "type" "dfmul_media")])
225e4f43
R
8887
8888(define_insn "muldf3_i"
4b9580a5
R
8889 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8890 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8891 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8892 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8893 "TARGET_SH4"
8894 "fmul %2,%0"
d64264ff
R
8895 [(set_attr "type" "dfp_arith")
8896 (set_attr "fp_mode" "double")])
225e4f43
R
8897
8898(define_expand "divdf3"
fa5322fa
AO
8899 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8900 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8901 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8902 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8903 "
8904{
8905 if (TARGET_SH4)
8906 {
8907 expand_df_binop (&gen_divdf3_i, operands);
8908 DONE;
8909 }
8910}")
8911
8912(define_insn "*divdf3_media"
8913 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8914 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8915 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8916 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8917 "fdiv.d %1, %2, %0"
8918 [(set_attr "type" "dfdiv_media")])
225e4f43
R
8919
8920(define_insn "divdf3_i"
4b9580a5
R
8921 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8922 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8923 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8924 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8925 "TARGET_SH4"
8926 "fdiv %2,%0"
d64264ff
R
8927 [(set_attr "type" "dfdiv")
8928 (set_attr "fp_mode" "double")])
225e4f43 8929
fa5322fa
AO
8930(define_insn "floatdidf2"
8931 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8932 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8933 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8934 "float.qd %1, %0"
8935 [(set_attr "type" "dfpconv_media")])
fa5322fa 8936
225e4f43 8937(define_expand "floatsidf2"
fa5322fa
AO
8938 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8939 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8940 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8941 "
8942{
fa5322fa
AO
8943 if (TARGET_SH4)
8944 {
8945 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8946 get_fpscr_rtx ()));
8947 DONE;
8948 }
225e4f43
R
8949}")
8950
fa5322fa
AO
8951(define_insn "*floatsidf2_media"
8952 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8953 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8954 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8955 "float.ld %1, %0"
8956 [(set_attr "type" "dfpconv_media")])
fa5322fa 8957
225e4f43 8958(define_insn "floatsidf2_i"
4b9580a5
R
8959 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8960 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8961 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8962 "TARGET_SH4"
0c4c9b16 8963 "float %1,%0"
d64264ff
R
8964 [(set_attr "type" "dfp_conv")
8965 (set_attr "fp_mode" "double")])
225e4f43 8966
fa5322fa
AO
8967(define_insn "fix_truncdfdi2"
8968 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8969 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8970 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8971 "ftrc.dq %1, %0"
8972 [(set_attr "type" "dfpconv_media")])
fa5322fa 8973
225e4f43 8974(define_expand "fix_truncdfsi2"
fa5322fa
AO
8975 [(set (match_operand:SI 0 "fpul_operand" "")
8976 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8977 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8978 "
8979{
fa5322fa
AO
8980 if (TARGET_SH4)
8981 {
8982 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8983 get_fpscr_rtx ()));
8984 DONE;
8985 }
225e4f43
R
8986}")
8987
fa5322fa
AO
8988(define_insn "*fix_truncdfsi2_media"
8989 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8990 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8991 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8992 "ftrc.dl %1, %0"
8993 [(set_attr "type" "dfpconv_media")])
fa5322fa 8994
225e4f43 8995(define_insn "fix_truncdfsi2_i"
4b9580a5
R
8996 [(set (match_operand:SI 0 "fpul_operand" "=y")
8997 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8998 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8999 "TARGET_SH4"
0c4c9b16
BS
9000 "ftrc %1,%0"
9001 [(set_attr "type" "dfp_conv")
c49439f1 9002 (set_attr "dfp_comp" "no")
d64264ff 9003 (set_attr "fp_mode" "double")])
225e4f43 9004
0c4c9b16
BS
9005;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
9006;; fix_truncdfsi2_i.
9007;; (define_insn "fix_truncdfsi2_i4"
9008;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9009;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9010;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 9011;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
9012;; "TARGET_SH4"
9013;; "#"
9014;; [(set_attr "length" "4")
9015;; (set_attr "fp_mode" "double")])
52702ae1 9016;;
0c4c9b16
BS
9017;; (define_split
9018;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9019;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9020;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 9021;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 9022;; "TARGET_SH4"
4773afa4 9023;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 9024;; (use (match_dup 2))])
4773afa4 9025;; (set (match_dup 0) (reg:SI FPUL_REG))])
225e4f43
R
9026
9027(define_insn "cmpgtdf_t"
4773afa4
AO
9028 [(set (reg:SI T_REG)
9029 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9030 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
9031 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9032 "TARGET_SH4"
9033 "fcmp/gt %1,%0"
d64264ff
R
9034 [(set_attr "type" "dfp_cmp")
9035 (set_attr "fp_mode" "double")])
225e4f43
R
9036
9037(define_insn "cmpeqdf_t"
4773afa4
AO
9038 [(set (reg:SI T_REG)
9039 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9040 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
9041 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9042 "TARGET_SH4"
9043 "fcmp/eq %1,%0"
d64264ff
R
9044 [(set_attr "type" "dfp_cmp")
9045 (set_attr "fp_mode" "double")])
225e4f43
R
9046
9047(define_insn "*ieee_ccmpeqdf_t"
4773afa4
AO
9048 [(set (reg:SI T_REG)
9049 (ior:SI (reg:SI T_REG)
9050 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9051 (match_operand:DF 1 "arith_reg_operand" "f"))))
225e4f43
R
9052 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9053 "TARGET_IEEE && TARGET_SH4"
9054 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
9055 [(set_attr "length" "4")
9056 (set_attr "fp_mode" "double")])
52702ae1 9057
fa5322fa
AO
9058(define_insn "cmpeqdf_media"
9059 [(set (match_operand:DI 0 "register_operand" "=r")
9060 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9061 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9062 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9063 "fcmpeq.d %1,%2,%0"
9064 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
9065
9066(define_insn "cmpgtdf_media"
9067 [(set (match_operand:DI 0 "register_operand" "=r")
9068 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9069 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9070 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9071 "fcmpgt.d %1,%2,%0"
9072 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
9073
9074(define_insn "cmpgedf_media"
9075 [(set (match_operand:DI 0 "register_operand" "=r")
9076 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9077 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9078 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9079 "fcmpge.d %1,%2,%0"
9080 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
9081
9082(define_insn "cmpundf_media"
9083 [(set (match_operand:DI 0 "register_operand" "=r")
9084 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9085 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9086 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9087 "fcmpun.d %1,%2,%0"
9088 [(set_attr "type" "fcmp_media")])
fa5322fa 9089
225e4f43 9090(define_expand "cmpdf"
4773afa4
AO
9091 [(set (reg:SI T_REG)
9092 (compare (match_operand:DF 0 "arith_operand" "")
9093 (match_operand:DF 1 "arith_operand" "")))]
fa5322fa 9094 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9095 "
9096{
9097 sh_compare_op0 = operands[0];
9098 sh_compare_op1 = operands[1];
9099 DONE;
9100}")
9101
9102(define_expand "negdf2"
fa5322fa
AO
9103 [(set (match_operand:DF 0 "arith_reg_operand" "")
9104 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9105 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9106 "
9107{
9108 if (TARGET_SH4)
9109 {
9110 expand_df_unop (&gen_negdf2_i, operands);
9111 DONE;
9112 }
9113}")
9114
9115(define_insn "*negdf2_media"
9116 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9117 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9118 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9119 "fneg.d %1, %0"
9120 [(set_attr "type" "fmove_media")])
225e4f43
R
9121
9122(define_insn "negdf2_i"
9123 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9124 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9125 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9126 "TARGET_SH4"
9127 "fneg %0"
d64264ff
R
9128 [(set_attr "type" "fmove")
9129 (set_attr "fp_mode" "double")])
225e4f43
R
9130
9131(define_expand "sqrtdf2"
fa5322fa
AO
9132 [(set (match_operand:DF 0 "arith_reg_operand" "")
9133 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9134 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9135 "
9136{
9137 if (TARGET_SH4)
9138 {
9139 expand_df_unop (&gen_sqrtdf2_i, operands);
9140 DONE;
9141 }
9142}")
9143
9144(define_insn "*sqrtdf2_media"
9145 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9146 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9147 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9148 "fsqrt.d %1, %0"
9149 [(set_attr "type" "dfdiv_media")])
225e4f43
R
9150
9151(define_insn "sqrtdf2_i"
9152 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9153 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9154 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9155 "TARGET_SH4"
9156 "fsqrt %0"
d64264ff
R
9157 [(set_attr "type" "dfdiv")
9158 (set_attr "fp_mode" "double")])
225e4f43
R
9159
9160(define_expand "absdf2"
fa5322fa
AO
9161 [(set (match_operand:DF 0 "arith_reg_operand" "")
9162 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9163 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9164 "
9165{
9166 if (TARGET_SH4)
9167 {
9168 expand_df_unop (&gen_absdf2_i, operands);
9169 DONE;
9170 }
9171}")
9172
9173(define_insn "*absdf2_media"
9174 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9175 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9176 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9177 "fabs.d %1, %0"
9178 [(set_attr "type" "fmove_media")])
225e4f43
R
9179
9180(define_insn "absdf2_i"
9181 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9182 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9183 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9184 "TARGET_SH4"
9185 "fabs %0"
d64264ff
R
9186 [(set_attr "type" "fmove")
9187 (set_attr "fp_mode" "double")])
225e4f43
R
9188
9189(define_expand "extendsfdf2"
fa5322fa
AO
9190 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9191 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9192 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9193 "
9194{
fa5322fa
AO
9195 if (TARGET_SH4)
9196 {
9197 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9198 get_fpscr_rtx ()));
9199 DONE;
9200 }
225e4f43
R
9201}")
9202
fa5322fa
AO
9203(define_insn "*extendsfdf2_media"
9204 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9205 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9206 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9207 "fcnv.sd %1, %0"
9208 [(set_attr "type" "dfpconv_media")])
fa5322fa 9209
225e4f43 9210(define_insn "extendsfdf2_i4"
4b9580a5
R
9211 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9212 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
0c4c9b16 9213 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 9214 "TARGET_SH4"
0c4c9b16 9215 "fcnvsd %1,%0"
d64264ff
R
9216 [(set_attr "type" "fp")
9217 (set_attr "fp_mode" "double")])
225e4f43
R
9218
9219(define_expand "truncdfsf2"
fa5322fa
AO
9220 [(set (match_operand:SF 0 "fpul_operand" "")
9221 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9222 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9223 "
9224{
fa5322fa
AO
9225 if (TARGET_SH4)
9226 {
9227 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9228 get_fpscr_rtx ()));
9229 DONE;
9230 }
225e4f43
R
9231}")
9232
fa5322fa
AO
9233(define_insn "*truncdfsf2_media"
9234 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9235 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9236 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9237 "fcnv.ds %1, %0"
9238 [(set_attr "type" "dfpconv_media")])
fa5322fa 9239
225e4f43 9240(define_insn "truncdfsf2_i4"
4b9580a5
R
9241 [(set (match_operand:SF 0 "fpul_operand" "=y")
9242 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 9243 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 9244 "TARGET_SH4"
0c4c9b16 9245 "fcnvds %1,%0"
d64264ff
R
9246 [(set_attr "type" "fp")
9247 (set_attr "fp_mode" "double")])
45348d9e 9248\f
725de644
JW
9249;; Bit field extract patterns. These give better code for packed bitfields,
9250;; because they allow auto-increment addresses to be generated.
9251
9252(define_expand "insv"
9253 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9254 (match_operand:SI 1 "immediate_operand" "")
9255 (match_operand:SI 2 "immediate_operand" ""))
9256 (match_operand:SI 3 "general_operand" ""))]
fa5322fa 9257 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
725de644
JW
9258 "
9259{
a7f52356
R
9260 rtx addr_target, orig_address, shift_reg, qi_val;
9261 HOST_WIDE_INT bitsize, size, v;
9262 rtx x = operands[3];
725de644
JW
9263
9264 /* ??? expmed doesn't care for non-register predicates. */
9265 if (! memory_operand (operands[0], VOIDmode)
9266 || ! immediate_operand (operands[1], VOIDmode)
9267 || ! immediate_operand (operands[2], VOIDmode)
a7f52356 9268 || ! general_operand (x, VOIDmode))
725de644
JW
9269 FAIL;
9270 /* If this isn't a 16 / 24 / 32 bit field, or if
9271 it doesn't start on a byte boundary, then fail. */
a7f52356
R
9272 bitsize = INTVAL (operands[1]);
9273 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
725de644
JW
9274 || (INTVAL (operands[2]) % 8) != 0)
9275 FAIL;
9276
a7f52356 9277 size = bitsize / 8;
725de644 9278 orig_address = XEXP (operands[0], 0);
725de644 9279 shift_reg = gen_reg_rtx (SImode);
a7f52356
R
9280 if (GET_CODE (x) == CONST_INT)
9281 {
9282 v = INTVAL (x);
9283 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9284 }
9285 else
9286 {
9287 emit_insn (gen_movsi (shift_reg, operands[3]));
9288 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9289 }
ea3cbda5 9290 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
725de644 9291
792760b9 9292 operands[0] = replace_equiv_address (operands[0], addr_target);
a7f52356 9293 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9294
9295 while (size -= 1)
9296 {
a7f52356
R
9297 if (GET_CODE (x) == CONST_INT)
9298 qi_val
9299 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9300 else
9301 {
9302 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9303 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9304 }
a556fd39 9305 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
a7f52356 9306 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9307 }
9308
9309 DONE;
9310}")
9311\f
51bd623f
JW
9312;; -------------------------------------------------------------------------
9313;; Peepholes
9314;; -------------------------------------------------------------------------
961c4780 9315
51bd623f
JW
9316;; This matches cases where a stack pointer increment at the start of the
9317;; epilogue combines with a stack slot read loading the return value.
aa684c94 9318
07a45e5c 9319(define_peephole
51bd623f
JW
9320 [(set (match_operand:SI 0 "arith_reg_operand" "")
9321 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9322 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
fa5322fa 9323 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
51bd623f 9324 "mov.l @%1+,%0")
00f8ff66 9325
51bd623f 9326;; See the comment on the dt combiner pattern above.
00f8ff66 9327
07a45e5c
JW
9328(define_peephole
9329 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
00f8ff66
SC
9330 (plus:SI (match_dup 0)
9331 (const_int -1)))
4773afa4 9332 (set (reg:SI T_REG)
00f8ff66
SC
9333 (eq:SI (match_dup 0)
9334 (const_int 0)))]
9335 "TARGET_SH2"
9336 "dt %0")
e4931540
RK
9337
9338;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9339;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9340;; reload when the constant is too large for a reg+offset address.
9341
9342;; ??? We would get much better code if this was done in reload. This would
9343;; require modifying find_reloads_address to recognize that if the constant
9344;; is out-of-range for an immediate add, then we get better code by reloading
9345;; the constant into a register than by reloading the sum into a register,
9346;; since the former is one instruction shorter if the address does not need
9347;; to be offsettable. Unfortunately this does not work, because there is
9348;; only one register, r0, that can be used as an index register. This register
9349;; is also the function return value register. So, if we try to force reload
9350;; to use double-reg addresses, then we end up with some instructions that
9351;; need to use r0 twice. The only way to fix this is to change the calling
9352;; convention so that r0 is not used to return values.
9353
9354(define_peephole
9355 [(set (match_operand:SI 0 "register_operand" "=r")
9356 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9357 (set (mem:SI (match_dup 0))
9358 (match_operand:SI 2 "general_movsrc_operand" ""))]
fa5322fa 9359 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9360 "mov.l %2,@(%0,%1)")
9361
9362(define_peephole
9363 [(set (match_operand:SI 0 "register_operand" "=r")
9364 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9365 (set (match_operand:SI 2 "general_movdst_operand" "")
9366 (mem:SI (match_dup 0)))]
fa5322fa 9367 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9368 "mov.l @(%0,%1),%2")
9369
9370(define_peephole
9371 [(set (match_operand:SI 0 "register_operand" "=r")
9372 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9373 (set (mem:HI (match_dup 0))
9374 (match_operand:HI 2 "general_movsrc_operand" ""))]
fa5322fa 9375 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9376 "mov.w %2,@(%0,%1)")
9377
9378(define_peephole
9379 [(set (match_operand:SI 0 "register_operand" "=r")
9380 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9381 (set (match_operand:HI 2 "general_movdst_operand" "")
9382 (mem:HI (match_dup 0)))]
fa5322fa 9383 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9384 "mov.w @(%0,%1),%2")
9385
9386(define_peephole
9387 [(set (match_operand:SI 0 "register_operand" "=r")
9388 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9389 (set (mem:QI (match_dup 0))
9390 (match_operand:QI 2 "general_movsrc_operand" ""))]
fa5322fa 9391 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9392 "mov.b %2,@(%0,%1)")
9393
9394(define_peephole
9395 [(set (match_operand:SI 0 "register_operand" "=r")
9396 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9397 (set (match_operand:QI 2 "general_movdst_operand" "")
9398 (mem:QI (match_dup 0)))]
fa5322fa 9399 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9400 "mov.b @(%0,%1),%2")
9401
9402(define_peephole
9403 [(set (match_operand:SI 0 "register_operand" "=r")
9404 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9405 (set (mem:SF (match_dup 0))
9406 (match_operand:SF 2 "general_movsrc_operand" ""))]
fa5322fa 9407 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9408 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9409 || (GET_CODE (operands[2]) == SUBREG
9410 && REGNO (SUBREG_REG (operands[2])) < 16))
9411 && reg_unused_after (operands[0], insn)"
e4931540
RK
9412 "mov.l %2,@(%0,%1)")
9413
9414(define_peephole
9415 [(set (match_operand:SI 0 "register_operand" "=r")
9416 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9417 (set (match_operand:SF 2 "general_movdst_operand" "")
9418
9419 (mem:SF (match_dup 0)))]
fa5322fa 9420 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9421 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9422 || (GET_CODE (operands[2]) == SUBREG
9423 && REGNO (SUBREG_REG (operands[2])) < 16))
9424 && reg_unused_after (operands[0], insn)"
e4931540 9425 "mov.l @(%0,%1),%2")
45348d9e
JW
9426
9427(define_peephole
9428 [(set (match_operand:SI 0 "register_operand" "=r")
9429 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9430 (set (mem:SF (match_dup 0))
9431 (match_operand:SF 2 "general_movsrc_operand" ""))]
3a8699c7 9432 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
9433 && ((GET_CODE (operands[2]) == REG
9434 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9435 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9436 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9437 && reg_unused_after (operands[0], insn)"
1245df60 9438 "fmov{.s|} %2,@(%0,%1)")
45348d9e
JW
9439
9440(define_peephole
9441 [(set (match_operand:SI 0 "register_operand" "=r")
9442 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9443 (set (match_operand:SF 2 "general_movdst_operand" "")
9444
9445 (mem:SF (match_dup 0)))]
3a8699c7 9446 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
9447 && ((GET_CODE (operands[2]) == REG
9448 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9449 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9450 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9451 && reg_unused_after (operands[0], insn)"
1245df60 9452 "fmov{.s|} @(%0,%1),%2")
4408efce
JL
9453
9454;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9455(define_insn "sp_switch_1"
9456 [(const_int 1)]
fa5322fa 9457 "TARGET_SH1"
4408efce
JL
9458 "*
9459{
9460 rtx xoperands[1];
9461
9462 xoperands[0] = sp_switch;
9463 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9464 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9465 return \"mov r0,r15\";
9466}"
9467 [(set_attr "length" "10")])
4408efce 9468
956d6950 9469;; Switch back to the original stack for interrupt functions with the
4408efce
JL
9470;; sp_switch attribute. */
9471(define_insn "sp_switch_2"
9472 [(const_int 2)]
fa5322fa 9473 "TARGET_SH1"
4408efce
JL
9474 "mov.l @r15+,r15\;mov.l @r15+,r0"
9475 [(set_attr "length" "4")])
fae15c93 9476
c1b92d09
R
9477;; Integer vector moves
9478
9479(define_expand "movv8qi"
9480 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9481 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9482 "TARGET_SHMEDIA"
9483 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9484
9485(define_insn "movv8qi_i"
9486 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9487 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9488 "TARGET_SHMEDIA
9489 && (register_operand (operands[0], V8QImode)
d9da94a1 9490 || sh_register_operand (operands[1], V8QImode))"
c1b92d09
R
9491 "@
9492 add %1, r63, %0
9493 movi %1, %0
9494 #
9495 ld%M1.q %m1, %0
d9da94a1 9496 st%M0.q %m0, %N1"
c1b92d09
R
9497 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9498 (set_attr "length" "4,4,16,4,4")])
9499
9500(define_split
9501 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9502 (subreg:V8QI (const_int 0) 0))]
9503 "TARGET_SHMEDIA"
9504 [(set (match_dup 0)
9505 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9506 (const_int 0) (const_int 0) (const_int 0)
9507 (const_int 0) (const_int 0)]))])
9508
9509(define_split
9510 [(set (match_operand 0 "arith_reg_dest" "")
9511 (match_operand 1 "sh_rep_vec" ""))]
9512 "TARGET_SHMEDIA && reload_completed
9513 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9514 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9515 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9516 && (XVECEXP (operands[1], 0, 0) != const0_rtx
c034672a
R
9517 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9518 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9519 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
c1b92d09
R
9520 [(set (match_dup 0) (match_dup 1))
9521 (match_dup 2)]
9522 "
9523{
9524 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9525 rtx elt1 = XVECEXP (operands[1], 0, 1);
9526
9527 if (unit_size > 2)
9528 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9529 else
750afc12
R
9530 {
9531 if (unit_size < 2)
9532 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9533 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9534 }
c1b92d09
R
9535 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9536 operands[1] = XVECEXP (operands[1], 0, 0);
9537 if (unit_size < 2)
9538 {
9539 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
40779a72
R
9540 operands[1]
9541 = GEN_INT (TARGET_LITTLE_ENDIAN
9542 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9543 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
c1b92d09
R
9544 else
9545 {
9546 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9547 operands[1]
9548 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9549 }
9550 }
9551}")
9552
9553(define_split
9554 [(set (match_operand 0 "arith_reg_dest" "")
9555 (match_operand 1 "sh_const_vec" ""))]
9556 "TARGET_SHMEDIA && reload_completed
9557 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9558 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
0ac78517 9559 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
c1b92d09
R
9560 [(set (match_dup 0) (match_dup 1))]
9561 "
9562{
9563 rtx v = operands[1];
9564 enum machine_mode new_mode
9565 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9566
9567 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9568 operands[1]
52702ae1 9569 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
c1b92d09
R
9570}")
9571
9572(define_expand "movv2hi"
9573 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9574 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9575 "TARGET_SHMEDIA"
9576 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9577
9578(define_insn "movv2hi_i"
9579 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9580 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9581 "TARGET_SHMEDIA
9582 && (register_operand (operands[0], V2HImode)
d9da94a1 9583 || sh_register_operand (operands[1], V2HImode))"
c1b92d09
R
9584 "@
9585 addz.l %1, r63, %0
9586 movi %1, %0
9587 #
9588 ld%M1.l %m1, %0
d9da94a1 9589 st%M0.l %m0, %N1"
c1b92d09
R
9590 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9591 (set_attr "length" "4,4,16,4,4")])
9592
9593(define_expand "movv4hi"
9594 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9595 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9596 "TARGET_SHMEDIA"
9597 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9598
9599(define_insn "movv4hi_i"
9600 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9601 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9602 "TARGET_SHMEDIA
9603 && (register_operand (operands[0], V4HImode)
d9da94a1 9604 || sh_register_operand (operands[1], V4HImode))"
c1b92d09
R
9605 "@
9606 add %1, r63, %0
9607 movi %1, %0
9608 #
9609 ld%M1.q %m1, %0
d9da94a1 9610 st%M0.q %m0, %N1"
c1b92d09
R
9611 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9612 (set_attr "length" "4,4,16,4,4")])
9613
9614(define_expand "movv2si"
9615 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9616 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9617 "TARGET_SHMEDIA"
9618 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9619
9620(define_insn "movv2si_i"
9621 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9622 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9623 "TARGET_SHMEDIA
9624 && (register_operand (operands[0], V2SImode)
d9da94a1 9625 || sh_register_operand (operands[1], V2SImode))"
c1b92d09
R
9626 "@
9627 add %1, r63, %0
52702ae1 9628 #
c1b92d09
R
9629 #
9630 ld%M1.q %m1, %0
d9da94a1 9631 st%M0.q %m0, %N1"
c1b92d09
R
9632 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9633 (set_attr "length" "4,4,16,4,4")])
9634
9635;; Multimedia Intrinsics
9636
9637(define_insn "absv2si2"
9638 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9639 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9640 "TARGET_SHMEDIA"
9641 "mabs.l %1, %0"
9642 [(set_attr "type" "mcmp_media")])
9643
9644(define_insn "absv4hi2"
9645 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9646 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9647 "TARGET_SHMEDIA"
9648 "mabs.w %1, %0"
9649 [(set_attr "type" "mcmp_media")])
9650
9651(define_insn "addv2si3"
9652 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9653 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9654 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9655 "TARGET_SHMEDIA"
9656 "madd.l %1, %2, %0"
9657 [(set_attr "type" "arith_media")])
9658
9659(define_insn "addv4hi3"
9660 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9661 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9662 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9663 "TARGET_SHMEDIA"
9664 "madd.w %1, %2, %0"
9665 [(set_attr "type" "arith_media")])
9666
9667(define_insn "ssaddv2si3"
9668 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9669 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9670 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9671 "TARGET_SHMEDIA"
9672 "madds.l %1, %2, %0"
9673 [(set_attr "type" "mcmp_media")])
9674
9675(define_insn "usaddv8qi3"
9676 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9677 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9678 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9679 "TARGET_SHMEDIA"
9680 "madds.ub %1, %2, %0"
9681 [(set_attr "type" "mcmp_media")])
9682
9683(define_insn "ssaddv4hi3"
9684 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9685 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9686 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9687 "TARGET_SHMEDIA"
9688 "madds.w %1, %2, %0"
9689 [(set_attr "type" "mcmp_media")])
9690
9691(define_insn "negcmpeqv8qi"
9692 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
9693 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9694 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9695 "TARGET_SHMEDIA"
9696 "mcmpeq.b %N1, %N2, %0"
9697 [(set_attr "type" "mcmp_media")])
9698
9699(define_insn "negcmpeqv2si"
9700 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
9701 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9702 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9703 "TARGET_SHMEDIA"
9704 "mcmpeq.l %N1, %N2, %0"
9705 [(set_attr "type" "mcmp_media")])
9706
9707(define_insn "negcmpeqv4hi"
9708 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
9709 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9710 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9711 "TARGET_SHMEDIA"
9712 "mcmpeq.w %N1, %N2, %0"
9713 [(set_attr "type" "mcmp_media")])
9714
9715(define_insn "negcmpgtuv8qi"
9716 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
9717 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9718 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9719 "TARGET_SHMEDIA"
9720 "mcmpgt.ub %N1, %N2, %0"
9721 [(set_attr "type" "mcmp_media")])
9722
9723(define_insn "negcmpgtv2si"
9724 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
9725 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9726 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9727 "TARGET_SHMEDIA"
9728 "mcmpgt.l %N1, %N2, %0"
9729 [(set_attr "type" "mcmp_media")])
9730
9731(define_insn "negcmpgtv4hi"
9732 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
9733 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9734 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9735 "TARGET_SHMEDIA"
9736 "mcmpgt.w %N1, %N2, %0"
9737 [(set_attr "type" "mcmp_media")])
9738
9739(define_insn "mcmv"
9740 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9741 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9742 (match_operand:DI 2 "arith_reg_operand" "r"))
9743 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9744 (not:DI (match_dup 2)))))]
9745 "TARGET_SHMEDIA"
9746 "mcmv %N1, %2, %0"
9747 [(set_attr "type" "arith_media")])
9748
9749(define_insn "mcnvs_lw"
9750 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9751 (vec_concat:V4HI
735cb76e
R
9752 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9753 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9754 "TARGET_SHMEDIA"
9755 "mcnvs.lw %N1, %N2, %0"
9756 [(set_attr "type" "mcmp_media")])
9757
9758(define_insn "mcnvs_wb"
9759 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9760 (vec_concat:V8QI
735cb76e
R
9761 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9762 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9763 "TARGET_SHMEDIA"
9764 "mcnvs.wb %N1, %N2, %0"
9765 [(set_attr "type" "mcmp_media")])
9766
9767(define_insn "mcnvs_wub"
9768 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9769 (vec_concat:V8QI
735cb76e
R
9770 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9771 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9772 "TARGET_SHMEDIA"
9773 "mcnvs.wub %N1, %N2, %0"
9774 [(set_attr "type" "mcmp_media")])
9775
9776(define_insn "mextr_rl"
9777 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9778 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 9779 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 9780 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9781 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9782 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9783 "*
9784{
9785 static char templ[16];
9786
9787 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9788 (int) INTVAL (operands[3]) >> 3);
9789 return templ;
9790}"
9791 [(set_attr "type" "arith_media")])
9792
9793(define_insn "*mextr_lr"
9794 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9795 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 9796 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 9797 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9798 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9799 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9800 "*
9801{
9802 static char templ[16];
9803
9804 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9805 (int) INTVAL (operands[4]) >> 3);
9806 return templ;
9807}"
9808 [(set_attr "type" "arith_media")])
9809
9810; mextrN can be modelled with vec_select / vec_concat, but the selection
9811; vector then varies depending on endianness.
9812(define_expand "mextr1"
0ac78517 9813 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9814 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9815 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9816 "TARGET_SHMEDIA"
9817 "
9818{
0ac78517 9819 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9820 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9821 DONE;
9822}")
9823
9824(define_expand "mextr2"
0ac78517 9825 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9826 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9827 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9828 "TARGET_SHMEDIA"
9829 "
9830{
0ac78517 9831 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9832 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9833 DONE;
9834}")
9835
9836(define_expand "mextr3"
0ac78517 9837 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9838 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9839 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9840 "TARGET_SHMEDIA"
9841 "
9842{
0ac78517 9843 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9844 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9845 DONE;
9846}")
9847
9848(define_expand "mextr4"
0ac78517 9849 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9850 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9851 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9852 "TARGET_SHMEDIA"
9853 "
9854{
0ac78517 9855 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9856 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9857 DONE;
9858}")
9859
9860(define_expand "mextr5"
0ac78517 9861 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9862 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9863 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9864 "TARGET_SHMEDIA"
9865 "
9866{
0ac78517 9867 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9868 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9869 DONE;
9870}")
9871
9872(define_expand "mextr6"
0ac78517 9873 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9874 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9875 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9876 "TARGET_SHMEDIA"
9877 "
9878{
0ac78517 9879 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9880 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9881 DONE;
9882}")
9883
9884(define_expand "mextr7"
0ac78517 9885 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9886 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9887 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9888 "TARGET_SHMEDIA"
9889 "
9890{
0ac78517 9891 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9892 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9893 DONE;
9894}")
9895
9896(define_expand "mmacfx_wl"
9897 [(match_operand:V2SI 0 "arith_reg_dest" "")
9898 (match_operand:V2HI 1 "extend_reg_operand" "")
9899 (match_operand:V2HI 2 "extend_reg_operand" "")
9900 (match_operand:V2SI 3 "arith_reg_operand" "")]
9901 "TARGET_SHMEDIA"
9902 "
9903{
9904 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9905 operands[1], operands[2]));
9906 DONE;
9907}")
9908
9909(define_insn "mmacfx_wl_i"
9910 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9911 (ss_plus:V2SI
9912 (match_operand:V2SI 1 "arith_reg_operand" "0")
9913 (ss_truncate:V2SI
9914 (ashift:V2DI
9915 (sign_extend:V2DI
9916 (mult:V2SI
9917 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9918 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9919 (const_int 1)))))]
9920 "TARGET_SHMEDIA"
9921 "mmacfx.wl %2, %3, %0"
9922 [(set_attr "type" "mac_media")])
9923
9924(define_expand "mmacnfx_wl"
9925 [(match_operand:V2SI 0 "arith_reg_dest" "")
9926 (match_operand:V2HI 1 "extend_reg_operand" "")
9927 (match_operand:V2HI 2 "extend_reg_operand" "")
9928 (match_operand:V2SI 3 "arith_reg_operand" "")]
9929 "TARGET_SHMEDIA"
9930 "
9931{
9932 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9933 operands[1], operands[2]));
9934 DONE;
9935}")
9936
9937(define_insn "mmacnfx_wl_i"
9938 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9939 (ss_minus:V2SI
9940 (match_operand:V2SI 1 "arith_reg_operand" "0")
9941 (ss_truncate:V2SI
9942 (ashift:V2DI
9943 (sign_extend:V2DI
9944 (mult:V2SI
9945 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9946 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9947 (const_int 1)))))]
9948 "TARGET_SHMEDIA"
9949 "mmacnfx.wl %2, %3, %0"
9950 [(set_attr "type" "mac_media")])
9951
9952(define_insn "mulv2si3"
9953 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9954 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9955 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9956 "TARGET_SHMEDIA"
9957 "mmul.l %1, %2, %0"
9958 [(set_attr "type" "d2mpy_media")])
9959
9960(define_insn "mulv4hi3"
9961 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9962 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9963 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9964 "TARGET_SHMEDIA"
9965 "mmul.w %1, %2, %0"
9966 [(set_attr "type" "dmpy_media")])
9967
9968(define_insn "mmulfx_l"
9969 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9970 (ss_truncate:V2SI
9971 (ashiftrt:V2DI
9972 (mult:V2DI
9973 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9974 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9975 (const_int 31))))]
9976 "TARGET_SHMEDIA"
9977 "mmulfx.l %1, %2, %0"
9978 [(set_attr "type" "d2mpy_media")])
9979
9980(define_insn "mmulfx_w"
9981 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9982 (ss_truncate:V4HI
9983 (ashiftrt:V4SI
9984 (mult:V4SI
9985 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9986 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9987 (const_int 15))))]
9988 "TARGET_SHMEDIA"
9989 "mmulfx.w %1, %2, %0"
9990 [(set_attr "type" "dmpy_media")])
9991
9992(define_insn "mmulfxrp_w"
9993 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9994 (ss_truncate:V4HI
9995 (ashiftrt:V4SI
9996 (plus:V4SI
9997 (mult:V4SI
9998 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9999 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10000 (const_int 16384))
10001 (const_int 15))))]
10002 "TARGET_SHMEDIA"
10003 "mmulfxrp.w %1, %2, %0"
10004 [(set_attr "type" "dmpy_media")])
10005
10006(define_expand "mmulhi_wl"
10007 [(match_operand:V2SI 0 "arith_reg_dest" "")
10008 (match_operand:V4HI 1 "arith_reg_operand" "")
10009 (match_operand:V4HI 2 "arith_reg_operand" "")]
10010 "TARGET_SHMEDIA"
10011 "
10012{
10013 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10014 (operands[0], operands[1], operands[2]));
10015 DONE;
10016}")
10017
10018(define_expand "mmullo_wl"
10019 [(match_operand:V2SI 0 "arith_reg_dest" "")
10020 (match_operand:V4HI 1 "arith_reg_operand" "")
10021 (match_operand:V4HI 2 "arith_reg_operand" "")]
10022 "TARGET_SHMEDIA"
10023 "
10024{
10025 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10026 (operands[0], operands[1], operands[2]));
10027 DONE;
10028}")
10029
10030(define_insn "mmul23_wl"
10031 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10032 (vec_select:V2SI
10033 (mult:V4SI
10034 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10035 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 10036 (parallel [(const_int 2) (const_int 3)])))]
c1b92d09
R
10037 "TARGET_SHMEDIA"
10038 "* return (TARGET_LITTLE_ENDIAN
10039 ? \"mmulhi.wl %1, %2, %0\"
10040 : \"mmullo.wl %1, %2, %0\");"
10041 [(set_attr "type" "dmpy_media")])
10042
10043(define_insn "mmul01_wl"
10044 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10045 (vec_select:V2SI
10046 (mult:V4SI
10047 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10048 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 10049 (parallel [(const_int 0) (const_int 1)])))]
c1b92d09
R
10050 "TARGET_SHMEDIA"
10051 "* return (TARGET_LITTLE_ENDIAN
10052 ? \"mmullo.wl %1, %2, %0\"
10053 : \"mmulhi.wl %1, %2, %0\");"
10054 [(set_attr "type" "dmpy_media")])
10055
10056(define_expand "mmulsum_wq"
10057 [(match_operand:DI 0 "arith_reg_dest" "")
10058 (match_operand:V4HI 1 "arith_reg_operand" "")
10059 (match_operand:V4HI 2 "arith_reg_operand" "")
10060 (match_operand:DI 3 "arith_reg_operand" "")]
10061 "TARGET_SHMEDIA"
10062 "
10063{
10064 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10065 operands[1], operands[2]));
10066 DONE;
10067}")
10068
10069(define_insn "mmulsum_wq_i"
10070 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10071 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10072 (plus:DI
10073 (plus:DI
10074 (vec_select:DI
10075 (mult:V4DI
10076 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10077 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
0ac78517 10078 (parallel [(const_int 0)]))
c1b92d09
R
10079 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10080 (sign_extend:V4DI (match_dup 3)))
0ac78517 10081 (parallel [(const_int 1)])))
c1b92d09
R
10082 (plus:DI
10083 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10084 (sign_extend:V4DI (match_dup 3)))
0ac78517 10085 (parallel [(const_int 2)]))
c1b92d09
R
10086 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10087 (sign_extend:V4DI (match_dup 3)))
0ac78517 10088 (parallel [(const_int 3)]))))))]
c1b92d09
R
10089 "TARGET_SHMEDIA"
10090 "mmulsum.wq %2, %3, %0"
10091 [(set_attr "type" "mac_media")])
10092
10093(define_expand "mperm_w"
10094 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10095 (match_operand:V4HI 1 "arith_reg_operand" "r")
735cb76e 10096 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
c1b92d09
R
10097 "TARGET_SHMEDIA"
10098 "
10099{
10100 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10101 (operands[0], operands[1], operands[2]));
c49439f1 10102 DONE;
c1b92d09
R
10103}")
10104
10105; This use of vec_select isn't exactly correct according to rtl.texi
10106; (because not constant), but it seems a straightforward extension.
10107(define_insn "mperm_w_little"
10108 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10109 (vec_select:V4HI
10110 (match_operand:V4HI 1 "arith_reg_operand" "r")
10111 (parallel
735cb76e 10112 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
502e6d5a
R
10113 (const_int 2) (const_int 0))
10114 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10115 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10116 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
c1b92d09
R
10117 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10118 "mperm.w %1, %N2, %0"
10119 [(set_attr "type" "arith_media")])
10120
10121(define_insn "mperm_w_big"
10122 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10123 (vec_select:V4HI
10124 (match_operand:V4HI 1 "arith_reg_operand" "r")
10125 (parallel
502e6d5a 10126 [(zero_extract:QI (not:QI (match_operand:QI 2
735cb76e 10127 "extend_reg_or_0_operand" "rZ"))
502e6d5a
R
10128 (const_int 2) (const_int 0))
10129 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10130 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10131 (zero_extract:QI (not:QI (match_dup 2))
10132 (const_int 2) (const_int 6))])))]
c1b92d09
R
10133 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10134 "mperm.w %1, %N2, %0"
10135 [(set_attr "type" "arith_media")])
10136
10137(define_insn "mperm_w0"
10138 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10139 (vec_duplicate:V4HI (truncate:HI (match_operand 1
e69d1422 10140 "trunc_hi_operand" "r"))))]
c1b92d09
R
10141 "TARGET_SHMEDIA"
10142 "mperm.w %1, r63, %0"
10143 [(set_attr "type" "arith_media")])
10144
10145(define_expand "msad_ubq"
10146 [(match_operand:DI 0 "arith_reg_dest" "")
10147 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10148 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10149 (match_operand:DI 3 "arith_reg_operand" "")]
10150 "TARGET_SHMEDIA"
10151 "
10152{
10153 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10154 operands[1], operands[2]));
10155 DONE;
10156}")
10157
10158(define_insn "msad_ubq_i"
10159 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10160 (plus:DI
10161 (plus:DI
10162 (plus:DI
10163 (plus:DI
10164 (match_operand:DI 1 "arith_reg_operand" "0")
10165 (abs:DI (vec_select:DI
10166 (minus:V8DI
10167 (zero_extend:V8DI
735cb76e 10168 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
c1b92d09 10169 (zero_extend:V8DI
735cb76e 10170 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
0ac78517 10171 (parallel [(const_int 0)]))))
c1b92d09
R
10172 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10173 (zero_extend:V8DI (match_dup 3)))
0ac78517 10174 (parallel [(const_int 1)]))))
c1b92d09
R
10175 (plus:DI
10176 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10177 (zero_extend:V8DI (match_dup 3)))
0ac78517 10178 (parallel [(const_int 2)])))
c1b92d09
R
10179 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10180 (zero_extend:V8DI (match_dup 3)))
0ac78517 10181 (parallel [(const_int 3)])))))
c1b92d09
R
10182 (plus:DI
10183 (plus:DI
10184 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10185 (zero_extend:V8DI (match_dup 3)))
0ac78517 10186 (parallel [(const_int 4)])))
c1b92d09
R
10187 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10188 (zero_extend:V8DI (match_dup 3)))
0ac78517 10189 (parallel [(const_int 5)]))))
c1b92d09
R
10190 (plus:DI
10191 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10192 (zero_extend:V8DI (match_dup 3)))
0ac78517 10193 (parallel [(const_int 6)])))
c1b92d09
R
10194 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10195 (zero_extend:V8DI (match_dup 3)))
0ac78517 10196 (parallel [(const_int 7)])))))))]
c1b92d09
R
10197 "TARGET_SHMEDIA"
10198 "msad.ubq %N2, %N3, %0"
10199 [(set_attr "type" "mac_media")])
10200
10201(define_insn "mshalds_l"
10202 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10203 (ss_truncate:V2SI
10204 (ashift:V2DI
10205 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10206 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10207 (const_int 31)))))]
10208 "TARGET_SHMEDIA"
10209 "mshalds.l %1, %2, %0"
10210 [(set_attr "type" "mcmp_media")])
10211
10212(define_insn "mshalds_w"
10213 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10214 (ss_truncate:V4HI
10215 (ashift:V4SI
10216 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10217 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10218 (const_int 15)))))]
10219 "TARGET_SHMEDIA"
10220 "mshalds.w %1, %2, %0"
10221 [(set_attr "type" "mcmp_media")])
10222
10223(define_insn "ashrv2si3"
10224 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10225 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10226 (match_operand:DI 2 "arith_reg_operand" "r")))]
10227 "TARGET_SHMEDIA"
10228 "mshard.l %1, %2, %0"
10229 [(set_attr "type" "arith_media")])
10230
10231(define_insn "ashrv4hi3"
10232 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10233 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10234 (match_operand:DI 2 "arith_reg_operand" "r")))]
10235 "TARGET_SHMEDIA"
10236 "mshard.w %1, %2, %0"
10237 [(set_attr "type" "arith_media")])
10238
10239(define_insn "mshards_q"
10240 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10241 (ss_truncate:HI
10242 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
735cb76e 10243 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
10244 "TARGET_SHMEDIA"
10245 "mshards.q %1, %N2, %0"
10246 [(set_attr "type" "mcmp_media")])
10247
10248(define_expand "mshfhi_b"
10249 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
10250 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10251 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10252 "TARGET_SHMEDIA"
10253 "
10254{
10255 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10256 (operands[0], operands[1], operands[2]));
8721e3df 10257 DONE;
c1b92d09
R
10258}")
10259
10260(define_expand "mshflo_b"
10261 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
10262 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10263 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10264 "TARGET_SHMEDIA"
10265 "
10266{
10267 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10268 (operands[0], operands[1], operands[2]));
8721e3df 10269 DONE;
c1b92d09
R
10270}")
10271
10272(define_insn "mshf4_b"
10273 [(set
10274 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10275 (vec_select:V8QI
735cb76e
R
10276 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10277 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
10278 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10279 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
c1b92d09
R
10280 "TARGET_SHMEDIA"
10281 "* return (TARGET_LITTLE_ENDIAN
10282 ? \"mshfhi.b %N1, %N2, %0\"
10283 : \"mshflo.b %N1, %N2, %0\");"
10284 [(set_attr "type" "arith_media")])
10285
10286(define_insn "mshf0_b"
10287 [(set
10288 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10289 (vec_select:V8QI
735cb76e
R
10290 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10291 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
10292 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10293 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
c1b92d09
R
10294 "TARGET_SHMEDIA"
10295 "* return (TARGET_LITTLE_ENDIAN
10296 ? \"mshflo.b %N1, %N2, %0\"
10297 : \"mshfhi.b %N1, %N2, %0\");"
10298 [(set_attr "type" "arith_media")])
10299
10300(define_expand "mshfhi_l"
10301 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
10302 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10303 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10304 "TARGET_SHMEDIA"
10305 "
10306{
10307 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10308 (operands[0], operands[1], operands[2]));
8721e3df 10309 DONE;
c1b92d09
R
10310}")
10311
10312(define_expand "mshflo_l"
10313 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
10314 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10315 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10316 "TARGET_SHMEDIA"
10317 "
10318{
10319 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10320 (operands[0], operands[1], operands[2]));
8721e3df 10321 DONE;
c1b92d09
R
10322}")
10323
10324(define_insn "mshf4_l"
10325 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10326 (vec_select:V2SI
735cb76e
R
10327 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10328 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10329 (parallel [(const_int 1) (const_int 3)])))]
c1b92d09
R
10330 "TARGET_SHMEDIA"
10331 "* return (TARGET_LITTLE_ENDIAN
10332 ? \"mshfhi.l %N1, %N2, %0\"
10333 : \"mshflo.l %N1, %N2, %0\");"
10334 [(set_attr "type" "arith_media")])
10335
10336(define_insn "mshf0_l"
10337 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10338 (vec_select:V2SI
735cb76e
R
10339 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10340 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10341 (parallel [(const_int 0) (const_int 2)])))]
c1b92d09
R
10342 "TARGET_SHMEDIA"
10343 "* return (TARGET_LITTLE_ENDIAN
10344 ? \"mshflo.l %N1, %N2, %0\"
10345 : \"mshfhi.l %N1, %N2, %0\");"
10346 [(set_attr "type" "arith_media")])
10347
10348(define_expand "mshfhi_w"
10349 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
10350 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10351 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10352 "TARGET_SHMEDIA"
10353 "
10354{
10355 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10356 (operands[0], operands[1], operands[2]));
8721e3df 10357 DONE;
c1b92d09
R
10358}")
10359
10360(define_expand "mshflo_w"
10361 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
10362 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10363 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10364 "TARGET_SHMEDIA"
10365 "
10366{
10367 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10368 (operands[0], operands[1], operands[2]));
8721e3df 10369 DONE;
c1b92d09
R
10370}")
10371
10372(define_insn "mshf4_w"
10373 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10374 (vec_select:V4HI
735cb76e
R
10375 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10376 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10377 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
c1b92d09
R
10378 "TARGET_SHMEDIA"
10379 "* return (TARGET_LITTLE_ENDIAN
10380 ? \"mshfhi.w %N1, %N2, %0\"
10381 : \"mshflo.w %N1, %N2, %0\");"
10382 [(set_attr "type" "arith_media")])
10383
10384(define_insn "mshf0_w"
10385 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10386 (vec_select:V4HI
735cb76e
R
10387 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10388 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10389 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
c1b92d09
R
10390 "TARGET_SHMEDIA"
10391 "* return (TARGET_LITTLE_ENDIAN
10392 ? \"mshflo.w %N1, %N2, %0\"
10393 : \"mshfhi.w %N1, %N2, %0\");"
10394 [(set_attr "type" "arith_media")])
10395
0ac78517
R
10396(define_insn "mshflo_w_x"
10397 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10398 (vec_select:V4HI
735cb76e
R
10399 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10400 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
08c43ea7 10401 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
0ac78517
R
10402 "TARGET_SHMEDIA"
10403 "mshflo.w %N1, %N2, %0"
10404 [(set_attr "type" "arith_media")])
10405
c1b92d09 10406/* These are useful to expand ANDs and as combiner patterns. */
0ac78517
R
10407(define_insn_and_split "mshfhi_l_di"
10408 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
735cb76e 10409 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
c1b92d09 10410 (const_int 32))
735cb76e 10411 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
c1b92d09
R
10412 (const_int -4294967296))))]
10413 "TARGET_SHMEDIA"
0ac78517
R
10414 "@
10415 mshfhi.l %N1, %N2, %0
10416 #"
10417 "TARGET_SHMEDIA && reload_completed
10418 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10419 [(set (match_dup 3) (match_dup 4))
10420 (set (match_dup 5) (match_dup 6))]
10421 "
10422{
10423 operands[3] = gen_lowpart (SImode, operands[0]);
10424 operands[4] = gen_highpart (SImode, operands[1]);
10425 operands[5] = gen_highpart (SImode, operands[0]);
10426 operands[6] = gen_highpart (SImode, operands[2]);
10427}"
c1b92d09
R
10428 [(set_attr "type" "arith_media")])
10429
10430(define_insn "*mshfhi_l_di_rev"
10431 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10432 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10433 (const_int -4294967296))
735cb76e 10434 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10435 (const_int 32))))]
10436 "TARGET_SHMEDIA"
10437 "mshfhi.l %N2, %N1, %0"
10438 [(set_attr "type" "arith_media")])
10439
52702ae1
R
10440(define_split
10441 [(set (match_operand:DI 0 "arith_reg_dest" "")
10442 (ior:DI (zero_extend:DI (match_operand:SI 1
10443 "extend_reg_or_0_operand" ""))
10444 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10445 (const_int -4294967296))))
10446 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10447 "TARGET_SHMEDIA"
10448 [(const_int 0)]
10449 "
10450{
10451 emit_insn (gen_ashldi3_media (operands[3],
10452 simplify_gen_subreg (DImode, operands[1],
10453 SImode, 0),
10454 GEN_INT (32)));
10455 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10456 DONE;
10457}")
10458
c1b92d09
R
10459(define_insn "mshflo_l_di"
10460 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10461 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10462 (const_int 4294967295))
735cb76e 10463 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 10464 (const_int 32))))]
73774972 10465
c1b92d09
R
10466 "TARGET_SHMEDIA"
10467 "mshflo.l %N1, %N2, %0"
10468 [(set_attr "type" "arith_media")])
10469
10470(define_insn "*mshflo_l_di_rev"
10471 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10472 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10473 (const_int 32))
735cb76e 10474 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 10475 (const_int 4294967295))))]
73774972 10476
c1b92d09
R
10477 "TARGET_SHMEDIA"
10478 "mshflo.l %N2, %N1, %0"
10479 [(set_attr "type" "arith_media")])
10480
ca903bba
R
10481;; Combiner pattern for trampoline initialization.
10482(define_insn_and_split "*double_shori"
10483 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10484 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10485 (const_int 32))
10486 (match_operand:DI 2 "const_int_operand" "n")))]
10487 "TARGET_SHMEDIA
10488 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10489 "#"
10490 "rtx_equal_p (operands[0], operands[1])"
10491 [(const_int 0)]
10492 "
10493{
10494 HOST_WIDE_INT v = INTVAL (operands[2]);
10495
10496 emit_insn (gen_shori_media (operands[0], operands[0],
10497 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10498 emit_insn (gen_shori_media (operands[0], operands[0],
10499 gen_int_mode (v, HImode)));
10500 DONE;
10501}")
10502
10503
c1b92d09
R
10504(define_insn "*mshflo_l_di_x"
10505 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
0ac78517 10506 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
735cb76e
R
10507 "rZ"))
10508 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 10509 (const_int 32))))]
73774972 10510
c1b92d09
R
10511 "TARGET_SHMEDIA"
10512 "mshflo.l %N1, %N2, %0"
10513 [(set_attr "type" "arith_media")])
10514
0ac78517
R
10515(define_insn_and_split "concat_v2sf"
10516 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
735cb76e
R
10517;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10518 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10519 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
73774972 10520
0ac78517
R
10521 "TARGET_SHMEDIA"
10522 "@
10523 mshflo.l %N1, %N2, %0
10524 #
10525 #"
10526 "TARGET_SHMEDIA && reload_completed
10527 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10528 [(set (match_dup 3) (match_dup 1))
10529 (set (match_dup 4) (match_dup 2))]
10530 "
10531{
10532 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10533 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10534}"
10535 [(set_attr "type" "arith_media")])
10536
c1b92d09
R
10537(define_insn "*mshflo_l_di_x_rev"
10538 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10539 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10540 (const_int 32))
735cb76e 10541 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
73774972 10542
c1b92d09
R
10543 "TARGET_SHMEDIA"
10544 "mshflo.l %N2, %N1, %0"
10545 [(set_attr "type" "arith_media")])
10546
10547(define_insn "ashlv2si3"
10548 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10549 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10550 (match_operand:DI 2 "arith_reg_operand" "r")))]
10551 "TARGET_SHMEDIA"
10552 "mshlld.l %1, %2, %0"
10553 [(set_attr "type" "arith_media")])
10554
10555(define_insn "ashlv4hi3"
10556 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10557 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10558 (match_operand:DI 2 "arith_reg_operand" "r")))]
10559 "TARGET_SHMEDIA"
10560 "mshlld.w %1, %2, %0"
10561 [(set_attr "type" "arith_media")])
10562
10563(define_insn "lshrv2si3"
10564 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10565 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10566 (match_operand:DI 2 "arith_reg_operand" "r")))]
10567 "TARGET_SHMEDIA"
10568 "mshlrd.l %1, %2, %0"
10569 [(set_attr "type" "arith_media")])
10570
10571(define_insn "lshrv4hi3"
10572 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10573 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10574 (match_operand:DI 2 "arith_reg_operand" "r")))]
10575 "TARGET_SHMEDIA"
10576 "mshlrd.w %1, %2, %0"
10577 [(set_attr "type" "arith_media")])
10578
10579(define_insn "subv2si3"
10580 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 10581 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10582 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10583 "TARGET_SHMEDIA"
10584 "msub.l %N1, %2, %0"
10585 [(set_attr "type" "arith_media")])
10586
10587(define_insn "subv4hi3"
10588 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 10589 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10590 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10591 "TARGET_SHMEDIA"
10592 "msub.w %N1, %2, %0"
10593 [(set_attr "type" "arith_media")])
10594
10595(define_insn "sssubv2si3"
10596 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 10597 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10598 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10599 "TARGET_SHMEDIA"
10600 "msubs.l %N1, %2, %0"
10601 [(set_attr "type" "mcmp_media")])
10602
10603(define_insn "ussubv8qi3"
10604 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10605 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10606 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10607 "TARGET_SHMEDIA"
10608 "msubs.ub %1, %2, %0"
10609 [(set_attr "type" "mcmp_media")])
10610
10611(define_insn "sssubv4hi3"
10612 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 10613 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10614 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10615 "TARGET_SHMEDIA"
10616 "msubs.w %N1, %2, %0"
10617 [(set_attr "type" "mcmp_media")])
10618
10619;; Floating Point Intrinsics
10620
10621(define_insn "fcosa_s"
10622 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10623 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10624 UNSPEC_FCOSA))]
10625 "TARGET_SHMEDIA"
10626 "fcosa.s %1, %0"
10627 [(set_attr "type" "atrans_media")])
10628
10629(define_insn "fsina_s"
10630 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10631 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10632 UNSPEC_FSINA))]
10633 "TARGET_SHMEDIA"
10634 "fsina.s %1, %0"
10635 [(set_attr "type" "atrans_media")])
10636
10637(define_insn "fipr"
10638 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10639 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10640 "fp_arith_reg_operand" "f")
10641 (match_operand:V4SF 2
10642 "fp_arith_reg_operand" "f"))
0ac78517 10643 (parallel [(const_int 0)]))
c1b92d09 10644 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10645 (parallel [(const_int 1)])))
c1b92d09 10646 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10647 (parallel [(const_int 2)]))
c1b92d09 10648 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10649 (parallel [(const_int 3)])))))]
c1b92d09 10650 "TARGET_SHMEDIA"
40779a72 10651 "fipr.s %1, %2, %0"
c1b92d09
R
10652 [(set_attr "type" "fparith_media")])
10653
10654(define_insn "fsrra_s"
10655 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10656 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10657 UNSPEC_FSRRA))]
10658 "TARGET_SHMEDIA"
10659 "fsrra.s %1, %0"
10660 [(set_attr "type" "atrans_media")])
10661
10662(define_insn "ftrv"
10663 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10664 (plus:V4SF
10665 (plus:V4SF
10666 (mult:V4SF
10667 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
0ac78517
R
10668 (parallel [(const_int 0) (const_int 5)
10669 (const_int 10) (const_int 15)]))
c1b92d09
R
10670 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10671 (mult:V4SF
10672 (vec_select:V4SF (match_dup 1)
0ac78517
R
10673 (parallel [(const_int 4) (const_int 9)
10674 (const_int 14) (const_int 3)]))
c1b92d09 10675 (vec_select:V4SF (match_dup 2)
0ac78517 10676 (parallel [(const_int 1) (const_int 2)
40779a72 10677 (const_int 3) (const_int 0)]))))
c1b92d09
R
10678 (plus:V4SF
10679 (mult:V4SF
10680 (vec_select:V4SF (match_dup 1)
0ac78517
R
10681 (parallel [(const_int 8) (const_int 13)
10682 (const_int 2) (const_int 7)]))
c1b92d09 10683 (vec_select:V4SF (match_dup 2)
0ac78517
R
10684 (parallel [(const_int 2) (const_int 3)
10685 (const_int 0) (const_int 1)])))
c1b92d09
R
10686 (mult:V4SF
10687 (vec_select:V4SF (match_dup 1)
0ac78517
R
10688 (parallel [(const_int 12) (const_int 1)
10689 (const_int 6) (const_int 11)]))
c1b92d09 10690 (vec_select:V4SF (match_dup 2)
0ac78517
R
10691 (parallel [(const_int 3) (const_int 0)
10692 (const_int 1) (const_int 2)]))))))]
c1b92d09 10693 "TARGET_SHMEDIA"
40779a72 10694 "ftrv.s %1, %2, %0"
c1b92d09
R
10695 [(set_attr "type" "fparith_media")])
10696
b6d33983
R
10697(define_insn "nsb"
10698 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10699 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10700 UNSPEC_NSB))]
10701 "TARGET_SHMEDIA"
10702 "nsb %1, %0"
10703 [(set_attr "type" "arith_media")])
10704
10705(define_insn "nsbsi"
10706 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10707 (zero_extend:SI
10708 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10709 UNSPEC_NSB)))]
10710 "TARGET_SHMEDIA"
10711 "nsb %1, %0"
10712 [(set_attr "type" "arith_media")])
10713
10714(define_insn "nsbdi"
10715 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10716 (zero_extend:DI
10717 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10718 UNSPEC_NSB)))]
10719 "TARGET_SHMEDIA"
10720 "nsb %1, %0"
10721 [(set_attr "type" "arith_media")])
10722
10723(define_expand "ffsdi2"
10724 [(set (match_operand:DI 0 "arith_reg_dest" "")
10725 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10726 "TARGET_SHMEDIA"
10727 "
10728{
10729 rtx scratch = gen_reg_rtx (DImode);
10730 rtx last;
10731
a556fd39 10732 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
b6d33983
R
10733 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10734 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10735 emit_insn (gen_nsbdi (scratch, scratch));
10736 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10737 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10738 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10739 REG_NOTES (last)
10740 = gen_rtx_EXPR_LIST (REG_EQUAL,
10741 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10742 DONE;
10743}")
10744
10745(define_expand "ffssi2"
10746 [(set (match_operand:SI 0 "arith_reg_dest" "")
10747 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10748 "TARGET_SHMEDIA"
10749 "
10750{
10751 rtx scratch = gen_reg_rtx (SImode);
10752 rtx discratch = gen_reg_rtx (DImode);
10753 rtx last;
10754
e3c62520
R
10755 emit_insn (gen_adddi3 (discratch,
10756 simplify_gen_subreg (DImode, operands[1], SImode, 0),
a556fd39 10757 constm1_rtx));
e3c62520
R
10758 emit_insn (gen_andcdi3 (discratch,
10759 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10760 discratch));
b6d33983
R
10761 emit_insn (gen_nsbsi (scratch, discratch));
10762 last = emit_insn (gen_subsi3 (operands[0],
e3c62520 10763 force_reg (SImode, GEN_INT (63)), scratch));
b6d33983
R
10764 REG_NOTES (last)
10765 = gen_rtx_EXPR_LIST (REG_EQUAL,
10766 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10767 DONE;
10768}")
10769
10770(define_insn "byterev"
10771 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10772 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10773 (parallel [(const_int 7) (const_int 6) (const_int 5)
10774 (const_int 4) (const_int 3) (const_int 2)
10775 (const_int 1) (const_int 0)])))]
10776 "TARGET_SHMEDIA"
10777 "byterev %1, %0"
10778 [(set_attr "type" "arith_media")])
10779
88f08cca
R
10780(define_insn "prefetch"
10781 [(prefetch (match_operand:QI 0 "address_operand" "p")
10782 (match_operand:SI 1 "const_int_operand" "n")
10783 (match_operand:SI 2 "const_int_operand" "n"))]
10784 "TARGET_SHMEDIA"
10785 "*
10786{
10787 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10788 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10789 return \"\";
10790}"
10791 [(set_attr "type" "other")])
10792
fae15c93 10793;; The following description models the
73774972
EC
10794;; SH4 pipeline using the DFA based scheduler.
10795;; The DFA based description is better way to model
fae15c93 10796;; a superscalar pipeline as compared to function unit
73774972
EC
10797;; reservation model.
10798;; 1. The function unit based model is oriented to describe at most one
10799;; unit reservation by each insn. It is difficult to model unit reservations in multiple
fae15c93
VM
10800;; pipeline units by same insn. This can be done using DFA based description.
10801;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
73774972
EC
10802;; 3. Writing all unit reservations for an instruction class is more natural description
10803;; of the pipeline and makes interface of the hazard recognizer simpler than the
fae15c93
VM
10804;; old function unit based model.
10805;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10806
10807
10808;; Two automata are defined to reduce number of states
10809;; which a single large automaton will have.(Factoring)
10810
10811(define_automaton "inst_pipeline,fpu_pipe")
10812
10813;; This unit is basically the decode unit of the processor.
73774972 10814;; Since SH4 is a dual issue machine,it is as if there are two
fae15c93
VM
10815;; units so that any insn can be processed by either one
10816;; of the decoding unit.
10817
10818(define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10819
10820
10821;; The fixed point arithmetic calculator(?? EX Unit).
10822
10823(define_cpu_unit "int" "inst_pipeline")
10824
10825;; f1_1 and f1_2 are floating point units.Actually there is
10826;; a f1 unit which can overlap with other f1 unit but
10827;; not another F1 unit.It is as though there were two
10828;; f1 units.
10829
10830(define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10831
c49439f1 10832;; The floating point units (except FS - F2 always precedes it.)
fae15c93 10833
c49439f1 10834(define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
fae15c93
VM
10835
10836;; This is basically the MA unit of SH4
10837;; used in LOAD/STORE pipeline.
10838
10839(define_cpu_unit "memory" "inst_pipeline")
10840
c49439f1
R
10841;; However, there are LS group insns that don't use it, even ones that
10842;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10843(define_cpu_unit "load_store" "inst_pipeline")
10844
fae15c93 10845;; The address calculator used for branch instructions.
c49439f1 10846;; This will be reserved after "issue" of branch instructions
73774972
EC
10847;; and this is to make sure that no two branch instructions
10848;; can be issued in parallel.
fae15c93
VM
10849
10850(define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10851
10852;; ----------------------------------------------------
10853;; This reservation is to simplify the dual issue description.
10854
10855(define_reservation "issue" "pipe_01|pipe_02")
10856
10857;; This is to express the locking of D stage.
c49439f1 10858;; Note that the issue of a CO group insn also effectively locks the D stage.
fae15c93
VM
10859
10860(define_reservation "d_lock" "pipe_01+pipe_02")
10861
c49439f1
R
10862;; Every FE instruction but fipr / ftrv starts with issue and this.
10863(define_reservation "F01" "F0+F1")
10864
fae15c93
VM
10865;; This is to simplify description where F1,F2,FS
10866;; are used simultaneously.
10867
c49439f1 10868(define_reservation "fpu" "F1+F2")
fae15c93 10869
73774972 10870;; This is to highlight the fact that f1
fae15c93
VM
10871;; cannot overlap with F1.
10872
10873(exclusion_set "f1_1,f1_2" "F1")
10874
c49439f1
R
10875(define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10876
73774972 10877;; Although reg moves have a latency of zero
fae15c93
VM
10878;; we need to highlight that they use D stage
10879;; for one cycle.
10880
c49439f1
R
10881;; Group: MT
10882
fae15c93 10883(define_insn_reservation "reg_mov" 0
c49439f1
R
10884 (and (eq_attr "pipe_model" "sh4")
10885 (eq_attr "type" "move"))
10886 "issue")
10887
10888;; Group: LS
10889
10890(define_insn_reservation "freg_mov" 0
10891 (and (eq_attr "pipe_model" "sh4")
10892 (eq_attr "type" "fmove"))
10893 "issue+load_store")
10894
10895;; We don't model all pipeline stages; we model the issue ('D') stage
825db093
KH
10896;; inasmuch as we allow only two instructions to issue simultaneously,
10897;; and CO instructions prevent any simultaneous issue of another instruction.
c49439f1
R
10898;; (This uses pipe_01 and pipe_02).
10899;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10900;; Double issue of EX / BR insns is prevented by using the int unit /
10901;; pcr_addrcalc unit in the EX stage.
10902;; Double issue of BR / LS instructions is prevented by using the
10903;; pcr_addrcalc / load_store unit in the issue cycle.
10904;; Double issue of FE instructions is prevented by using F0 in the first
10905;; pipeline stage after the first D stage.
10906;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10907;; (except in the cases outlined above), nor to describe the FS stage after
10908;; the F2 stage.
fae15c93 10909
825db093 10910;; Other MT group instructions(1 step operations)
fae15c93
VM
10911;; Group: MT
10912;; Latency: 1
10913;; Issue Rate: 1
10914
10915(define_insn_reservation "mt" 1
c49439f1
R
10916 (and (eq_attr "pipe_model" "sh4")
10917 (eq_attr "type" "mt_group"))
10918 "issue")
fae15c93
VM
10919
10920;; Fixed Point Arithmetic Instructions(1 step operations)
10921;; Group: EX
10922;; Latency: 1
10923;; Issue Rate: 1
10924
73774972 10925(define_insn_reservation "sh4_simple_arith" 1
c49439f1
R
10926 (and (eq_attr "pipe_model" "sh4")
10927 (eq_attr "insn_class" "ex_group"))
10928 "issue,int")
10929
10930;; Load and store instructions have no alignment peculiarities for the SH4,
10931;; but they use the load-store unit, which they share with the fmove type
10932;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10933;; Loads have a latency of two.
10934;; However, call insns can only paired with a preceding insn, and have
10935;; a delay slot, so that we want two more insns to be scheduled between the
10936;; load of the function address and the call. This is equivalent to a
10937;; latency of three.
10938;; ADJUST_COST can only properly handle reductions of the cost, so we
10939;; use a latency of three here, which gets multiplied by 10 to yield 30.
10940;; We only do this for SImode loads of general registers, to make the work
10941;; for ADJUST_COST easier.
fae15c93
VM
10942
10943;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10944;; Group: LS
10945;; Latency: 2
10946;; Issue Rate: 1
10947
c49439f1
R
10948(define_insn_reservation "sh4_load" 2
10949 (and (eq_attr "pipe_model" "sh4")
10950 (eq_attr "type" "load,pcload"))
10951 "issue+load_store,nothing,memory")
10952
10953;; calls / sfuncs need an extra instruction for their delay slot.
10954;; Moreover, estimating the latency for SImode loads as 3 will also allow
10955;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10956;; count of a dynamic shift.
10957(define_insn_reservation "sh4_load_si" 3
10958 (and (eq_attr "pipe_model" "sh4")
10959 (eq_attr "type" "load_si,pcload_si"))
10960 "issue+load_store,nothing,memory")
10961
10962;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10963
10964;; The load latency is upped to three higher if the dependent insn does
10965;; double precision computation. We want the 'default' latency to reflect
10966;; that increased latency because otherwise the insn priorities won't
10967;; allow proper scheduling.
10968(define_insn_reservation "sh4_fload" 3
10969 (and (eq_attr "pipe_model" "sh4")
10970 (eq_attr "type" "fload,pcfload"))
10971 "issue+load_store,nothing,memory")
10972
10973;; (define_bypass 2 "sh4_fload" "!")
10974
10975(define_insn_reservation "sh4_store" 1
10976 (and (eq_attr "pipe_model" "sh4")
10977 (eq_attr "type" "store"))
10978 "issue+load_store,nothing,memory")
10979
10980;; Load Store instructions.
10981;; Group: LS
10982;; Latency: 1
10983;; Issue Rate: 1
10984
10985(define_insn_reservation "sh4_gp_fpul" 1
10986 (and (eq_attr "pipe_model" "sh4")
10987 (eq_attr "type" "gp_fpul"))
10988 "issue+load_store")
10989
10990;; Load Store instructions.
10991;; Group: LS
10992;; Latency: 3
10993;; Issue Rate: 1
10994
10995(define_insn_reservation "sh4_fpul_gp" 3
10996 (and (eq_attr "pipe_model" "sh4")
10997 (eq_attr "type" "fpul_gp"))
10998 "issue+load_store")
fae15c93
VM
10999
11000;; Branch (BF,BF/S,BT,BT/S,BRA)
11001;; Group: BR
c49439f1 11002;; Latency when taken: 2 (or 1)
fae15c93
VM
11003;; Issue Rate: 1
11004;; The latency is 1 when displacement is 0.
c49439f1
R
11005;; We can't really do much with the latency, even if we could express it,
11006;; but the pairing restrictions are useful to take into account.
11007;; ??? If the branch is likely, we might want to fill the delay slot;
11008;; if the branch is likely, but not very likely, should we pretend to use
11009;; a resource that CO instructions use, to get a pairable delay slot insn?
fae15c93 11010
c49439f1
R
11011(define_insn_reservation "sh4_branch" 1
11012 (and (eq_attr "pipe_model" "sh4")
11013 (eq_attr "type" "cbranch,jump"))
11014 "issue+pcr_addrcalc")
fae15c93
VM
11015
11016;; Branch Far (JMP,RTS,BRAF)
11017;; Group: CO
11018;; Latency: 3
11019;; Issue Rate: 2
c49439f1
R
11020;; ??? Scheduling happens before branch shortening, and hence jmp and braf
11021;; can't be distinguished from bra for the "jump" pattern.
fae15c93 11022
c49439f1
R
11023(define_insn_reservation "sh4_return" 3
11024 (and (eq_attr "pipe_model" "sh4")
11025 (eq_attr "type" "return,jump_ind"))
11026 "d_lock*2")
fae15c93
VM
11027
11028;; RTE
11029;; Group: CO
c49439f1 11030;; Latency: 5
fae15c93 11031;; Issue Rate: 5
73774972 11032;; this instruction can be executed in any of the pipelines
fae15c93
VM
11033;; and blocks the pipeline for next 4 stages.
11034
c49439f1
R
11035(define_insn_reservation "sh4_return_from_exp" 5
11036 (and (eq_attr "pipe_model" "sh4")
11037 (eq_attr "type" "rte"))
11038 "d_lock*5")
fae15c93
VM
11039
11040;; OCBP, OCBWB
11041;; Group: CO
c49439f1 11042;; Latency: 1-5
fae15c93
VM
11043;; Issue Rate: 1
11044
c49439f1
R
11045;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
11046;; ocbwb on its own would be "d_lock,nothing,memory*5"
11047(define_insn_reservation "ocbwb" 6
11048 (and (eq_attr "pipe_model" "sh4")
11049 (eq_attr "type" "cwb"))
11050 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
73774972 11051
fae15c93
VM
11052;; LDS to PR,JSR
11053;; Group: CO
11054;; Latency: 3
11055;; Issue Rate: 2
11056;; The SX stage is blocked for last 2 cycles.
c49439f1
R
11057;; OTOH, the only time that has an effect for insns generated by the compiler
11058;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
11059;; or when we are doing a function call - and we don't do inter-function
11060;; scheduling. For the function call case, it's really best that we end with
11061;; something that models an rts.
fae15c93 11062
73774972 11063(define_insn_reservation "sh4_lds_to_pr" 3
c49439f1
R
11064 (and (eq_attr "pipe_model" "sh4")
11065 (eq_attr "type" "prset") )
11066 "d_lock*2")
11067
11068;; calls introduce a longisch delay that is likely to flush the pipelines
11069;; of the caller's instructions. Ordinary functions tend to end with a
11070;; load to restore a register (in the delay slot of rts), while sfuncs
11071;; tend to end with an EX or MT insn. But that is not actually relevant,
11072;; since there are no instructions that contend for memory access early.
11073;; We could, of course, provide exact scheduling information for specific
11074;; sfuncs, if that should prove useful.
11075
73774972 11076(define_insn_reservation "sh4_call" 16
c49439f1
R
11077 (and (eq_attr "pipe_model" "sh4")
11078 (eq_attr "type" "call,sfunc"))
11079 "d_lock*16")
fae15c93 11080
73774972 11081;; LDS.L to PR
fae15c93
VM
11082;; Group: CO
11083;; Latency: 3
11084;; Issue Rate: 2
11085;; The SX unit is blocked for last 2 cycles.
73774972 11086
fae15c93 11087(define_insn_reservation "ldsmem_to_pr" 3
c49439f1
R
11088 (and (eq_attr "pipe_model" "sh4")
11089 (eq_attr "type" "pload"))
11090 "d_lock*2")
fae15c93
VM
11091
11092;; STS from PR
11093;; Group: CO
11094;; Latency: 2
11095;; Issue Rate: 2
11096;; The SX unit in second and third cycles.
11097
11098(define_insn_reservation "sts_from_pr" 2
c49439f1
R
11099 (and (eq_attr "pipe_model" "sh4")
11100 (eq_attr "type" "prget"))
11101 "d_lock*2")
fae15c93
VM
11102
11103;; STS.L from PR
11104;; Group: CO
11105;; Latency: 2
11106;; Issue Rate: 2
11107
73774972 11108(define_insn_reservation "sh4_prstore_mem" 2
c49439f1
R
11109 (and (eq_attr "pipe_model" "sh4")
11110 (eq_attr "type" "pstore"))
11111 "d_lock*2,nothing,memory")
fae15c93
VM
11112
11113;; LDS to FPSCR
11114;; Group: CO
11115;; Latency: 4
11116;; Issue Rate: 1
73774972 11117;; F1 is blocked for last three cycles.
fae15c93 11118
c49439f1
R
11119(define_insn_reservation "fpscr_load" 4
11120 (and (eq_attr "pipe_model" "sh4")
11121 (eq_attr "type" "gp_fpscr"))
11122 "d_lock,nothing,F1*3")
fae15c93
VM
11123
11124;; LDS.L to FPSCR
11125;; Group: CO
11126;; Latency: 1 / 4
11127;; Latency to update Rn is 1 and latency to update FPSCR is 4
11128;; Issue Rate: 1
11129;; F1 is blocked for last three cycles.
11130
c49439f1
R
11131(define_insn_reservation "fpscr_load_mem" 4
11132 (and (eq_attr "pipe_model" "sh4")
11133 (eq_attr "type" "mem_fpscr"))
11134 "d_lock,nothing,(F1+memory),F1*2")
fae15c93
VM
11135
11136\f
11137;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11138;; Group: CO
11139;; Latency: 4 / 4
11140;; Issue Rate: 1
11141
11142(define_insn_reservation "multi" 4
c49439f1
R
11143 (and (eq_attr "pipe_model" "sh4")
11144 (eq_attr "type" "smpy,dmpy"))
11145 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11146
11147;; Fixed STS from MACL / MACH
11148;; Group: CO
11149;; Latency: 3
11150;; Issue Rate: 1
11151
11152(define_insn_reservation "sh4_mac_gp" 3
11153 (and (eq_attr "pipe_model" "sh4")
11154 (eq_attr "type" "mac_gp"))
11155 "d_lock")
fae15c93
VM
11156
11157
11158;; Single precision floating point computation FCMP/EQ,
c49439f1 11159;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
fae15c93 11160;; Group: FE
c49439f1 11161;; Latency: 3/4
fae15c93
VM
11162;; Issue Rate: 1
11163
c49439f1
R
11164(define_insn_reservation "fp_arith" 3
11165 (and (eq_attr "pipe_model" "sh4")
11166 (eq_attr "type" "fp"))
11167 "issue,F01,F2")
11168
11169(define_insn_reservation "fp_arith_ftrc" 3
11170 (and (eq_attr "pipe_model" "sh4")
11171 (eq_attr "type" "ftrc_s"))
11172 "issue,F01,F2")
11173
11174(define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
fae15c93
VM
11175
11176;; Single Precision FDIV/SQRT
11177;; Group: FE
c49439f1 11178;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
fae15c93 11179;; Issue Rate: 1
c49439f1 11180;; We describe fdiv here; fsqrt is actually one cycle faster.
fae15c93 11181
c49439f1
R
11182(define_insn_reservation "fp_div" 12
11183 (and (eq_attr "pipe_model" "sh4")
11184 (eq_attr "type" "fdiv"))
11185 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
fae15c93
VM
11186
11187;; Double Precision floating point computation
11188;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11189;; Group: FE
11190;; Latency: (3,4)/5
11191;; Issue Rate: 1
11192
c49439f1
R
11193(define_insn_reservation "dp_float" 4
11194 (and (eq_attr "pipe_model" "sh4")
11195 (eq_attr "type" "dfp_conv"))
11196 "issue,F01,F1+F2,F2")
fae15c93 11197
73774972 11198;; Double-precision floating-point (FADD,FMUL,FSUB)
fae15c93
VM
11199;; Group: FE
11200;; Latency: (7,8)/9
11201;; Issue Rate: 1
11202
c49439f1
R
11203(define_insn_reservation "fp_double_arith" 8
11204 (and (eq_attr "pipe_model" "sh4")
11205 (eq_attr "type" "dfp_arith"))
11206 "issue,F01,F1+F2,fpu*4,F2")
fae15c93 11207
73774972 11208;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
c49439f1 11209;; Group: CO
fae15c93
VM
11210;; Latency: 3/5
11211;; Issue Rate: 2
11212
73774972 11213(define_insn_reservation "fp_double_cmp" 3
c49439f1
R
11214 (and (eq_attr "pipe_model" "sh4")
11215 (eq_attr "type" "dfp_cmp"))
11216 "d_lock,(d_lock+F01),F1+F2,F2")
fae15c93
VM
11217
11218;; Double precision FDIV/SQRT
11219;; Group: FE
11220;; Latency: (24,25)/26
11221;; Issue Rate: 1
11222
c49439f1
R
11223(define_insn_reservation "dp_div" 25
11224 (and (eq_attr "pipe_model" "sh4")
11225 (eq_attr "type" "dfdiv"))
11226 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11227
fae15c93 11228
c49439f1
R
11229;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11230;; case, we'd get a d_lock instead of issue at the end.
11231(define_insn_reservation "arith3" 3
11232 (and (eq_attr "pipe_model" "sh4")
11233 (eq_attr "type" "arith3"))
11234 "issue,d_lock+pcr_addrcalc,issue")
11235
11236;; arith3b insns schedule the same no matter if the branch is taken or not.
11237(define_insn_reservation "arith3b" 2
11238 (and (eq_attr "pipe_model" "sh4")
11239 (eq_attr "type" "arith3"))
11240 "issue,d_lock+pcr_addrcalc")