]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/sh.md
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / sh / sh.md
CommitLineData
7ab56274 1;;- Machine description for Hitachi / SuperH SH.
4dd8c093 2;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
4592bdcb 3;; Free Software Foundation, Inc.
51aea58d
JW
4;; Contributed by Steve Chamberlain (sac@cygnus.com).
5;; Improved by Jim Wilson (wilson@cygnus.com).
bc45ade3
SC
6
7;; This file is part of GNU CC.
8
9;; GNU CC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
14;; GNU CC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GNU CC; 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)
4773afa4
AO
139
140 ;; These are used with unspec_volatile.
141 (UNSPECV_BLOCKAGE 0)
b927e8c7 142 (UNSPECV_ALIGN 1)
4773afa4
AO
143 (UNSPECV_CONST2 2)
144 (UNSPECV_CONST4 4)
145 (UNSPECV_CONST8 6)
b91455de 146 (UNSPECV_WINDOW_END 10)
4773afa4
AO
147 (UNSPECV_CONST_END 11)
148])
149
bc45ade3
SC
150;; -------------------------------------------------------------------------
151;; Attributes
152;; -------------------------------------------------------------------------
153
eeb531d5 154;; Target CPU.
b9654711 155
1245df60 156(define_attr "cpu"
fa5322fa 157 "sh1,sh2,sh3,sh3e,sh4,sh5"
07a45e5c 158 (const (symbol_ref "sh_cpu_attr")))
961c4780 159
1245df60
R
160(define_attr "endian" "big,little"
161 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
162 (const_string "little") (const_string "big"))))
163
d64264ff
R
164;; Indicate if the default fpu mode is single precision.
165(define_attr "fpu_single" "yes,no"
166 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
167 (const_string "yes") (const_string "no"))))
168
225e4f43
R
169(define_attr "fmovd" "yes,no"
170 (const (if_then_else (symbol_ref "TARGET_FMOVD")
171 (const_string "yes") (const_string "no"))))
2ad65b0e
SC
172;; pipeline model
173(define_attr "pipe_model" "sh1,sh4,sh5media"
174 (const
175 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
176 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
177 (const_string "sh1"))))
225e4f43 178
0d7e008e
SC
179;; cbranch conditional branch instructions
180;; jump unconditional jumps
181;; arith ordinary arithmetic
956d6950 182;; arith3 a compound insn that behaves similarly to a sequence of
1245df60
R
183;; three insns of type arith
184;; arith3b like above, but might end with a redirected branch
0d7e008e 185;; load from memory
1245df60 186;; load_si Likewise, SImode variant for general register.
c49439f1 187;; fload Likewise, but load to fp register.
0d7e008e 188;; store to memory
c49439f1
R
189;; move general purpose register to register
190;; mt_group other sh4 mt instructions
1245df60 191;; fmove register to register, floating point
51bd623f
JW
192;; smpy word precision integer multiply
193;; dmpy longword or doublelongword precision integer multiply
0d7e008e 194;; return rts
ffae286a 195;; pload load of pr reg, which can't be put into delay slot of rts
99e87c10 196;; prset copy register to pr reg, ditto
ffae286a 197;; pstore store of pr reg, which can't be put into delay slot of jsr
99e87c10 198;; prget copy pr to register, ditto
22e1ebf1 199;; pcload pc relative load of constant value
c49439f1 200;; pcfload Likewise, but load to fp register.
1245df60 201;; pcload_si Likewise, SImode variant for general register.
0d7e008e
SC
202;; rte return from exception
203;; sfunc special function call with known used registers
ffae286a 204;; call function call
c1aef54d
ILT
205;; fp floating point
206;; fdiv floating point divide (or square root)
c49439f1
R
207;; gp_fpul move from general purpose register to fpul
208;; fpul_gp move from fpul to general purpose register
209;; mac_gp move from mac[lh] to general purpose register
225e4f43 210;; dfp_arith, dfp_cmp,dfp_conv
c49439f1 211;; ftrc_s fix_truncsfsi2_i4
225e4f43 212;; dfdiv double precision floating point divide (or square root)
c49439f1 213;; cwb ic_invalidate_line_i
2ad65b0e
SC
214;; arith_media SHmedia arithmetic, logical, and shift instructions
215;; cbranch_media SHmedia conditional branch instructions
216;; cmp_media SHmedia compare instructions
217;; dfdiv_media SHmedia double precision divide and square root
218;; dfmul_media SHmedia double precision multiply instruction
219;; dfparith_media SHmedia double precision floating point arithmetic
220;; dfpconv_media SHmedia double precision floating point conversions
221;; dmpy_media SHmedia longword multiply
222;; fcmp_media SHmedia floating point compare instructions
223;; fdiv_media SHmedia single precision divide and square root
224;; fload_media SHmedia floating point register load instructions
225;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
226;; fparith_media SHmedia single precision floating point arithmetic
227;; fpconv_media SHmedia single precision floating point conversions
228;; fstore_media SHmedia floating point register store instructions
229;; gettr_media SHmedia gettr instruction
230;; invalidate_line_media SHmedia invaldiate_line sequence
231;; jump_media SHmedia unconditional branch instructions
232;; load_media SHmedia general register load instructions
233;; pt_media SHmedia pt instruction (expanded by assembler)
234;; ptabs_media SHmedia ptabs instruction
235;; store_media SHmedia general register store instructions
236;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
237;; mac_media SHmedia mac-style fixed point operations
238;; d2mpy_media SHmedia: two 32 bit integer multiplies
239;; atrans SHmedia approximate transcendential functions
240;; ustore_media SHmedia unaligned stores
4dff12bf 241;; nil no-op move, will be deleted.
0d7e008e 242
07a45e5c 243(define_attr "type"
c49439f1 244 "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,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
245 (const_string "other"))
246
fae15c93 247;; We define a new attribute namely "insn_class".We use
c49439f1 248;; this for the DFA based pipeline description.
fae15c93
VM
249;;
250;; mt_group SH4 "mt" group instructions.
251;;
c49439f1
R
252;; ex_group SH4 "ex" group instructions.
253;;
254;; ls_group SH4 "ls" group instructions.
fae15c93 255;;
fae15c93
VM
256
257(define_attr "insn_class"
c49439f1
R
258 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
259 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
260 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
261 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
262 (eq_attr "type" "cbranch,jump") (const_string "br_group")
263 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
264 (const_string "fe_group")
265 (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")]
266 (const_string "none")))
267;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
268;; so these do not belong in an insn group, although they are modeled
269;; with their own define_insn_reservations.
fae15c93 270
d64264ff
R
271;; Indicate what precision must be selected in fpscr for this insn, if any.
272
273(define_attr "fp_mode" "single,double,none" (const_string "none"))
274
07a45e5c 275; If a conditional branch destination is within -252..258 bytes away
bc45ade3 276; from the instruction it can be 2 bytes long. Something in the
22e1ebf1 277; range -4090..4100 bytes can be 6 bytes long. All other conditional
1245df60
R
278; branches are initially assumed to be 16 bytes long.
279; In machine_dependent_reorg, we split all branches that are longer than
280; 2 bytes.
bc45ade3 281
536fe39c 282;; The maximum range used for SImode constant pool entries is 1018. A final
33f7f353
JR
283;; instruction can add 8 bytes while only being 4 bytes in size, thus we
284;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
285;; instruction around the pool table, 2 bytes of alignment before the table,
286;; and 30 bytes of alignment after the table. That gives a maximum total
287;; pool size of 1058 bytes.
288;; Worst case code/pool content size ratio is 1:2 (using asms).
289;; Thus, in the worst case, there is one instruction in front of a maximum
290;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
291;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
292;; If we have a forward branch, the initial table will be put after the
293;; unconditional branch.
294;;
295;; ??? We could do much better by keeping track of the actual pcloads within
296;; the branch range and in the pcload range in front of the branch range.
297
298;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
299;; inside an le.
300(define_attr "short_cbranch_p" "no,yes"
301 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
302 (const_string "no")
303 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
304 (const_string "yes")
305 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
306 (const_string "no")
307 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
308 (const_string "yes")
309 ] (const_string "no")))
310
311(define_attr "med_branch_p" "no,yes"
312 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
313 (const_int 1988))
314 (const_string "yes")
315 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
316 (const_string "no")
317 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
318 (const_int 8186))
319 (const_string "yes")
320 ] (const_string "no")))
321
322(define_attr "med_cbranch_p" "no,yes"
323 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
324 (const_int 1986))
325 (const_string "yes")
326 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
327 (const_string "no")
328 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
329 (const_int 8184))
330 (const_string "yes")
331 ] (const_string "no")))
332
333(define_attr "braf_branch_p" "no,yes"
334 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
335 (const_string "no")
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
337 (const_int 20660))
338 (const_string "yes")
339 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
340 (const_string "no")
341 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
342 (const_int 65530))
343 (const_string "yes")
344 ] (const_string "no")))
345
346(define_attr "braf_cbranch_p" "no,yes"
347 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
348 (const_string "no")
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
350 (const_int 20658))
351 (const_string "yes")
352 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353 (const_string "no")
354 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
355 (const_int 65528))
356 (const_string "yes")
357 ] (const_string "no")))
358
22e1ebf1 359; An unconditional jump in the range -4092..4098 can be 2 bytes long.
1245df60
R
360; For wider ranges, we need a combination of a code and a data part.
361; If we can get a scratch register for a long range jump, the code
362; part can be 4 bytes long; otherwise, it must be 8 bytes long.
363; If the jump is in the range -32764..32770, the data part can be 2 bytes
364; long; otherwise, it must be 6 bytes long.
bc45ade3
SC
365
366; All other instructions are two bytes long by default.
367
33f7f353
JR
368;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
369;; but getattrtab doesn't understand this.
07a45e5c 370(define_attr "length" ""
bc45ade3 371 (cond [(eq_attr "type" "cbranch")
33f7f353 372 (cond [(eq_attr "short_cbranch_p" "yes")
1245df60 373 (const_int 2)
33f7f353 374 (eq_attr "med_cbranch_p" "yes")
1245df60 375 (const_int 6)
33f7f353 376 (eq_attr "braf_cbranch_p" "yes")
1245df60 377 (const_int 12)
33f7f353
JR
378;; ??? using pc is not computed transitively.
379 (ne (match_dup 0) (match_dup 0))
380 (const_int 14)
e6dfd05f
AO
381 (ne (symbol_ref ("flag_pic")) (const_int 0))
382 (const_int 24)
1245df60 383 ] (const_int 16))
bc45ade3 384 (eq_attr "type" "jump")
33f7f353 385 (cond [(eq_attr "med_branch_p" "yes")
1245df60
R
386 (const_int 2)
387 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
388 (symbol_ref "INSN"))
389 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
390 (symbol_ref "code_for_indirect_jump_scratch")))
33f7f353 391 (if_then_else (eq_attr "braf_branch_p" "yes")
1245df60
R
392 (const_int 6)
393 (const_int 10))
33f7f353 394 (eq_attr "braf_branch_p" "yes")
1245df60 395 (const_int 10)
33f7f353
JR
396;; ??? using pc is not computed transitively.
397 (ne (match_dup 0) (match_dup 0))
1245df60 398 (const_int 12)
e6dfd05f
AO
399 (ne (symbol_ref ("flag_pic")) (const_int 0))
400 (const_int 22)
1245df60 401 ] (const_int 14))
2ad65b0e 402 (eq_attr "type" "pt_media")
fa5322fa
AO
403 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
404 (const_int 20) (const_int 12))
405 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
406 (const_int 4)
407 (const_int 2))))
b9654711
SC
408
409;; (define_function_unit {name} {num-units} {n-users} {test}
410;; {ready-delay} {issue-delay} [{conflict-list}])
07a45e5c 411
c1aef54d
ILT
412;; Load and store instructions save a cycle if they are aligned on a
413;; four byte boundary. Using a function unit for stores encourages
414;; gcc to separate load and store instructions by one instruction,
415;; which makes it more likely that the linker will be able to word
416;; align them when relaxing.
1245df60
R
417
418;; Loads have a latency of two.
deeef0ac 419;; However, call insns can have a delay slot, so that we want one more
1245df60
R
420;; insn to be scheduled between the load of the function address and the call.
421;; This is equivalent to a latency of three.
422;; We cannot use a conflict list for this, because we need to distinguish
423;; between the actual call address and the function arguments.
424;; ADJUST_COST can only properly handle reductions of the cost, so we
425;; use a latency of three here.
956d6950 426;; We only do this for SImode loads of general registers, to make the work
1245df60
R
427;; for ADJUST_COST easier.
428(define_function_unit "memory" 1 0
2ad65b0e 429 (and (eq_attr "pipe_model" "sh1")
225e4f43 430 (eq_attr "type" "load_si,pcload_si"))
1245df60 431 3 2)
c1aef54d 432(define_function_unit "memory" 1 0
2ad65b0e 433 (and (eq_attr "pipe_model" "sh1")
225e4f43 434 (eq_attr "type" "load,pcload,pload,store,pstore"))
1245df60
R
435 2 2)
436
437(define_function_unit "int" 1 0
2ad65b0e 438 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
1245df60
R
439
440(define_function_unit "int" 1 0
2ad65b0e 441 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
1245df60
R
442
443(define_function_unit "int" 1 0
2ad65b0e 444 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
c1aef54d
ILT
445
446;; ??? These are approximations.
225e4f43 447(define_function_unit "mpy" 1 0
2ad65b0e 448 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
225e4f43 449(define_function_unit "mpy" 1 0
2ad65b0e 450 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
225e4f43
R
451
452(define_function_unit "fp" 1 0
2ad65b0e 453 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
225e4f43 454(define_function_unit "fp" 1 0
2ad65b0e 455 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
225e4f43
R
456
457
2ad65b0e
SC
458;; SH-5 SHmedia scheduling
459;; When executing SHmedia code, the SH-5 is a fairly straightforward
460;; single-issue machine. It has four pipelines, the branch unit (br),
461;; the integer and multimedia unit (imu), the load/store unit (lsu), and
462;; the floating point unit (fpu).
463;; Here model the instructions with a latency greater than one cycle.
464
465;; Every instruction on SH-5 occupies the issue resource for at least one
466;; cycle.
467(define_function_unit "sh5issue" 1 0
468 (and (eq_attr "pipe_model" "sh5media")
469 (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)
470
471;; Specify the various types of instruction which have latency > 1
472(define_function_unit "sh5issue" 1 0
473 (and (eq_attr "pipe_model" "sh5media")
474 (eq_attr "type" "mcmp_media")) 2 1)
475
476(define_function_unit "sh5issue" 1 0
477 (and (eq_attr "pipe_model" "sh5media")
478 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
479;; but see sh_adjust_cost for mac_media exception.
480
481(define_function_unit "sh5issue" 1 0
482 (and (eq_attr "pipe_model" "sh5media")
483 (eq_attr "type" "fload_media,fmove_media")) 4 1)
484
485(define_function_unit "sh5issue" 1 0
486 (and (eq_attr "pipe_model" "sh5media")
487 (eq_attr "type" "d2mpy_media")) 4 2)
488
489(define_function_unit "sh5issue" 1 0
490 (and (eq_attr "pipe_model" "sh5media")
491 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
492
493(define_function_unit "sh5issue" 1 0
494 (and (eq_attr "pipe_model" "sh5media")
495 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
496
497(define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "invalidate_line_media")) 7 7)
500
501(define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
503
504(define_function_unit "sh5issue" 1 0
505 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
506
507;; Floating-point divide and square-root occupy an additional resource,
508;; which is not internally pipelined. However, other instructions
509;; can continue to issue.
510(define_function_unit "sh5fds" 1 0
511 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
512
513(define_function_unit "sh5fds" 1 0
514 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
fa5322fa 515
51bd623f 516; Definitions for filling branch delay slots.
bc45ade3 517
51bd623f
JW
518(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
519
225e4f43
R
520;; ??? This should be (nil) instead of (const_int 0)
521(define_attr "hit_stack" "yes,no"
4773afa4
AO
522 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
523 (const_int 0))
225e4f43
R
524 (const_string "no")]
525 (const_string "yes")))
51bd623f
JW
526
527(define_attr "interrupt_function" "no,yes"
552ecbd9 528 (const (symbol_ref "current_function_interrupt")))
51bd623f 529
07a45e5c 530(define_attr "in_delay_slot" "yes,no"
51bd623f 531 (cond [(eq_attr "type" "cbranch") (const_string "no")
1245df60 532 (eq_attr "type" "pcload,pcload_si") (const_string "no")
51bd623f
JW
533 (eq_attr "needs_delay_slot" "yes") (const_string "no")
534 (eq_attr "length" "2") (const_string "yes")
535 ] (const_string "no")))
536
c608a684
R
537(define_attr "cond_delay_slot" "yes,no"
538 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
539 ] (const_string "no")))
540
0603a39d
R
541(define_attr "is_sfunc" ""
542 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
543
2ad65b0e
SC
544(define_attr "is_mac_media" ""
545 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
546
c49439f1
R
547(define_attr "branch_zero" "yes,no"
548 (cond [(eq_attr "type" "!cbranch") (const_string "no")
549 (ne (symbol_ref "(next_active_insn (insn)\
550 == (prev_active_insn\
551 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
552 && get_attr_length (next_active_insn (insn)) == 2")
553 (const_int 0))
554 (const_string "yes")]
555 (const_string "no")))
556
557;; SH4 Double-precision computation with double-precision result -
558;; the two halves are ready at different times.
559(define_attr "dfp_comp" "yes,no"
560 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
561 (const_string "no")))
562
563;; Insns for which the latency of a preceding fp insn is decreased by one.
564(define_attr "late_fp_use" "yes,no" (const_string "no"))
565;; And feeding insns for which this relevant.
566(define_attr "any_fp_comp" "yes,no"
567 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
568 (const_string "yes")]
569 (const_string "no")))
570
571(define_attr "any_int_load" "yes,no"
572 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
573 (const_string "yes")]
574 (const_string "no")))
575
51bd623f 576(define_delay
0d7e008e 577 (eq_attr "needs_delay_slot" "yes")
b9654711
SC
578 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
579
51aea58d
JW
580;; On the SH and SH2, the rte instruction reads the return pc from the stack,
581;; and thus we can't put a pop instruction in its delay slot.
6b005b88
JW
582;; ??? On the SH3, the rte instruction does not use the stack, so a pop
583;; instruction can go in the delay slot.
51aea58d 584
ffae286a
JW
585;; Since a normal return (rts) implicitly uses the PR register,
586;; we can't allow PR register loads in an rts delay slot.
587
07a45e5c 588(define_delay
961c4780 589 (eq_attr "type" "return")
07a45e5c 590 [(and (eq_attr "in_delay_slot" "yes")
ffae286a 591 (ior (and (eq_attr "interrupt_function" "no")
99e87c10 592 (eq_attr "type" "!pload,prset"))
ffae286a 593 (and (eq_attr "interrupt_function" "yes")
552ecbd9
AH
594 (ior
595 (ne (symbol_ref "TARGET_SH3") (const_int 0))
596 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
ffae286a
JW
597
598;; Since a call implicitly uses the PR register, we can't allow
599;; a PR register store in a jsr delay slot.
600
601(define_delay
602 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
603 [(and (eq_attr "in_delay_slot" "yes")
99e87c10 604 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
ffae286a
JW
605
606;; Say that we have annulled true branches, since this gives smaller and
607;; faster code when branches are predicted as not taken.
608
07a45e5c
JW
609(define_delay
610 (and (eq_attr "type" "cbranch")
1245df60 611 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
c608a684 612 [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
bc45ade3
SC
613\f
614;; -------------------------------------------------------------------------
615;; SImode signed integer comparisons
616;; -------------------------------------------------------------------------
617
51bd623f 618(define_insn ""
4773afa4 619 [(set (reg:SI T_REG)
51bd623f
JW
620 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
621 (match_operand:SI 1 "arith_operand" "L,r"))
622 (const_int 0)))]
fa5322fa 623 "TARGET_SH1"
fae15c93 624 "tst %1,%0"
c49439f1 625 [(set_attr "type" "mt_group")])
0d7e008e 626
07a45e5c
JW
627;; ??? Perhaps should only accept reg/constant if the register is reg 0.
628;; That would still allow reload to create cmpi instructions, but would
629;; perhaps allow forcing the constant into a register when that is better.
ffae286a
JW
630;; Probably should use r0 for mem/imm compares, but force constant into a
631;; register for pseudo/imm compares.
07a45e5c 632
0d7e008e 633(define_insn "cmpeqsi_t"
4773afa4
AO
634 [(set (reg:SI T_REG)
635 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
636 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
fa5322fa 637 "TARGET_SH1"
0d7e008e 638 "@
51bd623f 639 tst %0,%0
0d7e008e 640 cmp/eq %1,%0
fae15c93 641 cmp/eq %1,%0"
c49439f1 642 [(set_attr "type" "mt_group")])
bc45ade3
SC
643
644(define_insn "cmpgtsi_t"
4773afa4
AO
645 [(set (reg:SI T_REG)
646 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
647 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 648 "TARGET_SH1"
0d7e008e 649 "@
22e1ebf1 650 cmp/gt %1,%0
fae15c93 651 cmp/pl %0"
c49439f1 652 [(set_attr "type" "mt_group")])
bc45ade3
SC
653
654(define_insn "cmpgesi_t"
4773afa4
AO
655 [(set (reg:SI T_REG)
656 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
657 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 658 "TARGET_SH1"
0d7e008e 659 "@
22e1ebf1 660 cmp/ge %1,%0
fae15c93 661 cmp/pz %0"
c49439f1 662 [(set_attr "type" "mt_group")])
fae15c93 663
bc45ade3
SC
664;; -------------------------------------------------------------------------
665;; SImode unsigned integer comparisons
666;; -------------------------------------------------------------------------
667
668(define_insn "cmpgeusi_t"
4773afa4
AO
669 [(set (reg:SI T_REG)
670 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
671 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 672 "TARGET_SH1"
fae15c93 673 "cmp/hs %1,%0"
c49439f1 674 [(set_attr "type" "mt_group")])
bc45ade3
SC
675
676(define_insn "cmpgtusi_t"
4773afa4
AO
677 [(set (reg:SI T_REG)
678 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
679 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 680 "TARGET_SH1"
fae15c93 681 "cmp/hi %1,%0"
c49439f1 682 [(set_attr "type" "mt_group")])
bc45ade3
SC
683
684;; We save the compare operands in the cmpxx patterns and use them when
685;; we generate the branch.
686
687(define_expand "cmpsi"
4773afa4
AO
688 [(set (reg:SI T_REG)
689 (compare (match_operand:SI 0 "arith_operand" "")
690 (match_operand:SI 1 "arith_operand" "")))]
fa5322fa 691 "TARGET_SH1"
bc45ade3 692 "
0d7e008e
SC
693{
694 sh_compare_op0 = operands[0];
bc45ade3
SC
695 sh_compare_op1 = operands[1];
696 DONE;
697}")
bc45ade3
SC
698\f
699;; -------------------------------------------------------------------------
1245df60
R
700;; DImode signed integer comparisons
701;; -------------------------------------------------------------------------
702
703;; ??? Could get better scheduling by splitting the initial test from the
704;; rest of the insn after reload. However, the gain would hardly justify
705;; the sh.md size increase necessary to do that.
706
707(define_insn ""
4773afa4 708 [(set (reg:SI T_REG)
1245df60
R
709 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
710 (match_operand:DI 1 "arith_operand" "r"))
711 (const_int 0)))]
fa5322fa 712 "TARGET_SH1"
1245df60
R
713 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
714 insn, operands);"
715 [(set_attr "length" "6")
716 (set_attr "type" "arith3b")])
717
718(define_insn "cmpeqdi_t"
4773afa4
AO
719 [(set (reg:SI T_REG)
720 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
fa5322fa 722 "TARGET_SH1"
712646d0 723 "@
4c0d0505
JR
724 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
725 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
1245df60
R
726 [(set_attr "length" "6")
727 (set_attr "type" "arith3b")])
728
1987b7bc 729(define_split
4773afa4 730 [(set (reg:SI T_REG)
e69d1422
R
731 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
732 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
712646d0
R
733;; If we applied this split when not optimizing, it would only be
734;; applied during the machine-dependent reorg, when no new basic blocks
735;; may be created.
fa5322fa 736 "TARGET_SH1 && reload_completed && optimize"
4773afa4
AO
737 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
738 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
712646d0
R
739 (label_ref (match_dup 6))
740 (pc)))
4773afa4 741 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
712646d0 742 (match_dup 6)]
1987b7bc
R
743 "
744{
745 operands[2]
746 = gen_rtx_REG (SImode,
747 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
748 operands[3]
749 = (operands[1] == const0_rtx
750 ? const0_rtx
751 : gen_rtx_REG (SImode,
752 true_regnum (operands[1])
753 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
754 operands[4] = gen_lowpart (SImode, operands[0]);
755 operands[5] = gen_lowpart (SImode, operands[1]);
712646d0 756 operands[6] = gen_label_rtx ();
1987b7bc
R
757}")
758
1245df60 759(define_insn "cmpgtdi_t"
4773afa4
AO
760 [(set (reg:SI T_REG)
761 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
762 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
763 "TARGET_SH2"
764 "@
765 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
766 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
767 [(set_attr "length" "8")
768 (set_attr "type" "arith3")])
769
770(define_insn "cmpgedi_t"
4773afa4
AO
771 [(set (reg:SI T_REG)
772 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
774 "TARGET_SH2"
775 "@
776 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
777 cmp/pz\\t%S0"
778 [(set_attr "length" "8,2")
c49439f1 779 (set_attr "type" "arith3,mt_group")])
1245df60
R
780\f
781;; -------------------------------------------------------------------------
782;; DImode unsigned integer comparisons
783;; -------------------------------------------------------------------------
784
785(define_insn "cmpgeudi_t"
4773afa4
AO
786 [(set (reg:SI T_REG)
787 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
788 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
789 "TARGET_SH2"
790 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
791 [(set_attr "length" "8")
792 (set_attr "type" "arith3")])
793
794(define_insn "cmpgtudi_t"
4773afa4
AO
795 [(set (reg:SI T_REG)
796 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
797 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
798 "TARGET_SH2"
799 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
800 [(set_attr "length" "8")
801 (set_attr "type" "arith3")])
802
fa5322fa 803(define_insn "cmpeqdi_media"
b6d33983
R
804 [(set (match_operand:DI 0 "register_operand" "=r")
805 (eq:DI (match_operand:DI 1 "register_operand" "%r")
806 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
fa5322fa 807 "TARGET_SHMEDIA"
b6d33983
R
808 "cmpeq %1, %N2, %0"
809 [(set_attr "type" "cmp_media")])
fa5322fa
AO
810
811(define_insn "cmpgtdi_media"
b6d33983
R
812 [(set (match_operand:DI 0 "register_operand" "=r")
813 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
814 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 815 "TARGET_SHMEDIA"
b6d33983
R
816 "cmpgt %N1, %N2, %0"
817 [(set_attr "type" "cmp_media")])
fa5322fa
AO
818
819(define_insn "cmpgtudi_media"
b6d33983
R
820 [(set (match_operand:DI 0 "register_operand" "=r")
821 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
822 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 823 "TARGET_SHMEDIA"
68cef009 824 "cmpgtu %N1, %N2, %0"
b6d33983 825 [(set_attr "type" "cmp_media")])
fa5322fa 826
1245df60
R
827;; We save the compare operands in the cmpxx patterns and use them when
828;; we generate the branch.
829
830(define_expand "cmpdi"
4773afa4
AO
831 [(set (reg:SI T_REG)
832 (compare (match_operand:DI 0 "arith_operand" "")
833 (match_operand:DI 1 "arith_operand" "")))]
fa5322fa 834 "TARGET_SH2 || TARGET_SHMEDIA"
1245df60
R
835 "
836{
837 sh_compare_op0 = operands[0];
838 sh_compare_op1 = operands[1];
839 DONE;
840}")
fa5322fa
AO
841;; -------------------------------------------------------------------------
842;; Conditional move instructions
843;; -------------------------------------------------------------------------
844
845;; The insn names may seem reversed, but note that cmveq performs the move
846;; if op1 == 0, and cmvne does it if op1 != 0.
847
848(define_insn "movdicc_false"
b6d33983
R
849 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
850 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 851 (const_int 0))
b6d33983
R
852 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
853 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 854 "TARGET_SHMEDIA"
b6d33983
R
855 "cmveq %1, %N2, %0"
856 [(set_attr "type" "arith_media")])
fa5322fa
AO
857
858(define_insn "movdicc_true"
b6d33983
R
859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
860 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 861 (const_int 0))
b6d33983
R
862 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
863 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 864 "TARGET_SHMEDIA"
b6d33983
R
865 "cmvne %1, %N2, %0"
866 [(set_attr "type" "arith_media")])
fa5322fa
AO
867
868(define_expand "movdicc"
869 [(set (match_operand:DI 0 "register_operand" "")
870 (if_then_else:DI (match_operand 1 "comparison_operator" "")
871 (match_operand:DI 2 "register_operand" "")
872 (match_operand:DI 3 "register_operand" "")))]
873 "TARGET_SHMEDIA"
874 "
875{
876 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
877 && GET_MODE (sh_compare_op0) == DImode
878 && sh_compare_op1 == const0_rtx)
879 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
880 sh_compare_op0, sh_compare_op1);
881 else
882 {
883 rtx tmp;
884
885 if (no_new_pseudos)
886 FAIL;
887
888 tmp = gen_reg_rtx (DImode);
889
890 switch (GET_CODE (operands[1]))
891 {
892 case EQ:
893 emit_insn (gen_seq (tmp));
894 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
895 break;
896
897 case NE:
898 emit_insn (gen_seq (tmp));
899 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
900 break;
901
902 case GT:
903 emit_insn (gen_sgt (tmp));
904 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
905 break;
906
907 case LT:
908 emit_insn (gen_slt (tmp));
909 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
910 break;
911
912 case GE:
913 emit_insn (gen_slt (tmp));
914 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
915 break;
916
917 case LE:
918 emit_insn (gen_sgt (tmp));
919 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
920 break;
921
922 case GTU:
923 emit_insn (gen_sgtu (tmp));
924 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
925 break;
926
927 case LTU:
928 emit_insn (gen_sltu (tmp));
929 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
930 break;
931
932 case GEU:
933 emit_insn (gen_sltu (tmp));
934 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
935 break;
936
937 case LEU:
938 emit_insn (gen_sgtu (tmp));
939 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
940 break;
941
942 case UNORDERED:
943 emit_insn (gen_sunordered (tmp));
944 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
945 break;
946
947 case ORDERED:
948 emit_insn (gen_sunordered (tmp));
949 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
950 break;
951
952 case UNEQ:
953 case UNGE:
954 case UNGT:
955 case UNLE:
956 case UNLT:
957 case LTGT:
958 FAIL;
959
960 default:
961 abort ();
962 }
963 }
964}")
1245df60
R
965\f
966;; -------------------------------------------------------------------------
bc45ade3
SC
967;; Addition instructions
968;; -------------------------------------------------------------------------
969
fa5322fa
AO
970(define_expand "adddi3"
971 [(set (match_operand:DI 0 "arith_reg_operand" "")
972 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
973 (match_operand:DI 2 "arith_operand" "")))]
974 ""
975 "
976{
977 if (TARGET_SH1)
978 {
979 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
980 FAIL;
981 operands[2] = force_reg (DImode, operands[2]);
982 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
983 DONE;
984 }
985}")
0d7e008e 986
fa5322fa
AO
987(define_insn "*adddi3_media"
988 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
989 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
990 (match_operand:DI 2 "arith_operand" "r,P")))]
991 "TARGET_SHMEDIA"
992 "@
993 add %1, %2, %0
2ad65b0e
SC
994 addi %1, %2, %0"
995 [(set_attr "type" "arith_media")])
fa5322fa 996
b6d33983
R
997(define_insn "adddi3z_media"
998 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
fa5322fa 999 (zero_extend:DI
b6d33983
R
1000 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1001 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
fa5322fa 1002 "TARGET_SHMEDIA"
b6d33983
R
1003 "addz.l %1, %N2, %0"
1004 [(set_attr "type" "arith_media")])
52702ae1 1005
fa5322fa 1006(define_insn "adddi3_compact"
07a45e5c
JW
1007 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1008 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1009 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1010 (clobber (reg:SI T_REG))]
fa5322fa 1011 "TARGET_SH1"
1245df60 1012 "#"
4fdd1f85 1013 [(set_attr "length" "6")])
961c4780 1014
1245df60 1015(define_split
e69d1422
R
1016 [(set (match_operand:DI 0 "arith_reg_operand" "")
1017 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1018 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1019 (clobber (reg:SI T_REG))]
fa5322fa 1020 "TARGET_SH1 && reload_completed"
1245df60
R
1021 [(const_int 0)]
1022 "
1023{
1024 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1025 high0 = gen_rtx_REG (SImode,
1026 true_regnum (operands[0])
1027 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1028 high2 = gen_rtx_REG (SImode,
1029 true_regnum (operands[2])
1030 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1031 emit_insn (gen_clrt ());
1032 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1033 emit_insn (gen_addc1 (high0, high0, high2));
1034 DONE;
1035}")
1036
1037(define_insn "addc"
1038 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1039 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1040 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1041 (reg:SI T_REG)))
1042 (set (reg:SI T_REG)
1245df60 1043 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1044 "TARGET_SH1"
1245df60 1045 "addc %2,%0"
c49439f1 1046 [(set_attr "type" "arith")])
1245df60
R
1047
1048(define_insn "addc1"
1049 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1051 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1052 (reg:SI T_REG)))
1053 (clobber (reg:SI T_REG))]
fa5322fa 1054 "TARGET_SH1"
1245df60 1055 "addc %2,%0"
c49439f1 1056 [(set_attr "type" "arith")])
1245df60 1057
fa5322fa
AO
1058(define_expand "addsi3"
1059 [(set (match_operand:SI 0 "arith_reg_operand" "")
1060 (plus:SI (match_operand:SI 1 "arith_operand" "")
1061 (match_operand:SI 2 "arith_operand" "")))]
1062 ""
1063 "
1064{
1065 if (TARGET_SHMEDIA)
1066 operands[1] = force_reg (SImode, operands[1]);
1067}")
1068
1069(define_insn "addsi3_media"
1070 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 1071 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
fa5322fa
AO
1072 (match_operand:SI 2 "arith_operand" "r,P")))]
1073 "TARGET_SHMEDIA"
1074 "@
1075 add.l %1, %2, %0
b6d33983
R
1076 addi.l %1, %2, %0"
1077 [(set_attr "type" "arith_media")])
52702ae1 1078
fa5322fa 1079(define_insn "*addsi3_compact"
aa684c94 1080 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f 1081 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
bc45ade3 1082 (match_operand:SI 2 "arith_operand" "rI")))]
fa5322fa 1083 "TARGET_SH1"
bc45ade3 1084 "add %2,%0"
c49439f1 1085 [(set_attr "type" "arith")])
fae15c93 1086
bc45ade3
SC
1087;; -------------------------------------------------------------------------
1088;; Subtraction instructions
1089;; -------------------------------------------------------------------------
1090
fa5322fa
AO
1091(define_expand "subdi3"
1092 [(set (match_operand:DI 0 "arith_reg_operand" "")
52702ae1 1093 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
fa5322fa
AO
1094 (match_operand:DI 2 "arith_reg_operand" "")))]
1095 ""
1096 "
1097{
1098 if (TARGET_SH1)
1099 {
52702ae1 1100 operands[1] = force_reg (DImode, operands[1]);
fa5322fa
AO
1101 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1102 DONE;
1103 }
1104}")
52702ae1 1105
fa5322fa
AO
1106(define_insn "*subdi3_media"
1107 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
52702ae1 1108 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
fa5322fa
AO
1109 (match_operand:DI 2 "arith_reg_operand" "r")))]
1110 "TARGET_SHMEDIA"
2ad65b0e
SC
1111 "sub %N1, %2, %0"
1112 [(set_attr "type" "arith_media")])
52702ae1 1113
fa5322fa 1114(define_insn "subdi3_compact"
07a45e5c
JW
1115 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1116 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1117 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1118 (clobber (reg:SI T_REG))]
fa5322fa 1119 "TARGET_SH1"
1245df60 1120 "#"
4fdd1f85 1121 [(set_attr "length" "6")])
bc45ade3 1122
1245df60 1123(define_split
e69d1422
R
1124 [(set (match_operand:DI 0 "arith_reg_operand" "")
1125 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1126 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1127 (clobber (reg:SI T_REG))]
fa5322fa 1128 "TARGET_SH1 && reload_completed"
1245df60
R
1129 [(const_int 0)]
1130 "
1131{
1132 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1133 high0 = gen_rtx_REG (SImode,
1134 true_regnum (operands[0])
1135 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1136 high2 = gen_rtx_REG (SImode,
1137 true_regnum (operands[2])
1138 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1139 emit_insn (gen_clrt ());
1140 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1141 emit_insn (gen_subc1 (high0, high0, high2));
1142 DONE;
1143}")
1144
1145(define_insn "subc"
1146 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1147 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1148 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1149 (reg:SI T_REG)))
1150 (set (reg:SI T_REG)
1245df60 1151 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1152 "TARGET_SH1"
1245df60 1153 "subc %2,%0"
c49439f1 1154 [(set_attr "type" "arith")])
1245df60
R
1155
1156(define_insn "subc1"
1157 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1158 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1159 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1160 (reg:SI T_REG)))
1161 (clobber (reg:SI T_REG))]
fa5322fa 1162 "TARGET_SH1"
1245df60 1163 "subc %2,%0"
c49439f1 1164 [(set_attr "type" "arith")])
1245df60 1165
caca3c8a 1166(define_insn "*subsi3_internal"
0d7e008e
SC
1167 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1169 (match_operand:SI 2 "arith_reg_operand" "r")))]
fa5322fa 1170 "TARGET_SH1"
0d7e008e 1171 "sub %2,%0"
c49439f1 1172 [(set_attr "type" "arith")])
caca3c8a 1173
fa5322fa
AO
1174(define_insn "*subsi3_media"
1175 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
b6d33983
R
1176 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1177 (match_operand:SI 2 "extend_reg_operand" "r")))]
fa5322fa 1178 "TARGET_SHMEDIA"
b6d33983
R
1179 "sub.l %N1, %2, %0"
1180 [(set_attr "type" "arith_media")])
fa5322fa 1181
caca3c8a
JW
1182;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1183;; will sometimes save one instruction. Otherwise we might get
1184;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1185;; are the same.
1186
1187(define_expand "subsi3"
1188 [(set (match_operand:SI 0 "arith_reg_operand" "")
1189 (minus:SI (match_operand:SI 1 "arith_operand" "")
1190 (match_operand:SI 2 "arith_reg_operand" "")))]
1191 ""
1192 "
1193{
fa5322fa 1194 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
caca3c8a
JW
1195 {
1196 emit_insn (gen_negsi2 (operands[0], operands[2]));
1197 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1198 DONE;
1199 }
fa5322fa
AO
1200 if (TARGET_SHMEDIA)
1201 {
b6d33983 1202 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
fa5322fa 1203 FAIL;
b6d33983
R
1204 if (operands[1] != const0_rtx)
1205 operands[1] = force_reg (SImode, operands[1]);
fa5322fa 1206 }
caca3c8a 1207}")
bc45ade3
SC
1208\f
1209;; -------------------------------------------------------------------------
0d7e008e 1210;; Division instructions
bc45ade3
SC
1211;; -------------------------------------------------------------------------
1212
ffae286a 1213;; We take advantage of the library routines which don't clobber as many
0d7e008e
SC
1214;; registers as a normal function call would.
1215
1245df60 1216;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
956d6950 1217;; also has an effect on the register that holds the address of the sfunc.
e69d1422 1218;; To make this work, we have an extra dummy insn that shows the use
1245df60
R
1219;; of this register for reorg.
1220
1221(define_insn "use_sfunc_addr"
4773afa4 1222 [(set (reg:SI PR_REG)
e69d1422 1223 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
fa5322fa 1224 "TARGET_SH1"
1245df60
R
1225 ""
1226 [(set_attr "length" "0")])
1227
ddd5a7c1 1228;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
e96a50cc
JW
1229;; hard register 0. If we used hard register 0, then the next instruction
1230;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1231;; gets allocated to a stack slot that needs its address reloaded, then
1232;; there is nothing to prevent reload from using r0 to reload the address.
1233;; This reload would clobber the value in r0 we are trying to store.
1234;; If we let reload allocate r0, then this problem can never happen.
0d7e008e 1235
a512fa97 1236(define_insn "udivsi3_i1"
1245df60 1237 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1238 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1239 (clobber (reg:SI T_REG))
1240 (clobber (reg:SI PR_REG))
1241 (clobber (reg:SI R4_REG))
1245df60 1242 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1243 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1244 "jsr @%1%#"
1245 [(set_attr "type" "sfunc")
1246 (set_attr "needs_delay_slot" "yes")])
1247
9e96203d
R
1248; Since shmedia-nofpu code could be linked against shcompact code, and
1249; the udivsi3 libcall has the same name, we must consider all registers
1250; clobbered that are in the union of the registers clobbered by the
1251; shmedia and the shcompact implementation. Note, if the shcompact
1252; implemenation actually used shcompact code, we'd need to clobber
1253; also r23 and fr23.
fa5322fa
AO
1254(define_insn "udivsi3_i1_media"
1255 [(set (match_operand:SI 0 "register_operand" "=z")
1256 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1257 (clobber (reg:SI T_MEDIA_REG))
1258 (clobber (reg:SI PR_MEDIA_REG))
9e96203d
R
1259 (clobber (reg:SI R20_REG))
1260 (clobber (reg:SI R21_REG))
1261 (clobber (reg:SI R22_REG))
fa5322fa
AO
1262 (clobber (reg:DI TR0_REG))
1263 (clobber (reg:DI TR1_REG))
1264 (clobber (reg:DI TR2_REG))
1265 (use (match_operand:DI 1 "target_operand" "b"))]
1266 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1267 "blink %1, r18"
1268 [(set_attr "type" "sfunc")
1269 (set_attr "needs_delay_slot" "yes")])
1270
1271(define_expand "udivsi3_i4_media"
b6d33983
R
1272 [(set (match_dup 3)
1273 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1274 (set (match_dup 4)
1275 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
fa5322fa 1276 (set (match_dup 5) (float:DF (match_dup 3)))
b6d33983
R
1277 (set (match_dup 6) (float:DF (match_dup 4)))
1278 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1279 (set (match_dup 8) (fix:DI (match_dup 7)))
0ac78517
R
1280 (set (match_operand:SI 0 "register_operand" "")
1281 (truncate:SI (match_dup 8)))]
fa5322fa
AO
1282 "TARGET_SHMEDIA_FPU"
1283 "
1284{
fa5322fa 1285 operands[3] = gen_reg_rtx (DImode);
b6d33983 1286 operands[4] = gen_reg_rtx (DImode);
fa5322fa
AO
1287 operands[5] = gen_reg_rtx (DFmode);
1288 operands[6] = gen_reg_rtx (DFmode);
b6d33983
R
1289 operands[7] = gen_reg_rtx (DFmode);
1290 operands[8] = gen_reg_rtx (DImode);
fa5322fa
AO
1291}")
1292
225e4f43
R
1293(define_insn "udivsi3_i4"
1294 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1295 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1296 (clobber (reg:SI T_REG))
4773afa4
AO
1297 (clobber (reg:SI PR_REG))
1298 (clobber (reg:DF DR0_REG))
1299 (clobber (reg:DF DR2_REG))
1300 (clobber (reg:DF DR4_REG))
1301 (clobber (reg:SI R0_REG))
1302 (clobber (reg:SI R1_REG))
1303 (clobber (reg:SI R4_REG))
1304 (clobber (reg:SI R5_REG))
1305 (use (reg:PSI FPSCR_REG))
225e4f43
R
1306 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1307 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1308 "jsr @%1%#"
1309 [(set_attr "type" "sfunc")
d64264ff 1310 (set_attr "fp_mode" "double")
225e4f43
R
1311 (set_attr "needs_delay_slot" "yes")])
1312
1313(define_insn "udivsi3_i4_single"
1314 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1315 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1316 (clobber (reg:SI T_REG))
4773afa4
AO
1317 (clobber (reg:SI PR_REG))
1318 (clobber (reg:DF DR0_REG))
1319 (clobber (reg:DF DR2_REG))
1320 (clobber (reg:DF DR4_REG))
1321 (clobber (reg:SI R0_REG))
1322 (clobber (reg:SI R1_REG))
1323 (clobber (reg:SI R4_REG))
1324 (clobber (reg:SI R5_REG))
225e4f43 1325 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1326 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1327 "jsr @%1%#"
0d7e008e 1328 [(set_attr "type" "sfunc")
0d7e008e
SC
1329 (set_attr "needs_delay_slot" "yes")])
1330
1331(define_expand "udivsi3"
a512fa97 1332 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
4773afa4
AO
1333 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1334 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1335 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1336 (udiv:SI (reg:SI R4_REG)
1337 (reg:SI R5_REG)))
1338 (clobber (reg:SI T_REG))
1339 (clobber (reg:SI PR_REG))
1340 (clobber (reg:SI R4_REG))
ffae286a 1341 (use (match_dup 3))])]
0d7e008e 1342 ""
225e4f43
R
1343 "
1344{
4392ebd3 1345 rtx first, last;
a512fa97 1346
fa5322fa 1347 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1348 /* Emit the move of the address to a pseudo outside of the libcall. */
7e2fda6e 1349 if (TARGET_HARD_SH4 && TARGET_SH3E)
225e4f43 1350 {
225e4f43
R
1351 emit_move_insn (operands[3],
1352 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1353 if (TARGET_FPU_SINGLE)
a512fa97 1354 last = gen_udivsi3_i4_single (operands[0], operands[3]);
225e4f43 1355 else
a512fa97 1356 last = gen_udivsi3_i4 (operands[0], operands[3]);
225e4f43 1357 }
fa5322fa 1358 else if (TARGET_SHMEDIA_FPU)
b6d33983
R
1359 {
1360 operands[1] = force_reg (SImode, operands[1]);
1361 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1362 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1363 DONE;
b6d33983 1364 }
fa5322fa
AO
1365 else if (TARGET_SH5)
1366 {
1367 emit_move_insn (operands[3],
1368 gen_rtx_SYMBOL_REF (Pmode,
1369 (TARGET_FPU_ANY
1370 ? \"__udivsi3_i4\"
1371 : \"__udivsi3\")));
1372
1373 if (TARGET_SHMEDIA)
1374 last = gen_udivsi3_i1_media (operands[0],
1375 Pmode == DImode
1376 ? operands[3]
1377 : gen_rtx_SUBREG (DImode, operands[3],
1378 0));
1379 else if (TARGET_FPU_ANY)
1380 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1381 else
1382 last = gen_udivsi3_i1 (operands[0], operands[3]);
1383 }
a512fa97
R
1384 else
1385 {
1386 emit_move_insn (operands[3],
1387 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1388 last = gen_udivsi3_i1 (operands[0], operands[3]);
1389 }
4392ebd3
RS
1390 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1391 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1392 last = emit_insn (last);
1393 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1394 invariant code motion can move it. */
1395 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1396 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1397 DONE;
225e4f43 1398}")
0d7e008e 1399
a512fa97 1400(define_insn "divsi3_i1"
1245df60 1401 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1402 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1403 (clobber (reg:SI T_REG))
1404 (clobber (reg:SI PR_REG))
1405 (clobber (reg:SI R1_REG))
1406 (clobber (reg:SI R2_REG))
1407 (clobber (reg:SI R3_REG))
1245df60 1408 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1409 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1410 "jsr @%1%#"
1411 [(set_attr "type" "sfunc")
1412 (set_attr "needs_delay_slot" "yes")])
1413
9e96203d 1414; Since shmedia-nofpu code could be linked against shcompact code, and
b6d33983 1415; the sdivsi3 libcall has the same name, we must consider all registers
9e96203d
R
1416; clobbered that are in the union of the registers clobbered by the
1417; shmedia and the shcompact implementation. Note, if the shcompact
1418; implemenation actually used shcompact code, we'd need to clobber
1419; also r22, r23 and fr23.
fa5322fa
AO
1420(define_insn "divsi3_i1_media"
1421 [(set (match_operand:SI 0 "register_operand" "=z")
1422 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1423 (clobber (reg:SI T_MEDIA_REG))
1424 (clobber (reg:SI PR_MEDIA_REG))
1425 (clobber (reg:SI R1_REG))
1426 (clobber (reg:SI R2_REG))
1427 (clobber (reg:SI R3_REG))
9e96203d
R
1428 (clobber (reg:SI R20_REG))
1429 (clobber (reg:SI R21_REG))
fa5322fa
AO
1430 (clobber (reg:DI TR0_REG))
1431 (clobber (reg:DI TR1_REG))
1432 (clobber (reg:DI TR2_REG))
1433 (use (match_operand:DI 1 "target_operand" "b"))]
1434 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
2ad65b0e
SC
1435 "blink %1, r18"
1436 [(set_attr "type" "sfunc")])
fa5322fa
AO
1437
1438(define_expand "divsi3_i4_media"
51214775
R
1439 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1440 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1441 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
fa5322fa 1442 (set (match_operand:SI 0 "register_operand" "=r")
51214775 1443 (fix:SI (match_dup 5)))]
fa5322fa
AO
1444 "TARGET_SHMEDIA_FPU"
1445 "
1446{
51214775 1447 operands[3] = gen_reg_rtx (DFmode);
fa5322fa
AO
1448 operands[4] = gen_reg_rtx (DFmode);
1449 operands[5] = gen_reg_rtx (DFmode);
fa5322fa
AO
1450}")
1451
225e4f43
R
1452(define_insn "divsi3_i4"
1453 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1454 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1455 (clobber (reg:SI PR_REG))
1456 (clobber (reg:DF DR0_REG))
1457 (clobber (reg:DF DR2_REG))
1458 (use (reg:PSI FPSCR_REG))
225e4f43
R
1459 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1460 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1461 "jsr @%1%#"
1462 [(set_attr "type" "sfunc")
d64264ff 1463 (set_attr "fp_mode" "double")
225e4f43
R
1464 (set_attr "needs_delay_slot" "yes")])
1465
1466(define_insn "divsi3_i4_single"
1467 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1468 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1469 (clobber (reg:SI PR_REG))
1470 (clobber (reg:DF DR0_REG))
1471 (clobber (reg:DF DR2_REG))
1472 (clobber (reg:SI R2_REG))
225e4f43 1473 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1474 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1475 "jsr @%1%#"
0d7e008e 1476 [(set_attr "type" "sfunc")
0d7e008e
SC
1477 (set_attr "needs_delay_slot" "yes")])
1478
1479(define_expand "divsi3"
a512fa97 1480 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
4773afa4
AO
1481 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1482 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1483 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1484 (div:SI (reg:SI R4_REG)
1485 (reg:SI R5_REG)))
1486 (clobber (reg:SI T_REG))
1487 (clobber (reg:SI PR_REG))
1488 (clobber (reg:SI R1_REG))
1489 (clobber (reg:SI R2_REG))
1490 (clobber (reg:SI R3_REG))
ffae286a 1491 (use (match_dup 3))])]
0d7e008e 1492 ""
225e4f43
R
1493 "
1494{
4392ebd3 1495 rtx first, last;
a512fa97 1496
fa5322fa 1497 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1498 /* Emit the move of the address to a pseudo outside of the libcall. */
7e2fda6e 1499 if (TARGET_HARD_SH4 && TARGET_SH3E)
225e4f43 1500 {
225e4f43
R
1501 emit_move_insn (operands[3],
1502 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1503 if (TARGET_FPU_SINGLE)
a512fa97 1504 last = gen_divsi3_i4_single (operands[0], operands[3]);
225e4f43 1505 else
a512fa97 1506 last = gen_divsi3_i4 (operands[0], operands[3]);
225e4f43 1507 }
fa5322fa 1508 else if (TARGET_SHMEDIA_FPU)
51214775
R
1509 {
1510 operands[1] = force_reg (SImode, operands[1]);
1511 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1512 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1513 DONE;
51214775 1514 }
fa5322fa
AO
1515 else if (TARGET_SH5)
1516 {
1517 emit_move_insn (operands[3],
1518 gen_rtx_SYMBOL_REF (Pmode,
1519 (TARGET_FPU_ANY
1520 ? \"__sdivsi3_i4\"
1521 : \"__sdivsi3\")));
1522
1523 if (TARGET_SHMEDIA)
52702ae1 1524 last = gen_divsi3_i1_media (operands[0],
fa5322fa
AO
1525 Pmode == DImode
1526 ? operands[3]
1527 : gen_rtx_SUBREG (DImode, operands[3],
1528 0));
1529 else if (TARGET_FPU_ANY)
1530 last = gen_divsi3_i4_single (operands[0], operands[3]);
1531 else
1532 last = gen_divsi3_i1 (operands[0], operands[3]);
1533 }
a512fa97
R
1534 else
1535 {
1536 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1537 last = gen_divsi3_i1 (operands[0], operands[3]);
1538 }
4392ebd3
RS
1539 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1540 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1541 last = emit_insn (last);
1542 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1543 invariant code motion can move it. */
1544 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1545 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1546 DONE;
225e4f43 1547}")
0d7e008e
SC
1548\f
1549;; -------------------------------------------------------------------------
1550;; Multiplication instructions
1551;; -------------------------------------------------------------------------
1552
a512fa97 1553(define_insn "umulhisi3_i"
4773afa4
AO
1554 [(set (reg:SI MACL_REG)
1555 (mult:SI (zero_extend:SI
1556 (match_operand:HI 0 "arith_reg_operand" "r"))
1557 (zero_extend:SI
1558 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1559 "TARGET_SH1"
e9a9e960 1560 "mulu.w %1,%0"
b9654711 1561 [(set_attr "type" "smpy")])
bc45ade3 1562
a512fa97 1563(define_insn "mulhisi3_i"
4773afa4 1564 [(set (reg:SI MACL_REG)
bc45ade3 1565 (mult:SI (sign_extend:SI
af55dae3 1566 (match_operand:HI 0 "arith_reg_operand" "r"))
bc45ade3 1567 (sign_extend:SI
af55dae3 1568 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1569 "TARGET_SH1"
e9a9e960 1570 "muls.w %1,%0"
b9654711 1571 [(set_attr "type" "smpy")])
bc45ade3
SC
1572
1573(define_expand "mulhisi3"
4773afa4 1574 [(set (reg:SI MACL_REG)
bc45ade3 1575 (mult:SI (sign_extend:SI
51aea58d 1576 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1577 (sign_extend:SI
51aea58d
JW
1578 (match_operand:HI 2 "arith_reg_operand" ""))))
1579 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1580 (reg:SI MACL_REG))]
fa5322fa 1581 "TARGET_SH1"
a512fa97
R
1582 "
1583{
1584 rtx first, last;
1585
1586 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
4773afa4 1587 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1588 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1589 invariant code motion can move it. */
1590 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1591 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1592 /* expand_binop can't find a suitable code in umul_widen_optab to
1593 make a REG_EQUAL note from, so make one here.
1594 See also smulsi3_highpart.
1595 ??? Alternatively, we could put this at the calling site of expand_binop,
1596 i.e. expand_expr. */
1597 REG_NOTES (last)
1598 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1599 REG_NOTES (last));
a512fa97
R
1600 DONE;
1601}")
bc45ade3
SC
1602
1603(define_expand "umulhisi3"
4773afa4 1604 [(set (reg:SI MACL_REG)
bc45ade3 1605 (mult:SI (zero_extend:SI
51aea58d 1606 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1607 (zero_extend:SI
51aea58d
JW
1608 (match_operand:HI 2 "arith_reg_operand" ""))))
1609 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1610 (reg:SI MACL_REG))]
fa5322fa 1611 "TARGET_SH1"
a512fa97
R
1612 "
1613{
1614 rtx first, last;
1615
1616 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
4773afa4 1617 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1618 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1619 invariant code motion can move it. */
1620 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1621 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1622 /* expand_binop can't find a suitable code in umul_widen_optab to
1623 make a REG_EQUAL note from, so make one here.
1624 See also smulsi3_highpart.
1625 ??? Alternatively, we could put this at the calling site of expand_binop,
1626 i.e. expand_expr. */
1627 REG_NOTES (last)
1628 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1629 REG_NOTES (last));
a512fa97
R
1630 DONE;
1631}")
bc45ade3 1632
0d7e008e
SC
1633;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1634;; a call to a routine which clobbers known registers.
1635
1636(define_insn ""
e96a50cc 1637 [(set (match_operand:SI 1 "register_operand" "=z")
4773afa4
AO
1638 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1639 (clobber (reg:SI MACL_REG))
1640 (clobber (reg:SI T_REG))
1641 (clobber (reg:SI PR_REG))
1642 (clobber (reg:SI R3_REG))
1643 (clobber (reg:SI R2_REG))
1644 (clobber (reg:SI R1_REG))
07a45e5c 1645 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 1646 "TARGET_SH1"
0d7e008e
SC
1647 "jsr @%0%#"
1648 [(set_attr "type" "sfunc")
0d7e008e
SC
1649 (set_attr "needs_delay_slot" "yes")])
1650
1651(define_expand "mulsi3_call"
4773afa4
AO
1652 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1653 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
51aea58d 1654 (parallel[(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1655 (mult:SI (reg:SI R4_REG)
1656 (reg:SI R5_REG)))
1657 (clobber (reg:SI MACL_REG))
1658 (clobber (reg:SI T_REG))
1659 (clobber (reg:SI PR_REG))
1660 (clobber (reg:SI R3_REG))
1661 (clobber (reg:SI R2_REG))
1662 (clobber (reg:SI R1_REG))
225e4f43 1663 (use (match_operand:SI 3 "register_operand" ""))])]
fa5322fa 1664 "TARGET_SH1"
225e4f43 1665 "")
07a45e5c 1666
0d7e008e 1667(define_insn "mul_l"
4773afa4 1668 [(set (reg:SI MACL_REG)
0d7e008e
SC
1669 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1670 (match_operand:SI 1 "arith_reg_operand" "r")))]
1671 "TARGET_SH2"
1672 "mul.l %1,%0"
51bd623f 1673 [(set_attr "type" "dmpy")])
0d7e008e
SC
1674
1675(define_expand "mulsi3"
4773afa4 1676 [(set (reg:SI MACL_REG)
51aea58d
JW
1677 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1678 (match_operand:SI 2 "arith_reg_operand" "")))
1679 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1680 (reg:SI MACL_REG))]
fa5322fa 1681 "TARGET_SH1"
51bd623f
JW
1682 "
1683{
225e4f43
R
1684 rtx first, last;
1685
51bd623f
JW
1686 if (!TARGET_SH2)
1687 {
225e4f43
R
1688 /* The address must be set outside the libcall,
1689 since it goes into a pseudo. */
a6f463a0
AO
1690 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1691 rtx addr = force_reg (SImode, sym);
1692 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1693 operands[2], addr);
fa60f36d
R
1694 first = insns;
1695 last = emit_insn (insns);
51bd623f 1696 }
225e4f43
R
1697 else
1698 {
1699 rtx macl = gen_rtx_REG (SImode, MACL_REG);
aa4778b6 1700
225e4f43 1701 first = emit_insn (gen_mul_l (operands[1], operands[2]));
aa4778b6
R
1702 /* consec_sets_giv can only recognize the first insn that sets a
1703 giv as the giv insn. So we must tag this also with a REG_EQUAL
1704 note. */
78d114ef 1705 last = emit_insn (gen_movsi_i ((operands[0]), macl));
225e4f43
R
1706 }
1707 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1708 invariant code motion can move it. */
1709 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1710 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1711 DONE;
51bd623f 1712}")
00f8ff66 1713
af55dae3 1714(define_insn "mulsidi3_i"
4773afa4 1715 [(set (reg:SI MACH_REG)
a512fa97 1716 (truncate:SI
4773afa4
AO
1717 (lshiftrt:DI
1718 (mult:DI
1719 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1720 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1721 (const_int 32))))
1722 (set (reg:SI MACL_REG)
a512fa97
R
1723 (mult:SI (match_dup 0)
1724 (match_dup 1)))]
06e1bace 1725 "TARGET_SH2"
af55dae3 1726 "dmuls.l %1,%0"
0d7e008e
SC
1727 [(set_attr "type" "dmpy")])
1728
fa5322fa
AO
1729(define_expand "mulsidi3"
1730 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1731 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1732 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1733 "TARGET_SH2 || TARGET_SHMEDIA"
1734 "
1735{
1736 if (TARGET_SH2)
1737 {
1738 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1739 operands[2]));
1740 DONE;
1741 }
1742}")
1743
1744(define_insn "mulsidi3_media"
1745 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1746 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1747 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1748 "TARGET_SHMEDIA"
b6d33983
R
1749 "muls.l %1, %2, %0"
1750 [(set_attr "type" "dmpy_media")])
52702ae1 1751
fa5322fa 1752(define_insn "mulsidi3_compact"
a512fa97 1753 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1754 (mult:DI
1755 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1756 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1757 (clobber (reg:SI MACH_REG))
1758 (clobber (reg:SI MACL_REG))]
a512fa97
R
1759 "TARGET_SH2"
1760 "#")
1761
1762(define_split
1763 [(set (match_operand:DI 0 "arith_reg_operand" "")
4773afa4
AO
1764 (mult:DI
1765 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1766 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1767 (clobber (reg:SI MACH_REG))
1768 (clobber (reg:SI MACL_REG))]
06e1bace 1769 "TARGET_SH2"
a512fa97 1770 [(const_int 0)]
af55dae3
JW
1771 "
1772{
a512fa97
R
1773 rtx low_dst = gen_lowpart (SImode, operands[0]);
1774 rtx high_dst = gen_highpart (SImode, operands[0]);
0d7e008e 1775
a512fa97 1776 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
af55dae3 1777
4773afa4
AO
1778 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1779 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1780 /* We need something to tag the possible REG_EQUAL notes on to. */
1781 emit_move_insn (operands[0], operands[0]);
1782 DONE;
af55dae3
JW
1783}")
1784
1785(define_insn "umulsidi3_i"
4773afa4 1786 [(set (reg:SI MACH_REG)
a512fa97 1787 (truncate:SI
4773afa4
AO
1788 (lshiftrt:DI
1789 (mult:DI
1790 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1791 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1792 (const_int 32))))
1793 (set (reg:SI MACL_REG)
a512fa97
R
1794 (mult:SI (match_dup 0)
1795 (match_dup 1)))]
06e1bace 1796 "TARGET_SH2"
af55dae3 1797 "dmulu.l %1,%0"
0d7e008e
SC
1798 [(set_attr "type" "dmpy")])
1799
fa5322fa
AO
1800(define_expand "umulsidi3"
1801 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1802 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1803 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1804 "TARGET_SH2 || TARGET_SHMEDIA"
1805 "
1806{
1807 if (TARGET_SH2)
1808 {
1809 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1810 operands[2]));
1811 DONE;
1812 }
1813}")
1814
1815(define_insn "umulsidi3_media"
1816 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1817 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1818 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1819 "TARGET_SHMEDIA"
b6d33983
R
1820 "mulu.l %1, %2, %0"
1821 [(set_attr "type" "dmpy_media")])
52702ae1 1822
fa5322fa 1823(define_insn "umulsidi3_compact"
a512fa97 1824 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1825 (mult:DI
1826 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1827 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1828 (clobber (reg:SI MACH_REG))
1829 (clobber (reg:SI MACL_REG))]
a512fa97
R
1830 "TARGET_SH2"
1831 "#")
1832
1833(define_split
1834 [(set (match_operand:DI 0 "arith_reg_operand" "")
51aea58d
JW
1835 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1836 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1837 (clobber (reg:SI MACH_REG))
1838 (clobber (reg:SI MACL_REG))]
06e1bace 1839 "TARGET_SH2"
a512fa97 1840 [(const_int 0)]
af55dae3
JW
1841 "
1842{
a512fa97
R
1843 rtx low_dst = gen_lowpart (SImode, operands[0]);
1844 rtx high_dst = gen_highpart (SImode, operands[0]);
af55dae3 1845
a512fa97 1846 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
af55dae3 1847
4773afa4
AO
1848 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1849 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1850 /* We need something to tag the possible REG_EQUAL notes on to. */
1851 emit_move_insn (operands[0], operands[0]);
1852 DONE;
af55dae3 1853}")
06e1bace 1854
a512fa97 1855(define_insn "smulsi3_highpart_i"
4773afa4 1856 [(set (reg:SI MACH_REG)
06e1bace 1857 (truncate:SI
4773afa4
AO
1858 (lshiftrt:DI
1859 (mult:DI
1860 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1861 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1862 (const_int 32))))
1863 (clobber (reg:SI MACL_REG))]
06e1bace 1864 "TARGET_SH2"
af55dae3 1865 "dmuls.l %1,%0"
06e1bace
RK
1866 [(set_attr "type" "dmpy")])
1867
1868(define_expand "smulsi3_highpart"
4773afa4
AO
1869 [(parallel
1870 [(set (reg:SI MACH_REG)
1871 (truncate:SI
1872 (lshiftrt:DI
1873 (mult:DI
1874 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1875 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1876 (const_int 32))))
1877 (clobber (reg:SI MACL_REG))])
06e1bace 1878 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1879 (reg:SI MACH_REG))]
06e1bace 1880 "TARGET_SH2"
a512fa97
R
1881 "
1882{
1883 rtx first, last;
06e1bace 1884
a512fa97 1885 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1886 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1887 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1888 invariant code motion can move it. */
1889 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1890 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
22d05f60
R
1891 /* expand_binop can't find a suitable code in mul_highpart_optab to
1892 make a REG_EQUAL note from, so make one here.
c49439f1 1893 See also {,u}mulhisi.
22d05f60
R
1894 ??? Alternatively, we could put this at the calling site of expand_binop,
1895 i.e. expand_mult_highpart. */
1896 REG_NOTES (last)
1897 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1898 REG_NOTES (last));
a512fa97
R
1899 DONE;
1900}")
1901
1902(define_insn "umulsi3_highpart_i"
4773afa4 1903 [(set (reg:SI MACH_REG)
06e1bace 1904 (truncate:SI
4773afa4
AO
1905 (lshiftrt:DI
1906 (mult:DI
1907 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1908 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1909 (const_int 32))))
1910 (clobber (reg:SI MACL_REG))]
06e1bace 1911 "TARGET_SH2"
af55dae3 1912 "dmulu.l %1,%0"
06e1bace
RK
1913 [(set_attr "type" "dmpy")])
1914
1915(define_expand "umulsi3_highpart"
4773afa4
AO
1916 [(parallel
1917 [(set (reg:SI MACH_REG)
1918 (truncate:SI
1919 (lshiftrt:DI
1920 (mult:DI
1921 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1922 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1923 (const_int 32))))
1924 (clobber (reg:SI MACL_REG))])
06e1bace 1925 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1926 (reg:SI MACH_REG))]
06e1bace 1927 "TARGET_SH2"
a512fa97
R
1928 "
1929{
1930 rtx first, last;
1931
1932 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1933 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1934 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1935 invariant code motion can move it. */
1936 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1937 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1938 DONE;
1939}")
bc45ade3
SC
1940\f
1941;; -------------------------------------------------------------------------
1942;; Logical operations
1943;; -------------------------------------------------------------------------
1944
b6d33983 1945(define_insn "*andsi3_compact"
aa684c94
SC
1946 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1947 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
bc45ade3 1948 (match_operand:SI 2 "logical_operand" "r,L")))]
fa5322fa 1949 "TARGET_SH1"
bc45ade3 1950 "and %2,%0"
c49439f1 1951 [(set_attr "type" "arith")])
bc45ade3 1952
43aa4e05 1953;; If the constant is 255, then emit an extu.b instruction instead of an
51bd623f
JW
1954;; and, since that will give better code.
1955
0d7e008e
SC
1956(define_expand "andsi3"
1957 [(set (match_operand:SI 0 "arith_reg_operand" "")
1958 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1959 (match_operand:SI 2 "logical_operand" "")))]
fa5322fa 1960 "TARGET_SH1"
51bd623f
JW
1961 "
1962{
1963 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1964 {
1965 emit_insn (gen_zero_extendqisi2 (operands[0],
1966 gen_lowpart (QImode, operands[1])));
1967 DONE;
1968 }
1969}")
0d7e008e 1970
c1b92d09
R
1971(define_insn_and_split "anddi3"
1972 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1973 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
b51dc045 1974 (match_operand:DI 2 "and_operand" "r,P,Z")))]
fa5322fa
AO
1975 "TARGET_SHMEDIA"
1976 "@
1977 and %1, %2, %0
c1b92d09
R
1978 andi %1, %2, %0
1979 #"
1980 "reload_completed
1981 && ! logical_operand (operands[2], DImode)"
1982 [(const_int 0)]
1983 "
1984{
1985 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1986 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1987 else
1988 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1989 DONE;
2ad65b0e
SC
1990}"
1991 [(set_attr "type" "arith_media")])
fa5322fa 1992
b6d33983 1993(define_insn "andcdi3"
fa5322fa
AO
1994 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1995 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1996 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1997 "TARGET_SHMEDIA"
2ad65b0e
SC
1998 "andc %1,%2,%0"
1999 [(set_attr "type" "arith_media")])
fa5322fa 2000
bc45ade3 2001(define_insn "iorsi3"
aa684c94
SC
2002 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2003 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
bc45ade3 2004 (match_operand:SI 2 "logical_operand" "r,L")))]
fa5322fa 2005 "TARGET_SH1"
1245df60 2006 "or %2,%0"
c49439f1 2007 [(set_attr "type" "arith")])
bc45ade3 2008
fa5322fa
AO
2009(define_insn "iordi3"
2010 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2011 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2012 (match_operand:DI 2 "logical_operand" "r,P")))]
2013 "TARGET_SHMEDIA"
2014 "@
2015 or %1, %2, %0
2ad65b0e
SC
2016 ori %1, %2, %0"
2017 [(set_attr "type" "arith_media")])
fa5322fa 2018
bc45ade3 2019(define_insn "xorsi3"
0d7e008e 2020 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
aa684c94 2021 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
0d7e008e 2022 (match_operand:SI 2 "logical_operand" "L,r")))]
fa5322fa 2023 "TARGET_SH1"
bc45ade3 2024 "xor %2,%0"
c49439f1 2025 [(set_attr "type" "arith")])
fa5322fa
AO
2026
2027(define_insn "xordi3"
2028 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2029 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2030 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2031 "TARGET_SHMEDIA"
2032 "@
2033 xor %1, %2, %0
2ad65b0e
SC
2034 xori %1, %2, %0"
2035 [(set_attr "type" "arith_media")])
ff881d52
R
2036
2037;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2038;; converts 2 * sign extend -> logical op into logical op -> sign extend
2039(define_split
2040 [(set (match_operand:DI 0 "arith_reg_operand" "")
2041 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2042 [(match_operand 1 "any_register_operand" "")
2043 (match_operand 2 "any_register_operand" "")])))]
2044 "TARGET_SHMEDIA"
2045 [(set (match_dup 5) (match_dup 4))
2046 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2047"
2048{
2049 enum machine_mode inmode = GET_MODE (operands[1]);
2050 int regno, offset = 0;
2051
2052 if (GET_CODE (operands[0]) == SUBREG)
2053 {
2054 offset = SUBREG_BYTE (operands[0]);
2055 operands[0] = SUBREG_REG (operands[0]);
2056 }
2057 if (GET_CODE (operands[0]) != REG)
2058 abort ();
2059 if (! TARGET_LITTLE_ENDIAN)
2060 offset += 8 - GET_MODE_SIZE (inmode);
2061 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2062}")
bc45ade3
SC
2063\f
2064;; -------------------------------------------------------------------------
2065;; Shifts and rotates
2066;; -------------------------------------------------------------------------
2067
b6d33983
R
2068(define_expand "rotldi3"
2069 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2070 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2071 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2072 "TARGET_SHMEDIA"
2073 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2074
2075(define_insn "rotldi3_mextr"
2076 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2077 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2078 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2079 "TARGET_SHMEDIA"
2080 "*
2081{
2082 static char templ[16];
2083
2084 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2085 8 - (int) (INTVAL (operands[2]) >> 3));
2086 return templ;
2087}"
2088 [(set_attr "type" "arith_media")])
2089
2090(define_expand "rotrdi3"
2091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2092 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2093 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2094 "TARGET_SHMEDIA"
2095 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2096
2097(define_insn "rotrdi3_mextr"
2098 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2099 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2100 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2101 "TARGET_SHMEDIA"
2102 "*
2103{
2104 static char templ[16];
2105
2106 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2107 return templ;
2108}"
2109 [(set_attr "type" "arith_media")])
2110
51bd623f 2111(define_insn "rotlsi3_1"
b9654711
SC
2112 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2113 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2114 (const_int 1)))
4773afa4 2115 (set (reg:SI T_REG)
51aea58d 2116 (lshiftrt:SI (match_dup 1) (const_int 31)))]
fa5322fa 2117 "TARGET_SH1"
1245df60 2118 "rotl %0"
c49439f1 2119 [(set_attr "type" "arith")])
b9654711 2120
51bd623f 2121(define_insn "rotlsi3_31"
b9654711 2122 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f
JW
2123 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2124 (const_int 31)))
4773afa4 2125 (clobber (reg:SI T_REG))]
fa5322fa 2126 "TARGET_SH1"
1245df60 2127 "rotr %0"
c49439f1 2128 [(set_attr "type" "arith")])
b9654711 2129
1245df60 2130(define_insn "rotlsi3_16"
51bd623f
JW
2131 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2133 (const_int 16)))]
fa5322fa 2134 "TARGET_SH1"
1245df60 2135 "swap.w %1,%0"
c49439f1 2136 [(set_attr "type" "arith")])
b9654711 2137
51bd623f
JW
2138(define_expand "rotlsi3"
2139 [(set (match_operand:SI 0 "arith_reg_operand" "")
2140 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2141 (match_operand:SI 2 "immediate_operand" "")))]
fa5322fa 2142 "TARGET_SH1"
51bd623f
JW
2143 "
2144{
0139adca 2145 static const char rot_tab[] = {
1245df60
R
2146 000, 000, 000, 000, 000, 000, 010, 001,
2147 001, 001, 011, 013, 003, 003, 003, 003,
2148 003, 003, 003, 003, 003, 013, 012, 002,
2149 002, 002, 010, 000, 000, 000, 000, 000,
2150 };
2151
2152 int count, choice;
2153
51bd623f
JW
2154 if (GET_CODE (operands[2]) != CONST_INT)
2155 FAIL;
1245df60
R
2156 count = INTVAL (operands[2]);
2157 choice = rot_tab[count];
2158 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2159 FAIL;
2160 choice &= 7;
2161 switch (choice)
51bd623f 2162 {
1245df60
R
2163 case 0:
2164 emit_move_insn (operands[0], operands[1]);
2165 count -= (count & 16) * 2;
2166 break;
2167 case 3:
2168 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2169 count -= 16;
2170 break;
2171 case 1:
2172 case 2:
2173 {
2174 rtx parts[2];
2175 parts[0] = gen_reg_rtx (SImode);
2176 parts[1] = gen_reg_rtx (SImode);
2177 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2178 parts[choice-1] = operands[1];
2179 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2180 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2181 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2182 count = (count & ~16) - 8;
2183 }
51bd623f 2184 }
1245df60
R
2185
2186 for (; count > 0; count--)
2187 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2188 for (; count < 0; count++)
2189 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2190
2191 DONE;
51bd623f
JW
2192}")
2193
1245df60 2194(define_insn "*rotlhi3_8"
51bd623f
JW
2195 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2196 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2197 (const_int 8)))]
fa5322fa 2198 "TARGET_SH1"
1245df60 2199 "swap.b %1,%0"
c49439f1 2200 [(set_attr "type" "arith")])
51bd623f
JW
2201
2202(define_expand "rotlhi3"
2203 [(set (match_operand:HI 0 "arith_reg_operand" "")
2204 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2205 (match_operand:HI 2 "immediate_operand" "")))]
fa5322fa 2206 "TARGET_SH1"
51bd623f
JW
2207 "
2208{
2209 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2210 FAIL;
2211}")
0d7e008e
SC
2212
2213;;
2214;; shift left
2215
7e2fda6e
BS
2216;; This pattern is used by init_expmed for computing the costs of shift
2217;; insns.
2218
2219(define_insn_and_split "ashlsi3_std"
2220 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2221 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2222 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2223 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2224 "TARGET_SH3
fa5322fa 2225 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
7e2fda6e 2226 && CONST_OK_FOR_K (INTVAL (operands[2])))"
0d7e008e 2227 "@
7e2fda6e
BS
2228 shld %2,%0
2229 add %0,%0
2230 shll%O2 %0
2231 #"
2232 "TARGET_SH3
615cd49b 2233 && reload_completed
7e2fda6e
BS
2234 && GET_CODE (operands[2]) == CONST_INT
2235 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2236 [(set (match_dup 3) (match_dup 2))
2237 (parallel
2238 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2239 (clobber (match_dup 4))])]
2240 "operands[4] = gen_rtx_SCRATCH (SImode);"
2241 [(set_attr "length" "*,*,*,4")
c49439f1 2242 (set_attr "type" "dyn_shift,arith,arith,arith")])
0d7e008e 2243
98e819b9
JW
2244(define_insn "ashlhi3_k"
2245 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2246 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2247 (match_operand:HI 2 "const_int_operand" "M,K")))]
fa5322fa 2248 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
98e819b9
JW
2249 "@
2250 add %0,%0
1245df60 2251 shll%O2 %0"
c49439f1 2252 [(set_attr "type" "arith")])
98e819b9 2253
0d7e008e
SC
2254(define_insn "ashlsi3_n"
2255 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2256 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2257 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2258 (clobber (reg:SI T_REG))]
fa5322fa 2259 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2260 "#"
2261 [(set (attr "length")
2262 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2263 (const_string "2")
2264 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2265 (const_string "4")
2266 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2267 (const_string "6")]
2268 (const_string "8")))
c49439f1 2269 (set_attr "type" "arith")])
bc45ade3 2270
07a45e5c
JW
2271(define_split
2272 [(set (match_operand:SI 0 "arith_reg_operand" "")
2273 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2274 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2275 (clobber (reg:SI T_REG))]
fa5322fa 2276 "TARGET_SH1 && reload_completed"
4773afa4 2277 [(use (reg:SI R0_REG))]
07a45e5c
JW
2278 "
2279{
2280 gen_shifty_op (ASHIFT, operands);
2281 DONE;
2282}")
2283
fa5322fa
AO
2284(define_insn "ashlsi3_media"
2285 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2286 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2287 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2288 "TARGET_SHMEDIA"
2289 "@
2290 shlld.l %1, %2, %0
b6d33983
R
2291 shlli.l %1, %2, %0"
2292 [(set_attr "type" "arith_media")])
fa5322fa 2293
bc45ade3 2294(define_expand "ashlsi3"
ffae286a
JW
2295 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2296 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2297 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2298 (clobber (reg:SI T_REG))])]
bc45ade3 2299 ""
d2f09a2f
JW
2300 "
2301{
fa5322fa
AO
2302 if (TARGET_SHMEDIA)
2303 {
2304 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2305 DONE;
2306 }
1245df60
R
2307 if (GET_CODE (operands[2]) == CONST_INT
2308 && sh_dynamicalize_shift_p (operands[2]))
2309 operands[2] = force_reg (SImode, operands[2]);
7e2fda6e 2310 if (TARGET_SH3)
6b005b88 2311 {
7e2fda6e 2312 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
6b005b88
JW
2313 DONE;
2314 }
d2f09a2f
JW
2315 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2316 FAIL;
2317}")
0d7e008e 2318
98e819b9
JW
2319(define_insn "ashlhi3"
2320 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2321 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2322 (match_operand:HI 2 "const_int_operand" "n")))
4773afa4 2323 (clobber (reg:SI T_REG))]
fa5322fa 2324 "TARGET_SH1"
98e819b9
JW
2325 "#"
2326 [(set (attr "length")
2327 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2328 (const_string "2")
2329 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2330 (const_string "4")]
2331 (const_string "6")))
2332 (set_attr "type" "arith")])
2333
2334(define_split
2335 [(set (match_operand:HI 0 "arith_reg_operand" "")
2336 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
e69d1422 2337 (match_operand:HI 2 "const_int_operand" "")))
4773afa4 2338 (clobber (reg:SI T_REG))]
fa5322fa 2339 "TARGET_SH1 && reload_completed"
4773afa4 2340 [(use (reg:SI R0_REG))]
98e819b9
JW
2341 "
2342{
2343 gen_shifty_hi_op (ASHIFT, operands);
2344 DONE;
2345}")
2346
0d7e008e
SC
2347;
2348; arithmetic shift right
2349;
bc45ade3
SC
2350
2351(define_insn "ashrsi3_k"
aa684c94
SC
2352 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2353 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2354 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2355 (clobber (reg:SI T_REG))]
fa5322fa 2356 "TARGET_SH1 && INTVAL (operands[2]) == 1"
bc45ade3 2357 "shar %0"
c49439f1 2358 [(set_attr "type" "arith")])
bc45ade3 2359
d0c42859
R
2360;; We can't do HImode right shifts correctly unless we start out with an
2361;; explicit zero / sign extension; doing that would result in worse overall
2362;; code, so just let the machine independent code widen the mode.
2363;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2364
98e819b9 2365
ffae286a
JW
2366;; ??? This should be a define expand.
2367
00f8ff66 2368(define_insn "ashrsi2_16"
07a45e5c
JW
2369 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2370 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3e8bd1ce 2371 (const_int 16)))]
fa5322fa 2372 "TARGET_SH1"
1245df60 2373 "#"
00f8ff66
SC
2374 [(set_attr "length" "4")])
2375
1245df60 2376(define_split
e69d1422
R
2377 [(set (match_operand:SI 0 "arith_reg_operand" "")
2378 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2379 (const_int 16)))]
fa5322fa 2380 "TARGET_SH1"
1245df60
R
2381 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2382 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2383 "operands[2] = gen_lowpart (HImode, operands[0]);")
2384
ffae286a
JW
2385;; ??? This should be a define expand.
2386
00f8ff66 2387(define_insn "ashrsi2_31"
6b005b88 2388 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1245df60
R
2389 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2390 (const_int 31)))
4773afa4 2391 (clobber (reg:SI T_REG))]
fa5322fa 2392 "TARGET_SH1"
1245df60 2393 "#"
6b005b88 2394 [(set_attr "length" "4")])
3e8bd1ce 2395
1245df60 2396(define_split
e69d1422
R
2397 [(set (match_operand:SI 0 "arith_reg_operand" "")
2398 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2399 (const_int 31)))
4773afa4 2400 (clobber (reg:SI T_REG))]
fa5322fa 2401 "TARGET_SH1"
1245df60
R
2402 [(const_int 0)]
2403 "
2404{
5bac82c5 2405 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
1245df60
R
2406 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2407 DONE;
2408}")
2409
2410(define_insn "ashlsi_c"
2411 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2412 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4773afa4
AO
2413 (set (reg:SI T_REG)
2414 (lt:SI (match_dup 1) (const_int 0)))]
fa5322fa 2415 "TARGET_SH1"
1245df60 2416 "shll %0"
c49439f1 2417 [(set_attr "type" "arith")])
1245df60 2418
6b005b88
JW
2419(define_insn "ashrsi3_d"
2420 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2421 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2422 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2423 "TARGET_SH3"
1245df60 2424 "shad %2,%0"
c49439f1 2425 [(set_attr "type" "dyn_shift")])
51aea58d 2426
0d7e008e 2427(define_insn "ashrsi3_n"
4773afa4
AO
2428 [(set (reg:SI R4_REG)
2429 (ashiftrt:SI (reg:SI R4_REG)
ffae286a 2430 (match_operand:SI 0 "const_int_operand" "i")))
4773afa4
AO
2431 (clobber (reg:SI T_REG))
2432 (clobber (reg:SI PR_REG))
0d7e008e 2433 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 2434 "TARGET_SH1"
0d7e008e
SC
2435 "jsr @%1%#"
2436 [(set_attr "type" "sfunc")
0d7e008e
SC
2437 (set_attr "needs_delay_slot" "yes")])
2438
fa5322fa
AO
2439(define_insn "ashrsi3_media"
2440 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2441 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2442 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2443 "TARGET_SHMEDIA"
2444 "@
2445 shard.l %1, %2, %0
b6d33983
R
2446 shari.l %1, %2, %0"
2447 [(set_attr "type" "arith_media")])
fa5322fa 2448
bc45ade3 2449(define_expand "ashrsi3"
ffae286a
JW
2450 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2451 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2452 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2453 (clobber (reg:SI T_REG))])]
bc45ade3 2454 ""
fa5322fa
AO
2455 "
2456{
2457 if (TARGET_SHMEDIA)
2458 {
2459 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2460 DONE;
2461 }
2462 if (expand_ashiftrt (operands))
2463 DONE;
2464 else
2465 FAIL;
2466}")
0d7e008e 2467
07a45e5c 2468;; logical shift right
bc45ade3 2469
6b005b88
JW
2470(define_insn "lshrsi3_d"
2471 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2472 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2473 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2474 "TARGET_SH3"
1245df60 2475 "shld %2,%0"
c49439f1 2476 [(set_attr "type" "dyn_shift")])
00f8ff66 2477
ffae286a 2478;; Only the single bit shift clobbers the T bit.
07a45e5c
JW
2479
2480(define_insn "lshrsi3_m"
2481 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2482 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2483 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2484 (clobber (reg:SI T_REG))]
fa5322fa 2485 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2486 "shlr %0"
c49439f1 2487 [(set_attr "type" "arith")])
0d7e008e 2488
07a45e5c
JW
2489(define_insn "lshrsi3_k"
2490 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2492 (match_operand:SI 2 "const_int_operand" "K")))]
fa5322fa 2493 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
07a45e5c 2494 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2495 "shlr%O2 %0"
c49439f1 2496 [(set_attr "type" "arith")])
0d7e008e
SC
2497
2498(define_insn "lshrsi3_n"
2499 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2500 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2501 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2502 (clobber (reg:SI T_REG))]
fa5322fa 2503 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2504 "#"
2505 [(set (attr "length")
2506 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2507 (const_string "2")
2508 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2509 (const_string "4")
2510 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2511 (const_string "6")]
2512 (const_string "8")))
bc45ade3
SC
2513 (set_attr "type" "arith")])
2514
07a45e5c
JW
2515(define_split
2516 [(set (match_operand:SI 0 "arith_reg_operand" "")
2517 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2518 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2519 (clobber (reg:SI T_REG))]
fa5322fa 2520 "TARGET_SH1 && reload_completed"
4773afa4 2521 [(use (reg:SI R0_REG))]
07a45e5c
JW
2522 "
2523{
2524 gen_shifty_op (LSHIFTRT, operands);
2525 DONE;
2526}")
2527
fa5322fa
AO
2528(define_insn "lshrsi3_media"
2529 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2530 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2531 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2532 "TARGET_SHMEDIA"
2533 "@
2534 shlrd.l %1, %2, %0
b6d33983
R
2535 shlri.l %1, %2, %0"
2536 [(set_attr "type" "arith_media")])
fa5322fa 2537
bc45ade3 2538(define_expand "lshrsi3"
ffae286a
JW
2539 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2540 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2541 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2542 (clobber (reg:SI T_REG))])]
bc45ade3 2543 ""
d2f09a2f
JW
2544 "
2545{
fa5322fa
AO
2546 if (TARGET_SHMEDIA)
2547 {
2548 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2549 DONE;
2550 }
1245df60
R
2551 if (GET_CODE (operands[2]) == CONST_INT
2552 && sh_dynamicalize_shift_p (operands[2]))
2553 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
2554 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2555 {
2556 rtx count = copy_to_mode_reg (SImode, operands[2]);
2557 emit_insn (gen_negsi2 (count, count));
7b7499bf 2558 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
6b005b88
JW
2559 DONE;
2560 }
d2f09a2f
JW
2561 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2562 FAIL;
2563}")
bc45ade3 2564
ffae286a
JW
2565;; ??? This should be a define expand.
2566
bc45ade3 2567(define_insn "ashldi3_k"
aa684c94
SC
2568 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2569 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2570 (const_int 1)))
4773afa4 2571 (clobber (reg:SI T_REG))]
fa5322fa 2572 "TARGET_SH1"
00f8ff66 2573 "shll %R0\;rotcl %S0"
1245df60 2574 [(set_attr "length" "4")
c49439f1 2575 (set_attr "type" "arith")])
bc45ade3 2576
fa5322fa
AO
2577(define_insn "ashldi3_media"
2578 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2579 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2580 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2581 "TARGET_SHMEDIA"
2582 "@
2583 shlld %1, %2, %0
2ad65b0e
SC
2584 shlli %1, %2, %0"
2585 [(set_attr "type" "arith_media")])
fa5322fa 2586
bc45ade3 2587(define_expand "ashldi3"
ffae286a
JW
2588 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2589 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2590 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2591 (clobber (reg:SI T_REG))])]
bc45ade3 2592 ""
fa5322fa
AO
2593 "
2594{
2595 if (TARGET_SHMEDIA)
2596 {
2597 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2598 DONE;
2599 }
2600 if (GET_CODE (operands[2]) != CONST_INT
2601 || INTVAL (operands[2]) != 1)
2602 FAIL;
2603}")
ffae286a
JW
2604
2605;; ??? This should be a define expand.
bc45ade3
SC
2606
2607(define_insn "lshrdi3_k"
aa684c94 2608 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b9654711 2609 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2610 (const_int 1)))
4773afa4 2611 (clobber (reg:SI T_REG))]
fa5322fa 2612 "TARGET_SH1"
00f8ff66 2613 "shlr %S0\;rotcr %R0"
1245df60 2614 [(set_attr "length" "4")
c49439f1 2615 (set_attr "type" "arith")])
bc45ade3 2616
fa5322fa
AO
2617(define_insn "lshrdi3_media"
2618 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2619 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2620 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2621 "TARGET_SHMEDIA"
2622 "@
2623 shlrd %1, %2, %0
2ad65b0e
SC
2624 shlri %1, %2, %0"
2625 [(set_attr "type" "arith_media")])
fa5322fa 2626
bc45ade3 2627(define_expand "lshrdi3"
ffae286a
JW
2628 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2629 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
bc45ade3 2630 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2631 (clobber (reg:SI T_REG))])]
bc45ade3 2632 ""
fa5322fa
AO
2633 "
2634{
2635 if (TARGET_SHMEDIA)
2636 {
2637 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2638 DONE;
2639 }
2640 if (GET_CODE (operands[2]) != CONST_INT
2641 || INTVAL (operands[2]) != 1)
2642 FAIL;
2643}")
ffae286a
JW
2644
2645;; ??? This should be a define expand.
bc45ade3
SC
2646
2647(define_insn "ashrdi3_k"
aa684c94
SC
2648 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2649 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2650 (const_int 1)))
4773afa4 2651 (clobber (reg:SI T_REG))]
fa5322fa 2652 "TARGET_SH1"
00f8ff66 2653 "shar %S0\;rotcr %R0"
1245df60 2654 [(set_attr "length" "4")
c49439f1 2655 (set_attr "type" "arith")])
bc45ade3 2656
fa5322fa
AO
2657(define_insn "ashrdi3_media"
2658 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2659 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2660 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2661 "TARGET_SHMEDIA"
2662 "@
2663 shard %1, %2, %0
2ad65b0e
SC
2664 shari %1, %2, %0"
2665 [(set_attr "type" "arith_media")])
fa5322fa 2666
bc45ade3 2667(define_expand "ashrdi3"
ffae286a
JW
2668 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2669 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2670 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2671 (clobber (reg:SI T_REG))])]
bc45ade3 2672 ""
fa5322fa
AO
2673 "
2674{
2675 if (TARGET_SHMEDIA)
2676 {
2677 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2678 DONE;
2679 }
2680 if (GET_CODE (operands[2]) != CONST_INT
2681 || INTVAL (operands[2]) != 1)
2682 FAIL;
2683}")
98e819b9
JW
2684
2685;; combined left/right shift
2686
2687(define_split
2688 [(set (match_operand:SI 0 "register_operand" "")
2689 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2690 (match_operand:SI 2 "const_int_operand" ""))
2691 (match_operand:SI 3 "const_int_operand" "")))]
85af47b9 2692 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2693 [(use (reg:SI R0_REG))]
98e819b9
JW
2694 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2695 DONE;")
2696
2697(define_split
2698 [(set (match_operand:SI 0 "register_operand" "")
2699 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2700 (match_operand:SI 2 "const_int_operand" ""))
2701 (match_operand:SI 3 "const_int_operand" "")))
4773afa4 2702 (clobber (reg:SI T_REG))]
85af47b9 2703 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2704 [(use (reg:SI R0_REG))]
98e819b9
JW
2705 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2706 DONE;")
2707
2708(define_insn ""
2709 [(set (match_operand:SI 0 "register_operand" "=r")
2710 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2711 (match_operand:SI 2 "const_int_operand" "n"))
2712 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2713 (clobber (reg:SI T_REG))]
fa5322fa 2714 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
98e819b9
JW
2715 "#"
2716 [(set (attr "length")
2717 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2718 (const_string "4")
2719 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2720 (const_string "6")
2721 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2722 (const_string "8")
2723 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2724 (const_string "10")
2725 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2726 (const_string "12")
2727 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2728 (const_string "14")
2729 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2730 (const_string "16")]
2731 (const_string "18")))
2732 (set_attr "type" "arith")])
2733
2734(define_insn ""
2735 [(set (match_operand:SI 0 "register_operand" "=z")
2736 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2737 (match_operand:SI 2 "const_int_operand" "n"))
2738 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2739 (clobber (reg:SI T_REG))]
fa5322fa 2740 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
98e819b9
JW
2741 "#"
2742 [(set (attr "length")
2743 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2744 (const_string "4")
2745 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2746 (const_string "6")
2747 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2748 (const_string "8")]
2749 (const_string "10")))
2750 (set_attr "type" "arith")])
2751
2752;; shift left / and combination with a scratch register: The combine pass
2753;; does not accept the individual instructions, even though they are
2754;; cheap. But it needs a precise description so that it is usable after
2755;; reload.
2756(define_insn "and_shl_scratch"
2757 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4773afa4
AO
2758 (lshiftrt:SI
2759 (ashift:SI
2760 (and:SI
2761 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2762 (match_operand:SI 2 "const_int_operand" "N,n"))
2763 (match_operand:SI 3 "" "0,r"))
2764 (match_operand:SI 4 "const_int_operand" "n,n"))
2765 (match_operand:SI 5 "const_int_operand" "n,n")))
2766 (clobber (reg:SI T_REG))]
fa5322fa 2767 "TARGET_SH1"
98e819b9
JW
2768 "#"
2769 [(set (attr "length")
2770 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2771 (const_string "4")
2772 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2773 (const_string "6")
2774 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
9788ff4d 2775 (const_string "8")
98e819b9
JW
2776 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2777 (const_string "10")]
2778 (const_string "12")))
2779 (set_attr "type" "arith")])
2780
2781(define_split
e69d1422 2782 [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
2783 (lshiftrt:SI
2784 (ashift:SI
2785 (and:SI
e69d1422
R
2786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2787 (match_operand:SI 2 "const_int_operand" ""))
2788 (match_operand:SI 3 "register_operand" ""))
2789 (match_operand:SI 4 "const_int_operand" ""))
2790 (match_operand:SI 5 "const_int_operand" "")))
4773afa4 2791 (clobber (reg:SI T_REG))]
fa5322fa 2792 "TARGET_SH1"
4773afa4 2793 [(use (reg:SI R0_REG))]
98e819b9
JW
2794 "
2795{
fc2380b9 2796 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
98e819b9
JW
2797
2798 if (INTVAL (operands[2]))
2799 {
2800 gen_shifty_op (LSHIFTRT, operands);
98e819b9
JW
2801 }
2802 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2803 operands[2] = operands[4];
2804 gen_shifty_op (ASHIFT, operands);
2805 if (INTVAL (operands[5]))
2806 {
2807 operands[2] = operands[5];
2808 gen_shifty_op (LSHIFTRT, operands);
2809 }
2810 DONE;
2811}")
2812
2813;; signed left/right shift combination.
2814(define_split
e69d1422 2815 [(set (match_operand:SI 0 "register_operand" "")
4773afa4 2816 (sign_extract:SI
e69d1422
R
2817 (ashift:SI (match_operand:SI 1 "register_operand" "")
2818 (match_operand:SI 2 "const_int_operand" ""))
2819 (match_operand:SI 3 "const_int_operand" "")
4773afa4
AO
2820 (const_int 0)))
2821 (clobber (reg:SI T_REG))]
fa5322fa 2822 "TARGET_SH1"
4773afa4 2823 [(use (reg:SI R0_REG))]
98e819b9
JW
2824 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2825 DONE;")
2826
2827(define_insn "shl_sext_ext"
2828 [(set (match_operand:SI 0 "register_operand" "=r")
4773afa4
AO
2829 (sign_extract:SI
2830 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2831 (match_operand:SI 2 "const_int_operand" "n"))
2832 (match_operand:SI 3 "const_int_operand" "n")
2833 (const_int 0)))
2834 (clobber (reg:SI T_REG))]
fa5322fa 2835 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
98e819b9
JW
2836 "#"
2837 [(set (attr "length")
2838 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2839 (const_string "2")
2840 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2841 (const_string "4")
2842 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2843 (const_string "6")
2844 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2845 (const_string "8")
2846 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2847 (const_string "10")
2848 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2849 (const_string "12")
2850 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2851 (const_string "14")
2852 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2853 (const_string "16")]
2854 (const_string "18")))
2855 (set_attr "type" "arith")])
2856
2857(define_insn "shl_sext_sub"
2858 [(set (match_operand:SI 0 "register_operand" "=z")
e11cddec
AO
2859 (sign_extract:SI
2860 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2861 (match_operand:SI 2 "const_int_operand" "n"))
2862 (match_operand:SI 3 "const_int_operand" "n")
2863 (const_int 0)))
4773afa4 2864 (clobber (reg:SI T_REG))]
fa5322fa 2865 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
98e819b9
JW
2866 "#"
2867 [(set (attr "length")
2868 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2869 (const_string "6")
2870 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2871 (const_string "8")
2872 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2873 (const_string "10")
2874 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2875 (const_string "12")]
2876 (const_string "14")))
2877 (set_attr "type" "arith")])
2878
977eef43
JW
2879;; These patterns are found in expansions of DImode shifts by 16, and
2880;; allow the xtrct instruction to be generated from C source.
2881
2882(define_insn "xtrct_left"
2883 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2884 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2885 (const_int 16))
2886 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2887 (const_int 16))))]
fa5322fa 2888 "TARGET_SH1"
1245df60 2889 "xtrct %1,%0"
c49439f1 2890 [(set_attr "type" "arith")])
977eef43
JW
2891
2892(define_insn "xtrct_right"
2893 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2894 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2895 (const_int 16))
2896 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2897 (const_int 16))))]
fa5322fa 2898 "TARGET_SH1"
1245df60 2899 "xtrct %2,%0"
c49439f1 2900 [(set_attr "type" "arith")])
fae15c93 2901
bc45ade3
SC
2902;; -------------------------------------------------------------------------
2903;; Unary arithmetic
2904;; -------------------------------------------------------------------------
2905
8e87e161
SC
2906(define_insn "negc"
2907 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 2908 (neg:SI (plus:SI (reg:SI T_REG)
51bd623f 2909 (match_operand:SI 1 "arith_reg_operand" "r"))))
4773afa4
AO
2910 (set (reg:SI T_REG)
2911 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
51bd623f 2912 (const_int 0)))]
fa5322fa 2913 "TARGET_SH1"
8e87e161 2914 "negc %1,%0"
c49439f1 2915 [(set_attr "type" "arith")])
bc45ade3 2916
fa5322fa
AO
2917(define_insn "*negdi_media"
2918 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2919 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2920 "TARGET_SHMEDIA"
2ad65b0e
SC
2921 "sub r63, %1, %0"
2922 [(set_attr "type" "arith_media")])
fa5322fa 2923
8e87e161 2924(define_expand "negdi2"
51aea58d 2925 [(set (match_operand:DI 0 "arith_reg_operand" "")
b6d33983 2926 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
8e87e161 2927 ""
ffae286a
JW
2928 "
2929{
fa5322fa
AO
2930 if (TARGET_SH1)
2931 {
2932 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2933 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
8e87e161 2934
fa5322fa
AO
2935 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2936 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
0a0b733a 2937
fa5322fa
AO
2938 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2939 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
8e87e161 2940
fa5322fa
AO
2941 emit_insn (gen_clrt ());
2942 emit_insn (gen_negc (low_dst, low_src));
2943 emit_insn (gen_negc (high_dst, high_src));
2944 DONE;
2945 }
ffae286a 2946}")
8e87e161 2947
bc45ade3 2948(define_insn "negsi2"
aa684c94
SC
2949 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2950 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2951 "TARGET_SH1"
bc45ade3 2952 "neg %1,%0"
c49439f1 2953 [(set_attr "type" "arith")])
bc45ade3
SC
2954
2955(define_insn "one_cmplsi2"
aa684c94
SC
2956 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2957 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2958 "TARGET_SH1"
bc45ade3 2959 "not %1,%0"
c49439f1 2960 [(set_attr "type" "arith")])
fa5322fa
AO
2961
2962(define_expand "one_cmpldi2"
2963 [(set (match_operand:DI 0 "arith_reg_operand" "")
2964 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2965 (const_int -1)))]
2966 "TARGET_SHMEDIA" "")
bc45ade3
SC
2967\f
2968;; -------------------------------------------------------------------------
2969;; Zero extension instructions
2970;; -------------------------------------------------------------------------
2971
fa5322fa
AO
2972(define_insn "zero_extendsidi2"
2973 [(set (match_operand:DI 0 "register_operand" "=r")
b6d33983 2974 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
fa5322fa 2975 "TARGET_SHMEDIA"
b6d33983
R
2976 "addz.l %1, r63, %0"
2977 [(set_attr "type" "arith_media")])
fa5322fa
AO
2978
2979(define_insn "zero_extendhidi2"
2980 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 2981 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
2982 "TARGET_SHMEDIA"
2983 "@
2984 #
b6d33983
R
2985 ld%M1.uw %m1, %0"
2986 [(set_attr "type" "*,load_media")])
fa5322fa
AO
2987
2988(define_split
e69d1422
R
2989 [(set (match_operand:DI 0 "register_operand" "")
2990 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
2991 "TARGET_SHMEDIA && reload_completed"
2992 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
2993 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2994 "
2995{
2996 if (GET_CODE (operands[1]) == TRUNCATE)
2997 operands[1] = XEXP (operands[1], 0);
2998}")
2999
3000;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3001;; reload the entrire truncate expression.
3002(define_insn_and_split "*loaddi_trunc"
e69d1422 3003 [(set (match_operand 0 "int_gpr_dest" "=r")
b6d33983
R
3004 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3005 "TARGET_SHMEDIA && reload_completed"
3006 "#"
3007 "TARGET_SHMEDIA && reload_completed"
3008 [(set (match_dup 0) (match_dup 1))]
3009 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
fa5322fa
AO
3010
3011(define_insn "zero_extendqidi2"
3012 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3013 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3014 "TARGET_SHMEDIA"
3015 "@
3016 andi %1, 255, %0
b6d33983
R
3017 ld%M1.ub %m1, %0"
3018 [(set_attr "type" "arith_media,load_media")])
3019
3020(define_expand "zero_extendhisi2"
3021 [(set (match_operand:SI 0 "arith_reg_operand" "")
3022 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3023 ""
3024 "
3025{
3026 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3027 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3028}")
fa5322fa 3029
b6d33983 3030(define_insn "*zero_extendhisi2_compact"
aa684c94
SC
3031 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3032 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
fa5322fa 3033 "TARGET_SH1"
bc45ade3 3034 "extu.w %1,%0"
c49439f1 3035 [(set_attr "type" "arith")])
bc45ade3 3036
b6d33983
R
3037(define_insn "*zero_extendhisi2_media"
3038 [(set (match_operand:SI 0 "register_operand" "=r,r")
3039 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3040 "TARGET_SHMEDIA"
3041 "@
3042 #
3043 ld%M1.uw %m1, %0"
3044 [(set_attr "type" "arith_media,load_media")])
3045
3046(define_split
e69d1422
R
3047 [(set (match_operand:SI 0 "register_operand" "")
3048 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3049 "TARGET_SHMEDIA && reload_completed"
3050 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3051 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3052 "
3053{
3054 if (GET_CODE (operands[1]) == TRUNCATE)
3055 operands[1] = XEXP (operands[1], 0);
3056}")
3057
3058(define_expand "zero_extendqisi2"
3059 [(set (match_operand:SI 0 "arith_reg_operand" "")
3060 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3061 ""
3062 "
3063{
3064 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3065 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3066}")
3067
3068(define_insn "*zero_extendqisi2_compact"
aa684c94
SC
3069 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3070 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3071 "TARGET_SH1"
bc45ade3 3072 "extu.b %1,%0"
c49439f1 3073 [(set_attr "type" "arith")])
bc45ade3 3074
b6d33983
R
3075(define_insn "*zero_extendqisi2_media"
3076 [(set (match_operand:SI 0 "register_operand" "=r,r")
3077 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3078 "TARGET_SHMEDIA"
3079 "@
3080 andi %1, 255, %0
3081 ld%M1.ub %m1, %0"
3082 [(set_attr "type" "arith_media,load_media")])
3083
bc45ade3 3084(define_insn "zero_extendqihi2"
aa684c94
SC
3085 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3086 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3087 "TARGET_SH1"
bc45ade3 3088 "extu.b %1,%0"
c49439f1 3089 [(set_attr "type" "arith")])
fae15c93 3090
bc45ade3
SC
3091;; -------------------------------------------------------------------------
3092;; Sign extension instructions
3093;; -------------------------------------------------------------------------
3094
ffae286a
JW
3095;; ??? This should be a define expand.
3096;; ??? Or perhaps it should be dropped?
3097
fa5322fa
AO
3098;; convert_move generates good code for SH[1-4].
3099(define_insn "extendsidi2"
3100 [(set (match_operand:DI 0 "register_operand" "=r,r")
3101 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3102 "TARGET_SHMEDIA"
3103 "@
3104 add.l %1, r63, %0
2ad65b0e
SC
3105 ld%M1.l %m1, %0"
3106 [(set_attr "type" "arith_media,load_media")])
fa5322fa
AO
3107
3108(define_insn "extendhidi2"
3109 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3110 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3111 "TARGET_SHMEDIA"
3112 "@
3113 #
b6d33983
R
3114 ld%M1.w %m1, %0"
3115 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3116
3117(define_split
e69d1422
R
3118 [(set (match_operand:DI 0 "register_operand" "")
3119 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3120 "TARGET_SHMEDIA && reload_completed"
3121 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
3122 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3123 "
3124{
3125 if (GET_CODE (operands[1]) == TRUNCATE)
3126 operands[1] = XEXP (operands[1], 0);
3127}")
fa5322fa
AO
3128
3129(define_insn "extendqidi2"
3130 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3131 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3132 "TARGET_SHMEDIA"
3133 "@
3134 #
b6d33983
R
3135 ld%M1.b %m1, %0"
3136 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3137
3138(define_split
e69d1422
R
3139 [(set (match_operand:DI 0 "register_operand" "")
3140 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3141 "TARGET_SHMEDIA && reload_completed"
3142 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
b6d33983
R
3143 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3144 "
3145{
3146 if (GET_CODE (operands[1]) == TRUNCATE)
3147 operands[1] = XEXP (operands[1], 0);
3148}")
3149
3150(define_expand "extendhisi2"
3151 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3152 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3153 ""
3154 "")
bc45ade3 3155
b6d33983 3156(define_insn "*extendhisi2_compact"
51bd623f
JW
3157 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3158 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3159 "TARGET_SH1"
0d7e008e
SC
3160 "@
3161 exts.w %1,%0
0d7e008e 3162 mov.w %1,%0"
c49439f1 3163 [(set_attr "type" "arith,load")])
bc45ade3 3164
b6d33983
R
3165(define_insn "*extendhisi2_media"
3166 [(set (match_operand:SI 0 "register_operand" "=r,r")
3167 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3168 "TARGET_SHMEDIA"
3169 "@
3170 #
3171 ld%M1.w %m1, %0"
3172 [(set_attr "type" "arith_media,load_media")])
3173
3174(define_split
e69d1422
R
3175 [(set (match_operand:SI 0 "register_operand" "")
3176 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3177 "TARGET_SHMEDIA && reload_completed"
3178 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3179 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3180 "
3181{
3182 if (GET_CODE (operands[1]) == TRUNCATE)
3183 operands[1] = XEXP (operands[1], 0);
3184}")
3185
3186(define_expand "extendqisi2"
3187 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3188 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3189 ""
3190 "")
3191
3192(define_insn "*extendqisi2_compact"
51bd623f
JW
3193 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3194 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3195 "TARGET_SH1"
0d7e008e
SC
3196 "@
3197 exts.b %1,%0
51bd623f 3198 mov.b %1,%0"
c49439f1 3199 [(set_attr "type" "arith,load")])
bc45ade3 3200
b6d33983
R
3201(define_insn "*extendqisi2_media"
3202 [(set (match_operand:SI 0 "register_operand" "=r,r")
3203 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3204 "TARGET_SHMEDIA"
3205 "@
3206 #
3207 ld%M1.b %m1, %0"
3208 [(set_attr "type" "arith_media,load_media")])
3209
3210(define_split
e69d1422
R
3211 [(set (match_operand:SI 0 "register_operand" "")
3212 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
b6d33983
R
3213 "TARGET_SHMEDIA && reload_completed"
3214 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3215 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3216 "
3217{
3218 if (GET_CODE (operands[1]) == TRUNCATE)
3219 operands[1] = XEXP (operands[1], 0);
3220}")
3221
bc45ade3 3222(define_insn "extendqihi2"
51bd623f
JW
3223 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3224 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3225 "TARGET_SH1"
0d7e008e
SC
3226 "@
3227 exts.b %1,%0
51bd623f 3228 mov.b %1,%0"
c49439f1 3229 [(set_attr "type" "arith,load")])
fae15c93 3230
b6d33983
R
3231/* It would seem useful to combine the truncXi patterns into the movXi
3232 patterns, but unary operators are ignored when matching constraints,
3233 so we need separate patterns. */
3234(define_insn "truncdisi2"
0ac78517 3235 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
b6d33983
R
3236 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3237 "TARGET_SHMEDIA"
3238 "@
3239 add.l %1, r63, %0
3240 st%M0.l %m0, %1
3241 fst%M0.s %m0, %T1
3242 fmov.ls %1, %0
3243 fmov.sl %T1, %0
3244 fmov.s %T1, %0"
3245 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3246
3247
3248(define_insn "truncdihi2"
0ac78517 3249 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
b6d33983
R
3250 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3251 "TARGET_SHMEDIA"
3252 "@
3253 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3254 st%M0.w %m0, %1"
3255 [(set_attr "type" "arith_media,store_media")
3256 (set_attr "length" "8,4")])
3257
59324685
R
3258; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3259; Because we use zero extension, we can't provide signed QImode compares
3260; using a simple compare or conditional banch insn.
b6d33983
R
3261(define_insn "truncdiqi2"
3262 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3263 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3264 "TARGET_SHMEDIA"
3265 "@
59324685 3266 and %1, 255, %0
b6d33983
R
3267 st%M0.b %m0, %1"
3268 [(set_attr "type" "arith_media,store")])
3269
bc45ade3
SC
3270;; -------------------------------------------------------------------------
3271;; Move instructions
3272;; -------------------------------------------------------------------------
3273
0d7e008e 3274;; define push and pop so it is easy for sh.c
fa5322fa
AO
3275;; We can't use push and pop on SHcompact because the stack must always
3276;; be 8-byte aligned.
b9654711 3277
225e4f43 3278(define_expand "push"
4773afa4 3279 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
ffae286a 3280 (match_operand:SI 0 "register_operand" "r,l,x"))]
fa5322fa 3281 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3282 "")
b9654711 3283
225e4f43 3284(define_expand "pop"
51bd623f 3285 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4773afa4 3286 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
fa5322fa 3287 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3288 "")
3289
3290(define_expand "push_e"
4773afa4 3291 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
225e4f43 3292 (match_operand:SF 0 "" ""))
4773afa4 3293 (use (reg:PSI FPSCR_REG))
225e4f43 3294 (clobber (scratch:SI))])]
fa5322fa 3295 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3296 "")
b9654711 3297
225e4f43 3298(define_insn "push_fpul"
4773afa4 3299 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
fa5322fa 3300 "TARGET_SH3E && ! TARGET_SH5"
225e4f43 3301 "sts.l fpul,@-r15"
45348d9e 3302 [(set_attr "type" "store")
c49439f1 3303 (set_attr "late_fp_use" "yes")
45348d9e
JW
3304 (set_attr "hit_stack" "yes")])
3305
225e4f43
R
3306;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3307;; so use that.
3308(define_expand "push_4"
4773afa4
AO
3309 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3310 (match_operand:DF 0 "" ""))
3311 (use (reg:PSI FPSCR_REG))
225e4f43 3312 (clobber (scratch:SI))])]
fa5322fa 3313 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3314 "")
3315
3316(define_expand "pop_e"
3317 [(parallel [(set (match_operand:SF 0 "" "")
4773afa4
AO
3318 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3319 (use (reg:PSI FPSCR_REG))
225e4f43 3320 (clobber (scratch:SI))])]
fa5322fa 3321 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3322 "")
3323
3324(define_insn "pop_fpul"
4773afa4 3325 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
fa5322fa 3326 "TARGET_SH3E && ! TARGET_SH5"
225e4f43 3327 "lds.l @r15+,fpul"
45348d9e
JW
3328 [(set_attr "type" "load")
3329 (set_attr "hit_stack" "yes")])
3330
225e4f43
R
3331(define_expand "pop_4"
3332 [(parallel [(set (match_operand:DF 0 "" "")
4773afa4
AO
3333 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3334 (use (reg:PSI FPSCR_REG))
225e4f43 3335 (clobber (scratch:SI))])]
fa5322fa 3336 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3337 "")
3338
7144b2d8
DD
3339(define_expand "push_fpscr"
3340 [(const_int 0)]
3341 "TARGET_SH3E"
3342 "
3343{
3344 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3345 gen_rtx (PRE_DEC, Pmode,
3346 stack_pointer_rtx)),
3347 get_fpscr_rtx ()));
3348 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3349 DONE;
3350}")
3351
3352(define_expand "pop_fpscr"
3353 [(const_int 0)]
3354 "TARGET_SH3E"
3355 "
3356{
3357 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3358 gen_rtx (MEM, PSImode,
3359 gen_rtx (POST_INC, Pmode,
3360 stack_pointer_rtx))));
3361 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3362 DONE;
3363}")
3364
e3391510
JW
3365;; These two patterns can happen as the result of optimization, when
3366;; comparisons get simplified to a move of zero or 1 into the T reg.
3367;; They don't disappear completely, because the T reg is a fixed hard reg.
ffae286a 3368
0d7e008e 3369(define_insn "clrt"
4773afa4 3370 [(set (reg:SI T_REG) (const_int 0))]
fa5322fa 3371 "TARGET_SH1"
0d7e008e 3372 "clrt")
bc45ade3 3373
e3391510 3374(define_insn "sett"
4773afa4 3375 [(set (reg:SI T_REG) (const_int 1))]
fa5322fa 3376 "TARGET_SH1"
e3391510
JW
3377 "sett")
3378
3ca0a524 3379;; t/r must come after r/r, lest reload will try to reload stuff like
4773afa4 3380;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
e11cddec 3381;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
0d7e008e 3382(define_insn "movsi_i"
99e87c10
AO
3383 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3384 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
fa5322fa
AO
3385 "TARGET_SH1
3386 && ! TARGET_SH3E
1245df60
R
3387 && (register_operand (operands[0], SImode)
3388 || register_operand (operands[1], SImode))"
8e87e161
SC
3389 "@
3390 mov.l %1,%0
3391 mov %1,%0
3ca0a524 3392 cmp/pl %1
8e87e161
SC
3393 mov.l %1,%0
3394 sts %1,%0
99e87c10 3395 sts %1,%0
8e87e161
SC
3396 movt %0
3397 mov.l %1,%0
3398 sts.l %1,%0
1245df60 3399 sts.l %1,%0
8e87e161 3400 lds %1,%0
99e87c10 3401 lds %1,%0
8e87e161 3402 lds.l %1,%0
1245df60 3403 lds.l %1,%0
51bd623f 3404 fake %1,%0"
c49439f1 3405 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
99e87c10 3406 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
07a45e5c 3407
1245df60 3408;; t/r must come after r/r, lest reload will try to reload stuff like
e11cddec 3409;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
45348d9e
JW
3410;; ??? This allows moves from macl to fpul to be recognized, but these moves
3411;; will require a reload.
ec555f32
R
3412;; ??? We can't include f/f because we need the proper FPSCR setting when
3413;; TARGET_FMOVD is in effect, and mode switching is done before reload.
45348d9e 3414(define_insn "movsi_ie"
ec555f32
R
3415 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3416 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
45348d9e
JW
3417 "TARGET_SH3E
3418 && (register_operand (operands[0], SImode)
3419 || register_operand (operands[1], SImode))"
3420 "@
45348d9e
JW
3421 mov.l %1,%0
3422 mov %1,%0
1245df60 3423 cmp/pl %1
45348d9e
JW
3424 mov.l %1,%0
3425 sts %1,%0
99e87c10 3426 sts %1,%0
45348d9e
JW
3427 movt %0
3428 mov.l %1,%0
3429 sts.l %1,%0
1245df60 3430 sts.l %1,%0
45348d9e 3431 lds %1,%0
99e87c10 3432 lds %1,%0
45348d9e 3433 lds.l %1,%0
1245df60 3434 lds.l %1,%0
225e4f43 3435 lds.l %1,%0
a92facbb 3436 sts.l %1,%0
45348d9e
JW
3437 fake %1,%0
3438 lds %1,%0
1245df60 3439 sts %1,%0
ec555f32
R
3440 fsts fpul,%0
3441 flds %1,fpul
3442 fmov %1,%0
1245df60 3443 ! move optimized away"
ec555f32
R
3444 [(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")
3445 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3446 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
1245df60
R
3447
3448(define_insn "movsi_i_lowpart"
99e87c10
AO
3449 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3450 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
fa5322fa
AO
3451 "TARGET_SH1
3452 && (register_operand (operands[0], SImode)
3453 || register_operand (operands[1], SImode))"
1245df60
R
3454 "@
3455 mov.l %1,%0
3456 mov %1,%0
3457 mov.l %1,%0
3458 sts %1,%0
99e87c10 3459 sts %1,%0
1245df60
R
3460 movt %0
3461 mov.l %1,%0
3462 fake %1,%0"
99e87c10 3463 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
a6f463a0 3464
fa5322fa 3465(define_insn "*movsi_media"
b6d33983 3466 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
d9da94a1 3467 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,rU,m,f,rU,f,f,r,*b,T"))]
fa5322fa
AO
3468 "TARGET_SHMEDIA_FPU
3469 && (register_operand (operands[0], SImode)
d9da94a1 3470 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3471 "@
3472 add.l %1, r63, %0
3473 movi %1, %0
3474 #
3475 ld%M1.l %m1, %0
d9da94a1 3476 st%M0.l %m0, %N1
fa5322fa
AO
3477 fld%M1.s %m1, %0
3478 fst%M0.s %m0, %1
0ac78517 3479 fmov.ls %N1, %0
fa5322fa
AO
3480 fmov.sl %1, %0
3481 fmov.s %1, %0
3482 ptabs %1, %0
3483 gettr %1, %0
3484 pt %1, %0"
2ad65b0e 3485 [(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
3486 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3487
3488(define_insn "*movsi_media_nofpu"
b6d33983 3489 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
d9da94a1 3490 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,rU,r,*b,T"))]
fa5322fa
AO
3491 "TARGET_SHMEDIA
3492 && (register_operand (operands[0], SImode)
d9da94a1 3493 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3494 "@
3495 add.l %1, r63, %0
3496 movi %1, %0
3497 #
3498 ld%M1.l %m1, %0
d9da94a1 3499 st%M0.l %m0, %N1
fa5322fa
AO
3500 ptabs %1, %0
3501 gettr %1, %0
3502 pt %1, %0"
2ad65b0e 3503 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3504 (set_attr "length" "4,4,8,4,4,4,4,12")])
3505
3506(define_split
e69d1422
R
3507 [(set (match_operand:SI 0 "arith_reg_operand" "")
3508 (match_operand:SI 1 "immediate_operand" ""))]
fa5322fa
AO
3509 "TARGET_SHMEDIA && reload_completed
3510 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3511 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3512 "
3513{
3514 operands[2] = shallow_copy_rtx (operands[1]);
3515 PUT_MODE (operands[2], DImode);
3516}")
3517
3518(define_split
e69d1422
R
3519 [(set (match_operand:SI 0 "register_operand" "")
3520 (match_operand:SI 1 "immediate_operand" ""))]
b6d33983 3521 "TARGET_SHMEDIA && reload_completed
fa5322fa
AO
3522 && ((GET_CODE (operands[1]) == CONST_INT
3523 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3524 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3525 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3526
bc45ade3 3527(define_expand "movsi"
0d7e008e
SC
3528 [(set (match_operand:SI 0 "general_movdst_operand" "")
3529 (match_operand:SI 1 "general_movsrc_operand" ""))]
bc45ade3 3530 ""
ffae286a 3531 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
961c4780 3532
225e4f43
R
3533(define_expand "ic_invalidate_line"
3534 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4773afa4 3535 (match_dup 1)] UNSPEC_ICACHE)
225e4f43 3536 (clobber (scratch:SI))])]
fa5322fa 3537 "TARGET_HARD_SH4 || TARGET_SH5"
225e4f43
R
3538 "
3539{
fa5322fa
AO
3540 if (TARGET_SHMEDIA)
3541 {
3542 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3543 DONE;
3544 }
3545 else if (TARGET_SHCOMPACT)
3546 {
3547 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3548 operands[1] = force_reg (Pmode, operands[1]);
3549 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3550 DONE;
3551 }
225e4f43 3552 operands[0] = force_reg (Pmode, operands[0]);
90e65b70
AO
3553 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3554 Pmode)));
225e4f43
R
3555}")
3556
3557;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
0aa54da2
R
3558;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3559;; the requirement *1*00 for associative address writes. The alignment of
225e4f43
R
3560;; %0 implies that its least significant bit is cleared,
3561;; thus we clear the V bit of a matching entry if there is one.
3562(define_insn "ic_invalidate_line_i"
0aa54da2 3563 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
4773afa4
AO
3564 (match_operand:SI 1 "register_operand" "r")]
3565 UNSPEC_ICACHE)
0aa54da2 3566 (clobber (match_scratch:SI 2 "=&r"))]
225e4f43 3567 "TARGET_HARD_SH4"
0aa54da2 3568 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
fae15c93 3569 [(set_attr "length" "8")
c49439f1 3570 (set_attr "type" "cwb")])
225e4f43 3571
ca903bba
R
3572;; ??? could make arg 0 an offsettable memory operand to allow to save
3573;; an add in the code that calculates the address.
fa5322fa
AO
3574(define_insn "ic_invalidate_line_media"
3575 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3576 UNSPEC_ICACHE)]
3577 "TARGET_SHMEDIA"
b6d33983
R
3578 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3579 [(set_attr "length" "16")
3580 (set_attr "type" "invalidate_line_media")])
fa5322fa
AO
3581
3582(define_insn "ic_invalidate_line_compact"
3583 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3584 (match_operand:SI 1 "register_operand" "r")]
3585 UNSPEC_ICACHE)
3586 (clobber (reg:SI PR_REG))]
3587 "TARGET_SHCOMPACT"
3588 "jsr @%1%#"
3589 [(set_attr "type" "sfunc")
3590 (set_attr "needs_delay_slot" "yes")])
3591
ca903bba
R
3592(define_expand "initialize_trampoline"
3593 [(match_operand:SI 0 "" "")
3594 (match_operand:SI 1 "" "")
3595 (match_operand:SI 2 "" "")]
3596 "TARGET_SHCOMPACT"
3597 "
3598{
3599 rtx sfun, tramp;
3600
e300c78c 3601 tramp = force_reg (Pmode, operands[0]);
ca903bba 3602 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
ca903bba
R
3603 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3604 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3605
3606 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3607 DONE;
3608}")
3609
3610(define_insn "initialize_trampoline_compact"
3611 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3612 (match_operand:SI 1 "register_operand" "r")
3613 (reg:SI R2_REG) (reg:SI R3_REG)]
3614 UNSPEC_INIT_TRAMP)
3615
3616 (clobber (reg:SI PR_REG))]
3617 "TARGET_SHCOMPACT"
3618 "jsr @%1%#"
3619 [(set_attr "type" "sfunc")
3620 (set_attr "needs_delay_slot" "yes")])
3621
bc45ade3 3622(define_insn "movqi_i"
07a45e5c
JW
3623 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3624 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
fa5322fa
AO
3625 "TARGET_SH1
3626 && (arith_reg_operand (operands[0], QImode)
3627 || arith_reg_operand (operands[1], QImode))"
bc45ade3
SC
3628 "@
3629 mov %1,%0
0d7e008e
SC
3630 mov.b %1,%0
3631 mov.b %1,%0
3632 movt %0
bc45ade3 3633 sts %1,%0
0d7e008e 3634 lds %1,%0"
22e1ebf1 3635 [(set_attr "type" "move,load,store,move,move,move")])
bc45ade3 3636
fa5322fa
AO
3637(define_insn "*movqi_media"
3638 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
d9da94a1 3639 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,rU"))]
fa5322fa
AO
3640 "TARGET_SHMEDIA
3641 && (arith_reg_operand (operands[0], QImode)
d9da94a1 3642 || arith_reg_or_0_operand (operands[1], QImode))"
fa5322fa
AO
3643 "@
3644 add.l %1, r63, %0
3645 movi %1, %0
59324685 3646 ld%M1.ub %m1, %0
d9da94a1 3647 st%M0.b %m0, %N1"
2ad65b0e 3648 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
fa5322fa 3649
bc45ade3
SC
3650(define_expand "movqi"
3651 [(set (match_operand:QI 0 "general_operand" "")
3652 (match_operand:QI 1 "general_operand" ""))]
3653 ""
ffae286a 3654 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
bc45ade3 3655
b6d33983
R
3656(define_expand "reload_inqi"
3657 [(set (match_operand:SI 2 "" "=&r")
3658 (match_operand:QI 1 "inqhi_operand" ""))
3659 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3660 (truncate:HI (match_dup 3)))]
3661 "TARGET_SHMEDIA"
3662 "
3663{
3664 rtx inner = XEXP (operands[1], 0);
3665 int regno = REGNO (inner);
3666
3667 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3668 operands[1] = gen_rtx_REG (SImode, regno);
3669 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3670}")
3671
bc45ade3 3672(define_insn "movhi_i"
07a45e5c
JW
3673 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3674 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
fa5322fa
AO
3675 "TARGET_SH1
3676 && (arith_reg_operand (operands[0], HImode)
3677 || arith_reg_operand (operands[1], HImode))"
8e87e161
SC
3678 "@
3679 mov.w %1,%0
3680 mov %1,%0
3681 mov.w %1,%0
3682 movt %0
3683 mov.w %1,%0
8e87e161 3684 sts %1,%0
51bd623f
JW
3685 lds %1,%0
3686 fake %1,%0"
27232d28 3687 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
bc45ade3 3688
fa5322fa
AO
3689(define_insn "*movhi_media"
3690 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
d9da94a1 3691 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,rU"))]
fa5322fa
AO
3692 "TARGET_SHMEDIA
3693 && (arith_reg_operand (operands[0], HImode)
d9da94a1 3694 || arith_reg_or_0_operand (operands[1], HImode))"
fa5322fa
AO
3695 "@
3696 add.l %1, r63, %0
3697 movi %1, %0
3698 #
3699 ld%M1.w %m1, %0
d9da94a1 3700 st%M0.w %m0, %N1"
2ad65b0e 3701 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
fa5322fa
AO
3702
3703(define_split
e69d1422
R
3704 [(set (match_operand:HI 0 "register_operand" "")
3705 (match_operand:HI 1 "immediate_operand" ""))]
b6d33983
R
3706 "TARGET_SHMEDIA && reload_completed
3707 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
fa5322fa
AO
3708 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3709
bc45ade3 3710(define_expand "movhi"
0d7e008e
SC
3711 [(set (match_operand:HI 0 "general_movdst_operand" "")
3712 (match_operand:HI 1 "general_movsrc_operand" ""))]
bc45ade3 3713 ""
ffae286a
JW
3714 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3715
b6d33983
R
3716(define_expand "reload_inhi"
3717 [(set (match_operand:SI 2 "" "=&r")
3718 (match_operand:HI 1 "inqhi_operand" ""))
3719 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3720 (truncate:HI (match_dup 3)))]
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
1245df60
R
3732;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3733;; compiled with -m2 -ml -O3 -funroll-loops
0113c3c0 3734(define_insn "*movdi_i"
1245df60
R
3735 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3736 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
fa5322fa
AO
3737 "TARGET_SH1
3738 && (arith_reg_operand (operands[0], DImode)
3739 || arith_reg_operand (operands[1], DImode))"
0d7e008e 3740 "* return output_movedouble (insn, operands, DImode);"
22e1ebf1 3741 [(set_attr "length" "4")
1245df60 3742 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
bc45ade3 3743
d0aae509 3744;; If the output is a register and the input is memory or a register, we have
52702ae1 3745;; to be careful and see which word needs to be loaded first.
b9b7c1c9 3746
8e87e161
SC
3747(define_split
3748 [(set (match_operand:DI 0 "general_movdst_operand" "")
3749 (match_operand:DI 1 "general_movsrc_operand" ""))]
fa5322fa 3750 "TARGET_SH1 && reload_completed"
8e87e161
SC
3751 [(set (match_dup 2) (match_dup 3))
3752 (set (match_dup 4) (match_dup 5))]
3753 "
d0aae509
RK
3754{
3755 int regno;
3756
3757 if ((GET_CODE (operands[0]) == MEM
3758 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3759 || (GET_CODE (operands[1]) == MEM
3760 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3761 FAIL;
3762
3763 if (GET_CODE (operands[0]) == REG)
3764 regno = REGNO (operands[0]);
3765 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 3766 regno = subreg_regno (operands[0]);
d0aae509
RK
3767 else if (GET_CODE (operands[0]) == MEM)
3768 regno = -1;
533f5e0f
KG
3769 else
3770 abort ();
d0aae509
RK
3771
3772 if (regno == -1
3773 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
3774 {
3775 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3776 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3777 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3778 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3779 }
3780 else
3781 {
3782 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3783 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3784 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3785 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3786 }
3787
3788 if (operands[2] == 0 || operands[3] == 0
3789 || operands[4] == 0 || operands[5] == 0)
3790 FAIL;
3791}")
961c4780 3792
fa5322fa 3793(define_insn "*movdi_media"
b6d33983 3794 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
d9da94a1 3795 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rlU,m,f,rU,f,f,r,*b,T"))]
fa5322fa
AO
3796 "TARGET_SHMEDIA_FPU
3797 && (register_operand (operands[0], DImode)
d9da94a1 3798 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3799 "@
3800 add %1, r63, %0
3801 movi %1, %0
3802 #
3803 ld%M1.q %m1, %0
d9da94a1 3804 st%M0.q %m0, %N1
fa5322fa
AO
3805 fld%M1.d %m1, %0
3806 fst%M0.d %m0, %1
0ac78517 3807 fmov.qd %N1, %0
fa5322fa
AO
3808 fmov.dq %1, %0
3809 fmov.d %1, %0
3810 ptabs %1, %0
3811 gettr %1, %0
3812 pt %1, %0"
2ad65b0e 3813 [(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
3814 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3815
3816(define_insn "*movdi_media_nofpu"
b6d33983 3817 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
d9da94a1 3818 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rlU,r,*b,T"))]
fa5322fa
AO
3819 "TARGET_SHMEDIA
3820 && (register_operand (operands[0], DImode)
d9da94a1 3821 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3822 "@
3823 add %1, r63, %0
3824 movi %1, %0
3825 #
3826 ld%M1.q %m1, %0
d9da94a1 3827 st%M0.q %m0, %N1
fa5322fa
AO
3828 ptabs %1, %0
3829 gettr %1, %0
3830 pt %1, %0"
2ad65b0e 3831 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3832 (set_attr "length" "4,4,16,4,4,4,4,*")])
3833
3834(define_split
e69d1422
R
3835 [(set (match_operand:DI 0 "arith_reg_operand" "")
3836 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3837 "TARGET_SHMEDIA && reload_completed
3838 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3839 [(set (match_dup 0) (match_dup 1))]
3840 "
3841{
3842 rtx insn;
3843
3844 if (TARGET_SHMEDIA64)
3845 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3846 else
3847 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3848
3849 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3850 REG_NOTES (insn));
3851
3852 DONE;
3853}")
3854
3855(define_expand "movdi_const"
3856 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3857 (const:DI (sign_extend:DI
3858 (truncate:HI
3859 (ashiftrt:DI
3860 (match_operand:DI 1 "immediate_operand" "s")
3861 (const_int 48))))))
3862 (set (match_dup 0)
3863 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3864 (zero_extend:DI
3865 (truncate:HI
3866 (const:DI
3867 (sign_extend:DI
3868 (truncate:HI
3869 (ashiftrt:SI
3870 (match_dup 1)
3871 (const_int 32)))))))))
3872 (set (match_dup 0)
3873 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3874 (zero_extend:DI
3875 (truncate:HI
3876 (const:DI
3877 (sign_extend:DI
3878 (truncate:HI
3879 (ashiftrt:SI
3880 (match_dup 1)
3881 (const_int 16)))))))))
3882 (set (match_dup 0)
3883 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3884 (zero_extend:DI
3885 (truncate:HI
3886 (const:DI
3887 (sign_extend:DI
3888 (truncate:HI
3889 (match_dup 1))))))))]
3890 "TARGET_SHMEDIA64 && reload_completed
3891 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3892 "
3893{
ea4210ef 3894 sh_mark_label (operands[1], 4);
fa5322fa
AO
3895}")
3896
3897(define_expand "movdi_const_32bit"
3898 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3899 (const:DI (sign_extend:DI
3900 (truncate:HI
3901 (ashiftrt:DI
3902 (match_operand:DI 1 "immediate_operand" "s")
3903 (const_int 16))))))
3904 (set (match_dup 0)
3905 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3906 (zero_extend:DI
3907 (truncate:HI
3908 (const:DI
3909 (sign_extend:DI
3910 (truncate:HI
3911 (match_dup 1))))))))]
3912 "TARGET_SHMEDIA32 && reload_completed
3913 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3914 "
3915{
ea4210ef 3916 sh_mark_label (operands[1], 2);
fa5322fa
AO
3917}")
3918
3919(define_expand "movdi_const_16bit"
3920 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3921 (const:DI (sign_extend:DI
3922 (truncate:HI
3923 (match_operand:DI 1 "immediate_operand" "s")))))]
3924 "TARGET_SHMEDIA && flag_pic && reload_completed
3925 && GET_CODE (operands[1]) == SYMBOL_REF"
3926 "")
3927
3928(define_split
e69d1422
R
3929 [(set (match_operand:DI 0 "arith_reg_operand" "")
3930 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3931 "TARGET_SHMEDIA && reload_completed
3932 && GET_CODE (operands[1]) == CONST_INT
3933 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3934 [(set (match_dup 0) (match_dup 2))
c1b92d09 3935 (match_dup 1)]
fa5322fa
AO
3936 "
3937{
c1b92d09
R
3938 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3939 unsigned HOST_WIDE_INT low = val;
3940 unsigned HOST_WIDE_INT high = val;
fa5322fa 3941 unsigned HOST_WIDE_INT sign;
c1b92d09 3942 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
fa5322fa
AO
3943
3944 /* Sign-extend the 16 least-significant bits. */
c1b92d09
R
3945 low &= 0xffff;
3946 low ^= 0x8000;
3947 low -= 0x8000;
fa5322fa
AO
3948
3949 /* Arithmetic shift right the word by 16 bits. */
c1b92d09 3950 high >>= 16;
fa5322fa
AO
3951 sign = 1;
3952 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
c1b92d09
R
3953 high ^= sign;
3954 high -= sign;
3955 do
3956 {
3957 /* If we can't generate the constant with a two-insn movi / shori
3958 sequence, try some other strategies. */
3959 if (! CONST_OK_FOR_J (high))
3960 {
3961 /* Try constant load / left shift. We know VAL != 0. */
3962 val2 = val ^ (val-1);
3963 if (val2 > 0x1ffff)
3964 {
3965 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3966
3967 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3968 || (! CONST_OK_FOR_J (high >> 16)
3969 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3970 {
3971 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3972 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3973 GEN_INT (trailing_zeroes));
3974 break;
3975 }
3976 }
3977 /* Try constant load / right shift. */
3978 val2 = (val >> 15) + 1;
3979 if (val2 == (val2 & -val2))
3980 {
3981 int shift = 49 - exact_log2 (val2);
3982
3983 val2 = trunc_int_for_mode (val << shift, DImode);
3984 if (CONST_OK_FOR_J (val2))
3985 {
3986 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3987 GEN_INT (shift));
3988 break;
3989 }
3990 }
3991 /* Try mperm.w . */
3992 val2 = val & 0xffff;
3993 if ((val >> 16 & 0xffff) == val2
3994 && (val >> 32 & 0xffff) == val2
3995 && (val >> 48 & 0xffff) == val2)
3996 {
3997 val2 = (HOST_WIDE_INT) val >> 48;
3998 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3999 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4000 break;
4001 }
4002 /* Try movi / mshflo.l */
4003 val2 = (HOST_WIDE_INT) val >> 32;
4004 if (val2 == trunc_int_for_mode (val, SImode))
4005 {
4006 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4007 operands[0]);
4008 break;
4009 }
4010 /* Try movi / mshflo.l w/ r63. */
4011 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4012 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4013 {
4014 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4015 GEN_INT (0));
4016 break;
4017 }
4018 }
4019 val2 = high;
4020 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4021 }
4022 while (0);
4023 operands[2] = GEN_INT (val2);
fa5322fa
AO
4024}")
4025
4026(define_split
e69d1422
R
4027 [(set (match_operand:DI 0 "arith_reg_operand" "")
4028 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
4029 "TARGET_SHMEDIA && reload_completed
4030 && GET_CODE (operands[1]) == CONST_DOUBLE"
4031 [(set (match_dup 0) (match_dup 2))
4032 (set (match_dup 0)
4033 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4034 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4035 "
4036{
4037 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4038 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4039 unsigned HOST_WIDE_INT val = low;
4040 unsigned HOST_WIDE_INT sign;
4041
4042 /* Sign-extend the 16 least-significant bits. */
4043 val &= 0xffff;
4044 val ^= 0x8000;
4045 val -= 0x8000;
4046 operands[1] = GEN_INT (val);
4047
4048 /* Arithmetic shift right the double-word by 16 bits. */
4049 low >>= 16;
4050 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4051 high >>= 16;
4052 sign = 1;
4053 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4054 high ^= sign;
4055 high -= sign;
4056
4057 /* This will only be true if high is a sign-extension of low, i.e.,
4058 it must be either 0 or (unsigned)-1, and be zero iff the
4059 most-significant bit of low is set. */
4060 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4061 operands[2] = GEN_INT (low);
4062 else
4063 operands[2] = immed_double_const (low, high, DImode);
4064}")
4065
c1b92d09 4066(define_insn "shori_media"
fa5322fa
AO
4067 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4068 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4069 (const_int 16))
4070 (zero_extend:DI
4071 (truncate:HI
4072 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4073 "TARGET_SHMEDIA"
4074 "@
4075 shori %u2, %0
2ad65b0e
SC
4076 #"
4077 [(set_attr "type" "arith_media,*")])
fa5322fa 4078
bc45ade3 4079(define_expand "movdi"
961c4780
SC
4080 [(set (match_operand:DI 0 "general_movdst_operand" "")
4081 (match_operand:DI 1 "general_movsrc_operand" ""))]
bc45ade3 4082 ""
a6f463a0 4083 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
ffae286a 4084
fa5322fa
AO
4085(define_insn "movdf_media"
4086 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
d9da94a1 4087 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,rU"))]
fa5322fa
AO
4088 "TARGET_SHMEDIA_FPU
4089 && (register_operand (operands[0], DFmode)
d9da94a1 4090 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4091 "@
4092 fmov.d %1, %0
0ac78517 4093 fmov.qd %N1, %0
fa5322fa
AO
4094 fmov.dq %1, %0
4095 add %1, r63, %0
4096 #
4097 fld%M1.d %m1, %0
4098 fst%M0.d %m0, %1
4099 ld%M1.q %m1, %0
d9da94a1 4100 st%M0.q %m0, %N1"
2ad65b0e 4101 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4102
4103(define_insn "movdf_media_nofpu"
4104 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
d9da94a1 4105 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rU"))]
fa5322fa
AO
4106 "TARGET_SHMEDIA
4107 && (register_operand (operands[0], DFmode)
d9da94a1 4108 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4109 "@
4110 add %1, r63, %0
4111 #
4112 ld%M1.q %m1, %0
d9da94a1 4113 st%M0.q %m0, %N1"
2ad65b0e 4114 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4115
4116(define_split
4117 [(set (match_operand:DF 0 "arith_reg_operand" "")
4118 (match_operand:DF 1 "immediate_operand" ""))]
4119 "TARGET_SHMEDIA && reload_completed"
4120 [(set (match_dup 3) (match_dup 2))]
4121 "
4122{
4123 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4124 long values[2];
4125 REAL_VALUE_TYPE value;
4126
4127 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4128 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4129
4130 if (HOST_BITS_PER_WIDE_INT >= 64)
4131 operands[2] = immed_double_const ((unsigned long) values[endian]
4132 | ((HOST_WIDE_INT) values[1 - endian]
4133 << 32), 0, DImode);
4134 else if (HOST_BITS_PER_WIDE_INT == 32)
4135 operands[2] = immed_double_const (values[endian], values[1 - endian],
4136 DImode);
4137 else
4138 abort ();
4139
4140 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4141}")
4142
ffae286a 4143;; ??? This should be a define expand.
bc45ade3 4144
bc45ade3 4145(define_insn "movdf_k"
3e943b59
JR
4146 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4147 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
fa5322fa
AO
4148 "TARGET_SH1
4149 && (! TARGET_SH4 || reload_completed
4150 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4151 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4152 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
225e4f43
R
4153 && (arith_reg_operand (operands[0], DFmode)
4154 || arith_reg_operand (operands[1], DFmode))"
0d7e008e 4155 "* return output_movedouble (insn, operands, DFmode);"
b9654711 4156 [(set_attr "length" "4")
3e943b59 4157 (set_attr "type" "move,pcload,load,store")])
bc45ade3 4158
225e4f43
R
4159;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4160;; However, the d/F/c/z alternative cannot be split directly; it is converted
4161;; with special code in machine_dependent_reorg into a load of the R0_REG and
4162;; the d/m/c/X alternative, which is split later into single-precision
4163;; instructions. And when not optimizing, no splits are done before fixing
4164;; up pcloads, so we need usable length information for that.
4165(define_insn "movdf_i4"
4166 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4167 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4168 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4169 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4170 "TARGET_SH4
4171 && (arith_reg_operand (operands[0], DFmode)
4172 || arith_reg_operand (operands[1], DFmode))"
4173 "@
4174 fmov %1,%0
4175 #
4176 #
4177 fmov.d %1,%0
4178 fmov.d %1,%0
4179 #
4180 #
4181 #
4182 #
4183 #"
4184 [(set_attr_alternative "length"
4185 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4186 (const_int 4)
4187 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4188 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4189 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4190 (const_int 4)
4191 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
fa5322fa
AO
4192 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4193 ;; increment or decrement r15 explicitly.
4194 (if_then_else
4195 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4196 (const_int 10) (const_int 8))
4197 (if_then_else
4198 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4199 (const_int 10) (const_int 8))])
c49439f1
R
4200 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4201 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
d64264ff
R
4202 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4203 (const_string "double")
4204 (const_string "none")))])
225e4f43
R
4205
4206;; Moving DFmode between fp/general registers through memory
4207;; (the top of the stack) is faster than moving through fpul even for
4208;; little endian. Because the type of an instruction is important for its
4209;; scheduling, it is beneficial to split these operations, rather than
4210;; emitting them in one single chunk, even if this will expose a stack
4211;; use that will prevent scheduling of other stack accesses beyond this
4212;; instruction.
4213(define_split
4214 [(set (match_operand:DF 0 "register_operand" "")
4215 (match_operand:DF 1 "register_operand" ""))
e69d1422 4216 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43
R
4217 (clobber (match_scratch:SI 3 "=X"))]
4218 "TARGET_SH4 && reload_completed
4219 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4220 [(const_int 0)]
4221 "
4222{
4223 rtx insn, tos;
4224
fa5322fa
AO
4225 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4226 {
4227 emit_move_insn (stack_pointer_rtx,
4228 plus_constant (stack_pointer_rtx, -8));
4229 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4230 }
4231 else
4232 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
225e4f43 4233 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
fa5322fa
AO
4234 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4235 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4236 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4237 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4238 else
4239 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
225e4f43 4240 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
fa5322fa
AO
4241 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4242 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4243 else
4244 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
225e4f43
R
4245 DONE;
4246}")
4247
4248;; local-alloc sometimes allocates scratch registers even when not required,
4249;; so we must be prepared to handle these.
4250
4251;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4252(define_split
4253 [(set (match_operand:DF 0 "general_movdst_operand" "")
4254 (match_operand:DF 1 "general_movsrc_operand" ""))
e69d1422
R
4255 (use (match_operand:PSI 2 "fpscr_operand" ""))
4256 (clobber (match_scratch:SI 3 ""))]
225e4f43
R
4257 "TARGET_SH4
4258 && reload_completed
4259 && true_regnum (operands[0]) < 16
4260 && true_regnum (operands[1]) < 16"
4261 [(set (match_dup 0) (match_dup 1))]
4262 "
4263{
4264 /* If this was a reg <-> mem operation with base + index reg addressing,
4265 we have to handle this in a special way. */
4266 rtx mem = operands[0];
4267 int store_p = 1;
4268 if (! memory_operand (mem, DFmode))
4269 {
4270 mem = operands[1];
4271 store_p = 0;
4272 }
ddef6bc7 4273 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
225e4f43
R
4274 mem = SUBREG_REG (mem);
4275 if (GET_CODE (mem) == MEM)
4276 {
4277 rtx addr = XEXP (mem, 0);
4278 if (GET_CODE (addr) == PLUS
4279 && GET_CODE (XEXP (addr, 0)) == REG
4280 && GET_CODE (XEXP (addr, 1)) == REG)
4281 {
4282 int offset;
4283 rtx reg0 = gen_rtx (REG, Pmode, 0);
4284 rtx regop = operands[store_p], word0 ,word1;
4285
4286 if (GET_CODE (regop) == SUBREG)
4dd8c093 4287 alter_subreg (&regop);
225e4f43
R
4288 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4289 offset = 2;
4290 else
4291 offset = 4;
4292 mem = copy_rtx (mem);
4293 PUT_MODE (mem, SImode);
4dd8c093
AO
4294 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4295 alter_subreg (&word0);
4296 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4297 alter_subreg (&word1);
18a7c2a7
AO
4298 if (store_p || ! refers_to_regno_p (REGNO (word0),
4299 REGNO (word0) + 1, addr, 0))
4300 {
4301 emit_insn (store_p
4302 ? gen_movsi_ie (mem, word0)
4303 : gen_movsi_ie (word0, mem));
4304 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4305 mem = copy_rtx (mem);
4306 emit_insn (store_p
4307 ? gen_movsi_ie (mem, word1)
4308 : gen_movsi_ie (word1, mem));
4309 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4310 }
4311 else
4312 {
4313 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4314 emit_insn (gen_movsi_ie (word1, mem));
4315 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4316 mem = copy_rtx (mem);
4317 emit_insn (gen_movsi_ie (word0, mem));
4318 }
225e4f43
R
4319 DONE;
4320 }
4321 }
4322}")
4323
4324;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4325(define_split
4326 [(set (match_operand:DF 0 "register_operand" "")
4327 (match_operand:DF 1 "memory_operand" ""))
e69d1422 4328 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4329 (clobber (reg:SI R0_REG))]
225e4f43
R
4330 "TARGET_SH4 && reload_completed"
4331 [(parallel [(set (match_dup 0) (match_dup 1))
4332 (use (match_dup 2))
4333 (clobber (scratch:SI))])]
4334 "")
4335
4336(define_expand "reload_indf"
4337 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4338 (match_operand:DF 1 "immediate_operand" "FQ"))
4773afa4 4339 (use (reg:PSI FPSCR_REG))
225e4f43 4340 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4341 "TARGET_SH1"
225e4f43
R
4342 "")
4343
4344(define_expand "reload_outdf"
4345 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4346 (match_operand:DF 1 "register_operand" "af,r"))
4347 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
fa5322fa 4348 "TARGET_SH1"
225e4f43
R
4349 "")
4350
4351;; Simplify no-op moves.
4352(define_split
4353 [(set (match_operand:SF 0 "register_operand" "")
4354 (match_operand:SF 1 "register_operand" ""))
4355 (use (match_operand:PSI 2 "fpscr_operand" ""))
4356 (clobber (match_scratch:SI 3 "X"))]
4357 "TARGET_SH3E && reload_completed
4358 && true_regnum (operands[0]) == true_regnum (operands[1])"
4359 [(set (match_dup 0) (match_dup 0))]
4360 "")
4361
4362;; fmovd substitute post-reload splits
4363(define_split
4364 [(set (match_operand:DF 0 "register_operand" "")
4365 (match_operand:DF 1 "register_operand" ""))
e69d1422 4366 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43
R
4367 (clobber (match_scratch:SI 3 "X"))]
4368 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b
AO
4369 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4370 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4371 [(const_int 0)]
4372 "
4373{
4374 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4375 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4376 gen_rtx (REG, SFmode, src), operands[2]));
4377 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4378 gen_rtx (REG, SFmode, src + 1), operands[2]));
4379 DONE;
4380}")
4381
4382(define_split
4383 [(set (match_operand:DF 0 "register_operand" "")
4384 (mem:DF (match_operand:SI 1 "register_operand" "")))
e69d1422
R
4385 (use (match_operand:PSI 2 "fpscr_operand" ""))
4386 (clobber (match_scratch:SI 3 ""))]
225e4f43 4387 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
b6c02328 4388 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
225e4f43
R
4389 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4390 [(const_int 0)]
4391 "
4392{
4393 int regno = true_regnum (operands[0]);
4394 rtx insn;
4395 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4396
4397 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4398 regno + !! TARGET_LITTLE_ENDIAN),
4399 mem2, operands[2]));
4400 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4401 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4402 regno + ! TARGET_LITTLE_ENDIAN),
4403 gen_rtx (MEM, SFmode, operands[1]),
4404 operands[2]));
4405 DONE;
4406}")
4407
4408(define_split
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
e69d1422
R
4411 (use (match_operand:PSI 2 "fpscr_operand" ""))
4412 (clobber (match_scratch:SI 3 ""))]
225e4f43 4413 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4414 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
225e4f43
R
4415 [(const_int 0)]
4416 "
4417{
4418 int regno = true_regnum (operands[0]);
4419 rtx addr, insn, adjust = NULL_RTX;
4420 rtx mem2 = copy_rtx (operands[1]);
4421 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4422 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4423
4424 PUT_MODE (mem2, SFmode);
4425 operands[1] = copy_rtx (mem2);
4426 addr = XEXP (mem2, 0);
4427 if (GET_CODE (addr) != POST_INC)
4428 {
4429 /* If we have to modify the stack pointer, the value that we have
4430 read with post-increment might be modified by an interrupt,
4431 so write it back. */
4432 if (REGNO (addr) == STACK_POINTER_REGNUM)
4433 adjust = gen_push_e (reg0);
4434 else
4435 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4436 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4437 }
4438 addr = XEXP (addr, 0);
4439 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4440 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4441 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4442 if (adjust)
4443 emit_insn (adjust);
4444 else
4445 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4446 DONE;
4447}")
4448
4449(define_split
4450 [(set (match_operand:DF 0 "memory_operand" "")
4451 (match_operand:DF 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
104ee20b 4455 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4456 [(const_int 0)]
4457 "
4458{
4459 int regno = true_regnum (operands[1]);
4460 rtx insn, addr, adjust = NULL_RTX;
4461
4462 operands[0] = copy_rtx (operands[0]);
4463 PUT_MODE (operands[0], SFmode);
4464 insn = emit_insn (gen_movsf_ie (operands[0],
4465 gen_rtx (REG, SFmode,
4466 regno + ! TARGET_LITTLE_ENDIAN),
4467 operands[2]));
4468 operands[0] = copy_rtx (operands[0]);
4469 addr = XEXP (operands[0], 0);
4470 if (GET_CODE (addr) != PRE_DEC)
4471 {
4472 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4473 emit_insn_before (adjust, insn);
4474 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4475 }
4476 addr = XEXP (addr, 0);
4477 if (! adjust)
4478 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4479 insn = emit_insn (gen_movsf_ie (operands[0],
4480 gen_rtx (REG, SFmode,
4481 regno + !! TARGET_LITTLE_ENDIAN),
4482 operands[2]));
4483 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4484 DONE;
4485}")
4486
d0aae509 4487;; If the output is a register and the input is memory or a register, we have
52702ae1 4488;; to be careful and see which word needs to be loaded first.
07a45e5c 4489
8e87e161
SC
4490(define_split
4491 [(set (match_operand:DF 0 "general_movdst_operand" "")
4492 (match_operand:DF 1 "general_movsrc_operand" ""))]
fa5322fa 4493 "TARGET_SH1 && reload_completed"
8e87e161
SC
4494 [(set (match_dup 2) (match_dup 3))
4495 (set (match_dup 4) (match_dup 5))]
4496 "
d0aae509
RK
4497{
4498 int regno;
4499
4500 if ((GET_CODE (operands[0]) == MEM
4501 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4502 || (GET_CODE (operands[1]) == MEM
4503 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4504 FAIL;
4505
4506 if (GET_CODE (operands[0]) == REG)
4507 regno = REGNO (operands[0]);
4508 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 4509 regno = subreg_regno (operands[0]);
d0aae509
RK
4510 else if (GET_CODE (operands[0]) == MEM)
4511 regno = -1;
533f5e0f
KG
4512 else
4513 abort ();
d0aae509
RK
4514
4515 if (regno == -1
4516 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
4517 {
4518 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4519 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4520 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4521 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4522 }
4523 else
4524 {
4525 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4526 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4527 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4528 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4529 }
4530
4531 if (operands[2] == 0 || operands[3] == 0
4532 || operands[4] == 0 || operands[5] == 0)
4533 FAIL;
4534}")
4535
653bd7a6
JW
4536;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4537;; used only once, let combine add in the index again.
4538
4539(define_split
4540 [(set (match_operand:SI 0 "register_operand" "")
4541 (match_operand:SI 1 "" ""))
4542 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4543 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4544 [(use (reg:SI R0_REG))]
653bd7a6
JW
4545 "
4546{
4547 rtx addr, reg, const_int;
4548
4549 if (GET_CODE (operands[1]) != MEM)
4550 FAIL;
4551 addr = XEXP (operands[1], 0);
4552 if (GET_CODE (addr) != PLUS)
4553 FAIL;
4554 reg = XEXP (addr, 0);
4555 const_int = XEXP (addr, 1);
f295bdb5
AH
4556 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4557 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4558 FAIL;
4559 emit_move_insn (operands[2], const_int);
4560 emit_move_insn (operands[0],
4561 change_address (operands[1], VOIDmode,
c5c76735 4562 gen_rtx_PLUS (SImode, reg, operands[2])));
653bd7a6
JW
4563 DONE;
4564}")
4565
4566(define_split
4567 [(set (match_operand:SI 1 "" "")
4568 (match_operand:SI 0 "register_operand" ""))
4569 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4570 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4571 [(use (reg:SI R0_REG))]
653bd7a6
JW
4572 "
4573{
4574 rtx addr, reg, const_int;
4575
4576 if (GET_CODE (operands[1]) != MEM)
4577 FAIL;
4578 addr = XEXP (operands[1], 0);
4579 if (GET_CODE (addr) != PLUS)
4580 FAIL;
4581 reg = XEXP (addr, 0);
4582 const_int = XEXP (addr, 1);
f295bdb5
AH
4583 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4584 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4585 FAIL;
4586 emit_move_insn (operands[2], const_int);
4587 emit_move_insn (change_address (operands[1], VOIDmode,
c5c76735 4588 gen_rtx_PLUS (SImode, reg, operands[2])),
653bd7a6
JW
4589 operands[0]);
4590 DONE;
4591}")
4592
bc45ade3 4593(define_expand "movdf"
0d7e008e
SC
4594 [(set (match_operand:DF 0 "general_movdst_operand" "")
4595 (match_operand:DF 1 "general_movsrc_operand" ""))]
bc45ade3 4596 ""
1245df60
R
4597 "
4598{
4599 if (prepare_move_operands (operands, DFmode)) DONE;
fa5322fa
AO
4600 if (TARGET_SHMEDIA)
4601 {
4602 if (TARGET_SHMEDIA_FPU)
4603 emit_insn (gen_movdf_media (operands[0], operands[1]));
4604 else
4605 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4606 DONE;
4607 }
225e4f43
R
4608 if (TARGET_SH4)
4609 {
4610 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
4611 DONE;
4612 }
1245df60
R
4613}")
4614
0ac78517
R
4615;;This is incompatible with the way gcc uses subregs.
4616;;(define_insn "movv2sf_i"
4617;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4618;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4619;; "TARGET_SHMEDIA_FPU
4620;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4621;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4622;; "@
4623;; #
4624;; fld%M1.p %m1, %0
4625;; fst%M0.p %m0, %1"
4626;; [(set_attr "type" "*,fload_media,fstore_media")])
4627
4628(define_insn_and_split "movv2sf_i"
4629 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4630 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4631 "TARGET_SHMEDIA_FPU"
4632 "#"
4633 "TARGET_SHMEDIA_FPU && reload_completed"
4634 [(set (match_dup 0) (match_dup 1))]
4635 "
4636{
4637 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4638 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4639}")
fa5322fa
AO
4640
4641(define_expand "movv2sf"
0ac78517
R
4642 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4643 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
fa5322fa
AO
4644 "TARGET_SHMEDIA_FPU"
4645 "
4646{
4647 if (prepare_move_operands (operands, V2SFmode))
4648 DONE;
4649}")
4650
0ac78517
R
4651(define_expand "addv2sf3"
4652 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4653 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4654 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4655 "TARGET_SHMEDIA_FPU"
4656 "
4657{
4658 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4659 DONE;
4660}")
4661
4662(define_expand "subv2sf3"
4663 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4664 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4665 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4666 "TARGET_SHMEDIA_FPU"
4667 "
4668{
4669 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4670 DONE;
4671}")
4672
4673(define_expand "mulv2sf3"
4674 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4675 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4676 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4677 "TARGET_SHMEDIA_FPU"
4678 "
4679{
4680 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4681 DONE;
4682}")
4683
4684(define_expand "divv2sf3"
4685 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4686 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4688 "TARGET_SHMEDIA_FPU"
4689 "
4690{
4691 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4692 DONE;
4693}")
4694
fa5322fa
AO
4695(define_insn_and_split "*movv4sf_i"
4696 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
d9da94a1 4697 (match_operand:V4SF 1 "general_operand" "fU,m,fU"))]
fa5322fa
AO
4698 "TARGET_SHMEDIA_FPU"
4699 "#"
4700 "&& reload_completed"
4701 [(const_int 0)]
4702 "
4703{
4704 int i;
4705
4706 for (i = 0; i < 4/2; i++)
4707 {
4708 rtx x, y;
4709
4710 if (GET_CODE (operands[0]) == MEM)
4711 x = gen_rtx_MEM (V2SFmode,
4712 plus_constant (XEXP (operands[0], 0),
4713 i * GET_MODE_SIZE (V2SFmode)));
4714 else
0ac78517 4715 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
fa5322fa
AO
4716
4717 if (GET_CODE (operands[1]) == MEM)
4718 y = gen_rtx_MEM (V2SFmode,
4719 plus_constant (XEXP (operands[1], 0),
4720 i * GET_MODE_SIZE (V2SFmode)));
4721 else
0ac78517 4722 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
fa5322fa
AO
4723
4724 emit_insn (gen_movv2sf_i (x, y));
4725 }
4726
4727 DONE;
4728}"
4729 [(set_attr "length" "8")])
52702ae1 4730
fa5322fa 4731(define_expand "movv4sf"
0ac78517
R
4732 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4733 (match_operand:V4SF 1 "general_operand" ""))]
fa5322fa
AO
4734 "TARGET_SHMEDIA_FPU"
4735 "
4736{
4737 if (prepare_move_operands (operands, V4SFmode))
4738 DONE;
4739}")
4740
4741(define_insn_and_split "*movv16sf_i"
4742 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4743 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4744 "TARGET_SHMEDIA_FPU"
4745 "#"
4746 "&& reload_completed"
4747 [(const_int 0)]
4748 "
4749{
4750 int i;
4751
4752 for (i = 0; i < 16/2; i++)
4753 {
4754 rtx x,y;
4755
4756 if (GET_CODE (operands[0]) == MEM)
4757 x = gen_rtx_MEM (V2SFmode,
4758 plus_constant (XEXP (operands[0], 0),
4759 i * GET_MODE_SIZE (V2SFmode)));
4760 else
4761 {
4762 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4763 alter_subreg (&x);
4764 }
4765
4766 if (GET_CODE (operands[1]) == MEM)
4767 y = gen_rtx_MEM (V2SFmode,
4768 plus_constant (XEXP (operands[1], 0),
4769 i * GET_MODE_SIZE (V2SFmode)));
4770 else
4771 {
4772 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4773 alter_subreg (&y);
4774 }
4775
4776 emit_insn (gen_movv2sf_i (x, y));
4777 }
4778
4779 DONE;
4780}"
4781 [(set_attr "length" "32")])
52702ae1 4782
fa5322fa
AO
4783(define_expand "movv16sf"
4784 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4785 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4786 "TARGET_SHMEDIA_FPU"
4787 "
4788{
4789 if (prepare_move_operands (operands, V16SFmode))
4790 DONE;
4791}")
4792
4793(define_insn "movsf_media"
4794 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
d9da94a1 4795 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,rU"))]
fa5322fa
AO
4796 "TARGET_SHMEDIA_FPU
4797 && (register_operand (operands[0], SFmode)
d9da94a1 4798 || sh_register_operand (operands[1], SFmode))"
fa5322fa
AO
4799 "@
4800 fmov.s %1, %0
0ac78517 4801 fmov.ls %N1, %0
fa5322fa 4802 fmov.sl %1, %0
b6d33983 4803 add.l %1, r63, %0
fa5322fa
AO
4804 #
4805 fld%M1.s %m1, %0
4806 fst%M0.s %m0, %1
4807 ld%M1.l %m1, %0
d9da94a1 4808 st%M0.l %m0, %N1"
b6d33983 4809 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4810
4811(define_insn "movsf_media_nofpu"
4812 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
d9da94a1 4813 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rU"))]
fa5322fa
AO
4814 "TARGET_SHMEDIA
4815 && (register_operand (operands[0], SFmode)
d9da94a1 4816 || sh_register_operand (operands[1], SFmode))"
fa5322fa 4817 "@
b6d33983 4818 add.l %1, r63, %0
fa5322fa
AO
4819 #
4820 ld%M1.l %m1, %0
d9da94a1 4821 st%M0.l %m0, %N1"
b6d33983 4822 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4823
4824(define_split
4825 [(set (match_operand:SF 0 "arith_reg_operand" "")
4826 (match_operand:SF 1 "immediate_operand" ""))]
0ac78517
R
4827 "TARGET_SHMEDIA && reload_completed
4828 && ! FP_REGISTER_P (true_regnum (operands[0]))"
fa5322fa
AO
4829 [(set (match_dup 3) (match_dup 2))]
4830 "
4831{
4832 long values;
4833 REAL_VALUE_TYPE value;
4834
4835 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4836 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4837 operands[2] = GEN_INT (values);
52702ae1 4838
fa5322fa
AO
4839 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4840}")
bc45ade3 4841
bc45ade3 4842(define_insn "movsf_i"
3e943b59 4843 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
225e4f43 4844 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
fa5322fa
AO
4845 "TARGET_SH1
4846 && (! TARGET_SH3E
4847 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4848 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4849 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
1245df60
R
4850 && (arith_reg_operand (operands[0], SFmode)
4851 || arith_reg_operand (operands[1], SFmode))"
bc45ade3
SC
4852 "@
4853 mov %1,%0
4854 mov %1,%0
4855 mov.l %1,%0
4856 mov.l %1,%0
3e943b59 4857 mov.l %1,%0
b9654711 4858 lds %1,%0
0d7e008e 4859 sts %1,%0"
3e943b59 4860 [(set_attr "type" "move,move,pcload,load,store,move,move")])
bc45ade3 4861
4dff12bf
R
4862;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4863;; update_flow_info would not know where to put REG_EQUAL notes
4864;; when the destination changes mode.
45348d9e 4865(define_insn "movsf_ie"
7f74cc8d 4866 [(set (match_operand:SF 0 "general_movdst_operand"
a92facbb 4867 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
7f74cc8d 4868 (match_operand:SF 1 "general_movsrc_operand"
a92facbb
AO
4869 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4870 (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"))
4871 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
7f74cc8d 4872
45348d9e
JW
4873 "TARGET_SH3E
4874 && (arith_reg_operand (operands[0], SFmode)
c2d10707
AO
4875 || arith_reg_operand (operands[1], SFmode)
4876 || arith_reg_operand (operands[3], SImode)
4877 || (fpul_operand (operands[0], SFmode)
4878 && memory_operand (operands[1], SFmode)
4879 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4880 || (fpul_operand (operands[1], SFmode)
4881 && memory_operand (operands[0], SFmode)
4882 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
45348d9e
JW
4883 "@
4884 fmov %1,%0
4885 mov %1,%0
4886 fldi0 %0
4887 fldi1 %0
7f74cc8d 4888 #
45348d9e
JW
4889 fmov.s %1,%0
4890 fmov.s %1,%0
4891 mov.l %1,%0
4892 mov.l %1,%0
3e943b59 4893 mov.l %1,%0
1245df60
R
4894 fsts fpul,%0
4895 flds %1,fpul
4896 lds.l %1,%0
4897 #
4dff12bf
R
4898 sts %1,%0
4899 lds %1,%0
a92facbb
AO
4900 sts.l %1,%0
4901 lds.l %1,%0
4dff12bf 4902 ! move optimized away"
c49439f1
R
4903 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4904 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
a92facbb 4905 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
d64264ff
R
4906 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4907 (const_string "single")
4908 (const_string "none")))])
79664856 4909
1245df60
R
4910(define_split
4911 [(set (match_operand:SF 0 "register_operand" "")
4912 (match_operand:SF 1 "register_operand" ""))
e69d1422 4913 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4914 (clobber (reg:SI FPUL_REG))]
fa5322fa 4915 "TARGET_SH1"
4773afa4 4916 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
225e4f43 4917 (use (match_dup 2))
1245df60 4918 (clobber (scratch:SI))])
4773afa4 4919 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
225e4f43 4920 (use (match_dup 2))
1245df60
R
4921 (clobber (scratch:SI))])]
4922 "")
4923
bc45ade3 4924(define_expand "movsf"
0d7e008e 4925 [(set (match_operand:SF 0 "general_movdst_operand" "")
3e943b59 4926 (match_operand:SF 1 "general_movsrc_operand" ""))]
bc45ade3 4927 ""
3e943b59
JR
4928 "
4929{
4930 if (prepare_move_operands (operands, SFmode))
4931 DONE;
fa5322fa
AO
4932 if (TARGET_SHMEDIA)
4933 {
4934 if (TARGET_SHMEDIA_FPU)
4935 emit_insn (gen_movsf_media (operands[0], operands[1]));
4936 else
4937 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4938 DONE;
4939 }
7f74cc8d 4940 if (TARGET_SH3E)
3e943b59 4941 {
225e4f43 4942 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
3e943b59
JR
4943 DONE;
4944 }
4945}")
7f74cc8d 4946
225e4f43 4947(define_insn "mov_nop"
e69d1422 4948 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
225e4f43
R
4949 "TARGET_SH3E"
4950 ""
4951 [(set_attr "length" "0")
4952 (set_attr "type" "nil")])
4953
7f74cc8d 4954(define_expand "reload_insf"
c2d10707 4955 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
7f74cc8d 4956 (match_operand:SF 1 "immediate_operand" "FQ"))
4773afa4 4957 (use (reg:PSI FPSCR_REG))
7f74cc8d 4958 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4959 "TARGET_SH1"
7f74cc8d 4960 "")
225e4f43
R
4961
4962(define_expand "reload_insi"
4963 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4964 (match_operand:SF 1 "immediate_operand" "FQ"))
4965 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4966 "TARGET_SH1"
225e4f43
R
4967 "")
4968
4969(define_insn "*movsi_y"
4970 [(set (match_operand:SI 0 "register_operand" "=y,y")
4971 (match_operand:SI 1 "immediate_operand" "Qi,I"))
c77e04ae 4972 (clobber (match_scratch:SI 2 "=&z,r"))]
225e4f43
R
4973 "TARGET_SH3E
4974 && (reload_in_progress || reload_completed)"
4975 "#"
4976 [(set_attr "length" "4")
4977 (set_attr "type" "pcload,move")])
4978
4979(define_split
997718c7
RH
4980 [(set (match_operand:SI 0 "register_operand" "")
4981 (match_operand:SI 1 "immediate_operand" ""))
4982 (clobber (match_operand:SI 2 "register_operand" ""))]
fa5322fa 4983 "TARGET_SH1"
225e4f43
R
4984 [(set (match_dup 2) (match_dup 1))
4985 (set (match_dup 0) (match_dup 2))]
4986 "")
4987
4988(define_split
997718c7
RH
4989 [(set (match_operand:SI 0 "register_operand" "")
4990 (match_operand:SI 1 "memory_operand" ""))
4773afa4 4991 (clobber (reg:SI R0_REG))]
fa5322fa 4992 "TARGET_SH1"
225e4f43
R
4993 [(set (match_dup 0) (match_dup 1))]
4994 "")
bc45ade3
SC
4995\f
4996;; ------------------------------------------------------------------------
4997;; Define the real conditional branch instructions.
4998;; ------------------------------------------------------------------------
4999
5000(define_insn "branch_true"
4773afa4 5001 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5002 (label_ref (match_operand 0 "" ""))
5003 (pc)))]
fa5322fa 5004 "TARGET_SH1"
51aea58d 5005 "* return output_branch (1, insn, operands);"
bc45ade3
SC
5006 [(set_attr "type" "cbranch")])
5007
5008(define_insn "branch_false"
4773afa4 5009 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5010 (label_ref (match_operand 0 "" ""))
5011 (pc)))]
fa5322fa 5012 "TARGET_SH1"
51aea58d 5013 "* return output_branch (0, insn, operands);"
bc45ade3
SC
5014 [(set_attr "type" "cbranch")])
5015
1245df60
R
5016;; Patterns to prevent reorg from re-combining a condbranch with a branch
5017;; which destination is too far away.
5018;; The const_int_operand is distinct for each branch target; it avoids
5019;; unwanted matches with redundant_insn.
5020(define_insn "block_branch_redirect"
e11cddec 5021 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
fa5322fa 5022 "TARGET_SH1"
1245df60
R
5023 ""
5024 [(set_attr "length" "0")])
bc45ade3 5025
1245df60
R
5026;; This one has the additional purpose to record a possible scratch register
5027;; for the following branch.
5028(define_insn "indirect_jump_scratch"
e69d1422
R
5029 [(set (match_operand:SI 0 "register_operand" "=r")
5030 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
fa5322fa 5031 "TARGET_SH1"
1245df60
R
5032 ""
5033 [(set_attr "length" "0")])
c608a684
R
5034
5035;; This one is used to preemt an insn from beyond the bra / braf / jmp
5036;; being pulled into the delay slot of a condbranch that has been made to
5037;; jump around the unconditional jump because it was out of range.
5038(define_insn "stuff_delay_slot"
5039 [(set (pc)
5040 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5041 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5042 "TARGET_SH1"
5043 ""
5044 [(set_attr "length" "0")
5045 (set_attr "cond_delay_slot" "yes")])
bc45ade3
SC
5046\f
5047;; Conditional branch insns
5048
fa5322fa 5049(define_expand "beq_media"
1245df60 5050 [(set (pc)
fa5322fa
AO
5051 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5052 (match_operand:DI 2 "arith_operand" "r,O"))
5053 (label_ref:DI (match_operand 0 "" ""))
bc45ade3 5054 (pc)))]
fa5322fa
AO
5055 "TARGET_SHMEDIA"
5056 "")
bc45ade3 5057
c8cc4417 5058(define_insn "*beq_media_i"
1245df60 5059 [(set (pc)
c8cc4417
R
5060 (if_then_else (match_operator 3 "equality_comparison_operator"
5061 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5062 (match_operand:DI 2 "arith_operand" "r,O")])
fa5322fa 5063 (match_operand:DI 0 "target_operand" "b,b")
1245df60 5064 (pc)))]
fa5322fa
AO
5065 "TARGET_SHMEDIA"
5066 "@
c8cc4417
R
5067 b%o3%' %1, %2, %0
5068 b%o3i%' %1, %2, %0"
5069 [(set_attr "type" "cbranch_media")])
bc45ade3 5070
fa5322fa 5071(define_expand "bne_media"
1245df60 5072 [(set (pc)
fa5322fa
AO
5073 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5074 (match_operand:DI 2 "arith_operand" "r,O"))
5075 (label_ref:DI (match_operand 0 "" ""))
ffae286a 5076 (pc)))]
fa5322fa
AO
5077 "TARGET_SHMEDIA"
5078 "")
bc45ade3 5079
fa5322fa 5080(define_expand "bgt_media"
1245df60 5081 [(set (pc)
b6d33983
R
5082 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5083 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa 5084 (label_ref:DI (match_operand 0 "" ""))
1245df60 5085 (pc)))]
fa5322fa
AO
5086 "TARGET_SHMEDIA"
5087 "")
5088
fa5322fa
AO
5089(define_expand "bge_media"
5090 [(set (pc)
b6d33983
R
5091 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5092 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5093 (label_ref:DI (match_operand 0 "" ""))
5094 (pc)))]
5095 "TARGET_SHMEDIA"
5096 "")
5097
fa5322fa
AO
5098(define_expand "bgtu_media"
5099 [(set (pc)
b6d33983
R
5100 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5101 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5102 (label_ref:DI (match_operand 0 "" ""))
5103 (pc)))]
5104 "TARGET_SHMEDIA"
5105 "")
5106
fa5322fa
AO
5107(define_expand "bgeu_media"
5108 [(set (pc)
b6d33983
R
5109 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5110 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5111 (label_ref:DI (match_operand 0 "" ""))
5112 (pc)))]
5113 "TARGET_SHMEDIA"
5114 "")
5115
c8cc4417 5116(define_insn "*bgt_media_i"
fa5322fa 5117 [(set (pc)
c8cc4417
R
5118 (if_then_else (match_operator 3 "greater_comparison_operator"
5119 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5120 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5121 (match_operand:DI 0 "target_operand" "b")
5122 (pc)))]
5123 "TARGET_SHMEDIA"
c8cc4417
R
5124 "b%o3%' %N1, %N2, %0"
5125 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5126
5127;; These are only needed to make invert_jump() happy.
b6d33983 5128(define_insn "*blt_media_i"
fa5322fa 5129 [(set (pc)
c8cc4417 5130 (if_then_else (match_operator 3 "less_comparison_operator"
b6d33983
R
5131 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5132 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5133 (match_operand:DI 0 "target_operand" "b")
5134 (pc)))]
5135 "TARGET_SHMEDIA"
c8cc4417
R
5136 "b%o3%' %N2, %N1, %0"
5137 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5138
5139(define_expand "beq"
5140 [(set (pc)
5141 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5142 (label_ref (match_operand 0 "" ""))
5143 (pc)))]
5144 ""
5145 "
5146{
5147 if (TARGET_SHMEDIA)
5148 {
5149 if (GET_MODE (sh_compare_op0) != DImode)
5150 {
5151 rtx tmp = gen_reg_rtx (DImode);
5152
5153 emit_insn (gen_seq (tmp));
5154 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5155 DONE;
5156 }
5157
5158 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5159 emit_jump_insn (gen_beq_media (operands[0],
5160 sh_compare_op0, sh_compare_op1));
5161 DONE;
5162 }
5163
5164 from_compare (operands, EQ);
5165}")
5166
5167(define_expand "bne"
5168 [(set (pc)
5169 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5170 (label_ref (match_operand 0 "" ""))
5171 (pc)))]
5172 ""
5173 "
5174{
5175 if (TARGET_SHMEDIA)
5176 {
5177 if (GET_MODE (sh_compare_op0) != DImode)
5178 {
5179 rtx tmp = gen_reg_rtx (DImode);
5180
5181 emit_insn (gen_seq (tmp));
5182 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5183 DONE;
5184 }
5185
5186 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5187 emit_jump_insn (gen_bne_media (operands[0],
5188 sh_compare_op0, sh_compare_op1));
5189 DONE;
5190 }
5191
5192 from_compare (operands, EQ);
5193}")
5194
5195(define_expand "bgt"
5196 [(set (pc)
5197 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5198 (label_ref (match_operand 0 "" ""))
5199 (pc)))]
5200 ""
5201 "
5202{
5203 if (TARGET_SHMEDIA)
5204 {
5205 if (GET_MODE (sh_compare_op0) != DImode)
5206 {
5207 rtx tmp = gen_reg_rtx (DImode);
5208
5209 emit_insn (gen_sgt (tmp));
5210 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5211 DONE;
5212 }
5213
c8cc4417
R
5214 if (sh_compare_op0 != const0_rtx)
5215 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5216 if (sh_compare_op1 != const0_rtx)
5217 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5218 emit_jump_insn (gen_bgt_media (operands[0],
5219 sh_compare_op0, sh_compare_op1));
5220 DONE;
5221 }
5222
5223 from_compare (operands, GT);
5224}")
5225
5226(define_expand "blt"
5227 [(set (pc)
5228 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5229 (label_ref (match_operand 0 "" ""))
5230 (pc)))]
5231 ""
5232 "
5233{
5234 if (TARGET_SHMEDIA)
5235 {
5236 if (GET_MODE (sh_compare_op0) != DImode)
5237 {
5238 rtx tmp = gen_reg_rtx (DImode);
5239
5240 emit_insn (gen_slt (tmp));
5241 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5242 DONE;
5243 }
5244
c8cc4417
R
5245 if (sh_compare_op0 != const0_rtx)
5246 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5247 if (sh_compare_op1 != const0_rtx)
5248 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5249 emit_jump_insn (gen_bgt_media (operands[0],
5250 sh_compare_op1, sh_compare_op0));
5251 DONE;
5252 }
5253
5254 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5255 {
5256 rtx tmp = sh_compare_op0;
5257 sh_compare_op0 = sh_compare_op1;
5258 sh_compare_op1 = tmp;
5259 emit_insn (gen_bgt (operands[0]));
5260 DONE;
5261 }
5262 from_compare (operands, GE);
5263}")
5264
5265(define_expand "ble"
5266 [(set (pc)
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5269 (pc)))]
5270 ""
5271 "
5272{
5273 if (TARGET_SHMEDIA)
5274 {
5275 if (GET_MODE (sh_compare_op0) != DImode)
5276 {
5277 rtx tmp = gen_reg_rtx (DImode);
5278
5279 emit_insn (gen_sle (tmp));
5280 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5281 DONE;
5282 }
5283
c8cc4417
R
5284 if (sh_compare_op0 != const0_rtx)
5285 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286 if (sh_compare_op1 != const0_rtx)
5287 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5288 emit_jump_insn (gen_bge_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5290 DONE;
5291 }
5292
5293 if (TARGET_SH3E
5294 && TARGET_IEEE
1245df60
R
5295 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5296 {
5297 rtx tmp = sh_compare_op0;
5298 sh_compare_op0 = sh_compare_op1;
5299 sh_compare_op1 = tmp;
5300 emit_insn (gen_bge (operands[0]));
5301 DONE;
5302 }
5303 from_compare (operands, GT);
5304}")
bc45ade3
SC
5305
5306(define_expand "bge"
1245df60 5307 [(set (pc)
4773afa4 5308 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5309 (label_ref (match_operand 0 "" ""))
ffae286a 5310 (pc)))]
bc45ade3 5311 ""
45348d9e
JW
5312 "
5313{
fa5322fa
AO
5314 if (TARGET_SHMEDIA)
5315 {
5316 if (GET_MODE (sh_compare_op0) != DImode)
5317 {
5318 rtx tmp = gen_reg_rtx (DImode);
5319
5320 emit_insn (gen_sge (tmp));
5321 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5322 DONE;
5323 }
5324
c8cc4417
R
5325 if (sh_compare_op0 != const0_rtx)
5326 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5327 if (sh_compare_op1 != const0_rtx)
5328 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5329 emit_jump_insn (gen_bge_media (operands[0],
5330 sh_compare_op0, sh_compare_op1));
5331 DONE;
5332 }
5333
1245df60
R
5334 if (TARGET_SH3E
5335 && ! TARGET_IEEE
5336 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e
JW
5337 {
5338 rtx tmp = sh_compare_op0;
5339 sh_compare_op0 = sh_compare_op1;
5340 sh_compare_op1 = tmp;
5341 emit_insn (gen_ble (operands[0]));
5342 DONE;
5343 }
5344 from_compare (operands, GE);
5345}")
bc45ade3
SC
5346
5347(define_expand "bgtu"
1245df60 5348 [(set (pc)
4773afa4 5349 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5350 (label_ref (match_operand 0 "" ""))
5351 (pc)))]
5352 ""
fa5322fa
AO
5353 "
5354{
5355 if (TARGET_SHMEDIA)
5356 {
c8cc4417
R
5357 if (sh_compare_op0 != const0_rtx)
5358 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5359 if (sh_compare_op1 != const0_rtx)
5360 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5361 emit_jump_insn (gen_bgtu_media (operands[0],
5362 sh_compare_op0, sh_compare_op1));
5363 DONE;
5364 }
5365
5366 from_compare (operands, GTU);
5367}")
bc45ade3
SC
5368
5369(define_expand "bltu"
1245df60 5370 [(set (pc)
4773afa4
AO
5371 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5372 (label_ref (match_operand 0 "" ""))
5373 (pc)))]
bc45ade3 5374 ""
fa5322fa
AO
5375 "
5376{
5377 if (TARGET_SHMEDIA)
5378 {
c8cc4417
R
5379 if (sh_compare_op0 != const0_rtx)
5380 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5381 if (sh_compare_op1 != const0_rtx)
5382 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5383 emit_jump_insn (gen_bgtu_media (operands[0],
5384 sh_compare_op1, sh_compare_op0));
5385 DONE;
5386 }
5387
5388 from_compare (operands, GEU);
5389}")
bc45ade3
SC
5390
5391(define_expand "bgeu"
1245df60 5392 [(set (pc)
4773afa4 5393 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5394 (label_ref (match_operand 0 "" ""))
ffae286a 5395 (pc)))]
bc45ade3 5396 ""
fa5322fa
AO
5397 "
5398{
5399 if (TARGET_SHMEDIA)
5400 {
c8cc4417
R
5401 if (sh_compare_op0 != const0_rtx)
5402 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5403 if (sh_compare_op1 != const0_rtx)
5404 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5405 emit_jump_insn (gen_bgeu_media (operands[0],
5406 sh_compare_op0, sh_compare_op1));
5407 DONE;
5408 }
5409
5410 from_compare (operands, GEU);
5411}")
bc45ade3
SC
5412
5413(define_expand "bleu"
1245df60 5414 [(set (pc)
4773afa4 5415 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1245df60
R
5416 (label_ref (match_operand 0 "" ""))
5417 (pc)))]
bc45ade3 5418 ""
fa5322fa
AO
5419 "
5420{
5421 if (TARGET_SHMEDIA)
5422 {
c8cc4417
R
5423 if (sh_compare_op0 != const0_rtx)
5424 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5425 if (sh_compare_op1 != const0_rtx)
5426 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5427 emit_jump_insn (gen_bgeu_media (operands[0],
5428 sh_compare_op1, sh_compare_op0));
5429 DONE;
5430 }
5431
5432 from_compare (operands, GTU);
5433}")
5434
5435(define_expand "bunordered"
5436 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5437 (set (pc)
5438 (if_then_else (ne (match_dup 1) (const_int 0))
5439 (label_ref:DI (match_operand 0 "" ""))
5440 (pc)))]
5441 "TARGET_SHMEDIA"
5442 "
5443{
5444 operands[1] = gen_reg_rtx (DImode);
5445 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5446 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5447}")
bc45ade3
SC
5448\f
5449;; ------------------------------------------------------------------------
5450;; Jump and linkage insns
5451;; ------------------------------------------------------------------------
5452
fa5322fa 5453(define_insn "jump_compact"
bc45ade3
SC
5454 [(set (pc)
5455 (label_ref (match_operand 0 "" "")))]
fa5322fa 5456 "TARGET_SH1"
bc45ade3
SC
5457 "*
5458{
22e1ebf1 5459 /* The length is 16 if the delay slot is unfilled. */
1245df60 5460 if (get_attr_length(insn) > 4)
51aea58d 5461 return output_far_jump(insn, operands[0]);
bc45ade3 5462 else
51aea58d 5463 return \"bra %l0%#\";
bc45ade3
SC
5464}"
5465 [(set_attr "type" "jump")
5466 (set_attr "needs_delay_slot" "yes")])
5467
fa5322fa
AO
5468(define_insn "jump_media"
5469 [(set (pc)
5470 (match_operand:DI 0 "target_operand" "b"))]
5471 "TARGET_SHMEDIA"
2ad65b0e
SC
5472 "blink %0, r63"
5473 [(set_attr "type" "jump_media")])
fa5322fa
AO
5474
5475(define_expand "jump"
5476 [(set (pc)
5477 (label_ref (match_operand 0 "" "")))]
5478 ""
5479 "
5480{
5481 if (TARGET_SH1)
8e831557 5482 emit_jump_insn (gen_jump_compact (operands[0]));
fa5322fa
AO
5483 else if (TARGET_SHMEDIA)
5484 {
5485 if (reload_in_progress || reload_completed)
5486 FAIL;
8e831557
KK
5487 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5488 operands[0])));
fa5322fa
AO
5489 }
5490 DONE;
5491}")
5492
5493(define_insn "force_mode_for_call"
5494 [(use (reg:PSI FPSCR_REG))]
5495 "TARGET_SHCOMPACT"
5496 ""
5497 [(set_attr "length" "0")
5498 (set (attr "fp_mode")
5499 (if_then_else (eq_attr "fpu_single" "yes")
5500 (const_string "single") (const_string "double")))])
5501
bc45ade3 5502(define_insn "calli"
aa684c94 5503 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
bc45ade3 5504 (match_operand 1 "" ""))
5d00b10a 5505 (use (reg:PSI FPSCR_REG))
4773afa4 5506 (clobber (reg:SI PR_REG))]
fa5322fa 5507 "TARGET_SH1"
bc45ade3 5508 "jsr @%0%#"
ffae286a 5509 [(set_attr "type" "call")
d64264ff
R
5510 (set (attr "fp_mode")
5511 (if_then_else (eq_attr "fpu_single" "yes")
5512 (const_string "single") (const_string "double")))
ffae286a 5513 (set_attr "needs_delay_slot" "yes")])
961c4780 5514
1a66cd67
AO
5515;; This is a pc-rel call, using bsrf, for use with PIC.
5516
5517(define_insn "calli_pcrel"
5518 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5519 (match_operand 1 "" ""))
5d00b10a 5520 (use (reg:PSI FPSCR_REG))
2d01e445 5521 (use (reg:SI PIC_REG))
1a66cd67 5522 (use (match_operand 2 "" ""))
4773afa4 5523 (clobber (reg:SI PR_REG))]
eb69f95c 5524 "TARGET_SH2"
1a66cd67
AO
5525 "bsrf %0\\n%O2:%#"
5526 [(set_attr "type" "call")
5527 (set (attr "fp_mode")
5528 (if_then_else (eq_attr "fpu_single" "yes")
5529 (const_string "single") (const_string "double")))
5530 (set_attr "needs_delay_slot" "yes")])
5531
2d01e445
AO
5532(define_insn_and_split "call_pcrel"
5533 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5534 (match_operand 1 "" ""))
5535 (use (reg:PSI FPSCR_REG))
5536 (use (reg:SI PIC_REG))
5537 (clobber (reg:SI PR_REG))
5538 (clobber (match_scratch:SI 2 "=r"))]
cb51ecd2 5539 "TARGET_SH2"
2d01e445
AO
5540 "#"
5541 "reload_completed"
5542 [(const_int 0)]
5543 "
5544{
8e831557 5545 rtx lab = PATTERN (gen_call_site ());
2d01e445
AO
5546
5547 if (SYMBOL_REF_FLAG (operands[0]))
5548 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5549 else
5550 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5551 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5552 DONE;
5553}"
5554 [(set_attr "type" "call")
5555 (set (attr "fp_mode")
5556 (if_then_else (eq_attr "fpu_single" "yes")
5557 (const_string "single") (const_string "double")))
5558 (set_attr "needs_delay_slot" "yes")])
5559
fa5322fa
AO
5560(define_insn "call_compact"
5561 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5562 (match_operand 1 "" ""))
5563 (match_operand 2 "immediate_operand" "n")
5564 (use (reg:SI R0_REG))
5565 (use (reg:SI R1_REG))
5566 (use (reg:PSI FPSCR_REG))
5567 (clobber (reg:SI PR_REG))]
5568 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5569 "jsr @%0%#"
5570 [(set_attr "type" "call")
5571 (set (attr "fp_mode")
5572 (if_then_else (eq_attr "fpu_single" "yes")
5573 (const_string "single") (const_string "double")))
5574 (set_attr "needs_delay_slot" "yes")])
5575
5576(define_insn "call_compact_rettramp"
5577 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5578 (match_operand 1 "" ""))
5579 (match_operand 2 "immediate_operand" "n")
5580 (use (reg:SI R0_REG))
5581 (use (reg:SI R1_REG))
5582 (use (reg:PSI FPSCR_REG))
5583 (clobber (reg:SI R10_REG))
5584 (clobber (reg:SI PR_REG))]
5585 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5586 "jsr @%0%#"
5587 [(set_attr "type" "call")
5588 (set (attr "fp_mode")
5589 (if_then_else (eq_attr "fpu_single" "yes")
5590 (const_string "single") (const_string "double")))
5591 (set_attr "needs_delay_slot" "yes")])
5592
5593(define_insn "call_media"
5594 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5595 (match_operand 1 "" ""))
5596 (clobber (reg:DI PR_MEDIA_REG))]
5597 "TARGET_SHMEDIA"
2ad65b0e
SC
5598 "blink %0, r18"
5599 [(set_attr "type" "jump_media")])
fa5322fa 5600
bc45ade3
SC
5601(define_insn "call_valuei"
5602 [(set (match_operand 0 "" "=rf")
aa684c94 5603 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
bc45ade3 5604 (match_operand 2 "" "")))
5d00b10a 5605 (use (reg:PSI FPSCR_REG))
4773afa4 5606 (clobber (reg:SI PR_REG))]
fa5322fa 5607 "TARGET_SH1"
bc45ade3 5608 "jsr @%1%#"
ffae286a 5609 [(set_attr "type" "call")
d64264ff
R
5610 (set (attr "fp_mode")
5611 (if_then_else (eq_attr "fpu_single" "yes")
5612 (const_string "single") (const_string "double")))
ffae286a 5613 (set_attr "needs_delay_slot" "yes")])
bc45ade3 5614
1a66cd67
AO
5615(define_insn "call_valuei_pcrel"
5616 [(set (match_operand 0 "" "=rf")
5617 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5618 (match_operand 2 "" "")))
5d00b10a 5619 (use (reg:PSI FPSCR_REG))
2d01e445 5620 (use (reg:SI PIC_REG))
1a66cd67 5621 (use (match_operand 3 "" ""))
4773afa4 5622 (clobber (reg:SI PR_REG))]
eb69f95c 5623 "TARGET_SH2"
1a66cd67
AO
5624 "bsrf %1\\n%O3:%#"
5625 [(set_attr "type" "call")
5626 (set (attr "fp_mode")
5627 (if_then_else (eq_attr "fpu_single" "yes")
5628 (const_string "single") (const_string "double")))
5629 (set_attr "needs_delay_slot" "yes")])
5630
2d01e445
AO
5631(define_insn_and_split "call_value_pcrel"
5632 [(set (match_operand 0 "" "=rf")
5633 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5634 (match_operand 2 "" "")))
5635 (use (reg:PSI FPSCR_REG))
5636 (use (reg:SI PIC_REG))
5637 (clobber (reg:SI PR_REG))
5638 (clobber (match_scratch:SI 3 "=r"))]
cb51ecd2 5639 "TARGET_SH2"
2d01e445
AO
5640 "#"
5641 "reload_completed"
5642 [(const_int 0)]
5643 "
5644{
8e831557 5645 rtx lab = PATTERN (gen_call_site ());
2d01e445
AO
5646
5647 if (SYMBOL_REF_FLAG (operands[1]))
5648 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5649 else
5650 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5651 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5652 operands[2], lab));
5653 DONE;
5654}"
5655 [(set_attr "type" "call")
5656 (set (attr "fp_mode")
5657 (if_then_else (eq_attr "fpu_single" "yes")
5658 (const_string "single") (const_string "double")))
5659 (set_attr "needs_delay_slot" "yes")])
5660
fa5322fa
AO
5661(define_insn "call_value_compact"
5662 [(set (match_operand 0 "" "=rf")
5663 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5664 (match_operand 2 "" "")))
5665 (match_operand 3 "immediate_operand" "n")
5666 (use (reg:SI R0_REG))
5667 (use (reg:SI R1_REG))
5668 (use (reg:PSI FPSCR_REG))
5669 (clobber (reg:SI PR_REG))]
5670 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5671 "jsr @%1%#"
5672 [(set_attr "type" "call")
5673 (set (attr "fp_mode")
5674 (if_then_else (eq_attr "fpu_single" "yes")
5675 (const_string "single") (const_string "double")))
5676 (set_attr "needs_delay_slot" "yes")])
5677
5678(define_insn "call_value_compact_rettramp"
5679 [(set (match_operand 0 "" "=rf")
5680 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5681 (match_operand 2 "" "")))
5682 (match_operand 3 "immediate_operand" "n")
5683 (use (reg:SI R0_REG))
5684 (use (reg:SI R1_REG))
5685 (use (reg:PSI FPSCR_REG))
5686 (clobber (reg:SI R10_REG))
5687 (clobber (reg:SI PR_REG))]
5688 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5689 "jsr @%1%#"
5690 [(set_attr "type" "call")
5691 (set (attr "fp_mode")
5692 (if_then_else (eq_attr "fpu_single" "yes")
5693 (const_string "single") (const_string "double")))
5694 (set_attr "needs_delay_slot" "yes")])
5695
5696(define_insn "call_value_media"
5697 [(set (match_operand 0 "" "=rf")
5698 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5699 (match_operand 2 "" "")))
5700 (clobber (reg:DI PR_MEDIA_REG))]
5701 "TARGET_SHMEDIA"
2ad65b0e
SC
5702 "blink %1, r18"
5703 [(set_attr "type" "jump_media")])
fa5322fa 5704
bc45ade3 5705(define_expand "call"
51aea58d
JW
5706 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5707 (match_operand 1 "" ""))
fa5322fa 5708 (match_operand 2 "" "")
5d00b10a 5709 (use (reg:PSI FPSCR_REG))
4773afa4 5710 (clobber (reg:SI PR_REG))])]
bc45ade3 5711 ""
1a66cd67 5712 "
827bdee4 5713{
fa5322fa
AO
5714 if (TARGET_SHMEDIA)
5715 {
5716 operands[0] = XEXP (operands[0], 0);
5717 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5718 {
5719 if (! SYMBOL_REF_FLAG (operands[0]))
5720 {
5721 rtx reg = gen_reg_rtx (Pmode);
52702ae1 5722
fa5322fa
AO
5723 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5724 operands[0] = reg;
5725 }
5726 else
5727 {
5728 operands[0] = gen_sym2PIC (operands[0]);
5729 PUT_MODE (operands[0], Pmode);
5730 }
5731 }
5732 if (GET_MODE (operands[0]) == SImode)
5733 {
5734 if (GET_CODE (operands[0]) == REG)
5735 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5736 else if (GET_CODE (operands[0]) == SUBREG)
5737 {
5738 operands[0] = SUBREG_REG (operands[0]);
5739 if (GET_MODE (operands[0]) != DImode)
5740 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5741 }
5742 else
5743 {
5744 operands[0] = shallow_copy_rtx (operands[0]);
5745 PUT_MODE (operands[0], DImode);
5746 }
5747 }
5748 if (! target_reg_operand (operands[0], DImode))
5749 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5750 emit_call_insn (gen_call_media (operands[0], operands[1]));
5751 DONE;
5752 }
5753 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5754 {
5755 rtx cookie_rtx = operands[2];
5756 long cookie = INTVAL (cookie_rtx);
5757 rtx func = XEXP (operands[0], 0);
5758 rtx r0, r1;
5759
5760 if (flag_pic)
5761 {
5762 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5763 {
5764 rtx reg = gen_reg_rtx (Pmode);
5765
5766 emit_insn (gen_symGOTPLT2reg (reg, func));
5767 func = reg;
5768 }
5769 else
5770 func = legitimize_pic_address (func, Pmode, 0);
5771 }
5772
5773 r0 = gen_rtx_REG (SImode, R0_REG);
5774 r1 = gen_rtx_REG (SImode, R1_REG);
5775
5776 /* Since such a call function may use all call-clobbered
5777 registers, we force a mode switch earlier, so that we don't
5778 run out of registers when adjusting fpscr for the call. */
5779 emit_insn (gen_force_mode_for_call ());
5780
5781 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5782 \"__GCC_shcompact_call_trampoline\");
5783 if (flag_pic)
5784 {
5785 rtx reg = gen_reg_rtx (Pmode);
5786
5787 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5788 operands[0] = reg;
5789 }
5790 operands[0] = force_reg (SImode, operands[0]);
5791
5792 emit_move_insn (r0, func);
5793 emit_move_insn (r1, cookie_rtx);
5794
5795 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5796 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5797 operands[2]));
5798 else
5799 emit_call_insn (gen_call_compact (operands[0], operands[1],
5800 operands[2]));
5801
5802 DONE;
5803 }
5804 else if (TARGET_SHCOMPACT && flag_pic
5805 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5806 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5807 {
5808 rtx reg = gen_reg_rtx (Pmode);
5809
5810 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5811 XEXP (operands[0], 0) = reg;
5812 }
cb51ecd2 5813 if (flag_pic && TARGET_SH2
827bdee4
AO
5814 && GET_CODE (operands[0]) == MEM
5815 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5816 {
2d01e445 5817 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
827bdee4
AO
5818 DONE;
5819 }
5820 else
5821 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
fa5322fa
AO
5822
5823 emit_call_insn (gen_calli (operands[0], operands[1]));
5824 DONE;
5825}")
5826
5827(define_insn "call_pop_compact"
5828 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5829 (match_operand 1 "" ""))
5830 (match_operand 2 "immediate_operand" "n")
5831 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5832 (match_operand 3 "immediate_operand" "n")))
5833 (use (reg:SI R0_REG))
5834 (use (reg:SI R1_REG))
5835 (use (reg:PSI FPSCR_REG))
5836 (clobber (reg:SI PR_REG))]
5837 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5838 "jsr @%0%#"
5839 [(set_attr "type" "call")
5840 (set (attr "fp_mode")
5841 (if_then_else (eq_attr "fpu_single" "yes")
5842 (const_string "single") (const_string "double")))
5843 (set_attr "needs_delay_slot" "yes")])
5844
5845(define_insn "call_pop_compact_rettramp"
5846 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5847 (match_operand 1 "" ""))
5848 (match_operand 2 "immediate_operand" "n")
5849 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5850 (match_operand 3 "immediate_operand" "n")))
5851 (use (reg:SI R0_REG))
5852 (use (reg:SI R1_REG))
5853 (use (reg:PSI FPSCR_REG))
5854 (clobber (reg:SI R10_REG))
5855 (clobber (reg:SI PR_REG))]
5856 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5857 "jsr @%0%#"
5858 [(set_attr "type" "call")
5859 (set (attr "fp_mode")
5860 (if_then_else (eq_attr "fpu_single" "yes")
5861 (const_string "single") (const_string "double")))
5862 (set_attr "needs_delay_slot" "yes")])
5863
5864(define_expand "call_pop"
5865 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5866 (match_operand 1 "" ""))
5867 (match_operand 2 "" "")
5868 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5869 (match_operand 3 "" "")))])]
5870 "TARGET_SHCOMPACT"
5871 "
5872{
5873 if (operands[2] && INTVAL (operands[2]))
5874 {
5875 rtx cookie_rtx = operands[2];
5876 long cookie = INTVAL (cookie_rtx);
5877 rtx func = XEXP (operands[0], 0);
5878 rtx r0, r1;
5879
5880 if (flag_pic)
5881 {
5882 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5883 {
5884 rtx reg = gen_reg_rtx (Pmode);
5885
5886 emit_insn (gen_symGOTPLT2reg (reg, func));
5887 func = reg;
5888 }
5889 else
5890 func = legitimize_pic_address (func, Pmode, 0);
5891 }
5892
5893 r0 = gen_rtx_REG (SImode, R0_REG);
5894 r1 = gen_rtx_REG (SImode, R1_REG);
5895
5896 /* Since such a call function may use all call-clobbered
5897 registers, we force a mode switch earlier, so that we don't
5898 run out of registers when adjusting fpscr for the call. */
5899 emit_insn (gen_force_mode_for_call ());
5900
5901 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5902 \"__GCC_shcompact_call_trampoline\");
5903 if (flag_pic)
5904 {
5905 rtx reg = gen_reg_rtx (Pmode);
5906
5907 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5908 operands[0] = reg;
5909 }
5910 operands[0] = force_reg (SImode, operands[0]);
5911
5912 emit_move_insn (r0, func);
5913 emit_move_insn (r1, cookie_rtx);
5914
5915 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5916 emit_call_insn (gen_call_pop_compact_rettramp
5917 (operands[0], operands[1], operands[2], operands[3]));
5918 else
5919 emit_call_insn (gen_call_pop_compact
5920 (operands[0], operands[1], operands[2], operands[3]));
5921
5922 DONE;
5923 }
5924
5925 abort ();
827bdee4 5926}")
bc45ade3
SC
5927
5928(define_expand "call_value"
51aea58d
JW
5929 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5930 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5931 (match_operand 2 "" "")))
fa5322fa 5932 (match_operand 3 "" "")
5d00b10a 5933 (use (reg:PSI FPSCR_REG))
4773afa4 5934 (clobber (reg:SI PR_REG))])]
bc45ade3 5935 ""
1a66cd67 5936 "
827bdee4 5937{
fa5322fa
AO
5938 if (TARGET_SHMEDIA)
5939 {
5940 operands[1] = XEXP (operands[1], 0);
5941 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5942 {
5943 if (! SYMBOL_REF_FLAG (operands[1]))
5944 {
5945 rtx reg = gen_reg_rtx (Pmode);
52702ae1 5946
fa5322fa
AO
5947 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5948 operands[1] = reg;
5949 }
5950 else
5951 {
5952 operands[1] = gen_sym2PIC (operands[1]);
5953 PUT_MODE (operands[1], Pmode);
5954 }
5955 }
5956 if (GET_MODE (operands[1]) == SImode)
5957 {
5958 if (GET_CODE (operands[1]) == REG)
5959 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5960 else if (GET_CODE (operands[1]) == SUBREG)
5961 {
5962 operands[1] = SUBREG_REG (operands[1]);
5963 if (GET_MODE (operands[1]) != DImode)
5964 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5965 }
5966 else
5967 {
5968 operands[1] = shallow_copy_rtx (operands[1]);
5969 PUT_MODE (operands[1], DImode);
5970 }
5971 }
5972 if (! target_reg_operand (operands[1], DImode))
5973 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5974 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5975 operands[2]));
5976 DONE;
5977 }
5978 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5979 {
5980 rtx cookie_rtx = operands[3];
5981 long cookie = INTVAL (cookie_rtx);
5982 rtx func = XEXP (operands[1], 0);
5983 rtx r0, r1;
5984
5985 if (flag_pic)
5986 {
5987 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5988 {
5989 rtx reg = gen_reg_rtx (Pmode);
5990
5991 emit_insn (gen_symGOTPLT2reg (reg, func));
5992 func = reg;
5993 }
5994 else
5995 func = legitimize_pic_address (func, Pmode, 0);
5996 }
5997
5998 r0 = gen_rtx_REG (SImode, R0_REG);
5999 r1 = gen_rtx_REG (SImode, R1_REG);
6000
6001 /* Since such a call function may use all call-clobbered
6002 registers, we force a mode switch earlier, so that we don't
6003 run out of registers when adjusting fpscr for the call. */
6004 emit_insn (gen_force_mode_for_call ());
6005
6006 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6007 \"__GCC_shcompact_call_trampoline\");
6008 if (flag_pic)
6009 {
6010 rtx reg = gen_reg_rtx (Pmode);
6011
6012 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6013 operands[1] = reg;
6014 }
6015 operands[1] = force_reg (SImode, operands[1]);
6016
6017 emit_move_insn (r0, func);
6018 emit_move_insn (r1, cookie_rtx);
6019
6020 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6021 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6022 operands[1],
6023 operands[2],
6024 operands[3]));
6025 else
6026 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6027 operands[2], operands[3]));
6028
6029 DONE;
6030 }
6031 else if (TARGET_SHCOMPACT && flag_pic
6032 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6033 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6034 {
6035 rtx reg = gen_reg_rtx (Pmode);
6036
6037 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6038 XEXP (operands[1], 0) = reg;
6039 }
cb51ecd2 6040 if (flag_pic && TARGET_SH2
827bdee4
AO
6041 && GET_CODE (operands[1]) == MEM
6042 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6043 {
2d01e445
AO
6044 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6045 operands[2]));
827bdee4
AO
6046 DONE;
6047 }
6048 else
6049 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
fa5322fa
AO
6050
6051 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6052 DONE;
827bdee4 6053}")
bc45ade3 6054
5db5a888 6055(define_insn "sibcalli"
cb51ecd2 6056 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5db5a888
AO
6057 (match_operand 1 "" ""))
6058 (use (reg:PSI FPSCR_REG))
6059 (return)]
fa5322fa 6060 "TARGET_SH1"
5db5a888
AO
6061 "jmp @%0%#"
6062 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6063 (set (attr "fp_mode")
6064 (if_then_else (eq_attr "fpu_single" "yes")
6065 (const_string "single") (const_string "double")))
5db5a888
AO
6066 (set_attr "type" "jump_ind")])
6067
6068(define_insn "sibcalli_pcrel"
cb51ecd2 6069 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5db5a888
AO
6070 (match_operand 1 "" ""))
6071 (use (match_operand 2 "" ""))
6072 (use (reg:PSI FPSCR_REG))
6073 (return)]
6074 "TARGET_SH2"
6075 "braf %0\\n%O2:%#"
6076 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6077 (set (attr "fp_mode")
6078 (if_then_else (eq_attr "fpu_single" "yes")
6079 (const_string "single") (const_string "double")))
5db5a888
AO
6080 (set_attr "type" "jump_ind")])
6081
6082(define_insn_and_split "sibcall_pcrel"
6083 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6084 (match_operand 1 "" ""))
6085 (use (reg:PSI FPSCR_REG))
cb51ecd2 6086 (clobber (match_scratch:SI 2 "=k"))
5db5a888 6087 (return)]
cb51ecd2 6088 "TARGET_SH2"
5db5a888
AO
6089 "#"
6090 "reload_completed"
6091 [(const_int 0)]
6092 "
6093{
8e831557 6094 rtx lab = PATTERN (gen_call_site ());
5db5a888
AO
6095 rtx call_insn;
6096
fa5322fa
AO
6097 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6098 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6099 lab));
6100 SIBLING_CALL_P (call_insn) = 1;
6101 DONE;
6102}"
6103 [(set_attr "needs_delay_slot" "yes")
6104 (set (attr "fp_mode")
6105 (if_then_else (eq_attr "fpu_single" "yes")
6106 (const_string "single") (const_string "double")))
6107 (set_attr "type" "jump_ind")])
6108
6109(define_insn "sibcall_compact"
6110 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6111 (match_operand 1 "" ""))
6112 (return)
e69d1422 6113 (use (match_operand:SI 2 "register_operand" "z,x"))
fa5322fa
AO
6114 (use (reg:SI R1_REG))
6115 (use (reg:PSI FPSCR_REG))
6116 ;; We want to make sure the `x' above will only match MACH_REG
6117 ;; because sibcall_epilogue may clobber MACL_REG.
6118 (clobber (reg:SI MACL_REG))]
6119 "TARGET_SHCOMPACT"
6120 "@
6121 jmp @%0%#
6122 jmp @%0\\n sts %2, r0"
6123 [(set_attr "needs_delay_slot" "yes,no")
6124 (set_attr "length" "2,4")
6125 (set (attr "fp_mode") (const_string "single"))
6126 (set_attr "type" "jump_ind")])
6127
6128(define_insn "sibcall_media"
6129 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6130 (match_operand 1 "" ""))
6131 (return)]
6132 "TARGET_SHMEDIA"
2ad65b0e
SC
6133 "blink %0, r63"
6134 [(set_attr "type" "jump_media")])
fa5322fa
AO
6135
6136(define_expand "sibcall"
6137 [(parallel
6138 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6139 (match_operand 1 "" ""))
6140 (match_operand 2 "" "")
6141 (use (reg:PSI FPSCR_REG))
6142 (return)])]
6143 ""
6144 "
6145{
6146 if (TARGET_SHMEDIA)
6147 {
6148 operands[0] = XEXP (operands[0], 0);
6149 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6150 {
6151 if (! SYMBOL_REF_FLAG (operands[0]))
6152 {
6153 rtx reg = gen_reg_rtx (Pmode);
52702ae1 6154
fa5322fa
AO
6155 /* We must not use GOTPLT for sibcalls, because PIC_REG
6156 must be restored before the PLT code gets to run. */
6157 emit_insn (gen_symGOT2reg (reg, operands[0]));
6158 operands[0] = reg;
6159 }
6160 else
6161 {
6162 operands[0] = gen_sym2PIC (operands[0]);
6163 PUT_MODE (operands[0], Pmode);
6164 }
6165 }
6166 if (GET_MODE (operands[0]) == SImode)
6167 {
6168 if (GET_CODE (operands[0]) == REG)
6169 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6170 else if (GET_CODE (operands[0]) == SUBREG)
6171 {
6172 operands[0] = SUBREG_REG (operands[0]);
6173 if (GET_MODE (operands[0]) != DImode)
6174 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6175 }
6176 else
6177 {
6178 operands[0] = shallow_copy_rtx (operands[0]);
6179 PUT_MODE (operands[0], DImode);
6180 }
6181 }
6182 if (! target_reg_operand (operands[0], DImode))
6183 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6184 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6185 DONE;
6186 }
6187 else if (TARGET_SHCOMPACT && operands[2]
6188 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6189 {
6190 rtx cookie_rtx = operands[2];
6191 long cookie = INTVAL (cookie_rtx);
6192 rtx func = XEXP (operands[0], 0);
6193 rtx mach, r1;
6194
6195 if (flag_pic)
6196 {
6197 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6198 {
6199 rtx reg = gen_reg_rtx (Pmode);
6200
6201 emit_insn (gen_symGOT2reg (reg, func));
6202 func = reg;
6203 }
6204 else
6205 func = legitimize_pic_address (func, Pmode, 0);
6206 }
5db5a888 6207
fa5322fa
AO
6208 /* FIXME: if we could tell whether all argument registers are
6209 already taken, we could decide whether to force the use of
6210 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6211 simple way to tell. We could use the CALL_COOKIE, but we
6212 can't currently tell a register used for regular argument
6213 passing from one that is unused. If we leave it up to reload
6214 to decide which register to use, it seems to always choose
6215 R0_REG, which leaves no available registers in SIBCALL_REGS
6216 to hold the address of the trampoline. */
6217 mach = gen_rtx_REG (SImode, MACH_REG);
6218 r1 = gen_rtx_REG (SImode, R1_REG);
6219
6220 /* Since such a call function may use all call-clobbered
6221 registers, we force a mode switch earlier, so that we don't
6222 run out of registers when adjusting fpscr for the call. */
6223 emit_insn (gen_force_mode_for_call ());
6224
6225 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6226 \"__GCC_shcompact_call_trampoline\");
6227 if (flag_pic)
6228 {
6229 rtx reg = gen_reg_rtx (Pmode);
6230
6231 emit_insn (gen_symGOT2reg (reg, operands[0]));
6232 operands[0] = reg;
6233 }
6234 operands[0] = force_reg (SImode, operands[0]);
6235
6236 /* We don't need a return trampoline, since the callee will
6237 return directly to the upper caller. */
6238 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6239 {
6240 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6241 cookie_rtx = GEN_INT (cookie);
6242 }
6243
6244 emit_move_insn (mach, func);
6245 emit_move_insn (r1, cookie_rtx);
6246
6247 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6248 DONE;
6249 }
6250 else if (TARGET_SHCOMPACT && flag_pic
6251 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6252 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6253 {
6254 rtx reg = gen_reg_rtx (Pmode);
6255
6256 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6257 XEXP (operands[0], 0) = reg;
6258 }
cb51ecd2 6259 if (flag_pic && TARGET_SH2
5db5a888
AO
6260 && GET_CODE (operands[0]) == MEM
6261 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6262 /* The PLT needs the PIC register, but the epilogue would have
6263 to restore it, so we can only use PC-relative PIC calls for
6264 static functions. */
6265 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6266 {
6267 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6268 DONE;
6269 }
6270 else
6271 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
fa5322fa
AO
6272
6273 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6274 DONE;
5db5a888
AO
6275}")
6276
6277(define_expand "sibcall_value"
6278 [(set (match_operand 0 "" "")
6279 (call (match_operand 1 "" "")
fa5322fa
AO
6280 (match_operand 2 "" "")))
6281 (match_operand 3 "" "")]
5db5a888
AO
6282 ""
6283 "
6284{
fa5322fa 6285 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5db5a888
AO
6286 DONE;
6287}")
6288
fa5322fa
AO
6289(define_insn "call_value_pop_compact"
6290 [(set (match_operand 0 "" "=rf")
6291 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6292 (match_operand 2 "" "")))
6293 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6294 (match_operand 4 "immediate_operand" "n")))
6295 (match_operand 3 "immediate_operand" "n")
6296 (use (reg:SI R0_REG))
6297 (use (reg:SI R1_REG))
6298 (use (reg:PSI FPSCR_REG))
6299 (clobber (reg:SI PR_REG))]
6300 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6301 "jsr @%1%#"
6302 [(set_attr "type" "call")
6303 (set (attr "fp_mode")
6304 (if_then_else (eq_attr "fpu_single" "yes")
6305 (const_string "single") (const_string "double")))
6306 (set_attr "needs_delay_slot" "yes")])
6307
6308(define_insn "call_value_pop_compact_rettramp"
6309 [(set (match_operand 0 "" "=rf")
6310 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6311 (match_operand 2 "" "")))
6312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6313 (match_operand 4 "immediate_operand" "n")))
6314 (match_operand 3 "immediate_operand" "n")
6315 (use (reg:SI R0_REG))
6316 (use (reg:SI R1_REG))
6317 (use (reg:PSI FPSCR_REG))
6318 (clobber (reg:SI R10_REG))
6319 (clobber (reg:SI PR_REG))]
6320 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6321 "jsr @%1%#"
6322 [(set_attr "type" "call")
6323 (set (attr "fp_mode")
6324 (if_then_else (eq_attr "fpu_single" "yes")
6325 (const_string "single") (const_string "double")))
6326 (set_attr "needs_delay_slot" "yes")])
6327
6328(define_expand "call_value_pop"
6329 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6330 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6331 (match_operand 2 "" "")))
6332 (match_operand 3 "" "")
6333 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6334 (match_operand 4 "" "")))])]
6335 "TARGET_SHCOMPACT"
6336 "
6337{
6338 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6339 {
6340 rtx cookie_rtx = operands[3];
6341 long cookie = INTVAL (cookie_rtx);
6342 rtx func = XEXP (operands[1], 0);
6343 rtx r0, r1;
6344
6345 if (flag_pic)
6346 {
6347 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6348 {
6349 rtx reg = gen_reg_rtx (Pmode);
6350
6351 emit_insn (gen_symGOTPLT2reg (reg, func));
6352 func = reg;
6353 }
6354 else
6355 func = legitimize_pic_address (func, Pmode, 0);
6356 }
6357
6358 r0 = gen_rtx_REG (SImode, R0_REG);
6359 r1 = gen_rtx_REG (SImode, R1_REG);
6360
6361 /* Since such a call function may use all call-clobbered
6362 registers, we force a mode switch earlier, so that we don't
6363 run out of registers when adjusting fpscr for the call. */
6364 emit_insn (gen_force_mode_for_call ());
6365
6366 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6367 \"__GCC_shcompact_call_trampoline\");
6368 if (flag_pic)
6369 {
6370 rtx reg = gen_reg_rtx (Pmode);
6371
6372 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6373 operands[1] = reg;
6374 }
6375 operands[1] = force_reg (SImode, operands[1]);
6376
6377 emit_move_insn (r0, func);
6378 emit_move_insn (r1, cookie_rtx);
6379
6380 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6381 emit_call_insn (gen_call_value_pop_compact_rettramp
6382 (operands[0], operands[1], operands[2],
6383 operands[3], operands[4]));
6384 else
6385 emit_call_insn (gen_call_value_pop_compact
6386 (operands[0], operands[1], operands[2],
6387 operands[3], operands[4]));
6388
6389 DONE;
6390 }
6391
6392 abort ();
6393}")
6394
5db5a888
AO
6395(define_expand "sibcall_epilogue"
6396 [(return)]
6397 ""
6398 "
6399{
6400 sh_expand_epilogue ();
fa5322fa
AO
6401 if (TARGET_SHCOMPACT)
6402 {
6403 rtx insn, set;
6404
6405 /* If epilogue clobbers r0, preserve it in macl. */
6406 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6407 if ((set = single_set (insn))
6408 && GET_CODE (SET_DEST (set)) == REG
6409 && REGNO (SET_DEST (set)) == R0_REG)
6410 {
6411 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6412 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6413 rtx i;
6414
6415 /* We can't tell at this point whether the sibcall is a
6416 sibcall_compact and, if it is, whether it uses r0 or
6417 mach as operand 2, so let the instructions that
6418 preserve r0 be optimized away if r0 turns out to be
6419 dead. */
6420 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6421 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6422 REG_NOTES (i));
6423 i = emit_move_insn (r0, tmp);
6424 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6425 REG_NOTES (i));
6426 break;
6427 }
6428 }
5db5a888
AO
6429 DONE;
6430}")
6431
fa5322fa 6432(define_insn "indirect_jump_compact"
bc45ade3 6433 [(set (pc)
aa684c94 6434 (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 6435 "TARGET_SH1"
b9654711 6436 "jmp @%0%#"
1245df60
R
6437 [(set_attr "needs_delay_slot" "yes")
6438 (set_attr "type" "jump_ind")])
a1a0806a 6439
fa5322fa
AO
6440(define_expand "indirect_jump"
6441 [(set (pc)
6442 (match_operand 0 "register_operand" ""))]
6443 ""
6444 "
6445{
6446 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6448}")
6449
1245df60 6450;; The use of operand 1 / 2 helps us distinguish case table jumps
f1ffca1c
JW
6451;; which can be present in structured code from indirect jumps which can not
6452;; be present in structured code. This allows -fprofile-arcs to work.
6453
1245df60
R
6454;; For SH1 processors.
6455(define_insn "casesi_jump_1"
f1ffca1c 6456 [(set (pc)
1245df60 6457 (match_operand:SI 0 "register_operand" "r"))
f1ffca1c 6458 (use (label_ref (match_operand 1 "" "")))]
fa5322fa 6459 "TARGET_SH1"
1245df60
R
6460 "jmp @%0%#"
6461 [(set_attr "needs_delay_slot" "yes")
6462 (set_attr "type" "jump_ind")])
6463
6464;; For all later processors.
6465(define_insn "casesi_jump_2"
6466 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
eb3881bf 6467 (label_ref (match_operand 1 "" ""))))
1245df60 6468 (use (label_ref (match_operand 2 "" "")))]
e6dfd05f
AO
6469 "TARGET_SH2
6470 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
1245df60
R
6471 "braf %0%#"
6472 [(set_attr "needs_delay_slot" "yes")
6473 (set_attr "type" "jump_ind")])
6474
fa5322fa
AO
6475(define_insn "casesi_jump_media"
6476 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6477 (use (label_ref (match_operand 1 "" "")))]
6478 "TARGET_SHMEDIA"
2ad65b0e
SC
6479 "blink %0, r63"
6480 [(set_attr "type" "jump_media")])
52702ae1 6481
a1a0806a
JW
6482;; Call subroutine returning any type.
6483;; ??? This probably doesn't work.
6484
6485(define_expand "untyped_call"
6486 [(parallel [(call (match_operand 0 "" "")
6487 (const_int 0))
6488 (match_operand 1 "" "")
6489 (match_operand 2 "" "")])]
fa5322fa 6490 "TARGET_SH3E || TARGET_SHMEDIA"
a1a0806a
JW
6491 "
6492{
6493 int i;
6494
fa5322fa 6495 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
a1a0806a
JW
6496
6497 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6498 {
6499 rtx set = XVECEXP (operands[2], 0, i);
6500 emit_move_insn (SET_DEST (set), SET_SRC (set));
6501 }
6502
6503 /* The optimizer does not know that the call sets the function value
6504 registers we stored in the result block. We avoid problems by
6505 claiming that all hard registers are used and clobbered at this
6506 point. */
6507 emit_insn (gen_blockage ());
6508
6509 DONE;
6510}")
bc45ade3
SC
6511\f
6512;; ------------------------------------------------------------------------
6513;; Misc insns
6514;; ------------------------------------------------------------------------
6515
51bd623f 6516(define_insn "dect"
4773afa4 6517 [(set (reg:SI T_REG)
aff48e32
JR
6518 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6519 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
51bd623f 6520 "TARGET_SH2"
1245df60
R
6521 "dt %0"
6522 [(set_attr "type" "arith")])
bc45ade3
SC
6523
6524(define_insn "nop"
6525 [(const_int 0)]
6526 ""
51bd623f 6527 "nop")
0d7e008e 6528
1245df60
R
6529;; Load address of a label. This is only generated by the casesi expand,
6530;; and by machine_dependent_reorg (fixing up fp moves).
6531;; This must use unspec, because this only works for labels that are
6532;; within range,
0d7e008e
SC
6533
6534(define_insn "mova"
4773afa4 6535 [(set (reg:SI R0_REG)
e69d1422 6536 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
fa5322fa 6537 "TARGET_SH1"
0d7e008e 6538 "mova %O0,r0"
1245df60
R
6539 [(set_attr "in_delay_slot" "no")
6540 (set_attr "type" "arith")])
0d7e008e 6541
43c05634
AO
6542;; machine_dependent_reorg() will make this a `mova'.
6543(define_insn "mova_const"
6544 [(set (reg:SI R0_REG)
e69d1422 6545 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
fa5322fa 6546 "TARGET_SH1"
43c05634
AO
6547 "#"
6548 [(set_attr "in_delay_slot" "no")
6549 (set_attr "type" "arith")])
6550
1a66cd67 6551(define_expand "GOTaddr2picreg"
4773afa4 6552 [(set (reg:SI R0_REG)
e69d1422
R
6553 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6554 UNSPEC_MOVA))
615cd49b 6555 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
4773afa4 6556 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
1a66cd67
AO
6557 "" "
6558{
fa5322fa 6559 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
1a66cd67 6560 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
fa5322fa
AO
6561
6562 if (TARGET_SH5)
6563 operands[1] = gen_datalabel_ref (operands[1]);
6564
6565 if (TARGET_SHMEDIA)
6566 {
6567 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6568 rtx dipic = operands[0];
8e831557 6569 rtx lab = PATTERN (gen_call_site ());
fa5322fa
AO
6570 rtx insn, equiv;
6571
6572 equiv = operands[1];
6573 operands[1] = gen_rtx_MINUS (DImode,
6574 operands[1],
6575 gen_rtx_CONST
6576 (DImode,
6577 gen_rtx_MINUS (DImode,
6578 gen_rtx_CONST (DImode,
6579 lab),
6580 pc_rtx)));
6581 operands[1] = gen_sym2PIC (operands[1]);
6582 PUT_MODE (operands[1], DImode);
6583
6584 if (GET_MODE (dipic) != DImode)
6585 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6586
6587 if (TARGET_SHMEDIA64)
6588 emit_insn (gen_movdi_const (dipic, operands[1]));
6589 else
6590 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6591
6592 emit_insn (gen_ptrel (tr, dipic, lab));
6593
6594 if (GET_MODE (operands[0]) != GET_MODE (tr))
6595 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6596
6597 insn = emit_move_insn (operands[0], tr);
52702ae1 6598
fa5322fa
AO
6599 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6600 REG_NOTES (insn));
6601
6602 DONE;
6603 }
1a66cd67
AO
6604}
6605")
6606
fa5322fa
AO
6607;; When generating PIC, we must match label_refs especially, because
6608;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6609;; them to do, because they can't be loaded directly into
6610;; non-branch-target registers.
6611(define_insn "*pt"
b6d33983 6612 [(set (match_operand:DI 0 "target_reg_operand" "=b")
fa5322fa
AO
6613 (match_operand:DI 1 "" "T"))]
6614 "TARGET_SHMEDIA && flag_pic
6615 && EXTRA_CONSTRAINT_T (operands[1])"
6616 "pt %1, %0"
2ad65b0e 6617 [(set_attr "type" "pt_media")
fa5322fa
AO
6618 (set_attr "length" "*")])
6619
6620(define_insn "*ptb"
b6d33983 6621 [(set (match_operand:DI 0 "target_reg_operand" "=b")
fa5322fa
AO
6622 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6623 UNSPEC_DATALABEL)))]
6624 "TARGET_SHMEDIA && flag_pic
6625 && EXTRA_CONSTRAINT_T (operands[1])"
6626 "ptb/u datalabel %1, %0"
2ad65b0e 6627 [(set_attr "type" "pt_media")
fa5322fa
AO
6628 (set_attr "length" "*")])
6629
6630(define_insn "ptrel"
e69d1422
R
6631 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6632 (plus:DI (match_operand:DI 1 "register_operand" "r")
fa5322fa
AO
6633 (pc)))
6634 (match_operand:DI 2 "" "")]
6635 "TARGET_SHMEDIA"
6636 "%O2: ptrel/u %1, %0"
2ad65b0e 6637 [(set_attr "type" "ptabs_media")])
fa5322fa 6638
001643af
KK
6639(define_expand "builtin_setjmp_receiver"
6640 [(match_operand 0 "" "")]
6641 "flag_pic"
6642 "
6643{
6644 emit_insn (gen_GOTaddr2picreg ());
6645 DONE;
6646}")
6647
2d01e445
AO
6648(define_expand "call_site"
6649 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
fa5322fa 6650 "TARGET_SH1"
2d01e445
AO
6651 "
6652{
6653 static HOST_WIDE_INT i = 0;
6654 operands[0] = GEN_INT (i);
6655 i++;
6656}")
6657
1a66cd67
AO
6658(define_expand "sym_label2reg"
6659 [(set (match_operand:SI 0 "" "")
a4f76ef9
AO
6660 (const:SI (minus:SI
6661 (const:SI
6662 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6663 (const:SI
6664 (plus:SI
6665 (match_operand:SI 2 "" "")
6666 (const_int 2))))))]
fa5322fa 6667 "TARGET_SH1" "")
1a66cd67 6668
e1d71275
AO
6669(define_expand "symGOT_load"
6670 [(set (match_dup 2) (match_operand 1 "" ""))
6671 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6672 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6673 ""
6674 "
6675{
6676 rtx insn;
6677
6678 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6679 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6680
fa5322fa
AO
6681 if (TARGET_SHMEDIA)
6682 {
6683 rtx reg = operands[2];
52702ae1 6684
fa5322fa
AO
6685 if (GET_MODE (reg) != DImode)
6686 reg = gen_rtx_SUBREG (DImode, reg, 0);
52702ae1 6687
fa5322fa
AO
6688 if (flag_pic > 1)
6689 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6690 else
6691 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6692 }
6693 else
6694 emit_move_insn (operands[2], operands[1]);
e1d71275
AO
6695
6696 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6697 operands[2],
6698 gen_rtx_REG (Pmode, PIC_REG)));
6699
6700 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6701
6702 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6703 0), 0, 0),
6704 REG_NOTES (insn));
52702ae1 6705
e1d71275
AO
6706 DONE;
6707}")
6708
6709(define_expand "sym2GOT"
6710 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6711 ""
6712 "")
6713
1a66cd67 6714(define_expand "symGOT2reg"
e1d71275 6715 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6716 ""
6717 "
6718{
e1d71275
AO
6719 rtx gotsym, insn;
6720
6721 gotsym = gen_sym2GOT (operands[1]);
6722 PUT_MODE (gotsym, Pmode);
6723 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6724
6725 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6726
6727 DONE;
1a66cd67
AO
6728}")
6729
fa5322fa
AO
6730(define_expand "sym2GOTPLT"
6731 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6732 ""
6733 "")
6734
6735(define_expand "symGOTPLT2reg"
6736 [(match_operand 0 "" "") (match_operand 1 "" "")]
6737 ""
6738 "
6739{
6740 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6741 DONE;
6742}")
6743
e1d71275
AO
6744(define_expand "sym2GOTOFF"
6745 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6746 ""
6747 "")
6748
1a66cd67 6749(define_expand "symGOTOFF2reg"
e1d71275 6750 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6751 ""
6752 "
6753{
e1d71275
AO
6754 rtx gotoffsym, insn;
6755 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6756
6757 gotoffsym = gen_sym2GOTOFF (operands[1]);
6758 PUT_MODE (gotoffsym, Pmode);
6759 emit_move_insn (t, gotoffsym);
6760 insn = emit_move_insn (operands[0],
6761 gen_rtx_PLUS (Pmode, t,
6762 gen_rtx_REG (Pmode, PIC_REG)));
6763
6764 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6765 REG_NOTES (insn));
6766
6767 DONE;
1a66cd67
AO
6768}")
6769
6770(define_expand "symPLT_label2reg"
6771 [(set (match_operand:SI 0 "" "")
e1d71275
AO
6772 (const:SI (minus:SI
6773 (const:SI
6774 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6775 (const:SI
6776 (minus:SI
6777 (const:SI (plus:SI
6778 (match_operand:SI 2 "" "")
6779 (const_int 2)))
6780 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6915629f
AO
6781 ;; Even though the PIC register is not really used by the call
6782 ;; sequence in which this is expanded, the PLT code assumes the PIC
6783 ;; register is set, so we must not skip its initialization. Since
6784 ;; we only use this expand as part of calling sequences, and never
6785 ;; to take the address of a function, this is the best point to
6786 ;; insert the (use). Using the PLT to take the address of a
6787 ;; function would be wrong, not only because the PLT entry could
6788 ;; then be called from a function that doesn't initialize the PIC
6789 ;; register to the proper GOT, but also because pointers to the
6790 ;; same function might not compare equal, should they be set by
6791 ;; different shared libraries.
6792 (use (reg:SI PIC_REG))]
fa5322fa
AO
6793 "TARGET_SH1"
6794 "")
6795
6796(define_expand "sym2PIC"
6797 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6915629f
AO
6798 ""
6799 "")
1a66cd67 6800
0d7e008e
SC
6801;; case instruction for switch statements.
6802
6803;; Operand 0 is index
6804;; operand 1 is the minimum bound
6805;; operand 2 is the maximum bound - minimum bound + 1
6806;; operand 3 is CODE_LABEL for the table;
6807;; operand 4 is the CODE_LABEL to go to if index out of range.
6808
6809(define_expand "casesi"
1245df60
R
6810 [(match_operand:SI 0 "arith_reg_operand" "")
6811 (match_operand:SI 1 "arith_reg_operand" "")
6812 (match_operand:SI 2 "arith_reg_operand" "")
6813 (match_operand 3 "" "") (match_operand 4 "" "")]
6814 ""
6815 "
6816{
6817 rtx reg = gen_reg_rtx (SImode);
6818 rtx reg2 = gen_reg_rtx (SImode);
fa5322fa
AO
6819 if (TARGET_SHMEDIA)
6820 {
6821 rtx reg = gen_reg_rtx (DImode);
6822 rtx reg2 = gen_reg_rtx (DImode);
6823 rtx reg3 = gen_reg_rtx (DImode);
6824 rtx reg4 = gen_reg_rtx (DImode);
6825 rtx reg5 = gen_reg_rtx (DImode);
6826
6827 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6828 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6829 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6830
6831 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6832 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6833 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6834 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6835 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6836 (DImode, operands[3])));
6837 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6838 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6839 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6840 emit_barrier ();
6841 DONE;
6842 }
1245df60
R
6843 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6844 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6845 /* If optimizing, casesi_worker depends on the mode of the instruction
6846 before label it 'uses' - operands[3]. */
6847 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6848 reg));
6849 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6850 if (TARGET_SH2)
eb3881bf 6851 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
1245df60 6852 else
eb3881bf 6853 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
1245df60
R
6854 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6855 operands[3], but to lab. We will fix this up in
6856 machine_dependent_reorg. */
6857 emit_barrier ();
6858 DONE;
6859}")
6860
6861(define_expand "casesi_0"
6862 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6863 (set (match_dup 4) (minus:SI (match_dup 4)
0d7e008e 6864 (match_operand:SI 1 "arith_operand" "")))
4773afa4 6865 (set (reg:SI T_REG)
1245df60 6866 (gtu:SI (match_dup 4)
22e1ebf1 6867 (match_operand:SI 2 "arith_reg_operand" "")))
0d7e008e 6868 (set (pc)
4773afa4 6869 (if_then_else (ne (reg:SI T_REG)
7c225e88 6870 (const_int 0))
1245df60
R
6871 (label_ref (match_operand 3 "" ""))
6872 (pc)))]
fa5322fa 6873 "TARGET_SH1"
1245df60 6874 "")
0d7e008e 6875
1245df60
R
6876;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6877;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6878;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6879
6880(define_insn "casesi_worker_0"
6881 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422 6882 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
4773afa4 6883 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
6884 (clobber (match_scratch:SI 3 "=X,1"))
6885 (clobber (match_scratch:SI 4 "=&z,z"))]
fa5322fa 6886 "TARGET_SH1"
1245df60
R
6887 "#")
6888
6889(define_split
6890 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
6891 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6892 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
6893 (clobber (match_scratch:SI 3 ""))
6894 (clobber (match_scratch:SI 4 ""))]
fa5322fa 6895 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
e69d1422 6896 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 6897 (parallel [(set (match_dup 0)
e69d1422
R
6898 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6899 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 6900 (clobber (match_dup 3))])
4773afa4 6901 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
b6d33983 6902 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
6903
6904(define_split
6905 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
6906 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6907 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
6908 (clobber (match_scratch:SI 3 ""))
6909 (clobber (match_scratch:SI 4 ""))]
6910 "TARGET_SH2 && reload_completed"
e69d1422 6911 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 6912 (parallel [(set (match_dup 0)
615cd49b 6913 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
e69d1422 6914 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 6915 (clobber (match_dup 3))])]
b6d33983 6916 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
6917
6918(define_insn "*casesi_worker"
6919 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422
R
6920 (unspec:SI [(reg:SI R0_REG)
6921 (match_operand:SI 1 "register_operand" "0,r")
6922 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60 6923 (clobber (match_scratch:SI 3 "=X,1"))]
fa5322fa 6924 "TARGET_SH1"
4fdd1f85 6925 "*
ffae286a 6926{
33f7f353
JR
6927 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6928
6929 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6930 abort ();
6931
6932 switch (GET_MODE (diff_vec))
1245df60
R
6933 {
6934 case SImode:
6935 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6936 case HImode:
6937 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6938 case QImode:
33f7f353 6939 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
1245df60 6940 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
33f7f353 6941 return \"mov.b @(r0,%1),%0\";
1245df60
R
6942 default:
6943 abort ();
6944 }
ffae286a 6945}"
51bd623f 6946 [(set_attr "length" "4")])
0d7e008e 6947
fa5322fa 6948(define_insn "casesi_shift_media"
51214775
R
6949 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6950 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6951 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6952 UNSPEC_CASESI)))]
fa5322fa
AO
6953 "TARGET_SHMEDIA"
6954 "*
6955{
6956 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6957
6958 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6959 abort ();
6960
6961 switch (GET_MODE (diff_vec))
6962 {
6963 case SImode:
6964 return \"shlli %1, 2, %0\";
6965 case HImode:
6966 return \"shlli %1, 1, %0\";
6967 case QImode:
6968 if (rtx_equal_p (operands[0], operands[1]))
6969 return \"\";
6970 return \"add %1, r63, %0\";
6971 default:
6972 abort ();
6973 }
2ad65b0e
SC
6974}"
6975 [(set_attr "type" "arith_media")])
fa5322fa
AO
6976
6977(define_insn "casesi_load_media"
6978 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6979 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6980 (match_operand 2 "arith_reg_operand" "r")
6981 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6982 "TARGET_SHMEDIA"
6983 "*
6984{
6985 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6986
6987 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6988 abort ();
6989
6990 switch (GET_MODE (diff_vec))
6991 {
6992 case SImode:
6993 return \"ldx.l %1, %2, %0\";
6994 case HImode:
6995#if 0
6996 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6997 return \"ldx.uw %1, %2, %0\";
6998#endif
6999 return \"ldx.w %1, %2, %0\";
7000 case QImode:
7001 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7002 return \"ldx.ub %1, %2, %0\";
7003 return \"ldx.b %1, %2, %0\";
7004 default:
7005 abort ();
7006 }
2ad65b0e
SC
7007}"
7008 [(set_attr "type" "load_media")])
fa5322fa 7009
afbc2905
R
7010(define_expand "return"
7011 [(return)]
7012 "reload_completed && ! sh_need_epilogue ()"
fa5322fa
AO
7013 "
7014{
7015 if (TARGET_SHMEDIA)
7016 {
7017 emit_jump_insn (gen_return_media ());
7018 DONE;
7019 }
7020
7021 if (TARGET_SHCOMPACT
7022 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7023 {
7024 emit_jump_insn (gen_shcompact_return_tramp ());
7025 DONE;
7026 }
7027}")
afbc2905
R
7028
7029(define_insn "*return_i"
0d7e008e 7030 [(return)]
fa5322fa
AO
7031 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7032 && (current_function_args_info.call_cookie
7033 & CALL_COOKIE_RET_TRAMP (1)))
7034 && reload_completed"
961c4780 7035 "%@ %#"
51bd623f
JW
7036 [(set_attr "type" "return")
7037 (set_attr "needs_delay_slot" "yes")])
b9654711 7038
fa5322fa
AO
7039(define_expand "shcompact_return_tramp"
7040 [(return)]
7041 "TARGET_SHCOMPACT
7042 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7043 "
7044{
7045 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7046 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7047 \"__GCC_shcompact_return_trampoline\");
7048
7049 if (flag_pic)
7050 emit_insn (gen_symGOTPLT2reg (reg, sym));
7051 else
7052 emit_move_insn (reg, sym);
7053
7054 emit_jump_insn (gen_shcompact_return_tramp_i ());
7055 DONE;
7056}")
7057
7058(define_insn "shcompact_return_tramp_i"
7059 [(parallel [(return) (use (reg:SI R0_REG))])]
7060 "TARGET_SHCOMPACT
7061 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7062 "jmp @r0%#"
7063 [(set_attr "type" "jump_ind")
7064 (set_attr "needs_delay_slot" "yes")])
7065
7066(define_insn "return_media_i"
7067 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7068 "TARGET_SHMEDIA && reload_completed"
2ad65b0e
SC
7069 "blink %0, r63"
7070 [(set_attr "type" "jump_media")])
fa5322fa
AO
7071
7072(define_expand "return_media"
7073 [(return)]
7074 "TARGET_SHMEDIA && reload_completed"
7075 "
7076{
7077 int tr_regno = sh_media_register_for_return ();
7078 rtx tr;
7079
7080 if (tr_regno < 0)
7081 {
7082 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7083
7084 tr_regno = TR0_REG;
7085 tr = gen_rtx_REG (DImode, tr_regno);
7086 emit_move_insn (tr, r18);
7087 }
7088 else
7089 tr = gen_rtx_REG (DImode, tr_regno);
7090
7091 emit_jump_insn (gen_return_media_i (tr));
7092 DONE;
7093}")
7094
7095(define_insn "shcompact_preserve_incoming_args"
e69d1422
R
7096 [(set (match_operand:SI 0 "register_operand" "+r")
7097 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
fa5322fa
AO
7098 "TARGET_SHCOMPACT"
7099 ""
7100 [(set_attr "length" "0")])
7101
7102(define_insn "shcompact_incoming_args"
e69d1422
R
7103 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7104 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7105 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7106 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7107 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7108 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7109 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7110 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa 7111 (set (mem:BLK (reg:SI MACL_REG))
e69d1422 7112 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa
AO
7113 (use (reg:SI R0_REG))
7114 (clobber (reg:SI R0_REG))
7115 (clobber (reg:SI MACL_REG))
7116 (clobber (reg:SI MACH_REG))
7117 (clobber (reg:SI PR_REG))]
7118 "TARGET_SHCOMPACT"
7119 "jsr @r0%#"
7120 [(set_attr "needs_delay_slot" "yes")])
7121
7122(define_insn "shmedia_save_restore_regs_compact"
7123 [(set (reg:SI SP_REG)
7124 (plus:SI (reg:SI SP_REG)
7125 (match_operand:SI 0 "immediate_operand" "i")))
7126 (use (reg:SI R0_REG))
7127 (clobber (reg:SI PR_REG))]
7128 "TARGET_SHCOMPACT
7129 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7130 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7131 "jsr @r0%#"
7132 [(set_attr "needs_delay_slot" "yes")])
7133
b9654711
SC
7134(define_expand "prologue"
7135 [(const_int 0)]
7136 ""
7137 "sh_expand_prologue (); DONE;")
7138
7139(define_expand "epilogue"
7140 [(return)]
7141 ""
fa5322fa
AO
7142 "
7143{
7144 sh_expand_epilogue ();
7145 emit_jump_insn (gen_return ());
7146 DONE;
7147}")
b9654711 7148
4977bab6
ZW
7149(define_expand "eh_return"
7150 [(use (match_operand 0 "register_operand" ""))
7151 (use (match_operand 1 "register_operand" ""))]
7152 ""
7153{
7154 rtx tmp, sa = operands[0], ra = operands[1];
7155
7156 if (TARGET_SHMEDIA64)
7157 emit_insn (gen_eh_set_ra_di (ra));
7158 else
7159 emit_insn (gen_eh_set_ra_si (ra));
7160
7161 emit_move_insn (EH_RETURN_STACKADJ_RTX, sa);
7162 DONE;
7163})
7164
7165;; Clobber the return address on the stack. We can't expand this
7166;; until we know where it will be put in the stack frame.
7167
7168(define_insn "eh_set_ra_si"
7169 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7170 (clobber (match_scratch:SI 1 "=&r"))]
7171 "! TARGET_SHMEDIA64"
7172 "#")
7173
7174(define_insn "eh_set_ra_di"
7175 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7176 (clobber (match_scratch:DI 1 "=&r"))]
7177 "TARGET_SHMEDIA64"
7178 "#")
7179
7180(define_split
7181 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7182 (clobber (match_scratch 1 ""))]
7183 "reload_completed"
7184 [(const_int 0)]
7185 "
7186{
7187 sh_set_return_address (operands[0], operands[1]);
7188 DONE;
7189}")
7190
b9654711 7191(define_insn "blockage"
4773afa4 7192 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
b9654711
SC
7193 ""
7194 ""
7195 [(set_attr "length" "0")])
bc45ade3
SC
7196\f
7197;; ------------------------------------------------------------------------
7198;; Scc instructions
7199;; ------------------------------------------------------------------------
7200
0d7e008e 7201(define_insn "movt"
aa684c94 7202 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 7203 (eq:SI (reg:SI T_REG) (const_int 1)))]
fa5322fa 7204 "TARGET_SH1"
1245df60
R
7205 "movt %0"
7206 [(set_attr "type" "arith")])
bc45ade3
SC
7207
7208(define_expand "seq"
aa684c94 7209 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7210 (match_dup 1))]
7211 ""
fa5322fa
AO
7212 "
7213{
7214 if (TARGET_SHMEDIA)
7215 {
7216 if (GET_MODE (operands[0]) != DImode)
7217 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7218 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7219 if (sh_compare_op1 != const0_rtx)
7220 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7221 ? GET_MODE (sh_compare_op0)
7222 : GET_MODE (sh_compare_op1),
7223 sh_compare_op1);
7224
7225 switch (GET_MODE (sh_compare_op0))
7226 {
7227 case DImode:
7228 emit_insn (gen_cmpeqdi_media (operands[0],
7229 sh_compare_op0, sh_compare_op1));
7230 break;
7231
7232 case SFmode:
7233 if (! TARGET_SHMEDIA_FPU)
7234 FAIL;
7235 emit_insn (gen_cmpeqsf_media (operands[0],
7236 sh_compare_op0, sh_compare_op1));
7237 break;
7238
7239 case DFmode:
7240 if (! TARGET_SHMEDIA_FPU)
7241 FAIL;
7242 emit_insn (gen_cmpeqdf_media (operands[0],
7243 sh_compare_op0, sh_compare_op1));
7244 break;
7245
7246 default:
7247 FAIL;
7248 }
7249 DONE;
7250 }
7251 operands[1] = prepare_scc_operands (EQ);
7252}")
bc45ade3
SC
7253
7254(define_expand "slt"
aa684c94 7255 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7256 (match_dup 1))]
7257 ""
fa5322fa
AO
7258 "
7259{
7260 if (TARGET_SHMEDIA)
7261 {
7262 if (GET_MODE (operands[0]) != DImode)
7263 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7264 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7265 if (sh_compare_op1 != const0_rtx)
7266 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7267 ? GET_MODE (sh_compare_op0)
7268 : GET_MODE (sh_compare_op1),
7269 sh_compare_op1);
7270
7271 switch (GET_MODE (sh_compare_op0))
7272 {
7273 case DImode:
7274 emit_insn (gen_cmpgtdi_media (operands[0],
7275 sh_compare_op1, sh_compare_op0));
7276 break;
7277
7278 case SFmode:
7279 if (! TARGET_SHMEDIA_FPU)
7280 FAIL;
7281 emit_insn (gen_cmpgtsf_media (operands[0],
7282 sh_compare_op1, sh_compare_op0));
7283 break;
7284
7285 case DFmode:
7286 if (! TARGET_SHMEDIA_FPU)
7287 FAIL;
7288 emit_insn (gen_cmpgtdf_media (operands[0],
7289 sh_compare_op1, sh_compare_op0));
7290 break;
7291
7292 default:
7293 FAIL;
7294 }
7295 DONE;
7296 }
7297 operands[1] = prepare_scc_operands (LT);
7298}")
bc45ade3
SC
7299
7300(define_expand "sle"
1245df60 7301 [(match_operand:SI 0 "arith_reg_operand" "")]
bc45ade3 7302 ""
45348d9e
JW
7303 "
7304{
1245df60 7305 rtx tmp = sh_compare_op0;
fa5322fa
AO
7306
7307 if (TARGET_SHMEDIA)
7308 {
7309 if (GET_MODE (operands[0]) != DImode)
7310 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7311 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7312 if (sh_compare_op1 != const0_rtx)
7313 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7314 ? GET_MODE (sh_compare_op0)
7315 : GET_MODE (sh_compare_op1),
7316 sh_compare_op1);
7317
7318 switch (GET_MODE (sh_compare_op0))
7319 {
7320 case DImode:
7321 {
7322 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7323
7324 emit_insn (gen_cmpgtdi_media (tmp,
7325 sh_compare_op0, sh_compare_op1));
7326 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7327 break;
7328 }
7329
7330 case SFmode:
7331 if (! TARGET_SHMEDIA_FPU)
7332 FAIL;
7333 emit_insn (gen_cmpgesf_media (operands[0],
7334 sh_compare_op1, sh_compare_op0));
7335 break;
7336
7337 case DFmode:
7338 if (! TARGET_SHMEDIA_FPU)
7339 FAIL;
7340 emit_insn (gen_cmpgedf_media (operands[0],
7341 sh_compare_op1, sh_compare_op0));
7342 break;
7343
7344 default:
7345 FAIL;
7346 }
7347 DONE;
7348 }
7349
1245df60
R
7350 sh_compare_op0 = sh_compare_op1;
7351 sh_compare_op1 = tmp;
7352 emit_insn (gen_sge (operands[0]));
7353 DONE;
45348d9e 7354}")
bc45ade3
SC
7355
7356(define_expand "sgt"
aa684c94 7357 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7358 (match_dup 1))]
7359 ""
fa5322fa
AO
7360 "
7361{
7362 if (TARGET_SHMEDIA)
7363 {
7364 if (GET_MODE (operands[0]) != DImode)
7365 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7366 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7367 if (sh_compare_op1 != const0_rtx)
7368 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7369 ? GET_MODE (sh_compare_op0)
7370 : GET_MODE (sh_compare_op1),
7371 sh_compare_op1);
7372
7373 switch (GET_MODE (sh_compare_op0))
7374 {
7375 case DImode:
7376 emit_insn (gen_cmpgtdi_media (operands[0],
7377 sh_compare_op0, sh_compare_op1));
7378 break;
7379
7380 case SFmode:
7381 if (! TARGET_SHMEDIA_FPU)
7382 FAIL;
7383 emit_insn (gen_cmpgtsf_media (operands[0],
7384 sh_compare_op0, sh_compare_op1));
7385 break;
7386
7387 case DFmode:
7388 if (! TARGET_SHMEDIA_FPU)
7389 FAIL;
7390 emit_insn (gen_cmpgtdf_media (operands[0],
7391 sh_compare_op0, sh_compare_op1));
7392 break;
7393
7394 default:
7395 FAIL;
7396 }
7397 DONE;
7398 }
7399 operands[1] = prepare_scc_operands (GT);
7400}")
bc45ade3
SC
7401
7402(define_expand "sge"
aa684c94 7403 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7404 (match_dup 1))]
7405 ""
45348d9e
JW
7406 "
7407{
fa5322fa
AO
7408 if (TARGET_SHMEDIA)
7409 {
7410 if (GET_MODE (operands[0]) != DImode)
7411 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7412 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7413 if (sh_compare_op1 != const0_rtx)
7414 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7415 ? GET_MODE (sh_compare_op0)
7416 : GET_MODE (sh_compare_op1),
7417 sh_compare_op1);
7418
7419 switch (GET_MODE (sh_compare_op0))
7420 {
7421 case DImode:
7422 {
7423 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7424
7425 emit_insn (gen_cmpgtdi_media (tmp,
7426 sh_compare_op1, sh_compare_op0));
7427 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7428 break;
7429 }
7430
7431 case SFmode:
7432 if (! TARGET_SHMEDIA_FPU)
7433 FAIL;
7434 emit_insn (gen_cmpgesf_media (operands[0],
7435 sh_compare_op0, sh_compare_op1));
7436 break;
7437
7438 case DFmode:
7439 if (! TARGET_SHMEDIA_FPU)
7440 FAIL;
7441 emit_insn (gen_cmpgedf_media (operands[0],
7442 sh_compare_op0, sh_compare_op1));
7443 break;
7444
7445 default:
7446 FAIL;
7447 }
7448 DONE;
7449 }
7450
225e4f43 7451 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e 7452 {
1245df60
R
7453 if (TARGET_IEEE)
7454 {
1245df60 7455 rtx lab = gen_label_rtx ();
225e4f43 7456 prepare_scc_operands (EQ);
1245df60 7457 emit_jump_insn (gen_branch_true (lab));
225e4f43 7458 prepare_scc_operands (GT);
1245df60
R
7459 emit_label (lab);
7460 emit_insn (gen_movt (operands[0]));
7461 }
7462 else
7463 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
45348d9e
JW
7464 DONE;
7465 }
7466 operands[1] = prepare_scc_operands (GE);
7467}")
bc45ade3
SC
7468
7469(define_expand "sgtu"
aa684c94 7470 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7471 (match_dup 1))]
7472 ""
fa5322fa
AO
7473 "
7474{
7475 if (TARGET_SHMEDIA)
7476 {
7477 if (GET_MODE (operands[0]) != DImode)
7478 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7479 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7480 if (sh_compare_op1 != const0_rtx)
7481 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7482 ? GET_MODE (sh_compare_op0)
7483 : GET_MODE (sh_compare_op1),
7484 sh_compare_op1);
7485
7486 emit_insn (gen_cmpgtudi_media (operands[0],
7487 sh_compare_op0, sh_compare_op1));
7488 DONE;
7489 }
7490 operands[1] = prepare_scc_operands (GTU);
7491}")
bc45ade3
SC
7492
7493(define_expand "sltu"
aa684c94 7494 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7495 (match_dup 1))]
7496 ""
fa5322fa
AO
7497 "
7498{
7499 if (TARGET_SHMEDIA)
7500 {
7501 if (GET_MODE (operands[0]) != DImode)
7502 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7503 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7504 if (sh_compare_op1 != const0_rtx)
7505 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7506 ? GET_MODE (sh_compare_op0)
7507 : GET_MODE (sh_compare_op1),
7508 sh_compare_op1);
7509
7510 emit_insn (gen_cmpgtudi_media (operands[0],
7511 sh_compare_op1, sh_compare_op0));
7512 DONE;
7513 }
7514 operands[1] = prepare_scc_operands (LTU);
7515}")
bc45ade3
SC
7516
7517(define_expand "sleu"
aa684c94 7518 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7519 (match_dup 1))]
7520 ""
fa5322fa
AO
7521 "
7522{
7523 if (TARGET_SHMEDIA)
7524 {
7525 rtx tmp;
7526
7527 if (GET_MODE (operands[0]) != DImode)
7528 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7529 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7530 if (sh_compare_op1 != const0_rtx)
7531 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7532 ? GET_MODE (sh_compare_op0)
7533 : GET_MODE (sh_compare_op1),
7534 sh_compare_op1);
7535
7536 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7537
7538 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7539 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7540
7541 DONE;
7542 }
7543 operands[1] = prepare_scc_operands (LEU);
7544}")
bc45ade3
SC
7545
7546(define_expand "sgeu"
aa684c94 7547 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7548 (match_dup 1))]
7549 ""
fa5322fa
AO
7550 "
7551{
7552 if (TARGET_SHMEDIA)
7553 {
7554 rtx tmp;
7555
7556 if (GET_MODE (operands[0]) != DImode)
7557 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7558 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7559 if (sh_compare_op1 != const0_rtx)
7560 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7561 ? GET_MODE (sh_compare_op0)
7562 : GET_MODE (sh_compare_op1),
7563 sh_compare_op1);
7564
7565 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7566
7567 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7568 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7569
7570 DONE;
7571 }
7572
7573 operands[1] = prepare_scc_operands (GEU);
7574}")
bc45ade3 7575
8bca10f4
JW
7576;; sne moves the complement of the T reg to DEST like this:
7577;; cmp/eq ...
7578;; mov #-1,temp
7579;; negc temp,dest
7580;; This is better than xoring compare result with 1 because it does
7581;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7582;; loop.
7583
bc45ade3 7584(define_expand "sne"
8bca10f4
JW
7585 [(set (match_dup 2) (const_int -1))
7586 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7587 (neg:SI (plus:SI (match_dup 1)
7588 (match_dup 2))))
4773afa4 7589 (set (reg:SI T_REG)
8bca10f4 7590 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
52702ae1 7591 (const_int 0)))])]
8bca10f4
JW
7592 ""
7593 "
7594{
fa5322fa
AO
7595 if (TARGET_SHMEDIA)
7596 {
7597 rtx tmp;
7598
7599 if (GET_MODE (operands[0]) != DImode)
7600 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7601
7602 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7603 FAIL;
7604
7605 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7606 if (sh_compare_op1 != const0_rtx)
7607 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7608 ? GET_MODE (sh_compare_op0)
7609 : GET_MODE (sh_compare_op1),
7610 sh_compare_op1);
7611
7612 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7613
7614 emit_insn (gen_seq (tmp));
7615 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7616
7617 DONE;
7618 }
7619
8bca10f4
JW
7620 operands[1] = prepare_scc_operands (EQ);
7621 operands[2] = gen_reg_rtx (SImode);
7622}")
7623
fa5322fa
AO
7624(define_expand "sunordered"
7625 [(set (match_operand:DI 0 "arith_reg_operand" "")
7626 (unordered:DI (match_dup 1) (match_dup 2)))]
7627 "TARGET_SHMEDIA_FPU"
7628 "
7629{
7630 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7631 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7632}")
7633
1245df60
R
7634;; Use the same trick for FP sle / sge
7635(define_expand "movnegt"
7636 [(set (match_dup 2) (const_int -1))
7637 (parallel [(set (match_operand 0 "" "")
7638 (neg:SI (plus:SI (match_dup 1)
7639 (match_dup 2))))
4773afa4 7640 (set (reg:SI T_REG)
1245df60 7641 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
52702ae1 7642 (const_int 0)))])]
fa5322fa 7643 "TARGET_SH1"
1245df60
R
7644 "operands[2] = gen_reg_rtx (SImode);")
7645
8bca10f4 7646;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
956d6950 7647;; This prevents a regression that occurred when we switched from xor to
8bca10f4
JW
7648;; mov/neg for sne.
7649
7650(define_split
aa684c94 7651 [(set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 7652 (plus:SI (reg:SI T_REG)
8bca10f4 7653 (const_int -1)))]
fa5322fa 7654 "TARGET_SH1"
4773afa4 7655 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
8bca10f4
JW
7656 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7657 "")
bc45ade3 7658
0d7e008e
SC
7659;; -------------------------------------------------------------------------
7660;; Instructions to cope with inline literal tables
7661;; -------------------------------------------------------------------------
7662
7663; 2 byte integer in line
b9654711 7664
0d7e008e 7665(define_insn "consttable_2"
b91455de
KK
7666 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7667 (match_operand 1 "" "")]
4773afa4 7668 UNSPECV_CONST2)]
0d7e008e
SC
7669 ""
7670 "*
7671{
b91455de 7672 if (operands[1] != const0_rtx)
c8af3574 7673 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
0d7e008e
SC
7674 return \"\";
7675}"
7676 [(set_attr "length" "2")
7677 (set_attr "in_delay_slot" "no")])
7678
7679; 4 byte integer in line
7680
7681(define_insn "consttable_4"
b91455de
KK
7682 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7683 (match_operand 1 "" "")]
4773afa4 7684 UNSPECV_CONST4)]
0d7e008e
SC
7685 ""
7686 "*
7687{
b91455de 7688 if (operands[1] != const0_rtx)
c8af3574 7689 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
0d7e008e
SC
7690 return \"\";
7691}"
7692 [(set_attr "length" "4")
7693 (set_attr "in_delay_slot" "no")])
7694
7695; 8 byte integer in line
7696
7697(define_insn "consttable_8"
b91455de
KK
7698 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7699 (match_operand 1 "" "")]
4773afa4 7700 UNSPECV_CONST8)]
0d7e008e
SC
7701 ""
7702 "*
7703{
b91455de 7704 if (operands[1] != const0_rtx)
c8af3574 7705 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
0d7e008e
SC
7706 return \"\";
7707}"
7708 [(set_attr "length" "8")
7709 (set_attr "in_delay_slot" "no")])
7710
3e943b59
JR
7711; 4 byte floating point
7712
7713(define_insn "consttable_sf"
b91455de
KK
7714 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7715 (match_operand 1 "" "")]
4773afa4 7716 UNSPECV_CONST4)]
3e943b59
JR
7717 ""
7718 "*
7719{
b91455de
KK
7720 if (operands[1] != const0_rtx)
7721 {
85654444
ZW
7722 REAL_VALUE_TYPE d;
7723 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7724 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
b91455de 7725 }
3e943b59
JR
7726 return \"\";
7727}"
7728 [(set_attr "length" "4")
7729 (set_attr "in_delay_slot" "no")])
7730
7731; 8 byte floating point
7732
7733(define_insn "consttable_df"
b91455de
KK
7734 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7735 (match_operand 1 "" "")]
4773afa4 7736 UNSPECV_CONST8)]
3e943b59
JR
7737 ""
7738 "*
7739{
b91455de
KK
7740 if (operands[1] != const0_rtx)
7741 {
85654444
ZW
7742 REAL_VALUE_TYPE d;
7743 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7744 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
b91455de 7745 }
3e943b59
JR
7746 return \"\";
7747}"
7748 [(set_attr "length" "8")
7749 (set_attr "in_delay_slot" "no")])
7750
1245df60
R
7751;; Alignment is needed for some constant tables; it may also be added for
7752;; Instructions at the start of loops, or after unconditional branches.
7753;; ??? We would get more accurate lengths if we did instruction
7754;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7755;; here is too conservative.
7756
0d7e008e
SC
7757; align to a two byte boundary
7758
33f7f353 7759(define_expand "align_2"
4773afa4 7760 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
0d7e008e 7761 ""
33f7f353 7762 "")
0d7e008e
SC
7763
7764; align to a four byte boundary
1245df60
R
7765;; align_4 and align_log are instructions for the starts of loops, or
7766;; after unconditional branches, which may take up extra room.
7767
7768(define_expand "align_4"
4773afa4 7769 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
1245df60
R
7770 ""
7771 "")
7772
7773; align to a cache line boundary
0d7e008e 7774
1245df60 7775(define_insn "align_log"
4773afa4 7776 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
0d7e008e 7777 ""
33f7f353
JR
7778 ""
7779 [(set_attr "length" "0")
1245df60 7780 (set_attr "in_delay_slot" "no")])
0d7e008e
SC
7781
7782; emitted at the end of the literal table, used to emit the
7783; 32bit branch labels if needed.
7784
7785(define_insn "consttable_end"
4773afa4 7786 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
0d7e008e
SC
7787 ""
7788 "* return output_jump_label_table ();"
7789 [(set_attr "in_delay_slot" "no")])
7790
b91455de
KK
7791; emitted at the end of the window in the literal table.
7792
7793(define_insn "consttable_window_end"
7794 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7795 ""
7796 ""
7797 [(set_attr "length" "0")
7798 (set_attr "in_delay_slot" "no")])
7799
0d7e008e
SC
7800;; -------------------------------------------------------------------------
7801;; Misc
7802;; -------------------------------------------------------------------------
7803
07a45e5c 7804;; String/block move insn.
0d7e008e
SC
7805
7806(define_expand "movstrsi"
7807 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7808 (mem:BLK (match_operand:BLK 1 "" "")))
7809 (use (match_operand:SI 2 "nonmemory_operand" ""))
7810 (use (match_operand:SI 3 "immediate_operand" ""))
4773afa4
AO
7811 (clobber (reg:SI PR_REG))
7812 (clobber (reg:SI R4_REG))
7813 (clobber (reg:SI R5_REG))
7814 (clobber (reg:SI R0_REG))])]
fa5322fa 7815 "TARGET_SH1 && ! TARGET_SH5"
0d7e008e
SC
7816 "
7817{
7818 if(expand_block_move (operands))
7819 DONE;
7820 else FAIL;
7821}")
7822
7823(define_insn "block_move_real"
4773afa4
AO
7824 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7825 (mem:BLK (reg:SI R5_REG)))
0d7e008e 7826 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
7827 (clobber (reg:SI PR_REG))
7828 (clobber (reg:SI R0_REG))])]
fa5322fa 7829 "TARGET_SH1 && ! TARGET_HARD_SH4"
0d7e008e 7830 "jsr @%0%#"
22e1ebf1 7831 [(set_attr "type" "sfunc")
0d7e008e
SC
7832 (set_attr "needs_delay_slot" "yes")])
7833
7834(define_insn "block_lump_real"
4773afa4
AO
7835 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7836 (mem:BLK (reg:SI R5_REG)))
0d7e008e 7837 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
7838 (use (reg:SI R6_REG))
7839 (clobber (reg:SI PR_REG))
7840 (clobber (reg:SI T_REG))
7841 (clobber (reg:SI R4_REG))
7842 (clobber (reg:SI R5_REG))
7843 (clobber (reg:SI R6_REG))
7844 (clobber (reg:SI R0_REG))])]
fa5322fa 7845 "TARGET_SH1 && ! TARGET_HARD_SH4"
225e4f43
R
7846 "jsr @%0%#"
7847 [(set_attr "type" "sfunc")
7848 (set_attr "needs_delay_slot" "yes")])
7849
7850(define_insn "block_move_real_i4"
4773afa4
AO
7851 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7852 (mem:BLK (reg:SI R5_REG)))
225e4f43 7853 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
7854 (clobber (reg:SI PR_REG))
7855 (clobber (reg:SI R0_REG))
7856 (clobber (reg:SI R1_REG))
7857 (clobber (reg:SI R2_REG))])]
225e4f43
R
7858 "TARGET_HARD_SH4"
7859 "jsr @%0%#"
7860 [(set_attr "type" "sfunc")
7861 (set_attr "needs_delay_slot" "yes")])
7862
7863(define_insn "block_lump_real_i4"
4773afa4
AO
7864 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7865 (mem:BLK (reg:SI R5_REG)))
225e4f43 7866 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
7867 (use (reg:SI R6_REG))
7868 (clobber (reg:SI PR_REG))
7869 (clobber (reg:SI T_REG))
7870 (clobber (reg:SI R4_REG))
7871 (clobber (reg:SI R5_REG))
7872 (clobber (reg:SI R6_REG))
7873 (clobber (reg:SI R0_REG))
7874 (clobber (reg:SI R1_REG))
7875 (clobber (reg:SI R2_REG))
7876 (clobber (reg:SI R3_REG))])]
225e4f43 7877 "TARGET_HARD_SH4"
0d7e008e 7878 "jsr @%0%#"
22e1ebf1 7879 [(set_attr "type" "sfunc")
0d7e008e 7880 (set_attr "needs_delay_slot" "yes")])
45348d9e
JW
7881\f
7882;; -------------------------------------------------------------------------
7883;; Floating point instructions.
7884;; -------------------------------------------------------------------------
7885
7886;; ??? All patterns should have a type attribute.
7887
225e4f43 7888(define_expand "fpu_switch0"
8845e874
AO
7889 [(set (match_operand:SI 0 "" "") (match_dup 2))
7890 (set (match_dup 1) (mem:PSI (match_dup 0)))]
ecfdeaeb 7891 "TARGET_SH4"
225e4f43
R
7892 "
7893{
8845e874
AO
7894 operands[1] = get_fpscr_rtx ();
7895 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
7896 if (flag_pic)
7897 operands[2] = legitimize_pic_address (operands[2], SImode,
7898 no_new_pseudos ? operands[0] : 0);
225e4f43
R
7899}")
7900
7901(define_expand "fpu_switch1"
8845e874
AO
7902 [(set (match_operand:SI 0 "" "") (match_dup 2))
7903 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7904 (set (match_dup 1) (mem:PSI (match_dup 3)))]
ecfdeaeb 7905 "TARGET_SH4"
225e4f43
R
7906 "
7907{
8845e874
AO
7908 operands[1] = get_fpscr_rtx ();
7909 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
7910 if (flag_pic)
7911 operands[2] = legitimize_pic_address (operands[2], SImode,
7912 no_new_pseudos ? operands[0] : 0);
8845e874 7913 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
225e4f43
R
7914}")
7915
7916(define_expand "movpsi"
7917 [(set (match_operand:PSI 0 "register_operand" "")
7918 (match_operand:PSI 1 "general_movsrc_operand" ""))]
ecfdeaeb 7919 "TARGET_SH4"
225e4f43
R
7920 "")
7921
7922;; The c / m alternative is a fake to guide reload to load directly into
7923;; fpscr, since reload doesn't know how to use post-increment.
7924;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7925;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7926;; predicate after reload.
c49439f1
R
7927;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7928;; like a mac -> gpr move.
225e4f43 7929(define_insn "fpu_switch"
7144b2d8
DD
7930 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
7931 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
7932 "TARGET_SH3E
ecfdeaeb
AO
7933 && (! reload_completed
7934 || true_regnum (operands[0]) != FPSCR_REG
7935 || GET_CODE (operands[1]) != MEM
7936 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
225e4f43
R
7937 "@
7938 ! precision stays the same
7939 lds.l %1,fpscr
7940 mov.l %1,%0
7941 #
7942 lds %1,fpscr
7943 mov %1,%0
7944 mov.l %1,%0
7144b2d8
DD
7945 sts fpscr,%0
7946 sts.l fpscr,%0"
7947 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
7948 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
225e4f43
R
7949
7950(define_split
4773afa4 7951 [(set (reg:PSI FPSCR_REG)
c1b92d09 7952 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 7953 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
225e4f43
R
7954 [(set (match_dup 0) (match_dup 0))]
7955 "
7956{
7957 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7958 gen_rtx (MEM, PSImode,
7959 gen_rtx (POST_INC, Pmode,
7960 operands[0]))));
7961 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7962}")
7963
7964(define_split
4773afa4 7965 [(set (reg:PSI FPSCR_REG)
c1b92d09 7966 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 7967 "TARGET_SH4"
225e4f43
R
7968 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7969 "
7970{
7971 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7972 gen_rtx (MEM, PSImode,
7973 gen_rtx (POST_INC, Pmode,
7974 operands[0]))));
7975 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7976}")
7977
7978;; ??? This uses the fp unit, but has no type indicating that.
7979;; If we did that, this would either give a bogus latency or introduce
7980;; a bogus FIFO constraint.
7981;; Since this insn is currently only used for prologues/epilogues,
7982;; it is probably best to claim no function unit, which matches the
7983;; current setting.
7984(define_insn "toggle_sz"
4773afa4
AO
7985 [(set (reg:PSI FPSCR_REG)
7986 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
225e4f43
R
7987 "TARGET_SH4"
7988 "fschg")
7989
7990(define_expand "addsf3"
fa5322fa
AO
7991 [(set (match_operand:SF 0 "arith_reg_operand" "")
7992 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7993 (match_operand:SF 2 "arith_reg_operand" "")))]
7994 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7995 "
7996{
7997 if (TARGET_SH3E)
7998 {
7999 expand_sf_binop (&gen_addsf3_i, operands);
8000 DONE;
8001 }
8002}")
8003
8004(define_insn "*addsf3_media"
8005 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8006 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8007 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8008 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8009 "fadd.s %1, %2, %0"
8010 [(set_attr "type" "fparith_media")])
225e4f43 8011
0ac78517
R
8012(define_insn_and_split "unary_sf_op"
8013 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8014 (vec_select:V2SF
8015 (vec_concat:V2SF
8016 (vec_select:SF
8017 (match_dup 0)
8018 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8019 (match_operator:SF 2 "unary_float_operator"
8020 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8021 (parallel [(match_operand 4
8022 "const_int_operand" "n")]))]))
8023 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8024 "TARGET_SHMEDIA_FPU"
8025 "#"
8026 "TARGET_SHMEDIA_FPU && reload_completed"
8027 [(set (match_dup 5) (match_dup 6))]
8028 "
8029{
8030 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8031 rtx op1 = gen_rtx_REG (SFmode,
8032 (true_regnum (operands[1])
8033 + (INTVAL (operands[4]) ^ endian)));
8034
8035 operands[7] = gen_rtx_REG (SFmode,
8036 (true_regnum (operands[0])
8037 + (INTVAL (operands[3]) ^ endian)));
8038 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8039}"
8040 [(set_attr "type" "fparith_media")])
8041
8042(define_insn_and_split "binary_sf_op"
8043 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8044 (vec_select:V2SF
8045 (vec_concat:V2SF
8046 (vec_select:SF
8047 (match_dup 0)
8048 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8049 (match_operator:SF 3 "binary_float_operator"
8050 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8051 (parallel [(match_operand 5
8052 "const_int_operand" "n")]))
8053 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8054 (parallel [(match_operand 6
8055 "const_int_operand" "n")]))]))
8056 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8057 "TARGET_SHMEDIA_FPU"
8058 "#"
8059 "TARGET_SHMEDIA_FPU && reload_completed"
8060 [(set (match_dup 7) (match_dup 8))]
8061 "
8062{
8063 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8064 rtx op1 = gen_rtx_REG (SFmode,
8065 (true_regnum (operands[1])
8066 + (INTVAL (operands[5]) ^ endian)));
8067 rtx op2 = gen_rtx_REG (SFmode,
8068 (true_regnum (operands[2])
8069 + (INTVAL (operands[6]) ^ endian)));
8070
8071 operands[7] = gen_rtx_REG (SFmode,
8072 (true_regnum (operands[0])
8073 + (INTVAL (operands[4]) ^ endian)));
8074 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8075}"
8076 [(set_attr "type" "fparith_media")])
8077
225e4f43 8078(define_insn "addsf3_i"
45348d9e
JW
8079 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8080 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
225e4f43
R
8081 (match_operand:SF 2 "arith_reg_operand" "f")))
8082 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
45348d9e 8083 "TARGET_SH3E"
c1aef54d 8084 "fadd %2,%0"
d64264ff
R
8085 [(set_attr "type" "fp")
8086 (set_attr "fp_mode" "single")])
45348d9e 8087
225e4f43 8088(define_expand "subsf3"
fa5322fa
AO
8089 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8090 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8091 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8092 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8093 "
8094{
8095 if (TARGET_SH3E)
8096 {
8097 expand_sf_binop (&gen_subsf3_i, operands);
8098 DONE;
8099 }
8100}")
8101
8102(define_insn "*subsf3_media"
8103 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8104 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8105 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8106 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8107 "fsub.s %1, %2, %0"
8108 [(set_attr "type" "fparith_media")])
225e4f43
R
8109
8110(define_insn "subsf3_i"
66c0b347
R
8111 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8112 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8113 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8114 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
45348d9e 8115 "TARGET_SH3E"
c1aef54d 8116 "fsub %2,%0"
d64264ff
R
8117 [(set_attr "type" "fp")
8118 (set_attr "fp_mode" "single")])
45348d9e 8119
225e4f43
R
8120;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8121;; register in feeding fp instructions. Thus, we cannot generate fmac for
8122;; mixed-precision SH4 targets. To allow it to be still generated for the
8123;; SH3E, we use a separate insn for SH3E mulsf3.
8124
8125(define_expand "mulsf3"
fa5322fa
AO
8126 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8127 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8128 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8129 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
225e4f43
R
8130 "
8131{
8132 if (TARGET_SH4)
8133 expand_sf_binop (&gen_mulsf3_i4, operands);
fa5322fa 8134 else if (TARGET_SH3E)
225e4f43 8135 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
fa5322fa
AO
8136 if (! TARGET_SHMEDIA)
8137 DONE;
225e4f43
R
8138}")
8139
fa5322fa
AO
8140(define_insn "*mulsf3_media"
8141 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8142 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8143 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8144 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8145 "fmul.s %1, %2, %0"
8146 [(set_attr "type" "fparith_media")])
fa5322fa 8147
225e4f43 8148(define_insn "mulsf3_i4"
4b9580a5
R
8149 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8150 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8151 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8152 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
45348d9e 8153 "TARGET_SH3E"
c1aef54d 8154 "fmul %2,%0"
d64264ff
R
8155 [(set_attr "type" "fp")
8156 (set_attr "fp_mode" "single")])
45348d9e 8157
225e4f43 8158(define_insn "mulsf3_ie"
4b9580a5
R
8159 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8160 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8161 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
225e4f43
R
8162 "TARGET_SH3E && ! TARGET_SH4"
8163 "fmul %2,%0"
8164 [(set_attr "type" "fp")])
8165
fa5322fa
AO
8166(define_insn "*mac_media"
8167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8169 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8170 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8171 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8172 "fmac.s %1, %2, %0"
8173 [(set_attr "type" "fparith_media")])
fa5322fa 8174
45348d9e 8175(define_insn "*macsf3"
4b9580a5
R
8176 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8177 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8178 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
225e4f43
R
8179 (match_operand:SF 3 "arith_reg_operand" "0")))
8180 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8181 "TARGET_SH3E && ! TARGET_SH4"
c1aef54d 8182 "fmac fr0,%2,%0"
d64264ff
R
8183 [(set_attr "type" "fp")
8184 (set_attr "fp_mode" "single")])
45348d9e 8185
225e4f43 8186(define_expand "divsf3"
fa5322fa
AO
8187 [(set (match_operand:SF 0 "arith_reg_operand" "")
8188 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8189 (match_operand:SF 2 "arith_reg_operand" "")))]
8190 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8191 "
8192{
8193 if (TARGET_SH3E)
8194 {
8195 expand_sf_binop (&gen_divsf3_i, operands);
8196 DONE;
8197 }
8198}")
8199
8200(define_insn "*divsf3_media"
8201 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8202 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8203 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8204 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8205 "fdiv.s %1, %2, %0"
8206 [(set_attr "type" "fdiv_media")])
225e4f43
R
8207
8208(define_insn "divsf3_i"
45348d9e
JW
8209 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8210 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
225e4f43
R
8211 (match_operand:SF 2 "arith_reg_operand" "f")))
8212 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
45348d9e 8213 "TARGET_SH3E"
c1aef54d 8214 "fdiv %2,%0"
d64264ff
R
8215 [(set_attr "type" "fdiv")
8216 (set_attr "fp_mode" "single")])
45348d9e 8217
fa5322fa
AO
8218(define_insn "floatdisf2"
8219 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8220 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8221 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8222 "float.qs %1, %0"
8223 [(set_attr "type" "fpconv_media")])
fa5322fa 8224
1245df60 8225(define_expand "floatsisf2"
4b9580a5
R
8226 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8227 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
fa5322fa 8228 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
225e4f43
R
8229 "
8230{
8231 if (TARGET_SH4)
8232 {
0c4c9b16 8233 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8234 DONE;
8235 }
225e4f43
R
8236}")
8237
fa5322fa
AO
8238(define_insn "*floatsisf2_media"
8239 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8240 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8241 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8242 "float.ls %1, %0"
8243 [(set_attr "type" "fpconv_media")])
fa5322fa 8244
225e4f43 8245(define_insn "floatsisf2_i4"
4b9580a5
R
8246 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8247 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8248 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
0f805606 8249 "TARGET_SH4"
0c4c9b16 8250 "float %1,%0"
d64264ff
R
8251 [(set_attr "type" "fp")
8252 (set_attr "fp_mode" "single")])
45348d9e 8253
0f805606 8254(define_insn "*floatsisf2_ie"
4b9580a5
R
8255 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8256 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
0f805606
BS
8257 "TARGET_SH3E && ! TARGET_SH4"
8258 "float %1,%0"
8259 [(set_attr "type" "fp")])
45348d9e 8260
fa5322fa
AO
8261(define_insn "fix_truncsfdi2"
8262 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8263 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8264 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8265 "ftrc.sq %1, %0"
8266 [(set_attr "type" "fpconv_media")])
fa5322fa 8267
1245df60 8268(define_expand "fix_truncsfsi2"
4b9580a5
R
8269 [(set (match_operand:SI 0 "fpul_operand" "=y")
8270 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
fa5322fa 8271 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
225e4f43
R
8272 "
8273{
8274 if (TARGET_SH4)
8275 {
0c4c9b16 8276 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8277 DONE;
8278 }
8279}")
8280
fa5322fa
AO
8281(define_insn "*fix_truncsfsi2_media"
8282 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8283 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8284 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8285 "ftrc.sl %1, %0"
8286 [(set_attr "type" "fpconv_media")])
fa5322fa 8287
225e4f43 8288(define_insn "fix_truncsfsi2_i4"
4b9580a5
R
8289 [(set (match_operand:SI 0 "fpul_operand" "=y")
8290 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8291 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8292 "TARGET_SH4"
0c4c9b16 8293 "ftrc %1,%0"
c49439f1 8294 [(set_attr "type" "ftrc_s")
d64264ff 8295 (set_attr "fp_mode" "single")])
225e4f43 8296
0c4c9b16
BS
8297;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8298;; fix_truncsfsi2_i4.
8299;; (define_insn "fix_truncsfsi2_i4_2"
8300;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8301;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
5d00b10a 8302;; (use (reg:PSI FPSCR_REG))
4773afa4 8303;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8304;; "TARGET_SH4"
8305;; "#"
8306;; [(set_attr "length" "4")
8307;; (set_attr "fp_mode" "single")])
8308
8309;;(define_split
8310;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8311;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8312;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8313;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8314;; "TARGET_SH4"
4773afa4 8315;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8316;; (use (match_dup 2))])
4773afa4 8317;; (set (match_dup 0) (reg:SI FPUL_REG))])
45348d9e 8318
1245df60 8319(define_insn "*fixsfsi"
4b9580a5
R
8320 [(set (match_operand:SI 0 "fpul_operand" "=y")
8321 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
225e4f43 8322 "TARGET_SH3E && ! TARGET_SH4"
0c4c9b16 8323 "ftrc %1,%0"
1245df60 8324 [(set_attr "type" "fp")])
45348d9e 8325
1245df60 8326(define_insn "cmpgtsf_t"
4773afa4
AO
8327 [(set (reg:SI T_REG)
8328 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8329 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
225e4f43 8330 "TARGET_SH3E && ! TARGET_SH4"
c1aef54d 8331 "fcmp/gt %1,%0"
d64264ff
R
8332 [(set_attr "type" "fp")
8333 (set_attr "fp_mode" "single")])
45348d9e 8334
1245df60 8335(define_insn "cmpeqsf_t"
4773afa4
AO
8336 [(set (reg:SI T_REG)
8337 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8338 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
225e4f43 8339 "TARGET_SH3E && ! TARGET_SH4"
c1aef54d 8340 "fcmp/eq %1,%0"
d64264ff
R
8341 [(set_attr "type" "fp")
8342 (set_attr "fp_mode" "single")])
45348d9e 8343
1245df60 8344(define_insn "ieee_ccmpeqsf_t"
4773afa4
AO
8345 [(set (reg:SI T_REG)
8346 (ior:SI (reg:SI T_REG)
4b9580a5
R
8347 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8348 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
225e4f43 8349 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
1245df60
R
8350 "* return output_ieee_ccmpeq (insn, operands);"
8351 [(set_attr "length" "4")])
8352
8353
225e4f43 8354(define_insn "cmpgtsf_t_i4"
4773afa4
AO
8355 [(set (reg:SI T_REG)
8356 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8357 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8358 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8359 "TARGET_SH4"
8360 "fcmp/gt %1,%0"
d64264ff
R
8361 [(set_attr "type" "fp")
8362 (set_attr "fp_mode" "single")])
225e4f43
R
8363
8364(define_insn "cmpeqsf_t_i4"
4773afa4
AO
8365 [(set (reg:SI T_REG)
8366 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8367 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8368 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8369 "TARGET_SH4"
8370 "fcmp/eq %1,%0"
d64264ff
R
8371 [(set_attr "type" "fp")
8372 (set_attr "fp_mode" "single")])
225e4f43
R
8373
8374(define_insn "*ieee_ccmpeqsf_t_4"
4773afa4
AO
8375 [(set (reg:SI T_REG)
8376 (ior:SI (reg:SI T_REG)
4b9580a5
R
8377 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8378 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
225e4f43
R
8379 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8380 "TARGET_IEEE && TARGET_SH4"
8381 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8382 [(set_attr "length" "4")
8383 (set_attr "fp_mode" "single")])
225e4f43 8384
fa5322fa
AO
8385(define_insn "cmpeqsf_media"
8386 [(set (match_operand:DI 0 "register_operand" "=r")
8387 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8388 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8389 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8390 "fcmpeq.s %1, %2, %0"
8391 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8392
8393(define_insn "cmpgtsf_media"
8394 [(set (match_operand:DI 0 "register_operand" "=r")
8395 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8396 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8397 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8398 "fcmpgt.s %1, %2, %0"
8399 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8400
8401(define_insn "cmpgesf_media"
8402 [(set (match_operand:DI 0 "register_operand" "=r")
8403 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8404 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8406 "fcmpge.s %1, %2, %0"
8407 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8408
8409(define_insn "cmpunsf_media"
8410 [(set (match_operand:DI 0 "register_operand" "=r")
8411 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8412 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8413 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8414 "fcmpun.s %1, %2, %0"
8415 [(set_attr "type" "fcmp_media")])
fa5322fa 8416
45348d9e 8417(define_expand "cmpsf"
4773afa4
AO
8418 [(set (reg:SI T_REG)
8419 (compare (match_operand:SF 0 "arith_operand" "")
8420 (match_operand:SF 1 "arith_operand" "")))]
fa5322fa 8421 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
45348d9e
JW
8422 "
8423{
8424 sh_compare_op0 = operands[0];
8425 sh_compare_op1 = operands[1];
8426 DONE;
8427}")
b9654711 8428
225e4f43 8429(define_expand "negsf2"
fa5322fa
AO
8430 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8431 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8432 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8433 "
8434{
8435 if (TARGET_SH3E)
8436 {
8437 expand_sf_unop (&gen_negsf2_i, operands);
8438 DONE;
8439 }
8440}")
8441
8442(define_insn "*negsf2_media"
8443 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8444 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8445 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8446 "fneg.s %1, %0"
8447 [(set_attr "type" "fmove_media")])
225e4f43
R
8448
8449(define_insn "negsf2_i"
4b9580a5
R
8450 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8451 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8452 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 8453 "TARGET_SH3E"
c1aef54d 8454 "fneg %0"
d64264ff
R
8455 [(set_attr "type" "fmove")
8456 (set_attr "fp_mode" "single")])
45348d9e 8457
225e4f43 8458(define_expand "sqrtsf2"
fa5322fa
AO
8459 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8460 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8461 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8462 "
8463{
8464 if (TARGET_SH3E)
8465 {
8466 expand_sf_unop (&gen_sqrtsf2_i, operands);
8467 DONE;
8468 }
8469}")
8470
8471(define_insn "*sqrtsf2_media"
8472 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8473 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8474 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8475 "fsqrt.s %1, %0"
8476 [(set_attr "type" "fdiv_media")])
225e4f43
R
8477
8478(define_insn "sqrtsf2_i"
4b9580a5
R
8479 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8480 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8481 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 8482 "TARGET_SH3E"
c1aef54d 8483 "fsqrt %0"
d64264ff
R
8484 [(set_attr "type" "fdiv")
8485 (set_attr "fp_mode" "single")])
45348d9e 8486
225e4f43 8487(define_expand "abssf2"
fa5322fa
AO
8488 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8489 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8490 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8491 "
8492{
8493 if (TARGET_SH3E)
8494 {
8495 expand_sf_unop (&gen_abssf2_i, operands);
8496 DONE;
8497 }
8498}")
8499
8500(define_insn "*abssf2_media"
8501 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8502 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8503 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8504 "fabs.s %1, %0"
8505 [(set_attr "type" "fmove_media")])
225e4f43
R
8506
8507(define_insn "abssf2_i"
4b9580a5
R
8508 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8509 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8510 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 8511 "TARGET_SH3E"
c1aef54d 8512 "fabs %0"
d64264ff
R
8513 [(set_attr "type" "fmove")
8514 (set_attr "fp_mode" "single")])
225e4f43
R
8515
8516(define_expand "adddf3"
fa5322fa
AO
8517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8518 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8519 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8520 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8521 "
8522{
8523 if (TARGET_SH4)
8524 {
8525 expand_df_binop (&gen_adddf3_i, operands);
8526 DONE;
8527 }
8528}")
8529
8530(define_insn "*adddf3_media"
8531 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8532 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8533 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8534 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8535 "fadd.d %1, %2, %0"
8536 [(set_attr "type" "dfparith_media")])
225e4f43
R
8537
8538(define_insn "adddf3_i"
4b9580a5
R
8539 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8540 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8541 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8542 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8543 "TARGET_SH4"
8544 "fadd %2,%0"
d64264ff
R
8545 [(set_attr "type" "dfp_arith")
8546 (set_attr "fp_mode" "double")])
225e4f43
R
8547
8548(define_expand "subdf3"
fa5322fa
AO
8549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8550 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8551 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8552 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8553 "
8554{
8555 if (TARGET_SH4)
8556 {
8557 expand_df_binop (&gen_subdf3_i, operands);
8558 DONE;
8559 }
8560}")
8561
8562(define_insn "*subdf3_media"
8563 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8564 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8565 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8566 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8567 "fsub.d %1, %2, %0"
8568 [(set_attr "type" "dfparith_media")])
225e4f43
R
8569
8570(define_insn "subdf3_i"
4b9580a5
R
8571 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8572 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8573 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8574 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8575 "TARGET_SH4"
8576 "fsub %2,%0"
d64264ff
R
8577 [(set_attr "type" "dfp_arith")
8578 (set_attr "fp_mode" "double")])
225e4f43
R
8579
8580(define_expand "muldf3"
fa5322fa
AO
8581 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8582 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8583 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8584 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8585 "
8586{
8587 if (TARGET_SH4)
8588 {
8589 expand_df_binop (&gen_muldf3_i, operands);
8590 DONE;
8591 }
8592}")
8593
8594(define_insn "*muldf3_media"
8595 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8596 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8597 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8598 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8599 "fmul.d %1, %2, %0"
8600 [(set_attr "type" "dfmul_media")])
225e4f43
R
8601
8602(define_insn "muldf3_i"
4b9580a5
R
8603 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8604 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8605 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8606 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8607 "TARGET_SH4"
8608 "fmul %2,%0"
d64264ff
R
8609 [(set_attr "type" "dfp_arith")
8610 (set_attr "fp_mode" "double")])
225e4f43
R
8611
8612(define_expand "divdf3"
fa5322fa
AO
8613 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8614 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8615 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8616 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8617 "
8618{
8619 if (TARGET_SH4)
8620 {
8621 expand_df_binop (&gen_divdf3_i, operands);
8622 DONE;
8623 }
8624}")
8625
8626(define_insn "*divdf3_media"
8627 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8628 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8629 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8630 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8631 "fdiv.d %1, %2, %0"
8632 [(set_attr "type" "dfdiv_media")])
225e4f43
R
8633
8634(define_insn "divdf3_i"
4b9580a5
R
8635 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8636 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8637 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8638 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8639 "TARGET_SH4"
8640 "fdiv %2,%0"
d64264ff
R
8641 [(set_attr "type" "dfdiv")
8642 (set_attr "fp_mode" "double")])
225e4f43 8643
fa5322fa
AO
8644(define_insn "floatdidf2"
8645 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8646 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8647 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8648 "float.qd %1, %0"
8649 [(set_attr "type" "dfpconv_media")])
fa5322fa 8650
225e4f43 8651(define_expand "floatsidf2"
fa5322fa
AO
8652 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8653 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8654 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8655 "
8656{
fa5322fa
AO
8657 if (TARGET_SH4)
8658 {
8659 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8660 get_fpscr_rtx ()));
8661 DONE;
8662 }
225e4f43
R
8663}")
8664
fa5322fa
AO
8665(define_insn "*floatsidf2_media"
8666 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8667 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8668 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8669 "float.ld %1, %0"
8670 [(set_attr "type" "dfpconv_media")])
fa5322fa 8671
225e4f43 8672(define_insn "floatsidf2_i"
4b9580a5
R
8673 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8674 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8675 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8676 "TARGET_SH4"
0c4c9b16 8677 "float %1,%0"
d64264ff
R
8678 [(set_attr "type" "dfp_conv")
8679 (set_attr "fp_mode" "double")])
225e4f43 8680
fa5322fa
AO
8681(define_insn "fix_truncdfdi2"
8682 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8683 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8684 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8685 "ftrc.dq %1, %0"
8686 [(set_attr "type" "dfpconv_media")])
fa5322fa 8687
225e4f43 8688(define_expand "fix_truncdfsi2"
fa5322fa
AO
8689 [(set (match_operand:SI 0 "fpul_operand" "")
8690 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8691 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8692 "
8693{
fa5322fa
AO
8694 if (TARGET_SH4)
8695 {
8696 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8697 get_fpscr_rtx ()));
8698 DONE;
8699 }
225e4f43
R
8700}")
8701
fa5322fa
AO
8702(define_insn "*fix_truncdfsi2_media"
8703 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8704 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8705 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8706 "ftrc.dl %1, %0"
8707 [(set_attr "type" "dfpconv_media")])
fa5322fa 8708
225e4f43 8709(define_insn "fix_truncdfsi2_i"
4b9580a5
R
8710 [(set (match_operand:SI 0 "fpul_operand" "=y")
8711 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8713 "TARGET_SH4"
0c4c9b16
BS
8714 "ftrc %1,%0"
8715 [(set_attr "type" "dfp_conv")
c49439f1 8716 (set_attr "dfp_comp" "no")
d64264ff 8717 (set_attr "fp_mode" "double")])
225e4f43 8718
0c4c9b16
BS
8719;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8720;; fix_truncdfsi2_i.
8721;; (define_insn "fix_truncdfsi2_i4"
8722;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8723;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8724;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8725;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8726;; "TARGET_SH4"
8727;; "#"
8728;; [(set_attr "length" "4")
8729;; (set_attr "fp_mode" "double")])
52702ae1 8730;;
0c4c9b16
BS
8731;; (define_split
8732;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8733;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8734;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8735;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8736;; "TARGET_SH4"
4773afa4 8737;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8738;; (use (match_dup 2))])
4773afa4 8739;; (set (match_dup 0) (reg:SI FPUL_REG))])
225e4f43
R
8740
8741(define_insn "cmpgtdf_t"
4773afa4
AO
8742 [(set (reg:SI T_REG)
8743 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8744 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
8745 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8746 "TARGET_SH4"
8747 "fcmp/gt %1,%0"
d64264ff
R
8748 [(set_attr "type" "dfp_cmp")
8749 (set_attr "fp_mode" "double")])
225e4f43
R
8750
8751(define_insn "cmpeqdf_t"
4773afa4
AO
8752 [(set (reg:SI T_REG)
8753 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8754 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
8755 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8756 "TARGET_SH4"
8757 "fcmp/eq %1,%0"
d64264ff
R
8758 [(set_attr "type" "dfp_cmp")
8759 (set_attr "fp_mode" "double")])
225e4f43
R
8760
8761(define_insn "*ieee_ccmpeqdf_t"
4773afa4
AO
8762 [(set (reg:SI T_REG)
8763 (ior:SI (reg:SI T_REG)
8764 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8765 (match_operand:DF 1 "arith_reg_operand" "f"))))
225e4f43
R
8766 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8767 "TARGET_IEEE && TARGET_SH4"
8768 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8769 [(set_attr "length" "4")
8770 (set_attr "fp_mode" "double")])
52702ae1 8771
fa5322fa
AO
8772(define_insn "cmpeqdf_media"
8773 [(set (match_operand:DI 0 "register_operand" "=r")
8774 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8775 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8776 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8777 "fcmpeq.d %1,%2,%0"
8778 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8779
8780(define_insn "cmpgtdf_media"
8781 [(set (match_operand:DI 0 "register_operand" "=r")
8782 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8783 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8784 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8785 "fcmpgt.d %1,%2,%0"
8786 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8787
8788(define_insn "cmpgedf_media"
8789 [(set (match_operand:DI 0 "register_operand" "=r")
8790 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8791 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8792 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8793 "fcmpge.d %1,%2,%0"
8794 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8795
8796(define_insn "cmpundf_media"
8797 [(set (match_operand:DI 0 "register_operand" "=r")
8798 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8799 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8800 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8801 "fcmpun.d %1,%2,%0"
8802 [(set_attr "type" "fcmp_media")])
fa5322fa 8803
225e4f43 8804(define_expand "cmpdf"
4773afa4
AO
8805 [(set (reg:SI T_REG)
8806 (compare (match_operand:DF 0 "arith_operand" "")
8807 (match_operand:DF 1 "arith_operand" "")))]
fa5322fa 8808 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8809 "
8810{
8811 sh_compare_op0 = operands[0];
8812 sh_compare_op1 = operands[1];
8813 DONE;
8814}")
8815
8816(define_expand "negdf2"
fa5322fa
AO
8817 [(set (match_operand:DF 0 "arith_reg_operand" "")
8818 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8819 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8820 "
8821{
8822 if (TARGET_SH4)
8823 {
8824 expand_df_unop (&gen_negdf2_i, operands);
8825 DONE;
8826 }
8827}")
8828
8829(define_insn "*negdf2_media"
8830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8831 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8832 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8833 "fneg.d %1, %0"
8834 [(set_attr "type" "fmove_media")])
225e4f43
R
8835
8836(define_insn "negdf2_i"
8837 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8838 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8839 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8840 "TARGET_SH4"
8841 "fneg %0"
d64264ff
R
8842 [(set_attr "type" "fmove")
8843 (set_attr "fp_mode" "double")])
225e4f43
R
8844
8845(define_expand "sqrtdf2"
fa5322fa
AO
8846 [(set (match_operand:DF 0 "arith_reg_operand" "")
8847 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8848 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8849 "
8850{
8851 if (TARGET_SH4)
8852 {
8853 expand_df_unop (&gen_sqrtdf2_i, operands);
8854 DONE;
8855 }
8856}")
8857
8858(define_insn "*sqrtdf2_media"
8859 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8860 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8861 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8862 "fsqrt.d %1, %0"
8863 [(set_attr "type" "dfdiv_media")])
225e4f43
R
8864
8865(define_insn "sqrtdf2_i"
8866 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8867 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8868 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8869 "TARGET_SH4"
8870 "fsqrt %0"
d64264ff
R
8871 [(set_attr "type" "dfdiv")
8872 (set_attr "fp_mode" "double")])
225e4f43
R
8873
8874(define_expand "absdf2"
fa5322fa
AO
8875 [(set (match_operand:DF 0 "arith_reg_operand" "")
8876 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8877 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8878 "
8879{
8880 if (TARGET_SH4)
8881 {
8882 expand_df_unop (&gen_absdf2_i, operands);
8883 DONE;
8884 }
8885}")
8886
8887(define_insn "*absdf2_media"
8888 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8889 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8890 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8891 "fabs.d %1, %0"
8892 [(set_attr "type" "fmove_media")])
225e4f43
R
8893
8894(define_insn "absdf2_i"
8895 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8896 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8897 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8898 "TARGET_SH4"
8899 "fabs %0"
d64264ff
R
8900 [(set_attr "type" "fmove")
8901 (set_attr "fp_mode" "double")])
225e4f43
R
8902
8903(define_expand "extendsfdf2"
fa5322fa
AO
8904 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8905 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8906 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8907 "
8908{
fa5322fa
AO
8909 if (TARGET_SH4)
8910 {
8911 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8912 get_fpscr_rtx ()));
8913 DONE;
8914 }
225e4f43
R
8915}")
8916
fa5322fa
AO
8917(define_insn "*extendsfdf2_media"
8918 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8919 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8920 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8921 "fcnv.sd %1, %0"
8922 [(set_attr "type" "dfpconv_media")])
fa5322fa 8923
225e4f43 8924(define_insn "extendsfdf2_i4"
4b9580a5
R
8925 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8926 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
0c4c9b16 8927 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8928 "TARGET_SH4"
0c4c9b16 8929 "fcnvsd %1,%0"
d64264ff
R
8930 [(set_attr "type" "fp")
8931 (set_attr "fp_mode" "double")])
225e4f43
R
8932
8933(define_expand "truncdfsf2"
fa5322fa
AO
8934 [(set (match_operand:SF 0 "fpul_operand" "")
8935 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8936 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8937 "
8938{
fa5322fa
AO
8939 if (TARGET_SH4)
8940 {
8941 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8942 get_fpscr_rtx ()));
8943 DONE;
8944 }
225e4f43
R
8945}")
8946
fa5322fa
AO
8947(define_insn "*truncdfsf2_media"
8948 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8949 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8950 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8951 "fcnv.ds %1, %0"
8952 [(set_attr "type" "dfpconv_media")])
fa5322fa 8953
225e4f43 8954(define_insn "truncdfsf2_i4"
4b9580a5
R
8955 [(set (match_operand:SF 0 "fpul_operand" "=y")
8956 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8957 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8958 "TARGET_SH4"
0c4c9b16 8959 "fcnvds %1,%0"
d64264ff
R
8960 [(set_attr "type" "fp")
8961 (set_attr "fp_mode" "double")])
45348d9e 8962\f
725de644
JW
8963;; Bit field extract patterns. These give better code for packed bitfields,
8964;; because they allow auto-increment addresses to be generated.
8965
8966(define_expand "insv"
8967 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8968 (match_operand:SI 1 "immediate_operand" "")
8969 (match_operand:SI 2 "immediate_operand" ""))
8970 (match_operand:SI 3 "general_operand" ""))]
fa5322fa 8971 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
725de644
JW
8972 "
8973{
a7f52356
R
8974 rtx addr_target, orig_address, shift_reg, qi_val;
8975 HOST_WIDE_INT bitsize, size, v;
8976 rtx x = operands[3];
725de644
JW
8977
8978 /* ??? expmed doesn't care for non-register predicates. */
8979 if (! memory_operand (operands[0], VOIDmode)
8980 || ! immediate_operand (operands[1], VOIDmode)
8981 || ! immediate_operand (operands[2], VOIDmode)
a7f52356 8982 || ! general_operand (x, VOIDmode))
725de644
JW
8983 FAIL;
8984 /* If this isn't a 16 / 24 / 32 bit field, or if
8985 it doesn't start on a byte boundary, then fail. */
a7f52356
R
8986 bitsize = INTVAL (operands[1]);
8987 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
725de644
JW
8988 || (INTVAL (operands[2]) % 8) != 0)
8989 FAIL;
8990
a7f52356 8991 size = bitsize / 8;
725de644 8992 orig_address = XEXP (operands[0], 0);
725de644 8993 shift_reg = gen_reg_rtx (SImode);
a7f52356
R
8994 if (GET_CODE (x) == CONST_INT)
8995 {
8996 v = INTVAL (x);
8997 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8998 }
8999 else
9000 {
9001 emit_insn (gen_movsi (shift_reg, operands[3]));
9002 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9003 }
ea3cbda5 9004 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
725de644 9005
792760b9 9006 operands[0] = replace_equiv_address (operands[0], addr_target);
a7f52356 9007 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9008
9009 while (size -= 1)
9010 {
a7f52356
R
9011 if (GET_CODE (x) == CONST_INT)
9012 qi_val
9013 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9014 else
9015 {
9016 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9017 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9018 }
725de644 9019 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
a7f52356 9020 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9021 }
9022
9023 DONE;
9024}")
9025\f
51bd623f
JW
9026;; -------------------------------------------------------------------------
9027;; Peepholes
9028;; -------------------------------------------------------------------------
961c4780 9029
51bd623f
JW
9030;; This matches cases where a stack pointer increment at the start of the
9031;; epilogue combines with a stack slot read loading the return value.
aa684c94 9032
07a45e5c 9033(define_peephole
51bd623f
JW
9034 [(set (match_operand:SI 0 "arith_reg_operand" "")
9035 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9036 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
fa5322fa 9037 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
51bd623f 9038 "mov.l @%1+,%0")
00f8ff66 9039
51bd623f 9040;; See the comment on the dt combiner pattern above.
00f8ff66 9041
07a45e5c
JW
9042(define_peephole
9043 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
00f8ff66
SC
9044 (plus:SI (match_dup 0)
9045 (const_int -1)))
4773afa4 9046 (set (reg:SI T_REG)
00f8ff66
SC
9047 (eq:SI (match_dup 0)
9048 (const_int 0)))]
9049 "TARGET_SH2"
9050 "dt %0")
e4931540
RK
9051
9052;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9053;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9054;; reload when the constant is too large for a reg+offset address.
9055
9056;; ??? We would get much better code if this was done in reload. This would
9057;; require modifying find_reloads_address to recognize that if the constant
9058;; is out-of-range for an immediate add, then we get better code by reloading
9059;; the constant into a register than by reloading the sum into a register,
9060;; since the former is one instruction shorter if the address does not need
9061;; to be offsettable. Unfortunately this does not work, because there is
9062;; only one register, r0, that can be used as an index register. This register
9063;; is also the function return value register. So, if we try to force reload
9064;; to use double-reg addresses, then we end up with some instructions that
9065;; need to use r0 twice. The only way to fix this is to change the calling
9066;; convention so that r0 is not used to return values.
9067
9068(define_peephole
9069 [(set (match_operand:SI 0 "register_operand" "=r")
9070 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9071 (set (mem:SI (match_dup 0))
9072 (match_operand:SI 2 "general_movsrc_operand" ""))]
fa5322fa 9073 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9074 "mov.l %2,@(%0,%1)")
9075
9076(define_peephole
9077 [(set (match_operand:SI 0 "register_operand" "=r")
9078 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9079 (set (match_operand:SI 2 "general_movdst_operand" "")
9080 (mem:SI (match_dup 0)))]
fa5322fa 9081 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9082 "mov.l @(%0,%1),%2")
9083
9084(define_peephole
9085 [(set (match_operand:SI 0 "register_operand" "=r")
9086 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9087 (set (mem:HI (match_dup 0))
9088 (match_operand:HI 2 "general_movsrc_operand" ""))]
fa5322fa 9089 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9090 "mov.w %2,@(%0,%1)")
9091
9092(define_peephole
9093 [(set (match_operand:SI 0 "register_operand" "=r")
9094 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9095 (set (match_operand:HI 2 "general_movdst_operand" "")
9096 (mem:HI (match_dup 0)))]
fa5322fa 9097 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9098 "mov.w @(%0,%1),%2")
9099
9100(define_peephole
9101 [(set (match_operand:SI 0 "register_operand" "=r")
9102 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9103 (set (mem:QI (match_dup 0))
9104 (match_operand:QI 2 "general_movsrc_operand" ""))]
fa5322fa 9105 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9106 "mov.b %2,@(%0,%1)")
9107
9108(define_peephole
9109 [(set (match_operand:SI 0 "register_operand" "=r")
9110 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9111 (set (match_operand:QI 2 "general_movdst_operand" "")
9112 (mem:QI (match_dup 0)))]
fa5322fa 9113 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9114 "mov.b @(%0,%1),%2")
9115
9116(define_peephole
9117 [(set (match_operand:SI 0 "register_operand" "=r")
9118 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9119 (set (mem:SF (match_dup 0))
9120 (match_operand:SF 2 "general_movsrc_operand" ""))]
fa5322fa 9121 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9122 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9123 || (GET_CODE (operands[2]) == SUBREG
9124 && REGNO (SUBREG_REG (operands[2])) < 16))
9125 && reg_unused_after (operands[0], insn)"
e4931540
RK
9126 "mov.l %2,@(%0,%1)")
9127
9128(define_peephole
9129 [(set (match_operand:SI 0 "register_operand" "=r")
9130 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9131 (set (match_operand:SF 2 "general_movdst_operand" "")
9132
9133 (mem:SF (match_dup 0)))]
fa5322fa 9134 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9135 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9136 || (GET_CODE (operands[2]) == SUBREG
9137 && REGNO (SUBREG_REG (operands[2])) < 16))
9138 && reg_unused_after (operands[0], insn)"
e4931540 9139 "mov.l @(%0,%1),%2")
45348d9e
JW
9140
9141(define_peephole
9142 [(set (match_operand:SI 0 "register_operand" "=r")
9143 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9144 (set (mem:SF (match_dup 0))
9145 (match_operand:SF 2 "general_movsrc_operand" ""))]
fa5322fa 9146 "TARGET_SH3E && REGNO (operands[0]) == 0
104ee20b
AO
9147 && ((GET_CODE (operands[2]) == REG
9148 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9149 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9150 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9151 && reg_unused_after (operands[0], insn)"
1245df60 9152 "fmov{.s|} %2,@(%0,%1)")
45348d9e
JW
9153
9154(define_peephole
9155 [(set (match_operand:SI 0 "register_operand" "=r")
9156 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9157 (set (match_operand:SF 2 "general_movdst_operand" "")
9158
9159 (mem:SF (match_dup 0)))]
fa5322fa 9160 "TARGET_SH3E && REGNO (operands[0]) == 0
104ee20b
AO
9161 && ((GET_CODE (operands[2]) == REG
9162 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9163 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9164 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9165 && reg_unused_after (operands[0], insn)"
1245df60 9166 "fmov{.s|} @(%0,%1),%2")
4408efce
JL
9167
9168;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9169(define_insn "sp_switch_1"
9170 [(const_int 1)]
fa5322fa 9171 "TARGET_SH1"
4408efce
JL
9172 "*
9173{
9174 rtx xoperands[1];
9175
9176 xoperands[0] = sp_switch;
9177 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9178 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9179 return \"mov r0,r15\";
9180}"
9181 [(set_attr "length" "10")])
4408efce 9182
956d6950 9183;; Switch back to the original stack for interrupt functions with the
4408efce
JL
9184;; sp_switch attribute. */
9185(define_insn "sp_switch_2"
9186 [(const_int 2)]
fa5322fa 9187 "TARGET_SH1"
4408efce
JL
9188 "mov.l @r15+,r15\;mov.l @r15+,r0"
9189 [(set_attr "length" "4")])
fae15c93 9190
c1b92d09
R
9191;; Integer vector moves
9192
9193(define_expand "movv8qi"
9194 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9195 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9196 "TARGET_SHMEDIA"
9197 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9198
9199(define_insn "movv8qi_i"
9200 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
d9da94a1 9201 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
c1b92d09
R
9202 "TARGET_SHMEDIA
9203 && (register_operand (operands[0], V8QImode)
d9da94a1 9204 || sh_register_operand (operands[1], V8QImode))"
c1b92d09
R
9205 "@
9206 add %1, r63, %0
9207 movi %1, %0
9208 #
9209 ld%M1.q %m1, %0
d9da94a1 9210 st%M0.q %m0, %N1"
c1b92d09
R
9211 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9212 (set_attr "length" "4,4,16,4,4")])
9213
9214(define_split
9215 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9216 (subreg:V8QI (const_int 0) 0))]
9217 "TARGET_SHMEDIA"
9218 [(set (match_dup 0)
9219 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9220 (const_int 0) (const_int 0) (const_int 0)
9221 (const_int 0) (const_int 0)]))])
9222
9223(define_split
9224 [(set (match_operand 0 "arith_reg_dest" "")
9225 (match_operand 1 "sh_rep_vec" ""))]
9226 "TARGET_SHMEDIA && reload_completed
9227 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9228 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9229 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9230 && (XVECEXP (operands[1], 0, 0) != const0_rtx
c034672a
R
9231 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9232 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9233 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
c1b92d09
R
9234 [(set (match_dup 0) (match_dup 1))
9235 (match_dup 2)]
9236 "
9237{
9238 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9239 rtx elt1 = XVECEXP (operands[1], 0, 1);
9240
9241 if (unit_size > 2)
9242 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9243 else
750afc12
R
9244 {
9245 if (unit_size < 2)
9246 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9247 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9248 }
c1b92d09
R
9249 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9250 operands[1] = XVECEXP (operands[1], 0, 0);
9251 if (unit_size < 2)
9252 {
9253 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9254 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9255 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9256 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9257 else
9258 {
9259 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9260 operands[1]
9261 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9262 }
9263 }
9264}")
9265
9266(define_split
9267 [(set (match_operand 0 "arith_reg_dest" "")
9268 (match_operand 1 "sh_const_vec" ""))]
9269 "TARGET_SHMEDIA && reload_completed
9270 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9271 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
0ac78517 9272 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
c1b92d09
R
9273 [(set (match_dup 0) (match_dup 1))]
9274 "
9275{
9276 rtx v = operands[1];
9277 enum machine_mode new_mode
9278 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9279
9280 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9281 operands[1]
52702ae1 9282 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
c1b92d09
R
9283}")
9284
9285(define_expand "movv2hi"
9286 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9287 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9288 "TARGET_SHMEDIA"
9289 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9290
9291(define_insn "movv2hi_i"
9292 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
d9da94a1 9293 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
c1b92d09
R
9294 "TARGET_SHMEDIA
9295 && (register_operand (operands[0], V2HImode)
d9da94a1 9296 || sh_register_operand (operands[1], V2HImode))"
c1b92d09
R
9297 "@
9298 addz.l %1, r63, %0
9299 movi %1, %0
9300 #
9301 ld%M1.l %m1, %0
d9da94a1 9302 st%M0.l %m0, %N1"
c1b92d09
R
9303 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9304 (set_attr "length" "4,4,16,4,4")])
9305
9306(define_expand "movv4hi"
9307 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9308 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9309 "TARGET_SHMEDIA"
9310 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9311
9312(define_insn "movv4hi_i"
9313 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
d9da94a1 9314 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
c1b92d09
R
9315 "TARGET_SHMEDIA
9316 && (register_operand (operands[0], V4HImode)
d9da94a1 9317 || sh_register_operand (operands[1], V4HImode))"
c1b92d09
R
9318 "@
9319 add %1, r63, %0
9320 movi %1, %0
9321 #
9322 ld%M1.q %m1, %0
d9da94a1 9323 st%M0.q %m0, %N1"
c1b92d09
R
9324 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9325 (set_attr "length" "4,4,16,4,4")])
9326
9327(define_expand "movv2si"
9328 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9329 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9330 "TARGET_SHMEDIA"
9331 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9332
9333(define_insn "movv2si_i"
9334 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
d9da94a1 9335 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
c1b92d09
R
9336 "TARGET_SHMEDIA
9337 && (register_operand (operands[0], V2SImode)
d9da94a1 9338 || sh_register_operand (operands[1], V2SImode))"
c1b92d09
R
9339 "@
9340 add %1, r63, %0
52702ae1 9341 #
c1b92d09
R
9342 #
9343 ld%M1.q %m1, %0
d9da94a1 9344 st%M0.q %m0, %N1"
c1b92d09
R
9345 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9346 (set_attr "length" "4,4,16,4,4")])
9347
9348;; Multimedia Intrinsics
9349
9350(define_insn "absv2si2"
9351 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9352 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9353 "TARGET_SHMEDIA"
9354 "mabs.l %1, %0"
9355 [(set_attr "type" "mcmp_media")])
9356
9357(define_insn "absv4hi2"
9358 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9359 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9360 "TARGET_SHMEDIA"
9361 "mabs.w %1, %0"
9362 [(set_attr "type" "mcmp_media")])
9363
9364(define_insn "addv2si3"
9365 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9366 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9367 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9368 "TARGET_SHMEDIA"
9369 "madd.l %1, %2, %0"
9370 [(set_attr "type" "arith_media")])
9371
9372(define_insn "addv4hi3"
9373 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9374 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9375 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9376 "TARGET_SHMEDIA"
9377 "madd.w %1, %2, %0"
9378 [(set_attr "type" "arith_media")])
9379
9380(define_insn "ssaddv2si3"
9381 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9382 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9383 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9384 "TARGET_SHMEDIA"
9385 "madds.l %1, %2, %0"
9386 [(set_attr "type" "mcmp_media")])
9387
9388(define_insn "usaddv8qi3"
9389 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9390 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9391 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9392 "TARGET_SHMEDIA"
9393 "madds.ub %1, %2, %0"
9394 [(set_attr "type" "mcmp_media")])
9395
9396(define_insn "ssaddv4hi3"
9397 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9398 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9399 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9400 "TARGET_SHMEDIA"
9401 "madds.w %1, %2, %0"
9402 [(set_attr "type" "mcmp_media")])
9403
9404(define_insn "negcmpeqv8qi"
9405 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9406 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9407 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9408 "TARGET_SHMEDIA"
9409 "mcmpeq.b %N1, %N2, %0"
9410 [(set_attr "type" "mcmp_media")])
9411
9412(define_insn "negcmpeqv2si"
9413 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9414 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9415 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9416 "TARGET_SHMEDIA"
9417 "mcmpeq.l %N1, %N2, %0"
9418 [(set_attr "type" "mcmp_media")])
9419
9420(define_insn "negcmpeqv4hi"
9421 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9422 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9423 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9424 "TARGET_SHMEDIA"
9425 "mcmpeq.w %N1, %N2, %0"
9426 [(set_attr "type" "mcmp_media")])
9427
9428(define_insn "negcmpgtuv8qi"
9429 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9430 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9431 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9432 "TARGET_SHMEDIA"
9433 "mcmpgt.ub %N1, %N2, %0"
9434 [(set_attr "type" "mcmp_media")])
9435
9436(define_insn "negcmpgtv2si"
9437 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9438 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9439 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9440 "TARGET_SHMEDIA"
9441 "mcmpgt.l %N1, %N2, %0"
9442 [(set_attr "type" "mcmp_media")])
9443
9444(define_insn "negcmpgtv4hi"
9445 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9446 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9447 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9448 "TARGET_SHMEDIA"
9449 "mcmpgt.w %N1, %N2, %0"
9450 [(set_attr "type" "mcmp_media")])
9451
9452(define_insn "mcmv"
9453 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9454 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9455 (match_operand:DI 2 "arith_reg_operand" "r"))
9456 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9457 (not:DI (match_dup 2)))))]
9458 "TARGET_SHMEDIA"
9459 "mcmv %N1, %2, %0"
9460 [(set_attr "type" "arith_media")])
9461
9462(define_insn "mcnvs_lw"
9463 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9464 (vec_concat:V4HI
9465 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9466 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9467 "TARGET_SHMEDIA"
9468 "mcnvs.lw %N1, %N2, %0"
9469 [(set_attr "type" "mcmp_media")])
9470
9471(define_insn "mcnvs_wb"
9472 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9473 (vec_concat:V8QI
9474 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9475 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9476 "TARGET_SHMEDIA"
9477 "mcnvs.wb %N1, %N2, %0"
9478 [(set_attr "type" "mcmp_media")])
9479
9480(define_insn "mcnvs_wub"
9481 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9482 (vec_concat:V8QI
9483 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9484 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9485 "TARGET_SHMEDIA"
9486 "mcnvs.wub %N1, %N2, %0"
9487 [(set_attr "type" "mcmp_media")])
9488
9489(define_insn "mextr_rl"
9490 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9491 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9492 (match_operand:HI 3 "mextr_bit_offset" "i"))
9493 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9494 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9495 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9496 "*
9497{
9498 static char templ[16];
9499
9500 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9501 (int) INTVAL (operands[3]) >> 3);
9502 return templ;
9503}"
9504 [(set_attr "type" "arith_media")])
9505
9506(define_insn "*mextr_lr"
9507 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9508 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9509 (match_operand:HI 3 "mextr_bit_offset" "i"))
9510 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9511 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9512 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9513 "*
9514{
9515 static char templ[16];
9516
9517 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9518 (int) INTVAL (operands[4]) >> 3);
9519 return templ;
9520}"
9521 [(set_attr "type" "arith_media")])
9522
9523; mextrN can be modelled with vec_select / vec_concat, but the selection
9524; vector then varies depending on endianness.
9525(define_expand "mextr1"
0ac78517
R
9526 [(match_operand:DI 0 "arith_reg_dest" "")
9527 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9528 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9529 "TARGET_SHMEDIA"
9530 "
9531{
0ac78517 9532 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9533 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9534 DONE;
9535}")
9536
9537(define_expand "mextr2"
0ac78517
R
9538 [(match_operand:DI 0 "arith_reg_dest" "")
9539 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9540 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9541 "TARGET_SHMEDIA"
9542 "
9543{
0ac78517 9544 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9545 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9546 DONE;
9547}")
9548
9549(define_expand "mextr3"
0ac78517
R
9550 [(match_operand:DI 0 "arith_reg_dest" "")
9551 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9552 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9553 "TARGET_SHMEDIA"
9554 "
9555{
0ac78517 9556 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9557 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9558 DONE;
9559}")
9560
9561(define_expand "mextr4"
0ac78517
R
9562 [(match_operand:DI 0 "arith_reg_dest" "")
9563 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9564 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9565 "TARGET_SHMEDIA"
9566 "
9567{
0ac78517 9568 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9569 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9570 DONE;
9571}")
9572
9573(define_expand "mextr5"
0ac78517
R
9574 [(match_operand:DI 0 "arith_reg_dest" "")
9575 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9576 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9577 "TARGET_SHMEDIA"
9578 "
9579{
0ac78517 9580 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9581 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9582 DONE;
9583}")
9584
9585(define_expand "mextr6"
0ac78517
R
9586 [(match_operand:DI 0 "arith_reg_dest" "")
9587 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9588 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9589 "TARGET_SHMEDIA"
9590 "
9591{
0ac78517 9592 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9593 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9594 DONE;
9595}")
9596
9597(define_expand "mextr7"
0ac78517
R
9598 [(match_operand:DI 0 "arith_reg_dest" "")
9599 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9600 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
c1b92d09
R
9601 "TARGET_SHMEDIA"
9602 "
9603{
0ac78517 9604 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9605 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9606 DONE;
9607}")
9608
9609(define_expand "mmacfx_wl"
9610 [(match_operand:V2SI 0 "arith_reg_dest" "")
9611 (match_operand:V2HI 1 "extend_reg_operand" "")
9612 (match_operand:V2HI 2 "extend_reg_operand" "")
9613 (match_operand:V2SI 3 "arith_reg_operand" "")]
9614 "TARGET_SHMEDIA"
9615 "
9616{
9617 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9618 operands[1], operands[2]));
9619 DONE;
9620}")
9621
9622(define_insn "mmacfx_wl_i"
9623 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9624 (ss_plus:V2SI
9625 (match_operand:V2SI 1 "arith_reg_operand" "0")
9626 (ss_truncate:V2SI
9627 (ashift:V2DI
9628 (sign_extend:V2DI
9629 (mult:V2SI
9630 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9631 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9632 (const_int 1)))))]
9633 "TARGET_SHMEDIA"
9634 "mmacfx.wl %2, %3, %0"
9635 [(set_attr "type" "mac_media")])
9636
9637(define_expand "mmacnfx_wl"
9638 [(match_operand:V2SI 0 "arith_reg_dest" "")
9639 (match_operand:V2HI 1 "extend_reg_operand" "")
9640 (match_operand:V2HI 2 "extend_reg_operand" "")
9641 (match_operand:V2SI 3 "arith_reg_operand" "")]
9642 "TARGET_SHMEDIA"
9643 "
9644{
9645 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9646 operands[1], operands[2]));
9647 DONE;
9648}")
9649
9650(define_insn "mmacnfx_wl_i"
9651 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9652 (ss_minus:V2SI
9653 (match_operand:V2SI 1 "arith_reg_operand" "0")
9654 (ss_truncate:V2SI
9655 (ashift:V2DI
9656 (sign_extend:V2DI
9657 (mult:V2SI
9658 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9659 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9660 (const_int 1)))))]
9661 "TARGET_SHMEDIA"
9662 "mmacnfx.wl %2, %3, %0"
9663 [(set_attr "type" "mac_media")])
9664
9665(define_insn "mulv2si3"
9666 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9667 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9668 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9669 "TARGET_SHMEDIA"
9670 "mmul.l %1, %2, %0"
9671 [(set_attr "type" "d2mpy_media")])
9672
9673(define_insn "mulv4hi3"
9674 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9675 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9676 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9677 "TARGET_SHMEDIA"
9678 "mmul.w %1, %2, %0"
9679 [(set_attr "type" "dmpy_media")])
9680
9681(define_insn "mmulfx_l"
9682 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9683 (ss_truncate:V2SI
9684 (ashiftrt:V2DI
9685 (mult:V2DI
9686 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9687 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9688 (const_int 31))))]
9689 "TARGET_SHMEDIA"
9690 "mmulfx.l %1, %2, %0"
9691 [(set_attr "type" "d2mpy_media")])
9692
9693(define_insn "mmulfx_w"
9694 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9695 (ss_truncate:V4HI
9696 (ashiftrt:V4SI
9697 (mult:V4SI
9698 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9699 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9700 (const_int 15))))]
9701 "TARGET_SHMEDIA"
9702 "mmulfx.w %1, %2, %0"
9703 [(set_attr "type" "dmpy_media")])
9704
9705(define_insn "mmulfxrp_w"
9706 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9707 (ss_truncate:V4HI
9708 (ashiftrt:V4SI
9709 (plus:V4SI
9710 (mult:V4SI
9711 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9712 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9713 (const_int 16384))
9714 (const_int 15))))]
9715 "TARGET_SHMEDIA"
9716 "mmulfxrp.w %1, %2, %0"
9717 [(set_attr "type" "dmpy_media")])
9718
9719(define_expand "mmulhi_wl"
9720 [(match_operand:V2SI 0 "arith_reg_dest" "")
9721 (match_operand:V4HI 1 "arith_reg_operand" "")
9722 (match_operand:V4HI 2 "arith_reg_operand" "")]
9723 "TARGET_SHMEDIA"
9724 "
9725{
9726 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9727 (operands[0], operands[1], operands[2]));
9728 DONE;
9729}")
9730
9731(define_expand "mmullo_wl"
9732 [(match_operand:V2SI 0 "arith_reg_dest" "")
9733 (match_operand:V4HI 1 "arith_reg_operand" "")
9734 (match_operand:V4HI 2 "arith_reg_operand" "")]
9735 "TARGET_SHMEDIA"
9736 "
9737{
9738 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9739 (operands[0], operands[1], operands[2]));
9740 DONE;
9741}")
9742
9743(define_insn "mmul23_wl"
9744 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9745 (vec_select:V2SI
9746 (mult:V4SI
9747 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9748 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 9749 (parallel [(const_int 2) (const_int 3)])))]
c1b92d09
R
9750 "TARGET_SHMEDIA"
9751 "* return (TARGET_LITTLE_ENDIAN
9752 ? \"mmulhi.wl %1, %2, %0\"
9753 : \"mmullo.wl %1, %2, %0\");"
9754 [(set_attr "type" "dmpy_media")])
9755
9756(define_insn "mmul01_wl"
9757 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9758 (vec_select:V2SI
9759 (mult:V4SI
9760 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9761 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 9762 (parallel [(const_int 0) (const_int 1)])))]
c1b92d09
R
9763 "TARGET_SHMEDIA"
9764 "* return (TARGET_LITTLE_ENDIAN
9765 ? \"mmullo.wl %1, %2, %0\"
9766 : \"mmulhi.wl %1, %2, %0\");"
9767 [(set_attr "type" "dmpy_media")])
9768
9769(define_expand "mmulsum_wq"
9770 [(match_operand:DI 0 "arith_reg_dest" "")
9771 (match_operand:V4HI 1 "arith_reg_operand" "")
9772 (match_operand:V4HI 2 "arith_reg_operand" "")
9773 (match_operand:DI 3 "arith_reg_operand" "")]
9774 "TARGET_SHMEDIA"
9775 "
9776{
9777 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9778 operands[1], operands[2]));
9779 DONE;
9780}")
9781
9782(define_insn "mmulsum_wq_i"
9783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9784 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9785 (plus:DI
9786 (plus:DI
9787 (vec_select:DI
9788 (mult:V4DI
9789 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9790 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
0ac78517 9791 (parallel [(const_int 0)]))
c1b92d09
R
9792 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9793 (sign_extend:V4DI (match_dup 3)))
0ac78517 9794 (parallel [(const_int 1)])))
c1b92d09
R
9795 (plus:DI
9796 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9797 (sign_extend:V4DI (match_dup 3)))
0ac78517 9798 (parallel [(const_int 2)]))
c1b92d09
R
9799 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9800 (sign_extend:V4DI (match_dup 3)))
0ac78517 9801 (parallel [(const_int 3)]))))))]
c1b92d09
R
9802 "TARGET_SHMEDIA"
9803 "mmulsum.wq %2, %3, %0"
9804 [(set_attr "type" "mac_media")])
9805
9806(define_expand "mperm_w"
9807 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9808 (match_operand:V4HI 1 "arith_reg_operand" "r")
9809 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9810 "TARGET_SHMEDIA"
9811 "
9812{
9813 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9814 (operands[0], operands[1], operands[2]));
c49439f1 9815 DONE;
c1b92d09
R
9816}")
9817
9818; This use of vec_select isn't exactly correct according to rtl.texi
9819; (because not constant), but it seems a straightforward extension.
9820(define_insn "mperm_w_little"
9821 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9822 (vec_select:V4HI
9823 (match_operand:V4HI 1 "arith_reg_operand" "r")
9824 (parallel
502e6d5a
R
9825 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9826 (const_int 2) (const_int 0))
9827 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9828 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9829 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
c1b92d09
R
9830 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9831 "mperm.w %1, %N2, %0"
9832 [(set_attr "type" "arith_media")])
9833
9834(define_insn "mperm_w_big"
9835 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9836 (vec_select:V4HI
9837 (match_operand:V4HI 1 "arith_reg_operand" "r")
9838 (parallel
502e6d5a
R
9839 [(zero_extract:QI (not:QI (match_operand:QI 2
9840 "extend_reg_or_0_operand" "rU"))
9841 (const_int 2) (const_int 0))
9842 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9843 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9844 (zero_extract:QI (not:QI (match_dup 2))
9845 (const_int 2) (const_int 6))])))]
c1b92d09
R
9846 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9847 "mperm.w %1, %N2, %0"
9848 [(set_attr "type" "arith_media")])
9849
9850(define_insn "mperm_w0"
9851 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9852 (vec_duplicate:V4HI (truncate:HI (match_operand 1
e69d1422 9853 "trunc_hi_operand" "r"))))]
c1b92d09
R
9854 "TARGET_SHMEDIA"
9855 "mperm.w %1, r63, %0"
9856 [(set_attr "type" "arith_media")])
9857
9858(define_expand "msad_ubq"
9859 [(match_operand:DI 0 "arith_reg_dest" "")
9860 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9861 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9862 (match_operand:DI 3 "arith_reg_operand" "")]
9863 "TARGET_SHMEDIA"
9864 "
9865{
9866 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9867 operands[1], operands[2]));
9868 DONE;
9869}")
9870
9871(define_insn "msad_ubq_i"
9872 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9873 (plus:DI
9874 (plus:DI
9875 (plus:DI
9876 (plus:DI
9877 (match_operand:DI 1 "arith_reg_operand" "0")
9878 (abs:DI (vec_select:DI
9879 (minus:V8DI
9880 (zero_extend:V8DI
9881 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9882 (zero_extend:V8DI
9883 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
0ac78517 9884 (parallel [(const_int 0)]))))
c1b92d09
R
9885 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9886 (zero_extend:V8DI (match_dup 3)))
0ac78517 9887 (parallel [(const_int 1)]))))
c1b92d09
R
9888 (plus:DI
9889 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9890 (zero_extend:V8DI (match_dup 3)))
0ac78517 9891 (parallel [(const_int 2)])))
c1b92d09
R
9892 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9893 (zero_extend:V8DI (match_dup 3)))
0ac78517 9894 (parallel [(const_int 3)])))))
c1b92d09
R
9895 (plus:DI
9896 (plus:DI
9897 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9898 (zero_extend:V8DI (match_dup 3)))
0ac78517 9899 (parallel [(const_int 4)])))
c1b92d09
R
9900 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9901 (zero_extend:V8DI (match_dup 3)))
0ac78517 9902 (parallel [(const_int 5)]))))
c1b92d09
R
9903 (plus:DI
9904 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9905 (zero_extend:V8DI (match_dup 3)))
0ac78517 9906 (parallel [(const_int 6)])))
c1b92d09
R
9907 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9908 (zero_extend:V8DI (match_dup 3)))
0ac78517 9909 (parallel [(const_int 7)])))))))]
c1b92d09
R
9910 "TARGET_SHMEDIA"
9911 "msad.ubq %N2, %N3, %0"
9912 [(set_attr "type" "mac_media")])
9913
9914(define_insn "mshalds_l"
9915 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9916 (ss_truncate:V2SI
9917 (ashift:V2DI
9918 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9919 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9920 (const_int 31)))))]
9921 "TARGET_SHMEDIA"
9922 "mshalds.l %1, %2, %0"
9923 [(set_attr "type" "mcmp_media")])
9924
9925(define_insn "mshalds_w"
9926 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9927 (ss_truncate:V4HI
9928 (ashift:V4SI
9929 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9930 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9931 (const_int 15)))))]
9932 "TARGET_SHMEDIA"
9933 "mshalds.w %1, %2, %0"
9934 [(set_attr "type" "mcmp_media")])
9935
9936(define_insn "ashrv2si3"
9937 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9938 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9939 (match_operand:DI 2 "arith_reg_operand" "r")))]
9940 "TARGET_SHMEDIA"
9941 "mshard.l %1, %2, %0"
9942 [(set_attr "type" "arith_media")])
9943
9944(define_insn "ashrv4hi3"
9945 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9946 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9947 (match_operand:DI 2 "arith_reg_operand" "r")))]
9948 "TARGET_SHMEDIA"
9949 "mshard.w %1, %2, %0"
9950 [(set_attr "type" "arith_media")])
9951
9952(define_insn "mshards_q"
9953 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9954 (ss_truncate:HI
9955 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9956 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9957 "TARGET_SHMEDIA"
9958 "mshards.q %1, %N2, %0"
9959 [(set_attr "type" "mcmp_media")])
9960
9961(define_expand "mshfhi_b"
9962 [(match_operand:V8QI 0 "arith_reg_dest" "")
9963 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9964 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9965 "TARGET_SHMEDIA"
9966 "
9967{
9968 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9969 (operands[0], operands[1], operands[2]));
8721e3df 9970 DONE;
c1b92d09
R
9971}")
9972
9973(define_expand "mshflo_b"
9974 [(match_operand:V8QI 0 "arith_reg_dest" "")
9975 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9976 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9977 "TARGET_SHMEDIA"
9978 "
9979{
9980 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9981 (operands[0], operands[1], operands[2]));
8721e3df 9982 DONE;
c1b92d09
R
9983}")
9984
9985(define_insn "mshf4_b"
9986 [(set
9987 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9988 (vec_select:V8QI
9989 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9990 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
0ac78517
R
9991 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9992 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
c1b92d09
R
9993 "TARGET_SHMEDIA"
9994 "* return (TARGET_LITTLE_ENDIAN
9995 ? \"mshfhi.b %N1, %N2, %0\"
9996 : \"mshflo.b %N1, %N2, %0\");"
9997 [(set_attr "type" "arith_media")])
9998
9999(define_insn "mshf0_b"
10000 [(set
10001 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10002 (vec_select:V8QI
10003 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10004 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
0ac78517
R
10005 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10006 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
c1b92d09
R
10007 "TARGET_SHMEDIA"
10008 "* return (TARGET_LITTLE_ENDIAN
10009 ? \"mshflo.b %N1, %N2, %0\"
10010 : \"mshfhi.b %N1, %N2, %0\");"
10011 [(set_attr "type" "arith_media")])
10012
10013(define_expand "mshfhi_l"
10014 [(match_operand:V2SI 0 "arith_reg_dest" "")
10015 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10016 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10017 "TARGET_SHMEDIA"
10018 "
10019{
10020 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10021 (operands[0], operands[1], operands[2]));
8721e3df 10022 DONE;
c1b92d09
R
10023}")
10024
10025(define_expand "mshflo_l"
10026 [(match_operand:V2SI 0 "arith_reg_dest" "")
10027 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10028 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10029 "TARGET_SHMEDIA"
10030 "
10031{
10032 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10033 (operands[0], operands[1], operands[2]));
8721e3df 10034 DONE;
c1b92d09
R
10035}")
10036
10037(define_insn "mshf4_l"
10038 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10039 (vec_select:V2SI
10040 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10041 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
0ac78517 10042 (parallel [(const_int 1) (const_int 3)])))]
c1b92d09
R
10043 "TARGET_SHMEDIA"
10044 "* return (TARGET_LITTLE_ENDIAN
10045 ? \"mshfhi.l %N1, %N2, %0\"
10046 : \"mshflo.l %N1, %N2, %0\");"
10047 [(set_attr "type" "arith_media")])
10048
10049(define_insn "mshf0_l"
10050 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10051 (vec_select:V2SI
10052 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10053 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
0ac78517 10054 (parallel [(const_int 0) (const_int 2)])))]
c1b92d09
R
10055 "TARGET_SHMEDIA"
10056 "* return (TARGET_LITTLE_ENDIAN
10057 ? \"mshflo.l %N1, %N2, %0\"
10058 : \"mshfhi.l %N1, %N2, %0\");"
10059 [(set_attr "type" "arith_media")])
10060
10061(define_expand "mshfhi_w"
10062 [(match_operand:V4HI 0 "arith_reg_dest" "")
10063 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10064 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10065 "TARGET_SHMEDIA"
10066 "
10067{
10068 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10069 (operands[0], operands[1], operands[2]));
8721e3df 10070 DONE;
c1b92d09
R
10071}")
10072
10073(define_expand "mshflo_w"
10074 [(match_operand:V4HI 0 "arith_reg_dest" "")
10075 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10076 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10077 "TARGET_SHMEDIA"
10078 "
10079{
10080 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10081 (operands[0], operands[1], operands[2]));
8721e3df 10082 DONE;
c1b92d09
R
10083}")
10084
10085(define_insn "mshf4_w"
10086 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10087 (vec_select:V4HI
10088 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10089 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
0ac78517 10090 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
c1b92d09
R
10091 "TARGET_SHMEDIA"
10092 "* return (TARGET_LITTLE_ENDIAN
10093 ? \"mshfhi.w %N1, %N2, %0\"
10094 : \"mshflo.w %N1, %N2, %0\");"
10095 [(set_attr "type" "arith_media")])
10096
10097(define_insn "mshf0_w"
10098 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10099 (vec_select:V4HI
10100 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10101 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
0ac78517 10102 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
c1b92d09
R
10103 "TARGET_SHMEDIA"
10104 "* return (TARGET_LITTLE_ENDIAN
10105 ? \"mshflo.w %N1, %N2, %0\"
10106 : \"mshfhi.w %N1, %N2, %0\");"
10107 [(set_attr "type" "arith_media")])
10108
0ac78517
R
10109(define_insn "mshflo_w_x"
10110 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10111 (vec_select:V4HI
10112 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10113 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10114 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10115 "TARGET_SHMEDIA"
10116 "mshflo.w %N1, %N2, %0"
10117 [(set_attr "type" "arith_media")])
10118
c1b92d09 10119/* These are useful to expand ANDs and as combiner patterns. */
0ac78517
R
10120(define_insn_and_split "mshfhi_l_di"
10121 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10122 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
c1b92d09 10123 (const_int 32))
0ac78517 10124 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
c1b92d09
R
10125 (const_int -4294967296))))]
10126 "TARGET_SHMEDIA"
0ac78517
R
10127 "@
10128 mshfhi.l %N1, %N2, %0
10129 #"
10130 "TARGET_SHMEDIA && reload_completed
10131 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10132 [(set (match_dup 3) (match_dup 4))
10133 (set (match_dup 5) (match_dup 6))]
10134 "
10135{
10136 operands[3] = gen_lowpart (SImode, operands[0]);
10137 operands[4] = gen_highpart (SImode, operands[1]);
10138 operands[5] = gen_highpart (SImode, operands[0]);
10139 operands[6] = gen_highpart (SImode, operands[2]);
10140}"
c1b92d09
R
10141 [(set_attr "type" "arith_media")])
10142
10143(define_insn "*mshfhi_l_di_rev"
10144 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10145 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10146 (const_int -4294967296))
52702ae1 10147 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
c1b92d09
R
10148 (const_int 32))))]
10149 "TARGET_SHMEDIA"
10150 "mshfhi.l %N2, %N1, %0"
10151 [(set_attr "type" "arith_media")])
10152
52702ae1
R
10153(define_split
10154 [(set (match_operand:DI 0 "arith_reg_dest" "")
10155 (ior:DI (zero_extend:DI (match_operand:SI 1
10156 "extend_reg_or_0_operand" ""))
10157 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10158 (const_int -4294967296))))
10159 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10160 "TARGET_SHMEDIA"
10161 [(const_int 0)]
10162 "
10163{
10164 emit_insn (gen_ashldi3_media (operands[3],
10165 simplify_gen_subreg (DImode, operands[1],
10166 SImode, 0),
10167 GEN_INT (32)));
10168 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10169 DONE;
10170}")
10171
c1b92d09
R
10172(define_insn "mshflo_l_di"
10173 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10174 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10175 (const_int 4294967295))
10176 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10177 (const_int 32))))]
10178
10179 "TARGET_SHMEDIA"
10180 "mshflo.l %N1, %N2, %0"
10181 [(set_attr "type" "arith_media")])
10182
10183(define_insn "*mshflo_l_di_rev"
10184 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10185 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10186 (const_int 32))
10187 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10188 (const_int 4294967295))))]
10189
10190 "TARGET_SHMEDIA"
10191 "mshflo.l %N2, %N1, %0"
10192 [(set_attr "type" "arith_media")])
10193
ca903bba
R
10194;; Combiner pattern for trampoline initialization.
10195(define_insn_and_split "*double_shori"
10196 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10197 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10198 (const_int 32))
10199 (match_operand:DI 2 "const_int_operand" "n")))]
10200 "TARGET_SHMEDIA
10201 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10202 "#"
10203 "rtx_equal_p (operands[0], operands[1])"
10204 [(const_int 0)]
10205 "
10206{
10207 HOST_WIDE_INT v = INTVAL (operands[2]);
10208
10209 emit_insn (gen_shori_media (operands[0], operands[0],
10210 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10211 emit_insn (gen_shori_media (operands[0], operands[0],
10212 gen_int_mode (v, HImode)));
10213 DONE;
10214}")
10215
10216
c1b92d09
R
10217(define_insn "*mshflo_l_di_x"
10218 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
0ac78517
R
10219 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10220 "rU"))
c1b92d09
R
10221 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10222 (const_int 32))))]
10223
10224 "TARGET_SHMEDIA"
10225 "mshflo.l %N1, %N2, %0"
10226 [(set_attr "type" "arith_media")])
10227
0ac78517
R
10228(define_insn_and_split "concat_v2sf"
10229 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10230;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10231 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10232 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10233
10234 "TARGET_SHMEDIA"
10235 "@
10236 mshflo.l %N1, %N2, %0
10237 #
10238 #"
10239 "TARGET_SHMEDIA && reload_completed
10240 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10241 [(set (match_dup 3) (match_dup 1))
10242 (set (match_dup 4) (match_dup 2))]
10243 "
10244{
10245 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10246 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10247}"
10248 [(set_attr "type" "arith_media")])
10249
c1b92d09
R
10250(define_insn "*mshflo_l_di_x_rev"
10251 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10252 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10253 (const_int 32))
10254 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10255
10256 "TARGET_SHMEDIA"
10257 "mshflo.l %N2, %N1, %0"
10258 [(set_attr "type" "arith_media")])
10259
10260(define_insn "ashlv2si3"
10261 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10262 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10263 (match_operand:DI 2 "arith_reg_operand" "r")))]
10264 "TARGET_SHMEDIA"
10265 "mshlld.l %1, %2, %0"
10266 [(set_attr "type" "arith_media")])
10267
10268(define_insn "ashlv4hi3"
10269 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10270 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10271 (match_operand:DI 2 "arith_reg_operand" "r")))]
10272 "TARGET_SHMEDIA"
10273 "mshlld.w %1, %2, %0"
10274 [(set_attr "type" "arith_media")])
10275
10276(define_insn "lshrv2si3"
10277 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10278 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10279 (match_operand:DI 2 "arith_reg_operand" "r")))]
10280 "TARGET_SHMEDIA"
10281 "mshlrd.l %1, %2, %0"
10282 [(set_attr "type" "arith_media")])
10283
10284(define_insn "lshrv4hi3"
10285 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10286 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10287 (match_operand:DI 2 "arith_reg_operand" "r")))]
10288 "TARGET_SHMEDIA"
10289 "mshlrd.w %1, %2, %0"
10290 [(set_attr "type" "arith_media")])
10291
10292(define_insn "subv2si3"
10293 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10294 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10295 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10296 "TARGET_SHMEDIA"
10297 "msub.l %N1, %2, %0"
10298 [(set_attr "type" "arith_media")])
10299
10300(define_insn "subv4hi3"
10301 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10302 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10303 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10304 "TARGET_SHMEDIA"
10305 "msub.w %N1, %2, %0"
10306 [(set_attr "type" "arith_media")])
10307
10308(define_insn "sssubv2si3"
10309 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10310 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10311 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10312 "TARGET_SHMEDIA"
10313 "msubs.l %N1, %2, %0"
10314 [(set_attr "type" "mcmp_media")])
10315
10316(define_insn "ussubv8qi3"
10317 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10318 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10319 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10320 "TARGET_SHMEDIA"
10321 "msubs.ub %1, %2, %0"
10322 [(set_attr "type" "mcmp_media")])
10323
10324(define_insn "sssubv4hi3"
10325 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10326 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10327 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10328 "TARGET_SHMEDIA"
10329 "msubs.w %N1, %2, %0"
10330 [(set_attr "type" "mcmp_media")])
10331
10332;; Floating Point Intrinsics
10333
10334(define_insn "fcosa_s"
10335 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10336 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10337 UNSPEC_FCOSA))]
10338 "TARGET_SHMEDIA"
10339 "fcosa.s %1, %0"
10340 [(set_attr "type" "atrans_media")])
10341
10342(define_insn "fsina_s"
10343 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10344 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10345 UNSPEC_FSINA))]
10346 "TARGET_SHMEDIA"
10347 "fsina.s %1, %0"
10348 [(set_attr "type" "atrans_media")])
10349
10350(define_insn "fipr"
10351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10352 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10353 "fp_arith_reg_operand" "f")
10354 (match_operand:V4SF 2
10355 "fp_arith_reg_operand" "f"))
0ac78517 10356 (parallel [(const_int 0)]))
c1b92d09 10357 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10358 (parallel [(const_int 1)])))
c1b92d09 10359 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10360 (parallel [(const_int 2)]))
c1b92d09 10361 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10362 (parallel [(const_int 3)])))))]
c1b92d09
R
10363 "TARGET_SHMEDIA"
10364 "fipr %1, %2, %0"
10365 [(set_attr "type" "fparith_media")])
10366
10367(define_insn "fsrra_s"
10368 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10369 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10370 UNSPEC_FSRRA))]
10371 "TARGET_SHMEDIA"
10372 "fsrra.s %1, %0"
10373 [(set_attr "type" "atrans_media")])
10374
10375(define_insn "ftrv"
10376 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10377 (plus:V4SF
10378 (plus:V4SF
10379 (mult:V4SF
10380 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
0ac78517
R
10381 (parallel [(const_int 0) (const_int 5)
10382 (const_int 10) (const_int 15)]))
c1b92d09
R
10383 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10384 (mult:V4SF
10385 (vec_select:V4SF (match_dup 1)
0ac78517
R
10386 (parallel [(const_int 4) (const_int 9)
10387 (const_int 14) (const_int 3)]))
c1b92d09 10388 (vec_select:V4SF (match_dup 2)
0ac78517
R
10389 (parallel [(const_int 1) (const_int 2)
10390 (const_int 3) (const_int 0)]))))
c1b92d09
R
10391 (plus:V4SF
10392 (mult:V4SF
10393 (vec_select:V4SF (match_dup 1)
0ac78517
R
10394 (parallel [(const_int 8) (const_int 13)
10395 (const_int 2) (const_int 7)]))
c1b92d09 10396 (vec_select:V4SF (match_dup 2)
0ac78517
R
10397 (parallel [(const_int 2) (const_int 3)
10398 (const_int 0) (const_int 1)])))
c1b92d09
R
10399 (mult:V4SF
10400 (vec_select:V4SF (match_dup 1)
0ac78517
R
10401 (parallel [(const_int 12) (const_int 1)
10402 (const_int 6) (const_int 11)]))
c1b92d09 10403 (vec_select:V4SF (match_dup 2)
0ac78517
R
10404 (parallel [(const_int 3) (const_int 0)
10405 (const_int 1) (const_int 2)]))))))]
c1b92d09
R
10406 "TARGET_SHMEDIA"
10407 "ftrv %1, %2, %0"
10408 [(set_attr "type" "fparith_media")])
10409
b6d33983
R
10410(define_insn "nsb"
10411 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10412 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10413 UNSPEC_NSB))]
10414 "TARGET_SHMEDIA"
10415 "nsb %1, %0"
10416 [(set_attr "type" "arith_media")])
10417
10418(define_insn "nsbsi"
10419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10420 (zero_extend:SI
10421 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10422 UNSPEC_NSB)))]
10423 "TARGET_SHMEDIA"
10424 "nsb %1, %0"
10425 [(set_attr "type" "arith_media")])
10426
10427(define_insn "nsbdi"
10428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10429 (zero_extend:DI
10430 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10431 UNSPEC_NSB)))]
10432 "TARGET_SHMEDIA"
10433 "nsb %1, %0"
10434 [(set_attr "type" "arith_media")])
10435
10436(define_expand "ffsdi2"
10437 [(set (match_operand:DI 0 "arith_reg_dest" "")
10438 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10439 "TARGET_SHMEDIA"
10440 "
10441{
10442 rtx scratch = gen_reg_rtx (DImode);
10443 rtx last;
10444
10445 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10446 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10447 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10448 emit_insn (gen_nsbdi (scratch, scratch));
10449 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10450 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10451 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10452 REG_NOTES (last)
10453 = gen_rtx_EXPR_LIST (REG_EQUAL,
10454 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10455 DONE;
10456}")
10457
10458(define_expand "ffssi2"
10459 [(set (match_operand:SI 0 "arith_reg_dest" "")
10460 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10461 "TARGET_SHMEDIA"
10462 "
10463{
10464 rtx scratch = gen_reg_rtx (SImode);
10465 rtx discratch = gen_reg_rtx (DImode);
10466 rtx last;
10467
e3c62520
R
10468 emit_insn (gen_adddi3 (discratch,
10469 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10470 GEN_INT (-1)));
10471 emit_insn (gen_andcdi3 (discratch,
10472 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10473 discratch));
b6d33983
R
10474 emit_insn (gen_nsbsi (scratch, discratch));
10475 last = emit_insn (gen_subsi3 (operands[0],
e3c62520 10476 force_reg (SImode, GEN_INT (63)), scratch));
b6d33983
R
10477 REG_NOTES (last)
10478 = gen_rtx_EXPR_LIST (REG_EQUAL,
10479 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10480 DONE;
10481}")
10482
10483(define_insn "byterev"
10484 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10485 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10486 (parallel [(const_int 7) (const_int 6) (const_int 5)
10487 (const_int 4) (const_int 3) (const_int 2)
10488 (const_int 1) (const_int 0)])))]
10489 "TARGET_SHMEDIA"
10490 "byterev %1, %0"
10491 [(set_attr "type" "arith_media")])
10492
fae15c93
VM
10493;; The following description models the
10494;; SH4 pipeline using the DFA based scheduler.
10495;; The DFA based description is better way to model
10496;; a superscalar pipeline as compared to function unit
10497;; reservation model.
10498;; 1. The function unit based model is oriented to describe at most one
10499;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10500;; pipeline units by same insn. This can be done using DFA based description.
10501;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10502;; 3. Writing all unit reservations for an instruction class is more natural description
10503;; of the pipeline and makes interface of the hazard recognizer simpler than the
10504;; old function unit based model.
10505;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10506
10507
10508;; Two automata are defined to reduce number of states
10509;; which a single large automaton will have.(Factoring)
10510
10511(define_automaton "inst_pipeline,fpu_pipe")
10512
10513;; This unit is basically the decode unit of the processor.
10514;; Since SH4 is a dual issue machine,it is as if there are two
10515;; units so that any insn can be processed by either one
10516;; of the decoding unit.
10517
10518(define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10519
10520
10521;; The fixed point arithmetic calculator(?? EX Unit).
10522
10523(define_cpu_unit "int" "inst_pipeline")
10524
10525;; f1_1 and f1_2 are floating point units.Actually there is
10526;; a f1 unit which can overlap with other f1 unit but
10527;; not another F1 unit.It is as though there were two
10528;; f1 units.
10529
10530(define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10531
c49439f1 10532;; The floating point units (except FS - F2 always precedes it.)
fae15c93 10533
c49439f1 10534(define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
fae15c93
VM
10535
10536;; This is basically the MA unit of SH4
10537;; used in LOAD/STORE pipeline.
10538
10539(define_cpu_unit "memory" "inst_pipeline")
10540
c49439f1
R
10541;; However, there are LS group insns that don't use it, even ones that
10542;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10543(define_cpu_unit "load_store" "inst_pipeline")
10544
fae15c93 10545;; The address calculator used for branch instructions.
c49439f1
R
10546;; This will be reserved after "issue" of branch instructions
10547;; and this is to make sure that no two branch instructions
fae15c93
VM
10548;; can be issued in parallel.
10549
10550(define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10551
10552;; ----------------------------------------------------
10553;; This reservation is to simplify the dual issue description.
10554
10555(define_reservation "issue" "pipe_01|pipe_02")
10556
10557;; This is to express the locking of D stage.
c49439f1 10558;; Note that the issue of a CO group insn also effectively locks the D stage.
fae15c93
VM
10559
10560(define_reservation "d_lock" "pipe_01+pipe_02")
10561
c49439f1
R
10562;; Every FE instruction but fipr / ftrv starts with issue and this.
10563(define_reservation "F01" "F0+F1")
10564
fae15c93
VM
10565;; This is to simplify description where F1,F2,FS
10566;; are used simultaneously.
10567
c49439f1 10568(define_reservation "fpu" "F1+F2")
fae15c93
VM
10569
10570;; This is to highlight the fact that f1
10571;; cannot overlap with F1.
10572
10573(exclusion_set "f1_1,f1_2" "F1")
10574
c49439f1
R
10575(define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10576
fae15c93
VM
10577;; Although reg moves have a latency of zero
10578;; we need to highlight that they use D stage
10579;; for one cycle.
10580
c49439f1
R
10581;; Group: MT
10582
fae15c93 10583(define_insn_reservation "reg_mov" 0
c49439f1
R
10584 (and (eq_attr "pipe_model" "sh4")
10585 (eq_attr "type" "move"))
10586 "issue")
10587
10588;; Group: LS
10589
10590(define_insn_reservation "freg_mov" 0
10591 (and (eq_attr "pipe_model" "sh4")
10592 (eq_attr "type" "fmove"))
10593 "issue+load_store")
10594
10595;; We don't model all pipeline stages; we model the issue ('D') stage
10596;; inasmuch as we allow only two instructions to issue simultanously,
10597;; and CO instructions prevent any simultanous issue of another instruction.
10598;; (This uses pipe_01 and pipe_02).
10599;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10600;; Double issue of EX / BR insns is prevented by using the int unit /
10601;; pcr_addrcalc unit in the EX stage.
10602;; Double issue of BR / LS instructions is prevented by using the
10603;; pcr_addrcalc / load_store unit in the issue cycle.
10604;; Double issue of FE instructions is prevented by using F0 in the first
10605;; pipeline stage after the first D stage.
10606;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10607;; (except in the cases outlined above), nor to describe the FS stage after
10608;; the F2 stage.
fae15c93
VM
10609
10610;; Other MT group intructions(1 step operations)
10611;; Group: MT
10612;; Latency: 1
10613;; Issue Rate: 1
10614
10615(define_insn_reservation "mt" 1
c49439f1
R
10616 (and (eq_attr "pipe_model" "sh4")
10617 (eq_attr "type" "mt_group"))
10618 "issue")
fae15c93
VM
10619
10620;; Fixed Point Arithmetic Instructions(1 step operations)
10621;; Group: EX
10622;; Latency: 1
10623;; Issue Rate: 1
10624
c49439f1
R
10625(define_insn_reservation "sh4_simple_arith" 1
10626 (and (eq_attr "pipe_model" "sh4")
10627 (eq_attr "insn_class" "ex_group"))
10628 "issue,int")
10629
10630;; Load and store instructions have no alignment peculiarities for the SH4,
10631;; but they use the load-store unit, which they share with the fmove type
10632;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10633;; Loads have a latency of two.
10634;; However, call insns can only paired with a preceding insn, and have
10635;; a delay slot, so that we want two more insns to be scheduled between the
10636;; load of the function address and the call. This is equivalent to a
10637;; latency of three.
10638;; ADJUST_COST can only properly handle reductions of the cost, so we
10639;; use a latency of three here, which gets multiplied by 10 to yield 30.
10640;; We only do this for SImode loads of general registers, to make the work
10641;; for ADJUST_COST easier.
fae15c93
VM
10642
10643;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10644;; Group: LS
10645;; Latency: 2
10646;; Issue Rate: 1
10647
c49439f1
R
10648(define_insn_reservation "sh4_load" 2
10649 (and (eq_attr "pipe_model" "sh4")
10650 (eq_attr "type" "load,pcload"))
10651 "issue+load_store,nothing,memory")
10652
10653;; calls / sfuncs need an extra instruction for their delay slot.
10654;; Moreover, estimating the latency for SImode loads as 3 will also allow
10655;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10656;; count of a dynamic shift.
10657(define_insn_reservation "sh4_load_si" 3
10658 (and (eq_attr "pipe_model" "sh4")
10659 (eq_attr "type" "load_si,pcload_si"))
10660 "issue+load_store,nothing,memory")
10661
10662;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10663
10664;; The load latency is upped to three higher if the dependent insn does
10665;; double precision computation. We want the 'default' latency to reflect
10666;; that increased latency because otherwise the insn priorities won't
10667;; allow proper scheduling.
10668(define_insn_reservation "sh4_fload" 3
10669 (and (eq_attr "pipe_model" "sh4")
10670 (eq_attr "type" "fload,pcfload"))
10671 "issue+load_store,nothing,memory")
10672
10673;; (define_bypass 2 "sh4_fload" "!")
10674
10675(define_insn_reservation "sh4_store" 1
10676 (and (eq_attr "pipe_model" "sh4")
10677 (eq_attr "type" "store"))
10678 "issue+load_store,nothing,memory")
10679
10680;; Load Store instructions.
10681;; Group: LS
10682;; Latency: 1
10683;; Issue Rate: 1
10684
10685(define_insn_reservation "sh4_gp_fpul" 1
10686 (and (eq_attr "pipe_model" "sh4")
10687 (eq_attr "type" "gp_fpul"))
10688 "issue+load_store")
10689
10690;; Load Store instructions.
10691;; Group: LS
10692;; Latency: 3
10693;; Issue Rate: 1
10694
10695(define_insn_reservation "sh4_fpul_gp" 3
10696 (and (eq_attr "pipe_model" "sh4")
10697 (eq_attr "type" "fpul_gp"))
10698 "issue+load_store")
fae15c93
VM
10699
10700;; Branch (BF,BF/S,BT,BT/S,BRA)
10701;; Group: BR
c49439f1 10702;; Latency when taken: 2 (or 1)
fae15c93
VM
10703;; Issue Rate: 1
10704;; The latency is 1 when displacement is 0.
c49439f1
R
10705;; We can't really do much with the latency, even if we could express it,
10706;; but the pairing restrictions are useful to take into account.
10707;; ??? If the branch is likely, we might want to fill the delay slot;
10708;; if the branch is likely, but not very likely, should we pretend to use
10709;; a resource that CO instructions use, to get a pairable delay slot insn?
fae15c93 10710
c49439f1
R
10711(define_insn_reservation "sh4_branch" 1
10712 (and (eq_attr "pipe_model" "sh4")
10713 (eq_attr "type" "cbranch,jump"))
10714 "issue+pcr_addrcalc")
fae15c93
VM
10715
10716;; Branch Far (JMP,RTS,BRAF)
10717;; Group: CO
10718;; Latency: 3
10719;; Issue Rate: 2
c49439f1
R
10720;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10721;; can't be distinguished from bra for the "jump" pattern.
fae15c93 10722
c49439f1
R
10723(define_insn_reservation "sh4_return" 3
10724 (and (eq_attr "pipe_model" "sh4")
10725 (eq_attr "type" "return,jump_ind"))
10726 "d_lock*2")
fae15c93
VM
10727
10728;; RTE
10729;; Group: CO
c49439f1 10730;; Latency: 5
fae15c93
VM
10731;; Issue Rate: 5
10732;; this instruction can be executed in any of the pipelines
10733;; and blocks the pipeline for next 4 stages.
10734
c49439f1
R
10735(define_insn_reservation "sh4_return_from_exp" 5
10736 (and (eq_attr "pipe_model" "sh4")
10737 (eq_attr "type" "rte"))
10738 "d_lock*5")
fae15c93
VM
10739
10740;; OCBP, OCBWB
10741;; Group: CO
c49439f1 10742;; Latency: 1-5
fae15c93
VM
10743;; Issue Rate: 1
10744
c49439f1
R
10745;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10746;; ocbwb on its own would be "d_lock,nothing,memory*5"
10747(define_insn_reservation "ocbwb" 6
10748 (and (eq_attr "pipe_model" "sh4")
10749 (eq_attr "type" "cwb"))
10750 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
fae15c93
VM
10751
10752;; LDS to PR,JSR
10753;; Group: CO
10754;; Latency: 3
10755;; Issue Rate: 2
10756;; The SX stage is blocked for last 2 cycles.
c49439f1
R
10757;; OTOH, the only time that has an effect for insns generated by the compiler
10758;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10759;; or when we are doing a function call - and we don't do inter-function
10760;; scheduling. For the function call case, it's really best that we end with
10761;; something that models an rts.
fae15c93 10762
c49439f1
R
10763(define_insn_reservation "sh4_lds_to_pr" 3
10764 (and (eq_attr "pipe_model" "sh4")
10765 (eq_attr "type" "prset") )
10766 "d_lock*2")
10767
10768;; calls introduce a longisch delay that is likely to flush the pipelines
10769;; of the caller's instructions. Ordinary functions tend to end with a
10770;; load to restore a register (in the delay slot of rts), while sfuncs
10771;; tend to end with an EX or MT insn. But that is not actually relevant,
10772;; since there are no instructions that contend for memory access early.
10773;; We could, of course, provide exact scheduling information for specific
10774;; sfuncs, if that should prove useful.
10775
10776(define_insn_reservation "sh4_call" 16
10777 (and (eq_attr "pipe_model" "sh4")
10778 (eq_attr "type" "call,sfunc"))
10779 "d_lock*16")
fae15c93
VM
10780
10781;; LDS.L to PR
10782;; Group: CO
10783;; Latency: 3
10784;; Issue Rate: 2
10785;; The SX unit is blocked for last 2 cycles.
10786
10787(define_insn_reservation "ldsmem_to_pr" 3
c49439f1
R
10788 (and (eq_attr "pipe_model" "sh4")
10789 (eq_attr "type" "pload"))
10790 "d_lock*2")
fae15c93
VM
10791
10792;; STS from PR
10793;; Group: CO
10794;; Latency: 2
10795;; Issue Rate: 2
10796;; The SX unit in second and third cycles.
10797
10798(define_insn_reservation "sts_from_pr" 2
c49439f1
R
10799 (and (eq_attr "pipe_model" "sh4")
10800 (eq_attr "type" "prget"))
10801 "d_lock*2")
fae15c93
VM
10802
10803;; STS.L from PR
10804;; Group: CO
10805;; Latency: 2
10806;; Issue Rate: 2
10807
c49439f1
R
10808(define_insn_reservation "sh4_prstore_mem" 2
10809 (and (eq_attr "pipe_model" "sh4")
10810 (eq_attr "type" "pstore"))
10811 "d_lock*2,nothing,memory")
fae15c93
VM
10812
10813;; LDS to FPSCR
10814;; Group: CO
10815;; Latency: 4
10816;; Issue Rate: 1
10817;; F1 is blocked for last three cycles.
10818
c49439f1
R
10819(define_insn_reservation "fpscr_load" 4
10820 (and (eq_attr "pipe_model" "sh4")
10821 (eq_attr "type" "gp_fpscr"))
10822 "d_lock,nothing,F1*3")
fae15c93
VM
10823
10824;; LDS.L to FPSCR
10825;; Group: CO
10826;; Latency: 1 / 4
10827;; Latency to update Rn is 1 and latency to update FPSCR is 4
10828;; Issue Rate: 1
10829;; F1 is blocked for last three cycles.
10830
c49439f1
R
10831(define_insn_reservation "fpscr_load_mem" 4
10832 (and (eq_attr "pipe_model" "sh4")
10833 (eq_attr "type" "mem_fpscr"))
10834 "d_lock,nothing,(F1+memory),F1*2")
fae15c93
VM
10835
10836\f
10837;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10838;; Group: CO
10839;; Latency: 4 / 4
10840;; Issue Rate: 1
10841
10842(define_insn_reservation "multi" 4
c49439f1
R
10843 (and (eq_attr "pipe_model" "sh4")
10844 (eq_attr "type" "smpy,dmpy"))
10845 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10846
10847;; Fixed STS from MACL / MACH
10848;; Group: CO
10849;; Latency: 3
10850;; Issue Rate: 1
10851
10852(define_insn_reservation "sh4_mac_gp" 3
10853 (and (eq_attr "pipe_model" "sh4")
10854 (eq_attr "type" "mac_gp"))
10855 "d_lock")
fae15c93
VM
10856
10857
10858;; Single precision floating point computation FCMP/EQ,
c49439f1 10859;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
fae15c93 10860;; Group: FE
c49439f1 10861;; Latency: 3/4
fae15c93
VM
10862;; Issue Rate: 1
10863
c49439f1
R
10864(define_insn_reservation "fp_arith" 3
10865 (and (eq_attr "pipe_model" "sh4")
10866 (eq_attr "type" "fp"))
10867 "issue,F01,F2")
10868
10869(define_insn_reservation "fp_arith_ftrc" 3
10870 (and (eq_attr "pipe_model" "sh4")
10871 (eq_attr "type" "ftrc_s"))
10872 "issue,F01,F2")
10873
10874(define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
fae15c93
VM
10875
10876;; Single Precision FDIV/SQRT
10877;; Group: FE
c49439f1 10878;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
fae15c93 10879;; Issue Rate: 1
c49439f1 10880;; We describe fdiv here; fsqrt is actually one cycle faster.
fae15c93 10881
c49439f1
R
10882(define_insn_reservation "fp_div" 12
10883 (and (eq_attr "pipe_model" "sh4")
10884 (eq_attr "type" "fdiv"))
10885 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
fae15c93
VM
10886
10887;; Double Precision floating point computation
10888;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10889;; Group: FE
10890;; Latency: (3,4)/5
10891;; Issue Rate: 1
10892
c49439f1
R
10893(define_insn_reservation "dp_float" 4
10894 (and (eq_attr "pipe_model" "sh4")
10895 (eq_attr "type" "dfp_conv"))
10896 "issue,F01,F1+F2,F2")
fae15c93 10897
c49439f1 10898;; Double-precision floating-point (FADD,FMUL,FSUB)
fae15c93
VM
10899;; Group: FE
10900;; Latency: (7,8)/9
10901;; Issue Rate: 1
10902
c49439f1
R
10903(define_insn_reservation "fp_double_arith" 8
10904 (and (eq_attr "pipe_model" "sh4")
10905 (eq_attr "type" "dfp_arith"))
10906 "issue,F01,F1+F2,fpu*4,F2")
fae15c93
VM
10907
10908;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
c49439f1 10909;; Group: CO
fae15c93
VM
10910;; Latency: 3/5
10911;; Issue Rate: 2
10912
c49439f1
R
10913(define_insn_reservation "fp_double_cmp" 3
10914 (and (eq_attr "pipe_model" "sh4")
10915 (eq_attr "type" "dfp_cmp"))
10916 "d_lock,(d_lock+F01),F1+F2,F2")
fae15c93
VM
10917
10918;; Double precision FDIV/SQRT
10919;; Group: FE
10920;; Latency: (24,25)/26
10921;; Issue Rate: 1
10922
c49439f1
R
10923(define_insn_reservation "dp_div" 25
10924 (and (eq_attr "pipe_model" "sh4")
10925 (eq_attr "type" "dfdiv"))
10926 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10927
fae15c93 10928
c49439f1
R
10929;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10930;; case, we'd get a d_lock instead of issue at the end.
10931(define_insn_reservation "arith3" 3
10932 (and (eq_attr "pipe_model" "sh4")
10933 (eq_attr "type" "arith3"))
10934 "issue,d_lock+pcr_addrcalc,issue")
10935
10936;; arith3b insns schedule the same no matter if the branch is taken or not.
10937(define_insn_reservation "arith3b" 2
10938 (and (eq_attr "pipe_model" "sh4")
10939 (eq_attr "type" "arith3"))
10940 "issue,d_lock+pcr_addrcalc")