]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/sh.md
GNU CC -> GCC
[thirdparty/gcc.git] / gcc / config / sh / sh.md
CommitLineData
c8f0269d 1;;- Machine description for Renesas / SuperH SH.
3a8699c7 2;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 6
7ec022b2 7;; This file is part of GCC.
bc45ade3 8
7ec022b2 9;; GCC is free software; you can redistribute it and/or modify
bc45ade3
SC
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
7ec022b2 14;; GCC is distributed in the hope that it will be useful,
bc45ade3
SC
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
7ec022b2 20;; along with GCC; see the file COPYING. If not, write to
3f63df56
RK
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
bc45ade3 23
bc45ade3 24
d0aae509
RK
25;; ??? Should prepend a * to all pattern names which are not used.
26;; This will make the compiler smaller, and rebuilds after changes faster.
27
ffae286a
JW
28;; ??? Should be enhanced to include support for many more GNU superoptimizer
29;; sequences. Especially the sequences for arithmetic right shifts.
30
31;; ??? Should check all DImode patterns for consistency and usefulness.
32
51bd623f
JW
33;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34;; way to generate them.
35
ffae286a
JW
36;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37;; for a str* inline function.
38
4ed4cb9a
JR
39;; BSR is not generated by the compiler proper, but when relaxing, it
40;; generates .uses pseudo-ops that allow linker relaxation to create
41;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42
0d7e008e
SC
43;; Special constraints for SH machine description:
44;;
07a45e5c
JW
45;; t -- T
46;; x -- mac
47;; l -- pr
0d7e008e
SC
48;; z -- r0
49;;
50;; Special formats used for outputting SH instructions:
51;;
52;; %. -- print a .s if insn needs delay slot
51aea58d 53;; %@ -- print rte/rts if is/isn't an interrupt function
0d7e008e 54;; %# -- output a nop if there is nothing to put in the delay slot
0d7e008e 55;; %O -- print a constant without the #
51aea58d
JW
56;; %R -- print the lsw reg of a double
57;; %S -- print the msw reg of a double
58;; %T -- print next word of a double REG or MEM
0d7e008e
SC
59;;
60;; Special predicates:
61;;
62;; arith_operand -- operand is valid source for arithmetic op
63;; arith_reg_operand -- operand is valid register for arithmetic op
0d7e008e
SC
64;; general_movdst_operand -- operand is valid move destination
65;; general_movsrc_operand -- operand is valid move source
66;; logical_operand -- operand is valid source for logical op
4773afa4
AO
67
68;; -------------------------------------------------------------------------
69;; Constants
70;; -------------------------------------------------------------------------
71
72(define_constants [
fa5322fa
AO
73 (AP_REG 145)
74 (PR_REG 146)
75 (T_REG 147)
76 (GBR_REG 144)
77 (MACH_REG 148)
78 (MACL_REG 149)
79 (FPUL_REG 150)
80 (RAP_REG 152)
4773afa4 81
fa5322fa 82 (FPSCR_REG 151)
4773afa4
AO
83
84 (PIC_REG 12)
85 (FP_REG 14)
86 (SP_REG 15)
87
fa5322fa
AO
88 (PR_MEDIA_REG 18)
89 (T_MEDIA_REG 19)
90
4773afa4
AO
91 (R0_REG 0)
92 (R1_REG 1)
93 (R2_REG 2)
94 (R3_REG 3)
95 (R4_REG 4)
96 (R5_REG 5)
97 (R6_REG 6)
fa5322fa
AO
98 (R7_REG 7)
99 (R8_REG 8)
100 (R9_REG 9)
101 (R10_REG 10)
9e96203d
R
102 (R20_REG 20)
103 (R21_REG 21)
104 (R22_REG 22)
105 (R23_REG 23)
fa5322fa
AO
106
107 (DR0_REG 64)
108 (DR2_REG 66)
109 (DR4_REG 68)
9e96203d 110 (FR23_REG 87)
4773afa4 111
fa5322fa
AO
112 (TR0_REG 128)
113 (TR1_REG 129)
114 (TR2_REG 130)
4773afa4 115
fa5322fa 116 (XD0_REG 136)
4773afa4
AO
117
118 ;; These are used with unspec.
fa5322fa 119 (UNSPEC_COMPACT_ARGS 0)
4773afa4
AO
120 (UNSPEC_MOVA 1)
121 (UNSPEC_CASESI 2)
fa5322fa 122 (UNSPEC_DATALABEL 3)
4773afa4
AO
123 (UNSPEC_BBR 4)
124 (UNSPEC_SFUNC 5)
125 (UNSPEC_PIC 6)
126 (UNSPEC_GOT 7)
127 (UNSPEC_GOTOFF 8)
128 (UNSPEC_PLT 9)
2d01e445 129 (UNSPEC_CALLER 10)
fa5322fa 130 (UNSPEC_GOTPLT 11)
4773afa4 131 (UNSPEC_ICACHE 12)
c1b92d09
R
132 (UNSPEC_INIT_TRAMP 13)
133 (UNSPEC_FCOSA 14)
134 (UNSPEC_FSRRA 15)
135 (UNSPEC_FSINA 16)
136 (UNSPEC_NSB 17)
137 (UNSPEC_ALLOCO 18)
4977bab6 138 (UNSPEC_EH_RETURN 19)
463f02cd
KK
139 (UNSPEC_TLSGD 20)
140 (UNSPEC_TLSLDM 21)
141 (UNSPEC_TLSIE 22)
142 (UNSPEC_DTPOFF 23)
143 (UNSPEC_GOTTPOFF 24)
144 (UNSPEC_TPOFF 25)
7d73a2ba 145 (UNSPEC_RA 26)
4773afa4
AO
146
147 ;; These are used with unspec_volatile.
148 (UNSPECV_BLOCKAGE 0)
b927e8c7 149 (UNSPECV_ALIGN 1)
4773afa4
AO
150 (UNSPECV_CONST2 2)
151 (UNSPECV_CONST4 4)
152 (UNSPECV_CONST8 6)
b91455de 153 (UNSPECV_WINDOW_END 10)
4773afa4
AO
154 (UNSPECV_CONST_END 11)
155])
156
bc45ade3
SC
157;; -------------------------------------------------------------------------
158;; Attributes
159;; -------------------------------------------------------------------------
160
eeb531d5 161;; Target CPU.
b9654711 162
1245df60 163(define_attr "cpu"
3a8699c7 164 "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
07a45e5c 165 (const (symbol_ref "sh_cpu_attr")))
961c4780 166
1245df60
R
167(define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
170
d64264ff
R
171;; Indicate if the default fpu mode is single precision.
172(define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
175
225e4f43
R
176(define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
2ad65b0e
SC
179;; pipeline model
180(define_attr "pipe_model" "sh1,sh4,sh5media"
181 (const
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
225e4f43 185
0d7e008e
SC
186;; cbranch conditional branch instructions
187;; jump unconditional jumps
188;; arith ordinary arithmetic
956d6950 189;; arith3 a compound insn that behaves similarly to a sequence of
1245df60
R
190;; three insns of type arith
191;; arith3b like above, but might end with a redirected branch
0d7e008e 192;; load from memory
1245df60 193;; load_si Likewise, SImode variant for general register.
c49439f1 194;; fload Likewise, but load to fp register.
0d7e008e 195;; store to memory
c49439f1
R
196;; move general purpose register to register
197;; mt_group other sh4 mt instructions
1245df60 198;; fmove register to register, floating point
51bd623f
JW
199;; smpy word precision integer multiply
200;; dmpy longword or doublelongword precision integer multiply
0d7e008e 201;; return rts
ffae286a 202;; pload load of pr reg, which can't be put into delay slot of rts
99e87c10 203;; prset copy register to pr reg, ditto
ffae286a 204;; pstore store of pr reg, which can't be put into delay slot of jsr
99e87c10 205;; prget copy pr to register, ditto
22e1ebf1 206;; pcload pc relative load of constant value
c49439f1 207;; pcfload Likewise, but load to fp register.
1245df60 208;; pcload_si Likewise, SImode variant for general register.
0d7e008e
SC
209;; rte return from exception
210;; sfunc special function call with known used registers
ffae286a 211;; call function call
c1aef54d
ILT
212;; fp floating point
213;; fdiv floating point divide (or square root)
c49439f1
R
214;; gp_fpul move from general purpose register to fpul
215;; fpul_gp move from fpul to general purpose register
216;; mac_gp move from mac[lh] to general purpose register
225e4f43 217;; dfp_arith, dfp_cmp,dfp_conv
c49439f1 218;; ftrc_s fix_truncsfsi2_i4
225e4f43 219;; dfdiv double precision floating point divide (or square root)
c49439f1 220;; cwb ic_invalidate_line_i
463f02cd 221;; tls_load load TLS related address
2ad65b0e
SC
222;; arith_media SHmedia arithmetic, logical, and shift instructions
223;; cbranch_media SHmedia conditional branch instructions
224;; cmp_media SHmedia compare instructions
225;; dfdiv_media SHmedia double precision divide and square root
226;; dfmul_media SHmedia double precision multiply instruction
227;; dfparith_media SHmedia double precision floating point arithmetic
228;; dfpconv_media SHmedia double precision floating point conversions
229;; dmpy_media SHmedia longword multiply
230;; fcmp_media SHmedia floating point compare instructions
231;; fdiv_media SHmedia single precision divide and square root
232;; fload_media SHmedia floating point register load instructions
233;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
234;; fparith_media SHmedia single precision floating point arithmetic
235;; fpconv_media SHmedia single precision floating point conversions
236;; fstore_media SHmedia floating point register store instructions
237;; gettr_media SHmedia gettr instruction
825db093 238;; invalidate_line_media SHmedia invalidate_line sequence
2ad65b0e
SC
239;; jump_media SHmedia unconditional branch instructions
240;; load_media SHmedia general register load instructions
241;; pt_media SHmedia pt instruction (expanded by assembler)
242;; ptabs_media SHmedia ptabs instruction
243;; store_media SHmedia general register store instructions
244;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
245;; mac_media SHmedia mac-style fixed point operations
246;; d2mpy_media SHmedia: two 32 bit integer multiplies
825db093 247;; atrans SHmedia approximate transcendental functions
2ad65b0e 248;; ustore_media SHmedia unaligned stores
4dff12bf 249;; nil no-op move, will be deleted.
0d7e008e 250
07a45e5c 251(define_attr "type"
463f02cd 252 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
bc45ade3
SC
253 (const_string "other"))
254
fae15c93 255;; We define a new attribute namely "insn_class".We use
c49439f1 256;; this for the DFA based pipeline description.
fae15c93
VM
257;;
258;; mt_group SH4 "mt" group instructions.
259;;
c49439f1
R
260;; ex_group SH4 "ex" group instructions.
261;;
262;; ls_group SH4 "ls" group instructions.
fae15c93 263;;
fae15c93
VM
264
265(define_attr "insn_class"
c49439f1
R
266 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270 (eq_attr "type" "cbranch,jump") (const_string "br_group")
271 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272 (const_string "fe_group")
273 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
274 (const_string "none")))
275;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276;; so these do not belong in an insn group, although they are modeled
277;; with their own define_insn_reservations.
fae15c93 278
d64264ff
R
279;; Indicate what precision must be selected in fpscr for this insn, if any.
280
281(define_attr "fp_mode" "single,double,none" (const_string "none"))
282
07a45e5c 283; If a conditional branch destination is within -252..258 bytes away
bc45ade3 284; from the instruction it can be 2 bytes long. Something in the
22e1ebf1 285; range -4090..4100 bytes can be 6 bytes long. All other conditional
1245df60
R
286; branches are initially assumed to be 16 bytes long.
287; In machine_dependent_reorg, we split all branches that are longer than
288; 2 bytes.
bc45ade3 289
536fe39c 290;; The maximum range used for SImode constant pool entries is 1018. A final
33f7f353
JR
291;; instruction can add 8 bytes while only being 4 bytes in size, thus we
292;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
293;; instruction around the pool table, 2 bytes of alignment before the table,
294;; and 30 bytes of alignment after the table. That gives a maximum total
295;; pool size of 1058 bytes.
296;; Worst case code/pool content size ratio is 1:2 (using asms).
297;; Thus, in the worst case, there is one instruction in front of a maximum
298;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
299;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
300;; If we have a forward branch, the initial table will be put after the
301;; unconditional branch.
302;;
303;; ??? We could do much better by keeping track of the actual pcloads within
304;; the branch range and in the pcload range in front of the branch range.
305
306;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
307;; inside an le.
308(define_attr "short_cbranch_p" "no,yes"
309 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
310 (const_string "no")
311 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
312 (const_string "yes")
313 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
314 (const_string "no")
315 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
316 (const_string "yes")
317 ] (const_string "no")))
318
319(define_attr "med_branch_p" "no,yes"
320 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
321 (const_int 1988))
322 (const_string "yes")
323 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
324 (const_string "no")
325 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
326 (const_int 8186))
327 (const_string "yes")
328 ] (const_string "no")))
329
330(define_attr "med_cbranch_p" "no,yes"
331 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
332 (const_int 1986))
333 (const_string "yes")
334 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335 (const_string "no")
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
337 (const_int 8184))
338 (const_string "yes")
339 ] (const_string "no")))
340
341(define_attr "braf_branch_p" "no,yes"
342 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
343 (const_string "no")
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
345 (const_int 20660))
346 (const_string "yes")
347 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348 (const_string "no")
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
350 (const_int 65530))
351 (const_string "yes")
352 ] (const_string "no")))
353
354(define_attr "braf_cbranch_p" "no,yes"
355 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
356 (const_string "no")
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
358 (const_int 20658))
359 (const_string "yes")
360 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
361 (const_string "no")
362 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
363 (const_int 65528))
364 (const_string "yes")
365 ] (const_string "no")))
366
22e1ebf1 367; An unconditional jump in the range -4092..4098 can be 2 bytes long.
1245df60
R
368; For wider ranges, we need a combination of a code and a data part.
369; If we can get a scratch register for a long range jump, the code
370; part can be 4 bytes long; otherwise, it must be 8 bytes long.
371; If the jump is in the range -32764..32770, the data part can be 2 bytes
372; long; otherwise, it must be 6 bytes long.
bc45ade3
SC
373
374; All other instructions are two bytes long by default.
375
33f7f353
JR
376;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
377;; but getattrtab doesn't understand this.
07a45e5c 378(define_attr "length" ""
bc45ade3 379 (cond [(eq_attr "type" "cbranch")
33f7f353 380 (cond [(eq_attr "short_cbranch_p" "yes")
1245df60 381 (const_int 2)
33f7f353 382 (eq_attr "med_cbranch_p" "yes")
1245df60 383 (const_int 6)
33f7f353 384 (eq_attr "braf_cbranch_p" "yes")
1245df60 385 (const_int 12)
33f7f353
JR
386;; ??? using pc is not computed transitively.
387 (ne (match_dup 0) (match_dup 0))
388 (const_int 14)
e6dfd05f
AO
389 (ne (symbol_ref ("flag_pic")) (const_int 0))
390 (const_int 24)
1245df60 391 ] (const_int 16))
bc45ade3 392 (eq_attr "type" "jump")
33f7f353 393 (cond [(eq_attr "med_branch_p" "yes")
1245df60 394 (const_int 2)
10f4f635 395 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
1245df60 396 (symbol_ref "INSN"))
10f4f635 397 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
1245df60 398 (symbol_ref "code_for_indirect_jump_scratch")))
33f7f353 399 (if_then_else (eq_attr "braf_branch_p" "yes")
1245df60
R
400 (const_int 6)
401 (const_int 10))
33f7f353 402 (eq_attr "braf_branch_p" "yes")
1245df60 403 (const_int 10)
33f7f353
JR
404;; ??? using pc is not computed transitively.
405 (ne (match_dup 0) (match_dup 0))
1245df60 406 (const_int 12)
e6dfd05f
AO
407 (ne (symbol_ref ("flag_pic")) (const_int 0))
408 (const_int 22)
1245df60 409 ] (const_int 14))
2ad65b0e 410 (eq_attr "type" "pt_media")
fa5322fa
AO
411 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
412 (const_int 20) (const_int 12))
413 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
414 (const_int 4)
415 (const_int 2))))
b9654711
SC
416
417;; (define_function_unit {name} {num-units} {n-users} {test}
418;; {ready-delay} {issue-delay} [{conflict-list}])
07a45e5c 419
c1aef54d
ILT
420;; Load and store instructions save a cycle if they are aligned on a
421;; four byte boundary. Using a function unit for stores encourages
422;; gcc to separate load and store instructions by one instruction,
423;; which makes it more likely that the linker will be able to word
424;; align them when relaxing.
1245df60
R
425
426;; Loads have a latency of two.
deeef0ac 427;; However, call insns can have a delay slot, so that we want one more
1245df60
R
428;; insn to be scheduled between the load of the function address and the call.
429;; This is equivalent to a latency of three.
430;; We cannot use a conflict list for this, because we need to distinguish
431;; between the actual call address and the function arguments.
432;; ADJUST_COST can only properly handle reductions of the cost, so we
433;; use a latency of three here.
956d6950 434;; We only do this for SImode loads of general registers, to make the work
1245df60
R
435;; for ADJUST_COST easier.
436(define_function_unit "memory" 1 0
2ad65b0e 437 (and (eq_attr "pipe_model" "sh1")
225e4f43 438 (eq_attr "type" "load_si,pcload_si"))
1245df60 439 3 2)
c1aef54d 440(define_function_unit "memory" 1 0
2ad65b0e 441 (and (eq_attr "pipe_model" "sh1")
225e4f43 442 (eq_attr "type" "load,pcload,pload,store,pstore"))
1245df60
R
443 2 2)
444
445(define_function_unit "int" 1 0
2ad65b0e 446 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
1245df60
R
447
448(define_function_unit "int" 1 0
2ad65b0e 449 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
1245df60
R
450
451(define_function_unit "int" 1 0
2ad65b0e 452 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
c1aef54d
ILT
453
454;; ??? These are approximations.
225e4f43 455(define_function_unit "mpy" 1 0
2ad65b0e 456 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
225e4f43 457(define_function_unit "mpy" 1 0
2ad65b0e 458 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
225e4f43
R
459
460(define_function_unit "fp" 1 0
2ad65b0e 461 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
225e4f43 462(define_function_unit "fp" 1 0
2ad65b0e 463 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
225e4f43
R
464
465
2ad65b0e
SC
466;; SH-5 SHmedia scheduling
467;; When executing SHmedia code, the SH-5 is a fairly straightforward
468;; single-issue machine. It has four pipelines, the branch unit (br),
469;; the integer and multimedia unit (imu), the load/store unit (lsu), and
470;; the floating point unit (fpu).
471;; Here model the instructions with a latency greater than one cycle.
472
473;; Every instruction on SH-5 occupies the issue resource for at least one
474;; cycle.
475(define_function_unit "sh5issue" 1 0
476 (and (eq_attr "pipe_model" "sh5media")
477 (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)
478
479;; Specify the various types of instruction which have latency > 1
480(define_function_unit "sh5issue" 1 0
481 (and (eq_attr "pipe_model" "sh5media")
482 (eq_attr "type" "mcmp_media")) 2 1)
483
484(define_function_unit "sh5issue" 1 0
485 (and (eq_attr "pipe_model" "sh5media")
486 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
487;; but see sh_adjust_cost for mac_media exception.
488
489(define_function_unit "sh5issue" 1 0
490 (and (eq_attr "pipe_model" "sh5media")
491 (eq_attr "type" "fload_media,fmove_media")) 4 1)
492
493(define_function_unit "sh5issue" 1 0
494 (and (eq_attr "pipe_model" "sh5media")
495 (eq_attr "type" "d2mpy_media")) 4 2)
496
497(define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
500
501(define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
504
505(define_function_unit "sh5issue" 1 0
506 (and (eq_attr "pipe_model" "sh5media")
507 (eq_attr "type" "invalidate_line_media")) 7 7)
508
509(define_function_unit "sh5issue" 1 0
510 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
511
512(define_function_unit "sh5issue" 1 0
513 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
514
515;; Floating-point divide and square-root occupy an additional resource,
516;; which is not internally pipelined. However, other instructions
517;; can continue to issue.
518(define_function_unit "sh5fds" 1 0
519 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
520
521(define_function_unit "sh5fds" 1 0
522 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
fa5322fa 523
51bd623f 524; Definitions for filling branch delay slots.
bc45ade3 525
51bd623f
JW
526(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
527
225e4f43
R
528;; ??? This should be (nil) instead of (const_int 0)
529(define_attr "hit_stack" "yes,no"
4773afa4
AO
530 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
531 (const_int 0))
225e4f43
R
532 (const_string "no")]
533 (const_string "yes")))
51bd623f
JW
534
535(define_attr "interrupt_function" "no,yes"
552ecbd9 536 (const (symbol_ref "current_function_interrupt")))
51bd623f 537
07a45e5c 538(define_attr "in_delay_slot" "yes,no"
51bd623f 539 (cond [(eq_attr "type" "cbranch") (const_string "no")
1245df60 540 (eq_attr "type" "pcload,pcload_si") (const_string "no")
51bd623f
JW
541 (eq_attr "needs_delay_slot" "yes") (const_string "no")
542 (eq_attr "length" "2") (const_string "yes")
543 ] (const_string "no")))
544
c608a684
R
545(define_attr "cond_delay_slot" "yes,no"
546 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
547 ] (const_string "no")))
548
0603a39d
R
549(define_attr "is_sfunc" ""
550 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
551
2ad65b0e
SC
552(define_attr "is_mac_media" ""
553 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
554
c49439f1
R
555(define_attr "branch_zero" "yes,no"
556 (cond [(eq_attr "type" "!cbranch") (const_string "no")
557 (ne (symbol_ref "(next_active_insn (insn)\
558 == (prev_active_insn\
559 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
560 && get_attr_length (next_active_insn (insn)) == 2")
561 (const_int 0))
562 (const_string "yes")]
563 (const_string "no")))
564
565;; SH4 Double-precision computation with double-precision result -
566;; the two halves are ready at different times.
567(define_attr "dfp_comp" "yes,no"
568 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
569 (const_string "no")))
570
571;; Insns for which the latency of a preceding fp insn is decreased by one.
572(define_attr "late_fp_use" "yes,no" (const_string "no"))
573;; And feeding insns for which this relevant.
574(define_attr "any_fp_comp" "yes,no"
575 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
576 (const_string "yes")]
577 (const_string "no")))
578
579(define_attr "any_int_load" "yes,no"
580 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
581 (const_string "yes")]
582 (const_string "no")))
583
51bd623f 584(define_delay
0d7e008e 585 (eq_attr "needs_delay_slot" "yes")
b9654711
SC
586 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
587
51aea58d
JW
588;; On the SH and SH2, the rte instruction reads the return pc from the stack,
589;; and thus we can't put a pop instruction in its delay slot.
6b005b88
JW
590;; ??? On the SH3, the rte instruction does not use the stack, so a pop
591;; instruction can go in the delay slot.
51aea58d 592
ffae286a
JW
593;; Since a normal return (rts) implicitly uses the PR register,
594;; we can't allow PR register loads in an rts delay slot.
595
07a45e5c 596(define_delay
961c4780 597 (eq_attr "type" "return")
07a45e5c 598 [(and (eq_attr "in_delay_slot" "yes")
ffae286a 599 (ior (and (eq_attr "interrupt_function" "no")
99e87c10 600 (eq_attr "type" "!pload,prset"))
ffae286a 601 (and (eq_attr "interrupt_function" "yes")
552ecbd9
AH
602 (ior
603 (ne (symbol_ref "TARGET_SH3") (const_int 0))
604 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
ffae286a
JW
605
606;; Since a call implicitly uses the PR register, we can't allow
607;; a PR register store in a jsr delay slot.
608
609(define_delay
610 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
611 [(and (eq_attr "in_delay_slot" "yes")
99e87c10 612 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
ffae286a
JW
613
614;; Say that we have annulled true branches, since this gives smaller and
615;; faster code when branches are predicted as not taken.
616
07a45e5c
JW
617(define_delay
618 (and (eq_attr "type" "cbranch")
1245df60 619 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
3a8699c7
AO
620 ;; SH2e has a hardware bug that pretty much prohibits the use of
621 ;; annuled delay slots.
622 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
623 (not (eq_attr "cpu" "sh2e"))) (nil)])
bc45ade3
SC
624\f
625;; -------------------------------------------------------------------------
626;; SImode signed integer comparisons
627;; -------------------------------------------------------------------------
628
51bd623f 629(define_insn ""
4773afa4 630 [(set (reg:SI T_REG)
51bd623f 631 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
735cb76e 632 (match_operand:SI 1 "arith_operand" "K08,r"))
51bd623f 633 (const_int 0)))]
fa5322fa 634 "TARGET_SH1"
fae15c93 635 "tst %1,%0"
c49439f1 636 [(set_attr "type" "mt_group")])
0d7e008e 637
07a45e5c
JW
638;; ??? Perhaps should only accept reg/constant if the register is reg 0.
639;; That would still allow reload to create cmpi instructions, but would
640;; perhaps allow forcing the constant into a register when that is better.
ffae286a
JW
641;; Probably should use r0 for mem/imm compares, but force constant into a
642;; register for pseudo/imm compares.
07a45e5c 643
0d7e008e 644(define_insn "cmpeqsi_t"
4773afa4
AO
645 [(set (reg:SI T_REG)
646 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
735cb76e 647 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
fa5322fa 648 "TARGET_SH1"
0d7e008e 649 "@
51bd623f 650 tst %0,%0
0d7e008e 651 cmp/eq %1,%0
fae15c93 652 cmp/eq %1,%0"
c49439f1 653 [(set_attr "type" "mt_group")])
bc45ade3
SC
654
655(define_insn "cmpgtsi_t"
4773afa4
AO
656 [(set (reg:SI T_REG)
657 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
658 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 659 "TARGET_SH1"
0d7e008e 660 "@
22e1ebf1 661 cmp/gt %1,%0
fae15c93 662 cmp/pl %0"
c49439f1 663 [(set_attr "type" "mt_group")])
bc45ade3
SC
664
665(define_insn "cmpgesi_t"
4773afa4
AO
666 [(set (reg:SI T_REG)
667 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
668 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 669 "TARGET_SH1"
0d7e008e 670 "@
22e1ebf1 671 cmp/ge %1,%0
fae15c93 672 cmp/pz %0"
c49439f1 673 [(set_attr "type" "mt_group")])
fae15c93 674
bc45ade3
SC
675;; -------------------------------------------------------------------------
676;; SImode unsigned integer comparisons
677;; -------------------------------------------------------------------------
678
679(define_insn "cmpgeusi_t"
4773afa4
AO
680 [(set (reg:SI T_REG)
681 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
682 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 683 "TARGET_SH1"
fae15c93 684 "cmp/hs %1,%0"
c49439f1 685 [(set_attr "type" "mt_group")])
bc45ade3
SC
686
687(define_insn "cmpgtusi_t"
4773afa4
AO
688 [(set (reg:SI T_REG)
689 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 691 "TARGET_SH1"
fae15c93 692 "cmp/hi %1,%0"
c49439f1 693 [(set_attr "type" "mt_group")])
bc45ade3
SC
694
695;; We save the compare operands in the cmpxx patterns and use them when
696;; we generate the branch.
697
698(define_expand "cmpsi"
4773afa4
AO
699 [(set (reg:SI T_REG)
700 (compare (match_operand:SI 0 "arith_operand" "")
701 (match_operand:SI 1 "arith_operand" "")))]
fa5322fa 702 "TARGET_SH1"
bc45ade3 703 "
0d7e008e
SC
704{
705 sh_compare_op0 = operands[0];
bc45ade3
SC
706 sh_compare_op1 = operands[1];
707 DONE;
708}")
bc45ade3
SC
709\f
710;; -------------------------------------------------------------------------
1245df60
R
711;; DImode signed integer comparisons
712;; -------------------------------------------------------------------------
713
714;; ??? Could get better scheduling by splitting the initial test from the
715;; rest of the insn after reload. However, the gain would hardly justify
716;; the sh.md size increase necessary to do that.
717
718(define_insn ""
4773afa4 719 [(set (reg:SI T_REG)
1245df60
R
720 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
721 (match_operand:DI 1 "arith_operand" "r"))
722 (const_int 0)))]
fa5322fa 723 "TARGET_SH1"
1245df60
R
724 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
725 insn, operands);"
726 [(set_attr "length" "6")
727 (set_attr "type" "arith3b")])
728
729(define_insn "cmpeqdi_t"
4773afa4
AO
730 [(set (reg:SI T_REG)
731 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
732 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
fa5322fa 733 "TARGET_SH1"
712646d0 734 "@
4c0d0505
JR
735 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
736 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
1245df60
R
737 [(set_attr "length" "6")
738 (set_attr "type" "arith3b")])
739
1987b7bc 740(define_split
4773afa4 741 [(set (reg:SI T_REG)
e69d1422
R
742 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
743 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
712646d0
R
744;; If we applied this split when not optimizing, it would only be
745;; applied during the machine-dependent reorg, when no new basic blocks
746;; may be created.
fa5322fa 747 "TARGET_SH1 && reload_completed && optimize"
4773afa4
AO
748 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
749 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
712646d0
R
750 (label_ref (match_dup 6))
751 (pc)))
4773afa4 752 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
712646d0 753 (match_dup 6)]
1987b7bc
R
754 "
755{
756 operands[2]
757 = gen_rtx_REG (SImode,
758 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
759 operands[3]
760 = (operands[1] == const0_rtx
761 ? const0_rtx
762 : gen_rtx_REG (SImode,
763 true_regnum (operands[1])
764 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
765 operands[4] = gen_lowpart (SImode, operands[0]);
766 operands[5] = gen_lowpart (SImode, operands[1]);
712646d0 767 operands[6] = gen_label_rtx ();
1987b7bc
R
768}")
769
1245df60 770(define_insn "cmpgtdi_t"
4773afa4
AO
771 [(set (reg:SI T_REG)
772 (gt: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/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
777 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
778 [(set_attr "length" "8")
779 (set_attr "type" "arith3")])
780
781(define_insn "cmpgedi_t"
4773afa4
AO
782 [(set (reg:SI T_REG)
783 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
784 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
785 "TARGET_SH2"
786 "@
787 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
788 cmp/pz\\t%S0"
789 [(set_attr "length" "8,2")
c49439f1 790 (set_attr "type" "arith3,mt_group")])
1245df60
R
791\f
792;; -------------------------------------------------------------------------
793;; DImode unsigned integer comparisons
794;; -------------------------------------------------------------------------
795
796(define_insn "cmpgeudi_t"
4773afa4
AO
797 [(set (reg:SI T_REG)
798 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
799 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
800 "TARGET_SH2"
801 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
802 [(set_attr "length" "8")
803 (set_attr "type" "arith3")])
804
805(define_insn "cmpgtudi_t"
4773afa4
AO
806 [(set (reg:SI T_REG)
807 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
808 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
809 "TARGET_SH2"
810 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
811 [(set_attr "length" "8")
812 (set_attr "type" "arith3")])
813
fa5322fa 814(define_insn "cmpeqdi_media"
b6d33983
R
815 [(set (match_operand:DI 0 "register_operand" "=r")
816 (eq:DI (match_operand:DI 1 "register_operand" "%r")
817 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
fa5322fa 818 "TARGET_SHMEDIA"
b6d33983
R
819 "cmpeq %1, %N2, %0"
820 [(set_attr "type" "cmp_media")])
fa5322fa
AO
821
822(define_insn "cmpgtdi_media"
b6d33983
R
823 [(set (match_operand:DI 0 "register_operand" "=r")
824 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
825 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 826 "TARGET_SHMEDIA"
b6d33983
R
827 "cmpgt %N1, %N2, %0"
828 [(set_attr "type" "cmp_media")])
fa5322fa
AO
829
830(define_insn "cmpgtudi_media"
b6d33983
R
831 [(set (match_operand:DI 0 "register_operand" "=r")
832 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 834 "TARGET_SHMEDIA"
68cef009 835 "cmpgtu %N1, %N2, %0"
b6d33983 836 [(set_attr "type" "cmp_media")])
fa5322fa 837
1245df60
R
838;; We save the compare operands in the cmpxx patterns and use them when
839;; we generate the branch.
840
841(define_expand "cmpdi"
4773afa4
AO
842 [(set (reg:SI T_REG)
843 (compare (match_operand:DI 0 "arith_operand" "")
844 (match_operand:DI 1 "arith_operand" "")))]
fa5322fa 845 "TARGET_SH2 || TARGET_SHMEDIA"
1245df60
R
846 "
847{
848 sh_compare_op0 = operands[0];
849 sh_compare_op1 = operands[1];
850 DONE;
851}")
fa5322fa
AO
852;; -------------------------------------------------------------------------
853;; Conditional move instructions
854;; -------------------------------------------------------------------------
855
856;; The insn names may seem reversed, but note that cmveq performs the move
857;; if op1 == 0, and cmvne does it if op1 != 0.
858
859(define_insn "movdicc_false"
b6d33983
R
860 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
861 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 862 (const_int 0))
b6d33983
R
863 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
864 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 865 "TARGET_SHMEDIA"
b6d33983
R
866 "cmveq %1, %N2, %0"
867 [(set_attr "type" "arith_media")])
fa5322fa
AO
868
869(define_insn "movdicc_true"
b6d33983
R
870 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
871 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 872 (const_int 0))
b6d33983
R
873 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
874 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 875 "TARGET_SHMEDIA"
b6d33983
R
876 "cmvne %1, %N2, %0"
877 [(set_attr "type" "arith_media")])
fa5322fa
AO
878
879(define_expand "movdicc"
880 [(set (match_operand:DI 0 "register_operand" "")
881 (if_then_else:DI (match_operand 1 "comparison_operator" "")
882 (match_operand:DI 2 "register_operand" "")
883 (match_operand:DI 3 "register_operand" "")))]
884 "TARGET_SHMEDIA"
885 "
886{
887 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
888 && GET_MODE (sh_compare_op0) == DImode
889 && sh_compare_op1 == const0_rtx)
890 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
891 sh_compare_op0, sh_compare_op1);
892 else
893 {
894 rtx tmp;
895
896 if (no_new_pseudos)
897 FAIL;
898
899 tmp = gen_reg_rtx (DImode);
900
901 switch (GET_CODE (operands[1]))
902 {
903 case EQ:
904 emit_insn (gen_seq (tmp));
905 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
906 break;
907
908 case NE:
909 emit_insn (gen_seq (tmp));
910 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
911 break;
912
913 case GT:
914 emit_insn (gen_sgt (tmp));
915 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
916 break;
917
918 case LT:
919 emit_insn (gen_slt (tmp));
920 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
921 break;
922
923 case GE:
924 emit_insn (gen_slt (tmp));
925 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
926 break;
927
928 case LE:
929 emit_insn (gen_sgt (tmp));
930 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
931 break;
932
933 case GTU:
934 emit_insn (gen_sgtu (tmp));
935 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
936 break;
937
938 case LTU:
939 emit_insn (gen_sltu (tmp));
940 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
941 break;
942
943 case GEU:
944 emit_insn (gen_sltu (tmp));
945 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
946 break;
947
948 case LEU:
949 emit_insn (gen_sgtu (tmp));
950 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
951 break;
952
953 case UNORDERED:
954 emit_insn (gen_sunordered (tmp));
955 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
956 break;
957
958 case ORDERED:
959 emit_insn (gen_sunordered (tmp));
960 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
961 break;
962
963 case UNEQ:
964 case UNGE:
965 case UNGT:
966 case UNLE:
967 case UNLT:
968 case LTGT:
969 FAIL;
970
971 default:
972 abort ();
973 }
974 }
975}")
1245df60
R
976\f
977;; -------------------------------------------------------------------------
bc45ade3
SC
978;; Addition instructions
979;; -------------------------------------------------------------------------
980
fa5322fa
AO
981(define_expand "adddi3"
982 [(set (match_operand:DI 0 "arith_reg_operand" "")
983 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
984 (match_operand:DI 2 "arith_operand" "")))]
985 ""
986 "
987{
988 if (TARGET_SH1)
989 {
990 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
991 FAIL;
992 operands[2] = force_reg (DImode, operands[2]);
993 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
994 DONE;
995 }
996}")
0d7e008e 997
fa5322fa
AO
998(define_insn "*adddi3_media"
999 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1000 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 1001 (match_operand:DI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1002 "TARGET_SHMEDIA"
1003 "@
1004 add %1, %2, %0
2ad65b0e
SC
1005 addi %1, %2, %0"
1006 [(set_attr "type" "arith_media")])
fa5322fa 1007
b6d33983
R
1008(define_insn "adddi3z_media"
1009 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
fa5322fa 1010 (zero_extend:DI
b6d33983
R
1011 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1012 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
fa5322fa 1013 "TARGET_SHMEDIA"
b6d33983
R
1014 "addz.l %1, %N2, %0"
1015 [(set_attr "type" "arith_media")])
52702ae1 1016
fa5322fa 1017(define_insn "adddi3_compact"
38b3ef8b 1018 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
07a45e5c
JW
1019 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1020 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1021 (clobber (reg:SI T_REG))]
fa5322fa 1022 "TARGET_SH1"
1245df60 1023 "#"
4fdd1f85 1024 [(set_attr "length" "6")])
961c4780 1025
1245df60 1026(define_split
e69d1422
R
1027 [(set (match_operand:DI 0 "arith_reg_operand" "")
1028 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1029 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1030 (clobber (reg:SI T_REG))]
fa5322fa 1031 "TARGET_SH1 && reload_completed"
1245df60
R
1032 [(const_int 0)]
1033 "
1034{
1035 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1036 high0 = gen_rtx_REG (SImode,
1037 true_regnum (operands[0])
1038 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1039 high2 = gen_rtx_REG (SImode,
1040 true_regnum (operands[2])
1041 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1042 emit_insn (gen_clrt ());
1043 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1044 emit_insn (gen_addc1 (high0, high0, high2));
1045 DONE;
1046}")
1047
1048(define_insn "addc"
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 (set (reg:SI T_REG)
1245df60 1054 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1055 "TARGET_SH1"
1245df60 1056 "addc %2,%0"
c49439f1 1057 [(set_attr "type" "arith")])
1245df60
R
1058
1059(define_insn "addc1"
1060 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1062 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1063 (reg:SI T_REG)))
1064 (clobber (reg:SI T_REG))]
fa5322fa 1065 "TARGET_SH1"
1245df60 1066 "addc %2,%0"
c49439f1 1067 [(set_attr "type" "arith")])
1245df60 1068
fa5322fa
AO
1069(define_expand "addsi3"
1070 [(set (match_operand:SI 0 "arith_reg_operand" "")
1071 (plus:SI (match_operand:SI 1 "arith_operand" "")
1072 (match_operand:SI 2 "arith_operand" "")))]
1073 ""
1074 "
1075{
1076 if (TARGET_SHMEDIA)
1077 operands[1] = force_reg (SImode, operands[1]);
1078}")
1079
1080(define_insn "addsi3_media"
1081 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 1082 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
735cb76e 1083 (match_operand:SI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1084 "TARGET_SHMEDIA"
1085 "@
1086 add.l %1, %2, %0
b6d33983
R
1087 addi.l %1, %2, %0"
1088 [(set_attr "type" "arith_media")])
52702ae1 1089
fa5322fa 1090(define_insn "*addsi3_compact"
aa684c94 1091 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f 1092 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
735cb76e 1093 (match_operand:SI 2 "arith_operand" "rI08")))]
fa5322fa 1094 "TARGET_SH1"
bc45ade3 1095 "add %2,%0"
c49439f1 1096 [(set_attr "type" "arith")])
fae15c93 1097
bc45ade3
SC
1098;; -------------------------------------------------------------------------
1099;; Subtraction instructions
1100;; -------------------------------------------------------------------------
1101
fa5322fa
AO
1102(define_expand "subdi3"
1103 [(set (match_operand:DI 0 "arith_reg_operand" "")
52702ae1 1104 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
fa5322fa
AO
1105 (match_operand:DI 2 "arith_reg_operand" "")))]
1106 ""
1107 "
1108{
1109 if (TARGET_SH1)
1110 {
52702ae1 1111 operands[1] = force_reg (DImode, operands[1]);
fa5322fa
AO
1112 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1113 DONE;
1114 }
1115}")
52702ae1 1116
fa5322fa
AO
1117(define_insn "*subdi3_media"
1118 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
52702ae1 1119 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
fa5322fa
AO
1120 (match_operand:DI 2 "arith_reg_operand" "r")))]
1121 "TARGET_SHMEDIA"
2ad65b0e
SC
1122 "sub %N1, %2, %0"
1123 [(set_attr "type" "arith_media")])
52702ae1 1124
fa5322fa 1125(define_insn "subdi3_compact"
38b3ef8b 1126 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
07a45e5c
JW
1127 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1128 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1129 (clobber (reg:SI T_REG))]
fa5322fa 1130 "TARGET_SH1"
1245df60 1131 "#"
4fdd1f85 1132 [(set_attr "length" "6")])
bc45ade3 1133
1245df60 1134(define_split
e69d1422
R
1135 [(set (match_operand:DI 0 "arith_reg_operand" "")
1136 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1137 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1138 (clobber (reg:SI T_REG))]
fa5322fa 1139 "TARGET_SH1 && reload_completed"
1245df60
R
1140 [(const_int 0)]
1141 "
1142{
1143 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1144 high0 = gen_rtx_REG (SImode,
1145 true_regnum (operands[0])
1146 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1147 high2 = gen_rtx_REG (SImode,
1148 true_regnum (operands[2])
1149 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1150 emit_insn (gen_clrt ());
1151 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1152 emit_insn (gen_subc1 (high0, high0, high2));
1153 DONE;
1154}")
1155
1156(define_insn "subc"
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 (set (reg:SI T_REG)
1245df60 1162 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1163 "TARGET_SH1"
1245df60 1164 "subc %2,%0"
c49439f1 1165 [(set_attr "type" "arith")])
1245df60
R
1166
1167(define_insn "subc1"
1168 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1169 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1170 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1171 (reg:SI T_REG)))
1172 (clobber (reg:SI T_REG))]
fa5322fa 1173 "TARGET_SH1"
1245df60 1174 "subc %2,%0"
c49439f1 1175 [(set_attr "type" "arith")])
1245df60 1176
caca3c8a 1177(define_insn "*subsi3_internal"
0d7e008e
SC
1178 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1179 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1180 (match_operand:SI 2 "arith_reg_operand" "r")))]
fa5322fa 1181 "TARGET_SH1"
0d7e008e 1182 "sub %2,%0"
c49439f1 1183 [(set_attr "type" "arith")])
caca3c8a 1184
fa5322fa
AO
1185(define_insn "*subsi3_media"
1186 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
b6d33983
R
1187 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1188 (match_operand:SI 2 "extend_reg_operand" "r")))]
fa5322fa 1189 "TARGET_SHMEDIA"
b6d33983
R
1190 "sub.l %N1, %2, %0"
1191 [(set_attr "type" "arith_media")])
fa5322fa 1192
caca3c8a
JW
1193;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1194;; will sometimes save one instruction. Otherwise we might get
1195;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1196;; are the same.
1197
1198(define_expand "subsi3"
1199 [(set (match_operand:SI 0 "arith_reg_operand" "")
1200 (minus:SI (match_operand:SI 1 "arith_operand" "")
1201 (match_operand:SI 2 "arith_reg_operand" "")))]
1202 ""
1203 "
1204{
fa5322fa 1205 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
caca3c8a
JW
1206 {
1207 emit_insn (gen_negsi2 (operands[0], operands[2]));
1208 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1209 DONE;
1210 }
fa5322fa
AO
1211 if (TARGET_SHMEDIA)
1212 {
b6d33983 1213 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
fa5322fa 1214 FAIL;
b6d33983
R
1215 if (operands[1] != const0_rtx)
1216 operands[1] = force_reg (SImode, operands[1]);
fa5322fa 1217 }
caca3c8a 1218}")
bc45ade3
SC
1219\f
1220;; -------------------------------------------------------------------------
0d7e008e 1221;; Division instructions
bc45ade3
SC
1222;; -------------------------------------------------------------------------
1223
ffae286a 1224;; We take advantage of the library routines which don't clobber as many
0d7e008e
SC
1225;; registers as a normal function call would.
1226
1245df60 1227;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
956d6950 1228;; also has an effect on the register that holds the address of the sfunc.
e69d1422 1229;; To make this work, we have an extra dummy insn that shows the use
1245df60
R
1230;; of this register for reorg.
1231
1232(define_insn "use_sfunc_addr"
4773afa4 1233 [(set (reg:SI PR_REG)
e69d1422 1234 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
fa5322fa 1235 "TARGET_SH1"
1245df60
R
1236 ""
1237 [(set_attr "length" "0")])
1238
ddd5a7c1 1239;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
e96a50cc
JW
1240;; hard register 0. If we used hard register 0, then the next instruction
1241;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1242;; gets allocated to a stack slot that needs its address reloaded, then
1243;; there is nothing to prevent reload from using r0 to reload the address.
1244;; This reload would clobber the value in r0 we are trying to store.
1245;; If we let reload allocate r0, then this problem can never happen.
0d7e008e 1246
a512fa97 1247(define_insn "udivsi3_i1"
1245df60 1248 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1249 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1250 (clobber (reg:SI T_REG))
1251 (clobber (reg:SI PR_REG))
1252 (clobber (reg:SI R4_REG))
1245df60 1253 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1254 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1255 "jsr @%1%#"
1256 [(set_attr "type" "sfunc")
1257 (set_attr "needs_delay_slot" "yes")])
1258
9e96203d
R
1259; Since shmedia-nofpu code could be linked against shcompact code, and
1260; the udivsi3 libcall has the same name, we must consider all registers
1261; clobbered that are in the union of the registers clobbered by the
1262; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1263; implementation actually used shcompact code, we'd need to clobber
9e96203d 1264; also r23 and fr23.
fa5322fa
AO
1265(define_insn "udivsi3_i1_media"
1266 [(set (match_operand:SI 0 "register_operand" "=z")
1267 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1268 (clobber (reg:SI T_MEDIA_REG))
1269 (clobber (reg:SI PR_MEDIA_REG))
9e96203d
R
1270 (clobber (reg:SI R20_REG))
1271 (clobber (reg:SI R21_REG))
1272 (clobber (reg:SI R22_REG))
fa5322fa
AO
1273 (clobber (reg:DI TR0_REG))
1274 (clobber (reg:DI TR1_REG))
1275 (clobber (reg:DI TR2_REG))
1276 (use (match_operand:DI 1 "target_operand" "b"))]
1277 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1278 "blink %1, r18"
1279 [(set_attr "type" "sfunc")
1280 (set_attr "needs_delay_slot" "yes")])
1281
1282(define_expand "udivsi3_i4_media"
b6d33983
R
1283 [(set (match_dup 3)
1284 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1285 (set (match_dup 4)
1286 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
fa5322fa 1287 (set (match_dup 5) (float:DF (match_dup 3)))
b6d33983
R
1288 (set (match_dup 6) (float:DF (match_dup 4)))
1289 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1290 (set (match_dup 8) (fix:DI (match_dup 7)))
0ac78517
R
1291 (set (match_operand:SI 0 "register_operand" "")
1292 (truncate:SI (match_dup 8)))]
fa5322fa
AO
1293 "TARGET_SHMEDIA_FPU"
1294 "
1295{
fa5322fa 1296 operands[3] = gen_reg_rtx (DImode);
b6d33983 1297 operands[4] = gen_reg_rtx (DImode);
fa5322fa
AO
1298 operands[5] = gen_reg_rtx (DFmode);
1299 operands[6] = gen_reg_rtx (DFmode);
b6d33983
R
1300 operands[7] = gen_reg_rtx (DFmode);
1301 operands[8] = gen_reg_rtx (DImode);
fa5322fa
AO
1302}")
1303
225e4f43
R
1304(define_insn "udivsi3_i4"
1305 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1306 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1307 (clobber (reg:SI T_REG))
4773afa4
AO
1308 (clobber (reg:SI PR_REG))
1309 (clobber (reg:DF DR0_REG))
1310 (clobber (reg:DF DR2_REG))
1311 (clobber (reg:DF DR4_REG))
1312 (clobber (reg:SI R0_REG))
1313 (clobber (reg:SI R1_REG))
1314 (clobber (reg:SI R4_REG))
1315 (clobber (reg:SI R5_REG))
1316 (use (reg:PSI FPSCR_REG))
225e4f43
R
1317 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1318 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1319 "jsr @%1%#"
1320 [(set_attr "type" "sfunc")
d64264ff 1321 (set_attr "fp_mode" "double")
225e4f43
R
1322 (set_attr "needs_delay_slot" "yes")])
1323
1324(define_insn "udivsi3_i4_single"
1325 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1326 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1327 (clobber (reg:SI T_REG))
4773afa4
AO
1328 (clobber (reg:SI PR_REG))
1329 (clobber (reg:DF DR0_REG))
1330 (clobber (reg:DF DR2_REG))
1331 (clobber (reg:DF DR4_REG))
1332 (clobber (reg:SI R0_REG))
1333 (clobber (reg:SI R1_REG))
1334 (clobber (reg:SI R4_REG))
1335 (clobber (reg:SI R5_REG))
225e4f43 1336 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1337 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1338 "jsr @%1%#"
0d7e008e 1339 [(set_attr "type" "sfunc")
0d7e008e
SC
1340 (set_attr "needs_delay_slot" "yes")])
1341
1342(define_expand "udivsi3"
a512fa97 1343 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
4773afa4
AO
1344 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1345 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1346 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1347 (udiv:SI (reg:SI R4_REG)
1348 (reg:SI R5_REG)))
1349 (clobber (reg:SI T_REG))
1350 (clobber (reg:SI PR_REG))
1351 (clobber (reg:SI R4_REG))
ffae286a 1352 (use (match_dup 3))])]
0d7e008e 1353 ""
225e4f43
R
1354 "
1355{
4392ebd3 1356 rtx first, last;
a512fa97 1357
fa5322fa 1358 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1359 /* Emit the move of the address to a pseudo outside of the libcall. */
3a8699c7 1360 if (TARGET_HARD_SH4 && TARGET_SH2E)
225e4f43 1361 {
90534361 1362 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
225e4f43 1363 if (TARGET_FPU_SINGLE)
a512fa97 1364 last = gen_udivsi3_i4_single (operands[0], operands[3]);
225e4f43 1365 else
a512fa97 1366 last = gen_udivsi3_i4 (operands[0], operands[3]);
225e4f43 1367 }
fa5322fa 1368 else if (TARGET_SHMEDIA_FPU)
b6d33983
R
1369 {
1370 operands[1] = force_reg (SImode, operands[1]);
1371 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1372 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1373 DONE;
b6d33983 1374 }
fa5322fa
AO
1375 else if (TARGET_SH5)
1376 {
1377 emit_move_insn (operands[3],
90534361
R
1378 function_symbol (TARGET_FPU_ANY
1379 ? \"__udivsi3_i4\"
1380 : \"__udivsi3\"));
fa5322fa
AO
1381
1382 if (TARGET_SHMEDIA)
1383 last = gen_udivsi3_i1_media (operands[0],
1384 Pmode == DImode
1385 ? operands[3]
1386 : gen_rtx_SUBREG (DImode, operands[3],
1387 0));
1388 else if (TARGET_FPU_ANY)
1389 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1390 else
1391 last = gen_udivsi3_i1 (operands[0], operands[3]);
1392 }
a512fa97
R
1393 else
1394 {
90534361 1395 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
a512fa97
R
1396 last = gen_udivsi3_i1 (operands[0], operands[3]);
1397 }
4392ebd3
RS
1398 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1399 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1400 last = emit_insn (last);
1401 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1402 invariant code motion can move it. */
1403 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1404 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1405 DONE;
225e4f43 1406}")
0d7e008e 1407
a512fa97 1408(define_insn "divsi3_i1"
1245df60 1409 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1410 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1411 (clobber (reg:SI T_REG))
1412 (clobber (reg:SI PR_REG))
1413 (clobber (reg:SI R1_REG))
1414 (clobber (reg:SI R2_REG))
1415 (clobber (reg:SI R3_REG))
1245df60 1416 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1417 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1418 "jsr @%1%#"
1419 [(set_attr "type" "sfunc")
1420 (set_attr "needs_delay_slot" "yes")])
1421
9e96203d 1422; Since shmedia-nofpu code could be linked against shcompact code, and
b6d33983 1423; the sdivsi3 libcall has the same name, we must consider all registers
9e96203d
R
1424; clobbered that are in the union of the registers clobbered by the
1425; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1426; implementation actually used shcompact code, we'd need to clobber
9e96203d 1427; also r22, r23 and fr23.
fa5322fa
AO
1428(define_insn "divsi3_i1_media"
1429 [(set (match_operand:SI 0 "register_operand" "=z")
1430 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1431 (clobber (reg:SI T_MEDIA_REG))
1432 (clobber (reg:SI PR_MEDIA_REG))
1433 (clobber (reg:SI R1_REG))
1434 (clobber (reg:SI R2_REG))
1435 (clobber (reg:SI R3_REG))
9e96203d
R
1436 (clobber (reg:SI R20_REG))
1437 (clobber (reg:SI R21_REG))
fa5322fa
AO
1438 (clobber (reg:DI TR0_REG))
1439 (clobber (reg:DI TR1_REG))
1440 (clobber (reg:DI TR2_REG))
1441 (use (match_operand:DI 1 "target_operand" "b"))]
1442 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
2ad65b0e
SC
1443 "blink %1, r18"
1444 [(set_attr "type" "sfunc")])
fa5322fa
AO
1445
1446(define_expand "divsi3_i4_media"
51214775
R
1447 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1448 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1449 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
fa5322fa 1450 (set (match_operand:SI 0 "register_operand" "=r")
51214775 1451 (fix:SI (match_dup 5)))]
fa5322fa
AO
1452 "TARGET_SHMEDIA_FPU"
1453 "
1454{
51214775 1455 operands[3] = gen_reg_rtx (DFmode);
fa5322fa
AO
1456 operands[4] = gen_reg_rtx (DFmode);
1457 operands[5] = gen_reg_rtx (DFmode);
fa5322fa
AO
1458}")
1459
225e4f43
R
1460(define_insn "divsi3_i4"
1461 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1462 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1463 (clobber (reg:SI PR_REG))
1464 (clobber (reg:DF DR0_REG))
1465 (clobber (reg:DF DR2_REG))
1466 (use (reg:PSI FPSCR_REG))
225e4f43
R
1467 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1468 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1469 "jsr @%1%#"
1470 [(set_attr "type" "sfunc")
d64264ff 1471 (set_attr "fp_mode" "double")
225e4f43
R
1472 (set_attr "needs_delay_slot" "yes")])
1473
1474(define_insn "divsi3_i4_single"
1475 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1476 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1477 (clobber (reg:SI PR_REG))
1478 (clobber (reg:DF DR0_REG))
1479 (clobber (reg:DF DR2_REG))
1480 (clobber (reg:SI R2_REG))
225e4f43 1481 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1482 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1483 "jsr @%1%#"
0d7e008e 1484 [(set_attr "type" "sfunc")
0d7e008e
SC
1485 (set_attr "needs_delay_slot" "yes")])
1486
1487(define_expand "divsi3"
a512fa97 1488 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
4773afa4
AO
1489 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1490 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1491 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1492 (div:SI (reg:SI R4_REG)
1493 (reg:SI R5_REG)))
1494 (clobber (reg:SI T_REG))
1495 (clobber (reg:SI PR_REG))
1496 (clobber (reg:SI R1_REG))
1497 (clobber (reg:SI R2_REG))
1498 (clobber (reg:SI R3_REG))
ffae286a 1499 (use (match_dup 3))])]
0d7e008e 1500 ""
225e4f43
R
1501 "
1502{
4392ebd3 1503 rtx first, last;
a512fa97 1504
fa5322fa 1505 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1506 /* Emit the move of the address to a pseudo outside of the libcall. */
3a8699c7 1507 if (TARGET_HARD_SH4 && TARGET_SH2E)
225e4f43 1508 {
90534361 1509 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
225e4f43 1510 if (TARGET_FPU_SINGLE)
a512fa97 1511 last = gen_divsi3_i4_single (operands[0], operands[3]);
225e4f43 1512 else
a512fa97 1513 last = gen_divsi3_i4 (operands[0], operands[3]);
225e4f43 1514 }
fa5322fa 1515 else if (TARGET_SHMEDIA_FPU)
51214775
R
1516 {
1517 operands[1] = force_reg (SImode, operands[1]);
1518 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1519 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1520 DONE;
51214775 1521 }
fa5322fa
AO
1522 else if (TARGET_SH5)
1523 {
1524 emit_move_insn (operands[3],
90534361
R
1525 function_symbol (TARGET_FPU_ANY
1526 ? \"__sdivsi3_i4\"
1527 : \"__sdivsi3\"));
fa5322fa
AO
1528
1529 if (TARGET_SHMEDIA)
52702ae1 1530 last = gen_divsi3_i1_media (operands[0],
fa5322fa
AO
1531 Pmode == DImode
1532 ? operands[3]
1533 : gen_rtx_SUBREG (DImode, operands[3],
1534 0));
1535 else if (TARGET_FPU_ANY)
1536 last = gen_divsi3_i4_single (operands[0], operands[3]);
1537 else
1538 last = gen_divsi3_i1 (operands[0], operands[3]);
1539 }
a512fa97
R
1540 else
1541 {
90534361 1542 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
a512fa97
R
1543 last = gen_divsi3_i1 (operands[0], operands[3]);
1544 }
4392ebd3
RS
1545 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1546 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1547 last = emit_insn (last);
1548 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1549 invariant code motion can move it. */
1550 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1551 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1552 DONE;
225e4f43 1553}")
0d7e008e
SC
1554\f
1555;; -------------------------------------------------------------------------
1556;; Multiplication instructions
1557;; -------------------------------------------------------------------------
1558
a512fa97 1559(define_insn "umulhisi3_i"
4773afa4
AO
1560 [(set (reg:SI MACL_REG)
1561 (mult:SI (zero_extend:SI
1562 (match_operand:HI 0 "arith_reg_operand" "r"))
1563 (zero_extend:SI
1564 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1565 "TARGET_SH1"
e9a9e960 1566 "mulu.w %1,%0"
b9654711 1567 [(set_attr "type" "smpy")])
bc45ade3 1568
a512fa97 1569(define_insn "mulhisi3_i"
4773afa4 1570 [(set (reg:SI MACL_REG)
bc45ade3 1571 (mult:SI (sign_extend:SI
af55dae3 1572 (match_operand:HI 0 "arith_reg_operand" "r"))
bc45ade3 1573 (sign_extend:SI
af55dae3 1574 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1575 "TARGET_SH1"
e9a9e960 1576 "muls.w %1,%0"
b9654711 1577 [(set_attr "type" "smpy")])
bc45ade3
SC
1578
1579(define_expand "mulhisi3"
4773afa4 1580 [(set (reg:SI MACL_REG)
bc45ade3 1581 (mult:SI (sign_extend:SI
51aea58d 1582 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1583 (sign_extend:SI
51aea58d
JW
1584 (match_operand:HI 2 "arith_reg_operand" ""))))
1585 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1586 (reg:SI MACL_REG))]
fa5322fa 1587 "TARGET_SH1"
a512fa97
R
1588 "
1589{
1590 rtx first, last;
1591
1592 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
4773afa4 1593 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1594 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1595 invariant code motion can move it. */
1596 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1597 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1598 /* expand_binop can't find a suitable code in umul_widen_optab to
1599 make a REG_EQUAL note from, so make one here.
1600 See also smulsi3_highpart.
1601 ??? Alternatively, we could put this at the calling site of expand_binop,
1602 i.e. expand_expr. */
1603 REG_NOTES (last)
1604 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1605 REG_NOTES (last));
a512fa97
R
1606 DONE;
1607}")
bc45ade3
SC
1608
1609(define_expand "umulhisi3"
4773afa4 1610 [(set (reg:SI MACL_REG)
bc45ade3 1611 (mult:SI (zero_extend:SI
51aea58d 1612 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1613 (zero_extend:SI
51aea58d
JW
1614 (match_operand:HI 2 "arith_reg_operand" ""))))
1615 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1616 (reg:SI MACL_REG))]
fa5322fa 1617 "TARGET_SH1"
a512fa97
R
1618 "
1619{
1620 rtx first, last;
1621
1622 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
4773afa4 1623 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1624 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1625 invariant code motion can move it. */
1626 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1627 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1628 /* expand_binop can't find a suitable code in umul_widen_optab to
1629 make a REG_EQUAL note from, so make one here.
1630 See also smulsi3_highpart.
1631 ??? Alternatively, we could put this at the calling site of expand_binop,
1632 i.e. expand_expr. */
1633 REG_NOTES (last)
1634 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1635 REG_NOTES (last));
a512fa97
R
1636 DONE;
1637}")
bc45ade3 1638
0d7e008e
SC
1639;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1640;; a call to a routine which clobbers known registers.
1641
1642(define_insn ""
e96a50cc 1643 [(set (match_operand:SI 1 "register_operand" "=z")
4773afa4
AO
1644 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1645 (clobber (reg:SI MACL_REG))
1646 (clobber (reg:SI T_REG))
1647 (clobber (reg:SI PR_REG))
1648 (clobber (reg:SI R3_REG))
1649 (clobber (reg:SI R2_REG))
1650 (clobber (reg:SI R1_REG))
07a45e5c 1651 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 1652 "TARGET_SH1"
0d7e008e
SC
1653 "jsr @%0%#"
1654 [(set_attr "type" "sfunc")
0d7e008e
SC
1655 (set_attr "needs_delay_slot" "yes")])
1656
1657(define_expand "mulsi3_call"
4773afa4
AO
1658 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1659 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
51aea58d 1660 (parallel[(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1661 (mult:SI (reg:SI R4_REG)
1662 (reg:SI R5_REG)))
1663 (clobber (reg:SI MACL_REG))
1664 (clobber (reg:SI T_REG))
1665 (clobber (reg:SI PR_REG))
1666 (clobber (reg:SI R3_REG))
1667 (clobber (reg:SI R2_REG))
1668 (clobber (reg:SI R1_REG))
225e4f43 1669 (use (match_operand:SI 3 "register_operand" ""))])]
fa5322fa 1670 "TARGET_SH1"
225e4f43 1671 "")
07a45e5c 1672
0d7e008e 1673(define_insn "mul_l"
4773afa4 1674 [(set (reg:SI MACL_REG)
0d7e008e
SC
1675 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1676 (match_operand:SI 1 "arith_reg_operand" "r")))]
1677 "TARGET_SH2"
1678 "mul.l %1,%0"
51bd623f 1679 [(set_attr "type" "dmpy")])
0d7e008e
SC
1680
1681(define_expand "mulsi3"
4773afa4 1682 [(set (reg:SI MACL_REG)
51aea58d
JW
1683 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1684 (match_operand:SI 2 "arith_reg_operand" "")))
1685 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1686 (reg:SI MACL_REG))]
fa5322fa 1687 "TARGET_SH1"
51bd623f
JW
1688 "
1689{
225e4f43
R
1690 rtx first, last;
1691
51bd623f
JW
1692 if (!TARGET_SH2)
1693 {
225e4f43
R
1694 /* The address must be set outside the libcall,
1695 since it goes into a pseudo. */
90534361 1696 rtx sym = function_symbol (\"__mulsi3\");
a6f463a0
AO
1697 rtx addr = force_reg (SImode, sym);
1698 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1699 operands[2], addr);
fa60f36d
R
1700 first = insns;
1701 last = emit_insn (insns);
51bd623f 1702 }
225e4f43
R
1703 else
1704 {
1705 rtx macl = gen_rtx_REG (SImode, MACL_REG);
aa4778b6 1706
225e4f43 1707 first = emit_insn (gen_mul_l (operands[1], operands[2]));
aa4778b6
R
1708 /* consec_sets_giv can only recognize the first insn that sets a
1709 giv as the giv insn. So we must tag this also with a REG_EQUAL
1710 note. */
78d114ef 1711 last = emit_insn (gen_movsi_i ((operands[0]), macl));
225e4f43
R
1712 }
1713 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1714 invariant code motion can move it. */
1715 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1716 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1717 DONE;
51bd623f 1718}")
00f8ff66 1719
af55dae3 1720(define_insn "mulsidi3_i"
4773afa4 1721 [(set (reg:SI MACH_REG)
a512fa97 1722 (truncate:SI
4773afa4
AO
1723 (lshiftrt:DI
1724 (mult:DI
1725 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1726 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1727 (const_int 32))))
1728 (set (reg:SI MACL_REG)
a512fa97
R
1729 (mult:SI (match_dup 0)
1730 (match_dup 1)))]
06e1bace 1731 "TARGET_SH2"
af55dae3 1732 "dmuls.l %1,%0"
0d7e008e
SC
1733 [(set_attr "type" "dmpy")])
1734
fa5322fa
AO
1735(define_expand "mulsidi3"
1736 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1737 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1738 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1739 "TARGET_SH2 || TARGET_SHMEDIA"
1740 "
1741{
1742 if (TARGET_SH2)
1743 {
1744 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1745 operands[2]));
1746 DONE;
1747 }
1748}")
1749
1750(define_insn "mulsidi3_media"
1751 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1752 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1753 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1754 "TARGET_SHMEDIA"
b6d33983
R
1755 "muls.l %1, %2, %0"
1756 [(set_attr "type" "dmpy_media")])
52702ae1 1757
fa5322fa 1758(define_insn "mulsidi3_compact"
a512fa97 1759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1760 (mult:DI
1761 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1762 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1763 (clobber (reg:SI MACH_REG))
1764 (clobber (reg:SI MACL_REG))]
a512fa97
R
1765 "TARGET_SH2"
1766 "#")
1767
1768(define_split
1769 [(set (match_operand:DI 0 "arith_reg_operand" "")
4773afa4
AO
1770 (mult:DI
1771 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1772 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1773 (clobber (reg:SI MACH_REG))
1774 (clobber (reg:SI MACL_REG))]
06e1bace 1775 "TARGET_SH2"
a512fa97 1776 [(const_int 0)]
af55dae3
JW
1777 "
1778{
a512fa97
R
1779 rtx low_dst = gen_lowpart (SImode, operands[0]);
1780 rtx high_dst = gen_highpart (SImode, operands[0]);
0d7e008e 1781
a512fa97 1782 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
af55dae3 1783
4773afa4
AO
1784 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1785 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1786 /* We need something to tag the possible REG_EQUAL notes on to. */
1787 emit_move_insn (operands[0], operands[0]);
1788 DONE;
af55dae3
JW
1789}")
1790
1791(define_insn "umulsidi3_i"
4773afa4 1792 [(set (reg:SI MACH_REG)
a512fa97 1793 (truncate:SI
4773afa4
AO
1794 (lshiftrt:DI
1795 (mult:DI
1796 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1797 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1798 (const_int 32))))
1799 (set (reg:SI MACL_REG)
a512fa97
R
1800 (mult:SI (match_dup 0)
1801 (match_dup 1)))]
06e1bace 1802 "TARGET_SH2"
af55dae3 1803 "dmulu.l %1,%0"
0d7e008e
SC
1804 [(set_attr "type" "dmpy")])
1805
fa5322fa
AO
1806(define_expand "umulsidi3"
1807 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1808 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1809 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1810 "TARGET_SH2 || TARGET_SHMEDIA"
1811 "
1812{
1813 if (TARGET_SH2)
1814 {
1815 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1816 operands[2]));
1817 DONE;
1818 }
1819}")
1820
1821(define_insn "umulsidi3_media"
1822 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1823 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1824 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1825 "TARGET_SHMEDIA"
b6d33983
R
1826 "mulu.l %1, %2, %0"
1827 [(set_attr "type" "dmpy_media")])
52702ae1 1828
fa5322fa 1829(define_insn "umulsidi3_compact"
a512fa97 1830 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1831 (mult:DI
1832 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1833 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1834 (clobber (reg:SI MACH_REG))
1835 (clobber (reg:SI MACL_REG))]
a512fa97
R
1836 "TARGET_SH2"
1837 "#")
1838
1839(define_split
1840 [(set (match_operand:DI 0 "arith_reg_operand" "")
51aea58d
JW
1841 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1842 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1843 (clobber (reg:SI MACH_REG))
1844 (clobber (reg:SI MACL_REG))]
06e1bace 1845 "TARGET_SH2"
a512fa97 1846 [(const_int 0)]
af55dae3
JW
1847 "
1848{
a512fa97
R
1849 rtx low_dst = gen_lowpart (SImode, operands[0]);
1850 rtx high_dst = gen_highpart (SImode, operands[0]);
af55dae3 1851
a512fa97 1852 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
af55dae3 1853
4773afa4
AO
1854 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1855 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1856 /* We need something to tag the possible REG_EQUAL notes on to. */
1857 emit_move_insn (operands[0], operands[0]);
1858 DONE;
af55dae3 1859}")
06e1bace 1860
a512fa97 1861(define_insn "smulsi3_highpart_i"
4773afa4 1862 [(set (reg:SI MACH_REG)
06e1bace 1863 (truncate:SI
4773afa4
AO
1864 (lshiftrt:DI
1865 (mult:DI
1866 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1867 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1868 (const_int 32))))
1869 (clobber (reg:SI MACL_REG))]
06e1bace 1870 "TARGET_SH2"
af55dae3 1871 "dmuls.l %1,%0"
06e1bace
RK
1872 [(set_attr "type" "dmpy")])
1873
1874(define_expand "smulsi3_highpart"
4773afa4
AO
1875 [(parallel
1876 [(set (reg:SI MACH_REG)
1877 (truncate:SI
1878 (lshiftrt:DI
1879 (mult:DI
1880 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1881 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1882 (const_int 32))))
1883 (clobber (reg:SI MACL_REG))])
06e1bace 1884 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1885 (reg:SI MACH_REG))]
06e1bace 1886 "TARGET_SH2"
a512fa97
R
1887 "
1888{
1889 rtx first, last;
06e1bace 1890
a512fa97 1891 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1892 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1893 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1894 invariant code motion can move it. */
1895 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1896 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
22d05f60
R
1897 /* expand_binop can't find a suitable code in mul_highpart_optab to
1898 make a REG_EQUAL note from, so make one here.
c49439f1 1899 See also {,u}mulhisi.
22d05f60
R
1900 ??? Alternatively, we could put this at the calling site of expand_binop,
1901 i.e. expand_mult_highpart. */
1902 REG_NOTES (last)
1903 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1904 REG_NOTES (last));
a512fa97
R
1905 DONE;
1906}")
1907
1908(define_insn "umulsi3_highpart_i"
4773afa4 1909 [(set (reg:SI MACH_REG)
06e1bace 1910 (truncate:SI
4773afa4
AO
1911 (lshiftrt:DI
1912 (mult:DI
1913 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1914 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1915 (const_int 32))))
1916 (clobber (reg:SI MACL_REG))]
06e1bace 1917 "TARGET_SH2"
af55dae3 1918 "dmulu.l %1,%0"
06e1bace
RK
1919 [(set_attr "type" "dmpy")])
1920
1921(define_expand "umulsi3_highpart"
4773afa4
AO
1922 [(parallel
1923 [(set (reg:SI MACH_REG)
1924 (truncate:SI
1925 (lshiftrt:DI
1926 (mult:DI
1927 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1928 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1929 (const_int 32))))
1930 (clobber (reg:SI MACL_REG))])
06e1bace 1931 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1932 (reg:SI MACH_REG))]
06e1bace 1933 "TARGET_SH2"
a512fa97
R
1934 "
1935{
1936 rtx first, last;
1937
1938 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1939 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1940 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1941 invariant code motion can move it. */
1942 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1943 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1944 DONE;
1945}")
bc45ade3
SC
1946\f
1947;; -------------------------------------------------------------------------
1948;; Logical operations
1949;; -------------------------------------------------------------------------
1950
b6d33983 1951(define_insn "*andsi3_compact"
aa684c94
SC
1952 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1953 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 1954 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 1955 "TARGET_SH1"
bc45ade3 1956 "and %2,%0"
c49439f1 1957 [(set_attr "type" "arith")])
bc45ade3 1958
43aa4e05 1959;; If the constant is 255, then emit an extu.b instruction instead of an
51bd623f
JW
1960;; and, since that will give better code.
1961
0d7e008e
SC
1962(define_expand "andsi3"
1963 [(set (match_operand:SI 0 "arith_reg_operand" "")
1964 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1965 (match_operand:SI 2 "logical_operand" "")))]
fa5322fa 1966 "TARGET_SH1"
51bd623f
JW
1967 "
1968{
1969 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1970 {
1971 emit_insn (gen_zero_extendqisi2 (operands[0],
1972 gen_lowpart (QImode, operands[1])));
1973 DONE;
1974 }
1975}")
0d7e008e 1976
c1b92d09
R
1977(define_insn_and_split "anddi3"
1978 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1979 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
735cb76e 1980 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
fa5322fa
AO
1981 "TARGET_SHMEDIA"
1982 "@
1983 and %1, %2, %0
c1b92d09
R
1984 andi %1, %2, %0
1985 #"
1986 "reload_completed
1987 && ! logical_operand (operands[2], DImode)"
1988 [(const_int 0)]
1989 "
1990{
1991 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1992 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1993 else
1994 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1995 DONE;
2ad65b0e
SC
1996}"
1997 [(set_attr "type" "arith_media")])
fa5322fa 1998
b6d33983 1999(define_insn "andcdi3"
fa5322fa
AO
2000 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2001 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2002 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2003 "TARGET_SHMEDIA"
2ad65b0e
SC
2004 "andc %1,%2,%0"
2005 [(set_attr "type" "arith_media")])
fa5322fa 2006
bc45ade3 2007(define_insn "iorsi3"
aa684c94
SC
2008 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2009 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 2010 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 2011 "TARGET_SH1"
1245df60 2012 "or %2,%0"
c49439f1 2013 [(set_attr "type" "arith")])
bc45ade3 2014
fa5322fa
AO
2015(define_insn "iordi3"
2016 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2017 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 2018 (match_operand:DI 2 "logical_operand" "r,I10")))]
fa5322fa
AO
2019 "TARGET_SHMEDIA"
2020 "@
2021 or %1, %2, %0
2ad65b0e
SC
2022 ori %1, %2, %0"
2023 [(set_attr "type" "arith_media")])
fa5322fa 2024
bc45ade3 2025(define_insn "xorsi3"
0d7e008e 2026 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
aa684c94 2027 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 2028 (match_operand:SI 2 "logical_operand" "K08,r")))]
fa5322fa 2029 "TARGET_SH1"
bc45ade3 2030 "xor %2,%0"
c49439f1 2031 [(set_attr "type" "arith")])
fa5322fa
AO
2032
2033(define_insn "xordi3"
2034 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2035 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 2036 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
fa5322fa
AO
2037 "TARGET_SHMEDIA"
2038 "@
2039 xor %1, %2, %0
2ad65b0e
SC
2040 xori %1, %2, %0"
2041 [(set_attr "type" "arith_media")])
ff881d52
R
2042
2043;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2044;; converts 2 * sign extend -> logical op into logical op -> sign extend
2045(define_split
2046 [(set (match_operand:DI 0 "arith_reg_operand" "")
2047 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2048 [(match_operand 1 "any_register_operand" "")
2049 (match_operand 2 "any_register_operand" "")])))]
2050 "TARGET_SHMEDIA"
2051 [(set (match_dup 5) (match_dup 4))
2052 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2053"
2054{
2055 enum machine_mode inmode = GET_MODE (operands[1]);
fada1961 2056 int offset = 0;
ff881d52
R
2057
2058 if (GET_CODE (operands[0]) == SUBREG)
2059 {
2060 offset = SUBREG_BYTE (operands[0]);
2061 operands[0] = SUBREG_REG (operands[0]);
2062 }
2063 if (GET_CODE (operands[0]) != REG)
2064 abort ();
2065 if (! TARGET_LITTLE_ENDIAN)
2066 offset += 8 - GET_MODE_SIZE (inmode);
2067 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2068}")
bc45ade3
SC
2069\f
2070;; -------------------------------------------------------------------------
2071;; Shifts and rotates
2072;; -------------------------------------------------------------------------
2073
b6d33983
R
2074(define_expand "rotldi3"
2075 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2076 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2077 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2078 "TARGET_SHMEDIA"
2079 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2080
2081(define_insn "rotldi3_mextr"
2082 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2083 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2084 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2085 "TARGET_SHMEDIA"
2086 "*
2087{
2088 static char templ[16];
2089
2090 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2091 8 - (int) (INTVAL (operands[2]) >> 3));
2092 return templ;
2093}"
2094 [(set_attr "type" "arith_media")])
2095
2096(define_expand "rotrdi3"
2097 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2098 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2099 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2100 "TARGET_SHMEDIA"
2101 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2102
2103(define_insn "rotrdi3_mextr"
2104 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2105 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2106 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2107 "TARGET_SHMEDIA"
2108 "*
2109{
2110 static char templ[16];
2111
2112 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2113 return templ;
2114}"
2115 [(set_attr "type" "arith_media")])
2116
51bd623f 2117(define_insn "rotlsi3_1"
b9654711
SC
2118 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2119 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2120 (const_int 1)))
4773afa4 2121 (set (reg:SI T_REG)
51aea58d 2122 (lshiftrt:SI (match_dup 1) (const_int 31)))]
fa5322fa 2123 "TARGET_SH1"
1245df60 2124 "rotl %0"
c49439f1 2125 [(set_attr "type" "arith")])
b9654711 2126
51bd623f 2127(define_insn "rotlsi3_31"
b9654711 2128 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f
JW
2129 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2130 (const_int 31)))
4773afa4 2131 (clobber (reg:SI T_REG))]
fa5322fa 2132 "TARGET_SH1"
1245df60 2133 "rotr %0"
c49439f1 2134 [(set_attr "type" "arith")])
b9654711 2135
1245df60 2136(define_insn "rotlsi3_16"
51bd623f
JW
2137 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2138 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2139 (const_int 16)))]
fa5322fa 2140 "TARGET_SH1"
1245df60 2141 "swap.w %1,%0"
c49439f1 2142 [(set_attr "type" "arith")])
b9654711 2143
51bd623f
JW
2144(define_expand "rotlsi3"
2145 [(set (match_operand:SI 0 "arith_reg_operand" "")
2146 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2147 (match_operand:SI 2 "immediate_operand" "")))]
fa5322fa 2148 "TARGET_SH1"
51bd623f
JW
2149 "
2150{
0139adca 2151 static const char rot_tab[] = {
1245df60
R
2152 000, 000, 000, 000, 000, 000, 010, 001,
2153 001, 001, 011, 013, 003, 003, 003, 003,
2154 003, 003, 003, 003, 003, 013, 012, 002,
2155 002, 002, 010, 000, 000, 000, 000, 000,
2156 };
2157
2158 int count, choice;
2159
51bd623f
JW
2160 if (GET_CODE (operands[2]) != CONST_INT)
2161 FAIL;
1245df60
R
2162 count = INTVAL (operands[2]);
2163 choice = rot_tab[count];
2164 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2165 FAIL;
2166 choice &= 7;
2167 switch (choice)
51bd623f 2168 {
1245df60
R
2169 case 0:
2170 emit_move_insn (operands[0], operands[1]);
2171 count -= (count & 16) * 2;
2172 break;
2173 case 3:
2174 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2175 count -= 16;
2176 break;
2177 case 1:
2178 case 2:
2179 {
2180 rtx parts[2];
2181 parts[0] = gen_reg_rtx (SImode);
2182 parts[1] = gen_reg_rtx (SImode);
2183 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2184 parts[choice-1] = operands[1];
2185 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2186 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2187 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2188 count = (count & ~16) - 8;
2189 }
51bd623f 2190 }
1245df60
R
2191
2192 for (; count > 0; count--)
2193 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2194 for (; count < 0; count++)
2195 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2196
2197 DONE;
51bd623f
JW
2198}")
2199
1245df60 2200(define_insn "*rotlhi3_8"
51bd623f
JW
2201 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2202 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2203 (const_int 8)))]
fa5322fa 2204 "TARGET_SH1"
1245df60 2205 "swap.b %1,%0"
c49439f1 2206 [(set_attr "type" "arith")])
51bd623f
JW
2207
2208(define_expand "rotlhi3"
2209 [(set (match_operand:HI 0 "arith_reg_operand" "")
2210 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2211 (match_operand:HI 2 "immediate_operand" "")))]
fa5322fa 2212 "TARGET_SH1"
51bd623f
JW
2213 "
2214{
2215 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2216 FAIL;
2217}")
0d7e008e
SC
2218
2219;;
2220;; shift left
2221
7e2fda6e
BS
2222;; This pattern is used by init_expmed for computing the costs of shift
2223;; insns.
2224
2225(define_insn_and_split "ashlsi3_std"
2226 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2227 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
735cb76e 2228 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
7e2fda6e
BS
2229 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2230 "TARGET_SH3
fa5322fa 2231 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
735cb76e 2232 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
0d7e008e 2233 "@
7e2fda6e
BS
2234 shld %2,%0
2235 add %0,%0
2236 shll%O2 %0
2237 #"
2238 "TARGET_SH3
615cd49b 2239 && reload_completed
7e2fda6e 2240 && GET_CODE (operands[2]) == CONST_INT
735cb76e 2241 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
7e2fda6e
BS
2242 [(set (match_dup 3) (match_dup 2))
2243 (parallel
2244 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2245 (clobber (match_dup 4))])]
2246 "operands[4] = gen_rtx_SCRATCH (SImode);"
2247 [(set_attr "length" "*,*,*,4")
c49439f1 2248 (set_attr "type" "dyn_shift,arith,arith,arith")])
0d7e008e 2249
98e819b9
JW
2250(define_insn "ashlhi3_k"
2251 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2252 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
735cb76e
R
2253 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2254 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
98e819b9
JW
2255 "@
2256 add %0,%0
1245df60 2257 shll%O2 %0"
c49439f1 2258 [(set_attr "type" "arith")])
98e819b9 2259
0d7e008e
SC
2260(define_insn "ashlsi3_n"
2261 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2262 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2263 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2264 (clobber (reg:SI T_REG))]
fa5322fa 2265 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2266 "#"
2267 [(set (attr "length")
2268 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2269 (const_string "2")
2270 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2271 (const_string "4")
2272 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2273 (const_string "6")]
2274 (const_string "8")))
c49439f1 2275 (set_attr "type" "arith")])
bc45ade3 2276
07a45e5c
JW
2277(define_split
2278 [(set (match_operand:SI 0 "arith_reg_operand" "")
2279 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2280 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2281 (clobber (reg:SI T_REG))]
fa5322fa 2282 "TARGET_SH1 && reload_completed"
4773afa4 2283 [(use (reg:SI R0_REG))]
07a45e5c
JW
2284 "
2285{
2286 gen_shifty_op (ASHIFT, operands);
2287 DONE;
2288}")
2289
fa5322fa
AO
2290(define_insn "ashlsi3_media"
2291 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2292 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2293 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2294 "TARGET_SHMEDIA"
2295 "@
2296 shlld.l %1, %2, %0
b6d33983
R
2297 shlli.l %1, %2, %0"
2298 [(set_attr "type" "arith_media")])
fa5322fa 2299
bc45ade3 2300(define_expand "ashlsi3"
ffae286a
JW
2301 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2302 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2303 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2304 (clobber (reg:SI T_REG))])]
bc45ade3 2305 ""
d2f09a2f
JW
2306 "
2307{
fa5322fa
AO
2308 if (TARGET_SHMEDIA)
2309 {
2310 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2311 DONE;
2312 }
1245df60
R
2313 if (GET_CODE (operands[2]) == CONST_INT
2314 && sh_dynamicalize_shift_p (operands[2]))
2315 operands[2] = force_reg (SImode, operands[2]);
7e2fda6e 2316 if (TARGET_SH3)
6b005b88 2317 {
7e2fda6e 2318 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
6b005b88
JW
2319 DONE;
2320 }
d2f09a2f
JW
2321 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2322 FAIL;
2323}")
0d7e008e 2324
98e819b9
JW
2325(define_insn "ashlhi3"
2326 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2327 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2328 (match_operand:HI 2 "const_int_operand" "n")))
4773afa4 2329 (clobber (reg:SI T_REG))]
fa5322fa 2330 "TARGET_SH1"
98e819b9
JW
2331 "#"
2332 [(set (attr "length")
2333 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2334 (const_string "2")
2335 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2336 (const_string "4")]
2337 (const_string "6")))
2338 (set_attr "type" "arith")])
2339
2340(define_split
2341 [(set (match_operand:HI 0 "arith_reg_operand" "")
2342 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
e69d1422 2343 (match_operand:HI 2 "const_int_operand" "")))
4773afa4 2344 (clobber (reg:SI T_REG))]
fa5322fa 2345 "TARGET_SH1 && reload_completed"
4773afa4 2346 [(use (reg:SI R0_REG))]
98e819b9
JW
2347 "
2348{
2349 gen_shifty_hi_op (ASHIFT, operands);
2350 DONE;
2351}")
2352
0d7e008e
SC
2353;
2354; arithmetic shift right
2355;
bc45ade3
SC
2356
2357(define_insn "ashrsi3_k"
aa684c94
SC
2358 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2359 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2360 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2361 (clobber (reg:SI T_REG))]
fa5322fa 2362 "TARGET_SH1 && INTVAL (operands[2]) == 1"
bc45ade3 2363 "shar %0"
c49439f1 2364 [(set_attr "type" "arith")])
bc45ade3 2365
d0c42859
R
2366;; We can't do HImode right shifts correctly unless we start out with an
2367;; explicit zero / sign extension; doing that would result in worse overall
2368;; code, so just let the machine independent code widen the mode.
2369;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2370
98e819b9 2371
ffae286a
JW
2372;; ??? This should be a define expand.
2373
00f8ff66 2374(define_insn "ashrsi2_16"
07a45e5c
JW
2375 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2376 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3e8bd1ce 2377 (const_int 16)))]
fa5322fa 2378 "TARGET_SH1"
1245df60 2379 "#"
00f8ff66
SC
2380 [(set_attr "length" "4")])
2381
1245df60 2382(define_split
e69d1422
R
2383 [(set (match_operand:SI 0 "arith_reg_operand" "")
2384 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2385 (const_int 16)))]
fa5322fa 2386 "TARGET_SH1"
1245df60
R
2387 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2388 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2389 "operands[2] = gen_lowpart (HImode, operands[0]);")
2390
ffae286a
JW
2391;; ??? This should be a define expand.
2392
00f8ff66 2393(define_insn "ashrsi2_31"
6b005b88 2394 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1245df60
R
2395 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2396 (const_int 31)))
4773afa4 2397 (clobber (reg:SI T_REG))]
fa5322fa 2398 "TARGET_SH1"
1245df60 2399 "#"
6b005b88 2400 [(set_attr "length" "4")])
3e8bd1ce 2401
1245df60 2402(define_split
e69d1422
R
2403 [(set (match_operand:SI 0 "arith_reg_operand" "")
2404 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2405 (const_int 31)))
4773afa4 2406 (clobber (reg:SI T_REG))]
fa5322fa 2407 "TARGET_SH1"
1245df60
R
2408 [(const_int 0)]
2409 "
2410{
5bac82c5 2411 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
1245df60
R
2412 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2413 DONE;
2414}")
2415
2416(define_insn "ashlsi_c"
2417 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2418 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4773afa4
AO
2419 (set (reg:SI T_REG)
2420 (lt:SI (match_dup 1) (const_int 0)))]
fa5322fa 2421 "TARGET_SH1"
1245df60 2422 "shll %0"
c49439f1 2423 [(set_attr "type" "arith")])
1245df60 2424
6b005b88
JW
2425(define_insn "ashrsi3_d"
2426 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2427 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2428 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2429 "TARGET_SH3"
1245df60 2430 "shad %2,%0"
c49439f1 2431 [(set_attr "type" "dyn_shift")])
51aea58d 2432
0d7e008e 2433(define_insn "ashrsi3_n"
4773afa4
AO
2434 [(set (reg:SI R4_REG)
2435 (ashiftrt:SI (reg:SI R4_REG)
ffae286a 2436 (match_operand:SI 0 "const_int_operand" "i")))
4773afa4
AO
2437 (clobber (reg:SI T_REG))
2438 (clobber (reg:SI PR_REG))
0d7e008e 2439 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 2440 "TARGET_SH1"
0d7e008e
SC
2441 "jsr @%1%#"
2442 [(set_attr "type" "sfunc")
0d7e008e
SC
2443 (set_attr "needs_delay_slot" "yes")])
2444
fa5322fa
AO
2445(define_insn "ashrsi3_media"
2446 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2447 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2448 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2449 "TARGET_SHMEDIA"
2450 "@
2451 shard.l %1, %2, %0
b6d33983
R
2452 shari.l %1, %2, %0"
2453 [(set_attr "type" "arith_media")])
fa5322fa 2454
bc45ade3 2455(define_expand "ashrsi3"
ffae286a
JW
2456 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2457 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2458 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2459 (clobber (reg:SI T_REG))])]
bc45ade3 2460 ""
fa5322fa
AO
2461 "
2462{
2463 if (TARGET_SHMEDIA)
2464 {
2465 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2466 DONE;
2467 }
2468 if (expand_ashiftrt (operands))
2469 DONE;
2470 else
2471 FAIL;
2472}")
0d7e008e 2473
07a45e5c 2474;; logical shift right
bc45ade3 2475
6b005b88
JW
2476(define_insn "lshrsi3_d"
2477 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2479 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2480 "TARGET_SH3"
1245df60 2481 "shld %2,%0"
c49439f1 2482 [(set_attr "type" "dyn_shift")])
00f8ff66 2483
ffae286a 2484;; Only the single bit shift clobbers the T bit.
07a45e5c
JW
2485
2486(define_insn "lshrsi3_m"
2487 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2488 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2489 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2490 (clobber (reg:SI T_REG))]
fa5322fa 2491 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2492 "shlr %0"
c49439f1 2493 [(set_attr "type" "arith")])
0d7e008e 2494
07a45e5c
JW
2495(define_insn "lshrsi3_k"
2496 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2497 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
735cb76e
R
2498 (match_operand:SI 2 "const_int_operand" "P27")))]
2499 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
07a45e5c 2500 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2501 "shlr%O2 %0"
c49439f1 2502 [(set_attr "type" "arith")])
0d7e008e
SC
2503
2504(define_insn "lshrsi3_n"
2505 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2506 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2507 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2508 (clobber (reg:SI T_REG))]
fa5322fa 2509 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2510 "#"
2511 [(set (attr "length")
2512 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2513 (const_string "2")
2514 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2515 (const_string "4")
2516 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2517 (const_string "6")]
2518 (const_string "8")))
bc45ade3
SC
2519 (set_attr "type" "arith")])
2520
07a45e5c
JW
2521(define_split
2522 [(set (match_operand:SI 0 "arith_reg_operand" "")
2523 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2524 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2525 (clobber (reg:SI T_REG))]
fa5322fa 2526 "TARGET_SH1 && reload_completed"
4773afa4 2527 [(use (reg:SI R0_REG))]
07a45e5c
JW
2528 "
2529{
2530 gen_shifty_op (LSHIFTRT, operands);
2531 DONE;
2532}")
2533
fa5322fa
AO
2534(define_insn "lshrsi3_media"
2535 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2536 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2537 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2538 "TARGET_SHMEDIA"
2539 "@
2540 shlrd.l %1, %2, %0
b6d33983
R
2541 shlri.l %1, %2, %0"
2542 [(set_attr "type" "arith_media")])
fa5322fa 2543
bc45ade3 2544(define_expand "lshrsi3"
ffae286a
JW
2545 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2546 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2547 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2548 (clobber (reg:SI T_REG))])]
bc45ade3 2549 ""
d2f09a2f
JW
2550 "
2551{
fa5322fa
AO
2552 if (TARGET_SHMEDIA)
2553 {
2554 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2555 DONE;
2556 }
1245df60
R
2557 if (GET_CODE (operands[2]) == CONST_INT
2558 && sh_dynamicalize_shift_p (operands[2]))
2559 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
2560 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2561 {
2562 rtx count = copy_to_mode_reg (SImode, operands[2]);
2563 emit_insn (gen_negsi2 (count, count));
7b7499bf 2564 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
6b005b88
JW
2565 DONE;
2566 }
d2f09a2f
JW
2567 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2568 FAIL;
2569}")
bc45ade3 2570
ffae286a
JW
2571;; ??? This should be a define expand.
2572
bc45ade3 2573(define_insn "ashldi3_k"
aa684c94
SC
2574 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2575 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2576 (const_int 1)))
4773afa4 2577 (clobber (reg:SI T_REG))]
fa5322fa 2578 "TARGET_SH1"
00f8ff66 2579 "shll %R0\;rotcl %S0"
1245df60 2580 [(set_attr "length" "4")
c49439f1 2581 (set_attr "type" "arith")])
bc45ade3 2582
fa5322fa
AO
2583(define_insn "ashldi3_media"
2584 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2585 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2586 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2587 "TARGET_SHMEDIA"
2588 "@
2589 shlld %1, %2, %0
2ad65b0e
SC
2590 shlli %1, %2, %0"
2591 [(set_attr "type" "arith_media")])
fa5322fa 2592
bc45ade3 2593(define_expand "ashldi3"
ffae286a
JW
2594 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2595 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2596 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2597 (clobber (reg:SI T_REG))])]
bc45ade3 2598 ""
fa5322fa
AO
2599 "
2600{
2601 if (TARGET_SHMEDIA)
2602 {
2603 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2604 DONE;
2605 }
2606 if (GET_CODE (operands[2]) != CONST_INT
2607 || INTVAL (operands[2]) != 1)
2608 FAIL;
2609}")
ffae286a
JW
2610
2611;; ??? This should be a define expand.
bc45ade3
SC
2612
2613(define_insn "lshrdi3_k"
aa684c94 2614 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b9654711 2615 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2616 (const_int 1)))
4773afa4 2617 (clobber (reg:SI T_REG))]
fa5322fa 2618 "TARGET_SH1"
00f8ff66 2619 "shlr %S0\;rotcr %R0"
1245df60 2620 [(set_attr "length" "4")
c49439f1 2621 (set_attr "type" "arith")])
bc45ade3 2622
fa5322fa
AO
2623(define_insn "lshrdi3_media"
2624 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2625 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2626 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2627 "TARGET_SHMEDIA"
2628 "@
2629 shlrd %1, %2, %0
2ad65b0e
SC
2630 shlri %1, %2, %0"
2631 [(set_attr "type" "arith_media")])
fa5322fa 2632
bc45ade3 2633(define_expand "lshrdi3"
ffae286a
JW
2634 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2635 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
bc45ade3 2636 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2637 (clobber (reg:SI T_REG))])]
bc45ade3 2638 ""
fa5322fa
AO
2639 "
2640{
2641 if (TARGET_SHMEDIA)
2642 {
2643 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2644 DONE;
2645 }
2646 if (GET_CODE (operands[2]) != CONST_INT
2647 || INTVAL (operands[2]) != 1)
2648 FAIL;
2649}")
ffae286a
JW
2650
2651;; ??? This should be a define expand.
bc45ade3
SC
2652
2653(define_insn "ashrdi3_k"
aa684c94
SC
2654 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2655 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2656 (const_int 1)))
4773afa4 2657 (clobber (reg:SI T_REG))]
fa5322fa 2658 "TARGET_SH1"
00f8ff66 2659 "shar %S0\;rotcr %R0"
1245df60 2660 [(set_attr "length" "4")
c49439f1 2661 (set_attr "type" "arith")])
bc45ade3 2662
fa5322fa
AO
2663(define_insn "ashrdi3_media"
2664 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2665 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2666 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2667 "TARGET_SHMEDIA"
2668 "@
2669 shard %1, %2, %0
2ad65b0e
SC
2670 shari %1, %2, %0"
2671 [(set_attr "type" "arith_media")])
fa5322fa 2672
bc45ade3 2673(define_expand "ashrdi3"
ffae286a
JW
2674 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2675 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2676 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2677 (clobber (reg:SI T_REG))])]
bc45ade3 2678 ""
fa5322fa
AO
2679 "
2680{
2681 if (TARGET_SHMEDIA)
2682 {
2683 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2684 DONE;
2685 }
2686 if (GET_CODE (operands[2]) != CONST_INT
2687 || INTVAL (operands[2]) != 1)
2688 FAIL;
2689}")
98e819b9
JW
2690
2691;; combined left/right shift
2692
2693(define_split
2694 [(set (match_operand:SI 0 "register_operand" "")
2695 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2696 (match_operand:SI 2 "const_int_operand" ""))
2697 (match_operand:SI 3 "const_int_operand" "")))]
85af47b9 2698 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2699 [(use (reg:SI R0_REG))]
98e819b9
JW
2700 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2701 DONE;")
2702
2703(define_split
2704 [(set (match_operand:SI 0 "register_operand" "")
2705 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2706 (match_operand:SI 2 "const_int_operand" ""))
2707 (match_operand:SI 3 "const_int_operand" "")))
4773afa4 2708 (clobber (reg:SI T_REG))]
85af47b9 2709 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2710 [(use (reg:SI R0_REG))]
98e819b9
JW
2711 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2712 DONE;")
2713
2714(define_insn ""
2715 [(set (match_operand:SI 0 "register_operand" "=r")
2716 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2717 (match_operand:SI 2 "const_int_operand" "n"))
2718 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2719 (clobber (reg:SI T_REG))]
fa5322fa 2720 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
98e819b9
JW
2721 "#"
2722 [(set (attr "length")
2723 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2724 (const_string "4")
2725 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2726 (const_string "6")
2727 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2728 (const_string "8")
2729 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2730 (const_string "10")
2731 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2732 (const_string "12")
2733 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2734 (const_string "14")
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2736 (const_string "16")]
2737 (const_string "18")))
2738 (set_attr "type" "arith")])
2739
2740(define_insn ""
2741 [(set (match_operand:SI 0 "register_operand" "=z")
2742 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2743 (match_operand:SI 2 "const_int_operand" "n"))
2744 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2745 (clobber (reg:SI T_REG))]
fa5322fa 2746 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
98e819b9
JW
2747 "#"
2748 [(set (attr "length")
2749 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2750 (const_string "4")
2751 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2752 (const_string "6")
2753 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2754 (const_string "8")]
2755 (const_string "10")))
2756 (set_attr "type" "arith")])
2757
2758;; shift left / and combination with a scratch register: The combine pass
2759;; does not accept the individual instructions, even though they are
2760;; cheap. But it needs a precise description so that it is usable after
2761;; reload.
2762(define_insn "and_shl_scratch"
2763 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4773afa4
AO
2764 (lshiftrt:SI
2765 (ashift:SI
2766 (and:SI
2767 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2768 (match_operand:SI 2 "const_int_operand" "N,n"))
2769 (match_operand:SI 3 "" "0,r"))
2770 (match_operand:SI 4 "const_int_operand" "n,n"))
2771 (match_operand:SI 5 "const_int_operand" "n,n")))
2772 (clobber (reg:SI T_REG))]
fa5322fa 2773 "TARGET_SH1"
98e819b9
JW
2774 "#"
2775 [(set (attr "length")
2776 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2777 (const_string "4")
2778 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2779 (const_string "6")
2780 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
9788ff4d 2781 (const_string "8")
98e819b9
JW
2782 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2783 (const_string "10")]
2784 (const_string "12")))
2785 (set_attr "type" "arith")])
2786
2787(define_split
e69d1422 2788 [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
2789 (lshiftrt:SI
2790 (ashift:SI
2791 (and:SI
e69d1422
R
2792 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2793 (match_operand:SI 2 "const_int_operand" ""))
2794 (match_operand:SI 3 "register_operand" ""))
2795 (match_operand:SI 4 "const_int_operand" ""))
2796 (match_operand:SI 5 "const_int_operand" "")))
4773afa4 2797 (clobber (reg:SI T_REG))]
fa5322fa 2798 "TARGET_SH1"
4773afa4 2799 [(use (reg:SI R0_REG))]
98e819b9
JW
2800 "
2801{
fc2380b9 2802 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
98e819b9
JW
2803
2804 if (INTVAL (operands[2]))
2805 {
2806 gen_shifty_op (LSHIFTRT, operands);
98e819b9
JW
2807 }
2808 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2809 operands[2] = operands[4];
2810 gen_shifty_op (ASHIFT, operands);
2811 if (INTVAL (operands[5]))
2812 {
2813 operands[2] = operands[5];
2814 gen_shifty_op (LSHIFTRT, operands);
2815 }
2816 DONE;
2817}")
2818
2819;; signed left/right shift combination.
2820(define_split
e69d1422 2821 [(set (match_operand:SI 0 "register_operand" "")
4773afa4 2822 (sign_extract:SI
e69d1422
R
2823 (ashift:SI (match_operand:SI 1 "register_operand" "")
2824 (match_operand:SI 2 "const_int_operand" ""))
2825 (match_operand:SI 3 "const_int_operand" "")
4773afa4
AO
2826 (const_int 0)))
2827 (clobber (reg:SI T_REG))]
fa5322fa 2828 "TARGET_SH1"
4773afa4 2829 [(use (reg:SI R0_REG))]
98e819b9
JW
2830 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2831 DONE;")
2832
2833(define_insn "shl_sext_ext"
2834 [(set (match_operand:SI 0 "register_operand" "=r")
4773afa4
AO
2835 (sign_extract:SI
2836 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2837 (match_operand:SI 2 "const_int_operand" "n"))
2838 (match_operand:SI 3 "const_int_operand" "n")
2839 (const_int 0)))
2840 (clobber (reg:SI T_REG))]
fa5322fa 2841 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
98e819b9
JW
2842 "#"
2843 [(set (attr "length")
2844 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2845 (const_string "2")
2846 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2847 (const_string "4")
2848 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2849 (const_string "6")
2850 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2851 (const_string "8")
2852 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2853 (const_string "10")
2854 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2855 (const_string "12")
2856 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2857 (const_string "14")
2858 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2859 (const_string "16")]
2860 (const_string "18")))
2861 (set_attr "type" "arith")])
2862
2863(define_insn "shl_sext_sub"
2864 [(set (match_operand:SI 0 "register_operand" "=z")
e11cddec
AO
2865 (sign_extract:SI
2866 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2867 (match_operand:SI 2 "const_int_operand" "n"))
2868 (match_operand:SI 3 "const_int_operand" "n")
2869 (const_int 0)))
4773afa4 2870 (clobber (reg:SI T_REG))]
fa5322fa 2871 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
98e819b9
JW
2872 "#"
2873 [(set (attr "length")
2874 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2875 (const_string "6")
2876 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2877 (const_string "8")
2878 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2879 (const_string "10")
2880 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2881 (const_string "12")]
2882 (const_string "14")))
2883 (set_attr "type" "arith")])
2884
977eef43
JW
2885;; These patterns are found in expansions of DImode shifts by 16, and
2886;; allow the xtrct instruction to be generated from C source.
2887
2888(define_insn "xtrct_left"
2889 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2890 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2891 (const_int 16))
2892 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2893 (const_int 16))))]
fa5322fa 2894 "TARGET_SH1"
1245df60 2895 "xtrct %1,%0"
c49439f1 2896 [(set_attr "type" "arith")])
977eef43
JW
2897
2898(define_insn "xtrct_right"
2899 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2900 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2901 (const_int 16))
2902 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2903 (const_int 16))))]
fa5322fa 2904 "TARGET_SH1"
1245df60 2905 "xtrct %2,%0"
c49439f1 2906 [(set_attr "type" "arith")])
fae15c93 2907
bc45ade3
SC
2908;; -------------------------------------------------------------------------
2909;; Unary arithmetic
2910;; -------------------------------------------------------------------------
2911
8e87e161
SC
2912(define_insn "negc"
2913 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 2914 (neg:SI (plus:SI (reg:SI T_REG)
51bd623f 2915 (match_operand:SI 1 "arith_reg_operand" "r"))))
4773afa4
AO
2916 (set (reg:SI T_REG)
2917 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
51bd623f 2918 (const_int 0)))]
fa5322fa 2919 "TARGET_SH1"
8e87e161 2920 "negc %1,%0"
c49439f1 2921 [(set_attr "type" "arith")])
bc45ade3 2922
fa5322fa
AO
2923(define_insn "*negdi_media"
2924 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2925 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2926 "TARGET_SHMEDIA"
2ad65b0e
SC
2927 "sub r63, %1, %0"
2928 [(set_attr "type" "arith_media")])
fa5322fa 2929
8e87e161 2930(define_expand "negdi2"
51aea58d 2931 [(set (match_operand:DI 0 "arith_reg_operand" "")
b6d33983 2932 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
8e87e161 2933 ""
ffae286a
JW
2934 "
2935{
fa5322fa
AO
2936 if (TARGET_SH1)
2937 {
2938 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2939 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
8e87e161 2940
fa5322fa
AO
2941 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2942 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
0a0b733a 2943
fa5322fa
AO
2944 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2945 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
8e87e161 2946
fa5322fa
AO
2947 emit_insn (gen_clrt ());
2948 emit_insn (gen_negc (low_dst, low_src));
2949 emit_insn (gen_negc (high_dst, high_src));
2950 DONE;
2951 }
ffae286a 2952}")
8e87e161 2953
bc45ade3 2954(define_insn "negsi2"
aa684c94
SC
2955 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2956 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2957 "TARGET_SH1"
bc45ade3 2958 "neg %1,%0"
c49439f1 2959 [(set_attr "type" "arith")])
bc45ade3
SC
2960
2961(define_insn "one_cmplsi2"
aa684c94
SC
2962 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2963 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2964 "TARGET_SH1"
bc45ade3 2965 "not %1,%0"
c49439f1 2966 [(set_attr "type" "arith")])
fa5322fa
AO
2967
2968(define_expand "one_cmpldi2"
2969 [(set (match_operand:DI 0 "arith_reg_operand" "")
2970 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2971 (const_int -1)))]
2972 "TARGET_SHMEDIA" "")
bc45ade3
SC
2973\f
2974;; -------------------------------------------------------------------------
2975;; Zero extension instructions
2976;; -------------------------------------------------------------------------
2977
fa5322fa
AO
2978(define_insn "zero_extendsidi2"
2979 [(set (match_operand:DI 0 "register_operand" "=r")
b6d33983 2980 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
fa5322fa 2981 "TARGET_SHMEDIA"
b6d33983
R
2982 "addz.l %1, r63, %0"
2983 [(set_attr "type" "arith_media")])
fa5322fa
AO
2984
2985(define_insn "zero_extendhidi2"
2986 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 2987 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
2988 "TARGET_SHMEDIA"
2989 "@
2990 #
b6d33983
R
2991 ld%M1.uw %m1, %0"
2992 [(set_attr "type" "*,load_media")])
fa5322fa
AO
2993
2994(define_split
e69d1422
R
2995 [(set (match_operand:DI 0 "register_operand" "")
2996 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
2997 "TARGET_SHMEDIA && reload_completed"
2998 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
2999 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3000 "
3001{
3002 if (GET_CODE (operands[1]) == TRUNCATE)
3003 operands[1] = XEXP (operands[1], 0);
3004}")
3005
fae778eb
KH
3006;; ??? when a truncated input to a zero_extend is reloaded, reload will
3007;; reload the entire truncate expression.
b6d33983 3008(define_insn_and_split "*loaddi_trunc"
e69d1422 3009 [(set (match_operand 0 "int_gpr_dest" "=r")
b6d33983
R
3010 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3011 "TARGET_SHMEDIA && reload_completed"
3012 "#"
3013 "TARGET_SHMEDIA && reload_completed"
3014 [(set (match_dup 0) (match_dup 1))]
3015 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
fa5322fa
AO
3016
3017(define_insn "zero_extendqidi2"
3018 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3019 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3020 "TARGET_SHMEDIA"
3021 "@
3022 andi %1, 255, %0
b6d33983
R
3023 ld%M1.ub %m1, %0"
3024 [(set_attr "type" "arith_media,load_media")])
3025
3026(define_expand "zero_extendhisi2"
3027 [(set (match_operand:SI 0 "arith_reg_operand" "")
3028 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3029 ""
3030 "
3031{
3032 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3033 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3034}")
fa5322fa 3035
b6d33983 3036(define_insn "*zero_extendhisi2_compact"
aa684c94
SC
3037 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3038 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
fa5322fa 3039 "TARGET_SH1"
bc45ade3 3040 "extu.w %1,%0"
c49439f1 3041 [(set_attr "type" "arith")])
bc45ade3 3042
b6d33983
R
3043(define_insn "*zero_extendhisi2_media"
3044 [(set (match_operand:SI 0 "register_operand" "=r,r")
3045 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3046 "TARGET_SHMEDIA"
3047 "@
3048 #
3049 ld%M1.uw %m1, %0"
3050 [(set_attr "type" "arith_media,load_media")])
3051
3052(define_split
e69d1422
R
3053 [(set (match_operand:SI 0 "register_operand" "")
3054 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3055 "TARGET_SHMEDIA && reload_completed"
3056 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3057 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3058 "
3059{
3060 if (GET_CODE (operands[1]) == TRUNCATE)
3061 operands[1] = XEXP (operands[1], 0);
3062}")
3063
3064(define_expand "zero_extendqisi2"
3065 [(set (match_operand:SI 0 "arith_reg_operand" "")
3066 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3067 ""
3068 "
3069{
3070 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3071 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3072}")
3073
3074(define_insn "*zero_extendqisi2_compact"
aa684c94
SC
3075 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3076 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3077 "TARGET_SH1"
bc45ade3 3078 "extu.b %1,%0"
c49439f1 3079 [(set_attr "type" "arith")])
bc45ade3 3080
b6d33983
R
3081(define_insn "*zero_extendqisi2_media"
3082 [(set (match_operand:SI 0 "register_operand" "=r,r")
3083 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3084 "TARGET_SHMEDIA"
3085 "@
3086 andi %1, 255, %0
3087 ld%M1.ub %m1, %0"
3088 [(set_attr "type" "arith_media,load_media")])
3089
bc45ade3 3090(define_insn "zero_extendqihi2"
aa684c94
SC
3091 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3092 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3093 "TARGET_SH1"
bc45ade3 3094 "extu.b %1,%0"
c49439f1 3095 [(set_attr "type" "arith")])
fae15c93 3096
bc45ade3
SC
3097;; -------------------------------------------------------------------------
3098;; Sign extension instructions
3099;; -------------------------------------------------------------------------
3100
ffae286a
JW
3101;; ??? This should be a define expand.
3102;; ??? Or perhaps it should be dropped?
3103
fa5322fa
AO
3104;; convert_move generates good code for SH[1-4].
3105(define_insn "extendsidi2"
3106 [(set (match_operand:DI 0 "register_operand" "=r,r")
3107 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3108 "TARGET_SHMEDIA"
3109 "@
3110 add.l %1, r63, %0
2ad65b0e
SC
3111 ld%M1.l %m1, %0"
3112 [(set_attr "type" "arith_media,load_media")])
fa5322fa
AO
3113
3114(define_insn "extendhidi2"
3115 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3116 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3117 "TARGET_SHMEDIA"
3118 "@
3119 #
b6d33983
R
3120 ld%M1.w %m1, %0"
3121 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3122
3123(define_split
e69d1422
R
3124 [(set (match_operand:DI 0 "register_operand" "")
3125 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3126 "TARGET_SHMEDIA && reload_completed"
3127 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
3128 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3129 "
3130{
3131 if (GET_CODE (operands[1]) == TRUNCATE)
3132 operands[1] = XEXP (operands[1], 0);
3133}")
fa5322fa
AO
3134
3135(define_insn "extendqidi2"
3136 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3137 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3138 "TARGET_SHMEDIA"
3139 "@
3140 #
b6d33983
R
3141 ld%M1.b %m1, %0"
3142 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3143
3144(define_split
e69d1422
R
3145 [(set (match_operand:DI 0 "register_operand" "")
3146 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3147 "TARGET_SHMEDIA && reload_completed"
3148 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
b6d33983
R
3149 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3150 "
3151{
3152 if (GET_CODE (operands[1]) == TRUNCATE)
3153 operands[1] = XEXP (operands[1], 0);
3154}")
3155
3156(define_expand "extendhisi2"
3157 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3158 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3159 ""
3160 "")
bc45ade3 3161
b6d33983 3162(define_insn "*extendhisi2_compact"
51bd623f
JW
3163 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3164 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3165 "TARGET_SH1"
0d7e008e
SC
3166 "@
3167 exts.w %1,%0
0d7e008e 3168 mov.w %1,%0"
c49439f1 3169 [(set_attr "type" "arith,load")])
bc45ade3 3170
b6d33983
R
3171(define_insn "*extendhisi2_media"
3172 [(set (match_operand:SI 0 "register_operand" "=r,r")
3173 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3174 "TARGET_SHMEDIA"
3175 "@
3176 #
3177 ld%M1.w %m1, %0"
3178 [(set_attr "type" "arith_media,load_media")])
3179
3180(define_split
e69d1422
R
3181 [(set (match_operand:SI 0 "register_operand" "")
3182 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3183 "TARGET_SHMEDIA && reload_completed"
3184 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3185 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3186 "
3187{
3188 if (GET_CODE (operands[1]) == TRUNCATE)
3189 operands[1] = XEXP (operands[1], 0);
3190}")
3191
3192(define_expand "extendqisi2"
3193 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3194 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3195 ""
3196 "")
3197
3198(define_insn "*extendqisi2_compact"
51bd623f
JW
3199 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3200 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3201 "TARGET_SH1"
0d7e008e
SC
3202 "@
3203 exts.b %1,%0
51bd623f 3204 mov.b %1,%0"
c49439f1 3205 [(set_attr "type" "arith,load")])
bc45ade3 3206
b6d33983
R
3207(define_insn "*extendqisi2_media"
3208 [(set (match_operand:SI 0 "register_operand" "=r,r")
3209 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3210 "TARGET_SHMEDIA"
3211 "@
3212 #
3213 ld%M1.b %m1, %0"
3214 [(set_attr "type" "arith_media,load_media")])
3215
3216(define_split
e69d1422
R
3217 [(set (match_operand:SI 0 "register_operand" "")
3218 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
b6d33983
R
3219 "TARGET_SHMEDIA && reload_completed"
3220 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3221 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3222 "
3223{
3224 if (GET_CODE (operands[1]) == TRUNCATE)
3225 operands[1] = XEXP (operands[1], 0);
3226}")
3227
bc45ade3 3228(define_insn "extendqihi2"
51bd623f
JW
3229 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3230 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3231 "TARGET_SH1"
0d7e008e
SC
3232 "@
3233 exts.b %1,%0
51bd623f 3234 mov.b %1,%0"
c49439f1 3235 [(set_attr "type" "arith,load")])
fae15c93 3236
b6d33983
R
3237/* It would seem useful to combine the truncXi patterns into the movXi
3238 patterns, but unary operators are ignored when matching constraints,
3239 so we need separate patterns. */
3240(define_insn "truncdisi2"
0ac78517 3241 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
b6d33983
R
3242 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3243 "TARGET_SHMEDIA"
3244 "@
3245 add.l %1, r63, %0
3246 st%M0.l %m0, %1
3247 fst%M0.s %m0, %T1
3248 fmov.ls %1, %0
3249 fmov.sl %T1, %0
3250 fmov.s %T1, %0"
3251 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3252
3253
3254(define_insn "truncdihi2"
0ac78517 3255 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
b6d33983
R
3256 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3257 "TARGET_SHMEDIA"
3258 "@
3259 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3260 st%M0.w %m0, %1"
3261 [(set_attr "type" "arith_media,store_media")
3262 (set_attr "length" "8,4")])
3263
59324685
R
3264; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3265; Because we use zero extension, we can't provide signed QImode compares
3266; using a simple compare or conditional banch insn.
b6d33983
R
3267(define_insn "truncdiqi2"
3268 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3269 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3270 "TARGET_SHMEDIA"
3271 "@
59324685 3272 and %1, 255, %0
b6d33983
R
3273 st%M0.b %m0, %1"
3274 [(set_attr "type" "arith_media,store")])
3275
bc45ade3
SC
3276;; -------------------------------------------------------------------------
3277;; Move instructions
3278;; -------------------------------------------------------------------------
3279
0d7e008e 3280;; define push and pop so it is easy for sh.c
fa5322fa
AO
3281;; We can't use push and pop on SHcompact because the stack must always
3282;; be 8-byte aligned.
b9654711 3283
225e4f43 3284(define_expand "push"
4773afa4 3285 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
ffae286a 3286 (match_operand:SI 0 "register_operand" "r,l,x"))]
fa5322fa 3287 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3288 "")
b9654711 3289
225e4f43 3290(define_expand "pop"
51bd623f 3291 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4773afa4 3292 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
fa5322fa 3293 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3294 "")
3295
3296(define_expand "push_e"
4773afa4 3297 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
225e4f43 3298 (match_operand:SF 0 "" ""))
4773afa4 3299 (use (reg:PSI FPSCR_REG))
225e4f43 3300 (clobber (scratch:SI))])]
fa5322fa 3301 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3302 "")
b9654711 3303
225e4f43 3304(define_insn "push_fpul"
4773afa4 3305 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3a8699c7 3306 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 3307 "sts.l fpul,@-r15"
45348d9e 3308 [(set_attr "type" "store")
c49439f1 3309 (set_attr "late_fp_use" "yes")
45348d9e
JW
3310 (set_attr "hit_stack" "yes")])
3311
225e4f43
R
3312;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3313;; so use that.
3314(define_expand "push_4"
4773afa4
AO
3315 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3316 (match_operand:DF 0 "" ""))
3317 (use (reg:PSI FPSCR_REG))
225e4f43 3318 (clobber (scratch:SI))])]
fa5322fa 3319 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3320 "")
3321
3322(define_expand "pop_e"
3323 [(parallel [(set (match_operand:SF 0 "" "")
4773afa4
AO
3324 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3325 (use (reg:PSI FPSCR_REG))
225e4f43 3326 (clobber (scratch:SI))])]
fa5322fa 3327 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3328 "")
3329
3330(define_insn "pop_fpul"
4773afa4 3331 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3a8699c7 3332 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 3333 "lds.l @r15+,fpul"
45348d9e
JW
3334 [(set_attr "type" "load")
3335 (set_attr "hit_stack" "yes")])
3336
225e4f43
R
3337(define_expand "pop_4"
3338 [(parallel [(set (match_operand:DF 0 "" "")
4773afa4
AO
3339 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3340 (use (reg:PSI FPSCR_REG))
225e4f43 3341 (clobber (scratch:SI))])]
fa5322fa 3342 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3343 "")
3344
7144b2d8
DD
3345(define_expand "push_fpscr"
3346 [(const_int 0)]
603ff6b5 3347 "TARGET_SH2E"
7144b2d8
DD
3348 "
3349{
3350 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3351 gen_rtx (PRE_DEC, Pmode,
3352 stack_pointer_rtx)),
3353 get_fpscr_rtx ()));
3354 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3355 DONE;
3356}")
3357
3358(define_expand "pop_fpscr"
3359 [(const_int 0)]
603ff6b5 3360 "TARGET_SH2E"
7144b2d8
DD
3361 "
3362{
3363 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3364 gen_rtx (MEM, PSImode,
3365 gen_rtx (POST_INC, Pmode,
3366 stack_pointer_rtx))));
3367 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3368 DONE;
3369}")
3370
e3391510
JW
3371;; These two patterns can happen as the result of optimization, when
3372;; comparisons get simplified to a move of zero or 1 into the T reg.
3373;; They don't disappear completely, because the T reg is a fixed hard reg.
ffae286a 3374
0d7e008e 3375(define_insn "clrt"
4773afa4 3376 [(set (reg:SI T_REG) (const_int 0))]
fa5322fa 3377 "TARGET_SH1"
0d7e008e 3378 "clrt")
bc45ade3 3379
e3391510 3380(define_insn "sett"
4773afa4 3381 [(set (reg:SI T_REG) (const_int 1))]
fa5322fa 3382 "TARGET_SH1"
e3391510
JW
3383 "sett")
3384
3ca0a524 3385;; t/r must come after r/r, lest reload will try to reload stuff like
4773afa4 3386;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
e11cddec 3387;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
0d7e008e 3388(define_insn "movsi_i"
735cb76e
R
3389 [(set (match_operand:SI 0 "general_movdst_operand"
3390 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3391 (match_operand:SI 1 "general_movsrc_operand"
3392 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
fa5322fa 3393 "TARGET_SH1
3a8699c7 3394 && ! TARGET_SH2E
1245df60
R
3395 && (register_operand (operands[0], SImode)
3396 || register_operand (operands[1], SImode))"
8e87e161
SC
3397 "@
3398 mov.l %1,%0
3399 mov %1,%0
3ca0a524 3400 cmp/pl %1
8e87e161
SC
3401 mov.l %1,%0
3402 sts %1,%0
99e87c10 3403 sts %1,%0
8e87e161
SC
3404 movt %0
3405 mov.l %1,%0
3406 sts.l %1,%0
1245df60 3407 sts.l %1,%0
8e87e161 3408 lds %1,%0
99e87c10 3409 lds %1,%0
8e87e161 3410 lds.l %1,%0
1245df60 3411 lds.l %1,%0
51bd623f 3412 fake %1,%0"
c49439f1 3413 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
99e87c10 3414 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
07a45e5c 3415
1245df60 3416;; t/r must come after r/r, lest reload will try to reload stuff like
e11cddec 3417;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
45348d9e
JW
3418;; ??? This allows moves from macl to fpul to be recognized, but these moves
3419;; will require a reload.
ec555f32
R
3420;; ??? We can't include f/f because we need the proper FPSCR setting when
3421;; TARGET_FMOVD is in effect, and mode switching is done before reload.
45348d9e 3422(define_insn "movsi_ie"
735cb76e
R
3423 [(set (match_operand:SI 0 "general_movdst_operand"
3424 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3425 (match_operand:SI 1 "general_movsrc_operand"
3426 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3a8699c7 3427 "TARGET_SH2E
45348d9e
JW
3428 && (register_operand (operands[0], SImode)
3429 || register_operand (operands[1], SImode))"
3430 "@
45348d9e
JW
3431 mov.l %1,%0
3432 mov %1,%0
1245df60 3433 cmp/pl %1
45348d9e
JW
3434 mov.l %1,%0
3435 sts %1,%0
99e87c10 3436 sts %1,%0
45348d9e
JW
3437 movt %0
3438 mov.l %1,%0
3439 sts.l %1,%0
1245df60 3440 sts.l %1,%0
45348d9e 3441 lds %1,%0
99e87c10 3442 lds %1,%0
45348d9e 3443 lds.l %1,%0
1245df60 3444 lds.l %1,%0
225e4f43 3445 lds.l %1,%0
a92facbb 3446 sts.l %1,%0
45348d9e
JW
3447 fake %1,%0
3448 lds %1,%0
1245df60 3449 sts %1,%0
ec555f32
R
3450 fsts fpul,%0
3451 flds %1,fpul
3452 fmov %1,%0
1245df60 3453 ! move optimized away"
ec555f32
R
3454 [(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")
3455 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3456 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
1245df60
R
3457
3458(define_insn "movsi_i_lowpart"
99e87c10 3459 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
735cb76e 3460 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
fa5322fa
AO
3461 "TARGET_SH1
3462 && (register_operand (operands[0], SImode)
3463 || register_operand (operands[1], SImode))"
1245df60
R
3464 "@
3465 mov.l %1,%0
3466 mov %1,%0
3467 mov.l %1,%0
3468 sts %1,%0
99e87c10 3469 sts %1,%0
1245df60
R
3470 movt %0
3471 mov.l %1,%0
3472 fake %1,%0"
99e87c10 3473 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
a6f463a0 3474
7d73a2ba 3475(define_insn_and_split "load_ra"
b869f904 3476 [(set (match_operand:SI 0 "general_movdst_operand" "")
7d73a2ba 3477 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
dce20bbc 3478 "TARGET_SH1"
7d73a2ba
R
3479 "#"
3480 "&& ! rtx_equal_function_value_matters"
b869f904 3481 [(set (match_dup 0) (match_dup 1))]
7d73a2ba
R
3482 "
3483{
dce20bbc 3484 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
7d73a2ba
R
3485 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3486}")
b869f904 3487
fa5322fa 3488(define_insn "*movsi_media"
735cb76e
R
3489 [(set (match_operand:SI 0 "general_movdst_operand"
3490 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3491 (match_operand:SI 1 "general_movsrc_operand"
3492 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
fa5322fa
AO
3493 "TARGET_SHMEDIA_FPU
3494 && (register_operand (operands[0], SImode)
d9da94a1 3495 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3496 "@
3497 add.l %1, r63, %0
3498 movi %1, %0
3499 #
3500 ld%M1.l %m1, %0
d9da94a1 3501 st%M0.l %m0, %N1
fa5322fa
AO
3502 fld%M1.s %m1, %0
3503 fst%M0.s %m0, %1
0ac78517 3504 fmov.ls %N1, %0
fa5322fa
AO
3505 fmov.sl %1, %0
3506 fmov.s %1, %0
3507 ptabs %1, %0
3508 gettr %1, %0
3509 pt %1, %0"
2ad65b0e 3510 [(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
3511 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3512
3513(define_insn "*movsi_media_nofpu"
735cb76e
R
3514 [(set (match_operand:SI 0 "general_movdst_operand"
3515 "=r,r,r,r,m,*b,r,b")
3516 (match_operand:SI 1 "general_movsrc_operand"
3517 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
fa5322fa
AO
3518 "TARGET_SHMEDIA
3519 && (register_operand (operands[0], SImode)
d9da94a1 3520 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3521 "@
3522 add.l %1, r63, %0
3523 movi %1, %0
3524 #
3525 ld%M1.l %m1, %0
d9da94a1 3526 st%M0.l %m0, %N1
fa5322fa
AO
3527 ptabs %1, %0
3528 gettr %1, %0
3529 pt %1, %0"
2ad65b0e 3530 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3531 (set_attr "length" "4,4,8,4,4,4,4,12")])
3532
3533(define_split
e69d1422
R
3534 [(set (match_operand:SI 0 "arith_reg_operand" "")
3535 (match_operand:SI 1 "immediate_operand" ""))]
fa5322fa
AO
3536 "TARGET_SHMEDIA && reload_completed
3537 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3538 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3539 "
3540{
3541 operands[2] = shallow_copy_rtx (operands[1]);
3542 PUT_MODE (operands[2], DImode);
3543}")
3544
3545(define_split
e69d1422
R
3546 [(set (match_operand:SI 0 "register_operand" "")
3547 (match_operand:SI 1 "immediate_operand" ""))]
b6d33983 3548 "TARGET_SHMEDIA && reload_completed
fa5322fa 3549 && ((GET_CODE (operands[1]) == CONST_INT
735cb76e 3550 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
fa5322fa
AO
3551 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3552 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3553
bc45ade3 3554(define_expand "movsi"
0d7e008e
SC
3555 [(set (match_operand:SI 0 "general_movdst_operand" "")
3556 (match_operand:SI 1 "general_movsrc_operand" ""))]
bc45ade3 3557 ""
ffae286a 3558 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
961c4780 3559
225e4f43
R
3560(define_expand "ic_invalidate_line"
3561 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4773afa4 3562 (match_dup 1)] UNSPEC_ICACHE)
225e4f43 3563 (clobber (scratch:SI))])]
fa5322fa 3564 "TARGET_HARD_SH4 || TARGET_SH5"
225e4f43
R
3565 "
3566{
fa5322fa
AO
3567 if (TARGET_SHMEDIA)
3568 {
3569 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3570 DONE;
3571 }
3572 else if (TARGET_SHCOMPACT)
3573 {
90534361 3574 operands[1] = function_symbol (\"__ic_invalidate\");
fa5322fa
AO
3575 operands[1] = force_reg (Pmode, operands[1]);
3576 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3577 DONE;
3578 }
225e4f43 3579 operands[0] = force_reg (Pmode, operands[0]);
90e65b70
AO
3580 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3581 Pmode)));
225e4f43
R
3582}")
3583
3584;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
0aa54da2
R
3585;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3586;; the requirement *1*00 for associative address writes. The alignment of
225e4f43
R
3587;; %0 implies that its least significant bit is cleared,
3588;; thus we clear the V bit of a matching entry if there is one.
3589(define_insn "ic_invalidate_line_i"
0aa54da2 3590 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
4773afa4
AO
3591 (match_operand:SI 1 "register_operand" "r")]
3592 UNSPEC_ICACHE)
0aa54da2 3593 (clobber (match_scratch:SI 2 "=&r"))]
225e4f43 3594 "TARGET_HARD_SH4"
0aa54da2 3595 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
fae15c93 3596 [(set_attr "length" "8")
c49439f1 3597 (set_attr "type" "cwb")])
225e4f43 3598
ca903bba
R
3599;; ??? could make arg 0 an offsettable memory operand to allow to save
3600;; an add in the code that calculates the address.
fa5322fa
AO
3601(define_insn "ic_invalidate_line_media"
3602 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3603 UNSPEC_ICACHE)]
3604 "TARGET_SHMEDIA"
b6d33983
R
3605 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3606 [(set_attr "length" "16")
3607 (set_attr "type" "invalidate_line_media")])
fa5322fa
AO
3608
3609(define_insn "ic_invalidate_line_compact"
3610 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3611 (match_operand:SI 1 "register_operand" "r")]
3612 UNSPEC_ICACHE)
3613 (clobber (reg:SI PR_REG))]
3614 "TARGET_SHCOMPACT"
3615 "jsr @%1%#"
3616 [(set_attr "type" "sfunc")
3617 (set_attr "needs_delay_slot" "yes")])
3618
ca903bba
R
3619(define_expand "initialize_trampoline"
3620 [(match_operand:SI 0 "" "")
3621 (match_operand:SI 1 "" "")
3622 (match_operand:SI 2 "" "")]
3623 "TARGET_SHCOMPACT"
3624 "
3625{
3626 rtx sfun, tramp;
3627
e300c78c 3628 tramp = force_reg (Pmode, operands[0]);
90534361 3629 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
ca903bba
R
3630 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3631 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3632
3633 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3634 DONE;
3635}")
3636
3637(define_insn "initialize_trampoline_compact"
3638 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3639 (match_operand:SI 1 "register_operand" "r")
3640 (reg:SI R2_REG) (reg:SI R3_REG)]
3641 UNSPEC_INIT_TRAMP)
3642
3643 (clobber (reg:SI PR_REG))]
3644 "TARGET_SHCOMPACT"
3645 "jsr @%1%#"
3646 [(set_attr "type" "sfunc")
3647 (set_attr "needs_delay_slot" "yes")])
3648
bc45ade3 3649(define_insn "movqi_i"
07a45e5c
JW
3650 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3651 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
fa5322fa
AO
3652 "TARGET_SH1
3653 && (arith_reg_operand (operands[0], QImode)
3654 || arith_reg_operand (operands[1], QImode))"
bc45ade3
SC
3655 "@
3656 mov %1,%0
0d7e008e
SC
3657 mov.b %1,%0
3658 mov.b %1,%0
3659 movt %0
bc45ade3 3660 sts %1,%0
0d7e008e 3661 lds %1,%0"
22e1ebf1 3662 [(set_attr "type" "move,load,store,move,move,move")])
bc45ade3 3663
fa5322fa
AO
3664(define_insn "*movqi_media"
3665 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 3666 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
fa5322fa
AO
3667 "TARGET_SHMEDIA
3668 && (arith_reg_operand (operands[0], QImode)
d9da94a1 3669 || arith_reg_or_0_operand (operands[1], QImode))"
fa5322fa
AO
3670 "@
3671 add.l %1, r63, %0
3672 movi %1, %0
59324685 3673 ld%M1.ub %m1, %0
d9da94a1 3674 st%M0.b %m0, %N1"
2ad65b0e 3675 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
fa5322fa 3676
bc45ade3
SC
3677(define_expand "movqi"
3678 [(set (match_operand:QI 0 "general_operand" "")
3679 (match_operand:QI 1 "general_operand" ""))]
3680 ""
ffae286a 3681 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
bc45ade3 3682
b6d33983
R
3683(define_expand "reload_inqi"
3684 [(set (match_operand:SI 2 "" "=&r")
3685 (match_operand:QI 1 "inqhi_operand" ""))
3686 (set (match_operand:QI 0 "arith_reg_operand" "=r")
ea45c4b0 3687 (truncate:QI (match_dup 3)))]
b6d33983
R
3688 "TARGET_SHMEDIA"
3689 "
3690{
3691 rtx inner = XEXP (operands[1], 0);
3692 int regno = REGNO (inner);
3693
3694 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3695 operands[1] = gen_rtx_REG (SImode, regno);
3696 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3697}")
3698
266a2732 3699/* When storing r0, we have to avoid reg+reg addressing. */
bc45ade3 3700(define_insn "movhi_i"
735cb76e
R
3701 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3702 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
fa5322fa
AO
3703 "TARGET_SH1
3704 && (arith_reg_operand (operands[0], HImode)
266a2732
R
3705 || arith_reg_operand (operands[1], HImode))
3706 && (GET_CODE (operands[0]) != MEM
3707 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3708 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3709 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
8e87e161
SC
3710 "@
3711 mov.w %1,%0
3712 mov %1,%0
3713 mov.w %1,%0
3714 movt %0
3715 mov.w %1,%0
8e87e161 3716 sts %1,%0
51bd623f
JW
3717 lds %1,%0
3718 fake %1,%0"
27232d28 3719 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
bc45ade3 3720
fa5322fa 3721(define_insn "*movhi_media"
735cb76e
R
3722 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3723 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
fa5322fa
AO
3724 "TARGET_SHMEDIA
3725 && (arith_reg_operand (operands[0], HImode)
d9da94a1 3726 || arith_reg_or_0_operand (operands[1], HImode))"
fa5322fa
AO
3727 "@
3728 add.l %1, r63, %0
3729 movi %1, %0
3730 #
3731 ld%M1.w %m1, %0
d9da94a1 3732 st%M0.w %m0, %N1"
2ad65b0e 3733 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
fa5322fa
AO
3734
3735(define_split
e69d1422
R
3736 [(set (match_operand:HI 0 "register_operand" "")
3737 (match_operand:HI 1 "immediate_operand" ""))]
b6d33983 3738 "TARGET_SHMEDIA && reload_completed
735cb76e 3739 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa
AO
3740 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3741
bc45ade3 3742(define_expand "movhi"
0d7e008e
SC
3743 [(set (match_operand:HI 0 "general_movdst_operand" "")
3744 (match_operand:HI 1 "general_movsrc_operand" ""))]
bc45ade3 3745 ""
ffae286a
JW
3746 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3747
b6d33983
R
3748(define_expand "reload_inhi"
3749 [(set (match_operand:SI 2 "" "=&r")
3750 (match_operand:HI 1 "inqhi_operand" ""))
3751 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3752 (truncate:HI (match_dup 3)))]
3753 "TARGET_SHMEDIA"
3754 "
3755{
3756 rtx inner = XEXP (operands[1], 0);
3757 int regno = REGNO (inner);
3758
3759 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3760 operands[1] = gen_rtx_REG (SImode, regno);
3761 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3762}")
3763
1245df60
R
3764;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3765;; compiled with -m2 -ml -O3 -funroll-loops
0113c3c0 3766(define_insn "*movdi_i"
1245df60 3767 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
735cb76e 3768 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
fa5322fa
AO
3769 "TARGET_SH1
3770 && (arith_reg_operand (operands[0], DImode)
3771 || arith_reg_operand (operands[1], DImode))"
0d7e008e 3772 "* return output_movedouble (insn, operands, DImode);"
22e1ebf1 3773 [(set_attr "length" "4")
1245df60 3774 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
bc45ade3 3775
d0aae509 3776;; If the output is a register and the input is memory or a register, we have
52702ae1 3777;; to be careful and see which word needs to be loaded first.
b9b7c1c9 3778
8e87e161
SC
3779(define_split
3780 [(set (match_operand:DI 0 "general_movdst_operand" "")
3781 (match_operand:DI 1 "general_movsrc_operand" ""))]
fa5322fa 3782 "TARGET_SH1 && reload_completed"
8e87e161
SC
3783 [(set (match_dup 2) (match_dup 3))
3784 (set (match_dup 4) (match_dup 5))]
3785 "
d0aae509
RK
3786{
3787 int regno;
3788
3789 if ((GET_CODE (operands[0]) == MEM
3790 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3791 || (GET_CODE (operands[1]) == MEM
3792 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3793 FAIL;
3794
3795 if (GET_CODE (operands[0]) == REG)
3796 regno = REGNO (operands[0]);
3797 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 3798 regno = subreg_regno (operands[0]);
d0aae509
RK
3799 else if (GET_CODE (operands[0]) == MEM)
3800 regno = -1;
533f5e0f
KG
3801 else
3802 abort ();
d0aae509
RK
3803
3804 if (regno == -1
3805 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
3806 {
3807 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3808 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3809 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3810 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3811 }
3812 else
3813 {
3814 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3815 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3816 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3817 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3818 }
3819
3820 if (operands[2] == 0 || operands[3] == 0
3821 || operands[4] == 0 || operands[5] == 0)
3822 FAIL;
3823}")
961c4780 3824
fa5322fa 3825(define_insn "*movdi_media"
735cb76e
R
3826 [(set (match_operand:DI 0 "general_movdst_operand"
3827 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3828 (match_operand:DI 1 "general_movsrc_operand"
3829 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
fa5322fa
AO
3830 "TARGET_SHMEDIA_FPU
3831 && (register_operand (operands[0], DImode)
d9da94a1 3832 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3833 "@
3834 add %1, r63, %0
3835 movi %1, %0
3836 #
3837 ld%M1.q %m1, %0
d9da94a1 3838 st%M0.q %m0, %N1
fa5322fa
AO
3839 fld%M1.d %m1, %0
3840 fst%M0.d %m0, %1
0ac78517 3841 fmov.qd %N1, %0
fa5322fa
AO
3842 fmov.dq %1, %0
3843 fmov.d %1, %0
3844 ptabs %1, %0
3845 gettr %1, %0
3846 pt %1, %0"
2ad65b0e 3847 [(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
3848 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3849
3850(define_insn "*movdi_media_nofpu"
b6d33983 3851 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
735cb76e 3852 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
fa5322fa
AO
3853 "TARGET_SHMEDIA
3854 && (register_operand (operands[0], DImode)
d9da94a1 3855 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3856 "@
3857 add %1, r63, %0
3858 movi %1, %0
3859 #
3860 ld%M1.q %m1, %0
d9da94a1 3861 st%M0.q %m0, %N1
fa5322fa
AO
3862 ptabs %1, %0
3863 gettr %1, %0
3864 pt %1, %0"
2ad65b0e 3865 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3866 (set_attr "length" "4,4,16,4,4,4,4,*")])
3867
3868(define_split
e69d1422
R
3869 [(set (match_operand:DI 0 "arith_reg_operand" "")
3870 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3871 "TARGET_SHMEDIA && reload_completed
3872 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3873 [(set (match_dup 0) (match_dup 1))]
3874 "
3875{
3876 rtx insn;
3877
3878 if (TARGET_SHMEDIA64)
3879 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3880 else
3881 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3882
3883 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3884 REG_NOTES (insn));
3885
3886 DONE;
3887}")
3888
3889(define_expand "movdi_const"
3890 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3891 (const:DI (sign_extend:DI
3892 (truncate:HI
3893 (ashiftrt:DI
3894 (match_operand:DI 1 "immediate_operand" "s")
3895 (const_int 48))))))
3896 (set (match_dup 0)
3897 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3898 (zero_extend:DI
3899 (truncate:HI
3900 (const:DI
3901 (sign_extend:DI
3902 (truncate:HI
3903 (ashiftrt:SI
3904 (match_dup 1)
3905 (const_int 32)))))))))
3906 (set (match_dup 0)
3907 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3908 (zero_extend:DI
3909 (truncate:HI
3910 (const:DI
3911 (sign_extend:DI
3912 (truncate:HI
3913 (ashiftrt:SI
3914 (match_dup 1)
3915 (const_int 16)))))))))
3916 (set (match_dup 0)
3917 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3918 (zero_extend:DI
3919 (truncate:HI
3920 (const:DI
3921 (sign_extend:DI
3922 (truncate:HI
3923 (match_dup 1))))))))]
3924 "TARGET_SHMEDIA64 && reload_completed
3925 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3926 "
3927{
ea4210ef 3928 sh_mark_label (operands[1], 4);
fa5322fa
AO
3929}")
3930
3931(define_expand "movdi_const_32bit"
3932 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3933 (const:DI (sign_extend:DI
3934 (truncate:HI
3935 (ashiftrt:DI
3936 (match_operand:DI 1 "immediate_operand" "s")
3937 (const_int 16))))))
3938 (set (match_dup 0)
3939 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3940 (zero_extend:DI
3941 (truncate:HI
3942 (const:DI
3943 (sign_extend:DI
3944 (truncate:HI
3945 (match_dup 1))))))))]
3946 "TARGET_SHMEDIA32 && reload_completed
3947 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3948 "
3949{
ea4210ef 3950 sh_mark_label (operands[1], 2);
fa5322fa
AO
3951}")
3952
3953(define_expand "movdi_const_16bit"
3954 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3955 (const:DI (sign_extend:DI
3956 (truncate:HI
3957 (match_operand:DI 1 "immediate_operand" "s")))))]
3958 "TARGET_SHMEDIA && flag_pic && reload_completed
3959 && GET_CODE (operands[1]) == SYMBOL_REF"
3960 "")
3961
3962(define_split
e69d1422
R
3963 [(set (match_operand:DI 0 "arith_reg_operand" "")
3964 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3965 "TARGET_SHMEDIA && reload_completed
3966 && GET_CODE (operands[1]) == CONST_INT
735cb76e 3967 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa 3968 [(set (match_dup 0) (match_dup 2))
c1b92d09 3969 (match_dup 1)]
fa5322fa
AO
3970 "
3971{
c1b92d09
R
3972 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3973 unsigned HOST_WIDE_INT low = val;
3974 unsigned HOST_WIDE_INT high = val;
fa5322fa 3975 unsigned HOST_WIDE_INT sign;
c1b92d09 3976 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
fa5322fa
AO
3977
3978 /* Sign-extend the 16 least-significant bits. */
c1b92d09
R
3979 low &= 0xffff;
3980 low ^= 0x8000;
3981 low -= 0x8000;
fa5322fa
AO
3982
3983 /* Arithmetic shift right the word by 16 bits. */
c1b92d09 3984 high >>= 16;
fa5322fa
AO
3985 sign = 1;
3986 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
c1b92d09
R
3987 high ^= sign;
3988 high -= sign;
3989 do
3990 {
3991 /* If we can't generate the constant with a two-insn movi / shori
3992 sequence, try some other strategies. */
735cb76e 3993 if (! CONST_OK_FOR_I16 (high))
c1b92d09
R
3994 {
3995 /* Try constant load / left shift. We know VAL != 0. */
3996 val2 = val ^ (val-1);
3997 if (val2 > 0x1ffff)
3998 {
3999 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4000
735cb76e
R
4001 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4002 || (! CONST_OK_FOR_I16 (high >> 16)
4003 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
c1b92d09
R
4004 {
4005 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4006 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4007 GEN_INT (trailing_zeroes));
4008 break;
4009 }
4010 }
4011 /* Try constant load / right shift. */
4012 val2 = (val >> 15) + 1;
4013 if (val2 == (val2 & -val2))
4014 {
4015 int shift = 49 - exact_log2 (val2);
4016
4017 val2 = trunc_int_for_mode (val << shift, DImode);
735cb76e 4018 if (CONST_OK_FOR_I16 (val2))
c1b92d09
R
4019 {
4020 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4021 GEN_INT (shift));
4022 break;
4023 }
4024 }
4025 /* Try mperm.w . */
4026 val2 = val & 0xffff;
4027 if ((val >> 16 & 0xffff) == val2
4028 && (val >> 32 & 0xffff) == val2
4029 && (val >> 48 & 0xffff) == val2)
4030 {
4031 val2 = (HOST_WIDE_INT) val >> 48;
4032 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4033 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4034 break;
4035 }
4036 /* Try movi / mshflo.l */
4037 val2 = (HOST_WIDE_INT) val >> 32;
4038 if (val2 == trunc_int_for_mode (val, SImode))
4039 {
4040 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4041 operands[0]);
4042 break;
4043 }
4044 /* Try movi / mshflo.l w/ r63. */
4045 val2 = val + ((HOST_WIDE_INT) -1 << 32);
735cb76e 4046 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
c1b92d09
R
4047 {
4048 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4049 GEN_INT (0));
4050 break;
4051 }
4052 }
4053 val2 = high;
4054 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4055 }
4056 while (0);
4057 operands[2] = GEN_INT (val2);
fa5322fa
AO
4058}")
4059
4060(define_split
e69d1422
R
4061 [(set (match_operand:DI 0 "arith_reg_operand" "")
4062 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
4063 "TARGET_SHMEDIA && reload_completed
4064 && GET_CODE (operands[1]) == CONST_DOUBLE"
4065 [(set (match_dup 0) (match_dup 2))
4066 (set (match_dup 0)
4067 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4068 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4069 "
4070{
4071 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4072 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4073 unsigned HOST_WIDE_INT val = low;
4074 unsigned HOST_WIDE_INT sign;
4075
4076 /* Sign-extend the 16 least-significant bits. */
4077 val &= 0xffff;
4078 val ^= 0x8000;
4079 val -= 0x8000;
4080 operands[1] = GEN_INT (val);
4081
4082 /* Arithmetic shift right the double-word by 16 bits. */
4083 low >>= 16;
4084 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4085 high >>= 16;
4086 sign = 1;
4087 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4088 high ^= sign;
4089 high -= sign;
4090
4091 /* This will only be true if high is a sign-extension of low, i.e.,
4092 it must be either 0 or (unsigned)-1, and be zero iff the
4093 most-significant bit of low is set. */
4094 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4095 operands[2] = GEN_INT (low);
4096 else
4097 operands[2] = immed_double_const (low, high, DImode);
4098}")
4099
c1b92d09 4100(define_insn "shori_media"
fa5322fa
AO
4101 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4102 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4103 (const_int 16))
4104 (zero_extend:DI
4105 (truncate:HI
735cb76e 4106 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
fa5322fa
AO
4107 "TARGET_SHMEDIA"
4108 "@
4109 shori %u2, %0
2ad65b0e
SC
4110 #"
4111 [(set_attr "type" "arith_media,*")])
fa5322fa 4112
bc45ade3 4113(define_expand "movdi"
961c4780
SC
4114 [(set (match_operand:DI 0 "general_movdst_operand" "")
4115 (match_operand:DI 1 "general_movsrc_operand" ""))]
bc45ade3 4116 ""
a6f463a0 4117 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
ffae286a 4118
fa5322fa
AO
4119(define_insn "movdf_media"
4120 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 4121 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
4122 "TARGET_SHMEDIA_FPU
4123 && (register_operand (operands[0], DFmode)
d9da94a1 4124 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4125 "@
4126 fmov.d %1, %0
0ac78517 4127 fmov.qd %N1, %0
fa5322fa
AO
4128 fmov.dq %1, %0
4129 add %1, r63, %0
4130 #
4131 fld%M1.d %m1, %0
4132 fst%M0.d %m0, %1
4133 ld%M1.q %m1, %0
d9da94a1 4134 st%M0.q %m0, %N1"
2ad65b0e 4135 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4136
4137(define_insn "movdf_media_nofpu"
4138 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 4139 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
4140 "TARGET_SHMEDIA
4141 && (register_operand (operands[0], DFmode)
d9da94a1 4142 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4143 "@
4144 add %1, r63, %0
4145 #
4146 ld%M1.q %m1, %0
d9da94a1 4147 st%M0.q %m0, %N1"
2ad65b0e 4148 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4149
4150(define_split
4151 [(set (match_operand:DF 0 "arith_reg_operand" "")
4152 (match_operand:DF 1 "immediate_operand" ""))]
4153 "TARGET_SHMEDIA && reload_completed"
4154 [(set (match_dup 3) (match_dup 2))]
4155 "
4156{
4157 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4158 long values[2];
4159 REAL_VALUE_TYPE value;
4160
4161 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4162 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4163
4164 if (HOST_BITS_PER_WIDE_INT >= 64)
4165 operands[2] = immed_double_const ((unsigned long) values[endian]
4166 | ((HOST_WIDE_INT) values[1 - endian]
4167 << 32), 0, DImode);
4168 else if (HOST_BITS_PER_WIDE_INT == 32)
4169 operands[2] = immed_double_const (values[endian], values[1 - endian],
4170 DImode);
4171 else
4172 abort ();
4173
4174 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4175}")
4176
ffae286a 4177;; ??? This should be a define expand.
bc45ade3 4178
bc45ade3 4179(define_insn "movdf_k"
3e943b59
JR
4180 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4181 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
fa5322fa
AO
4182 "TARGET_SH1
4183 && (! TARGET_SH4 || reload_completed
4184 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4185 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4186 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
225e4f43
R
4187 && (arith_reg_operand (operands[0], DFmode)
4188 || arith_reg_operand (operands[1], DFmode))"
0d7e008e 4189 "* return output_movedouble (insn, operands, DFmode);"
b9654711 4190 [(set_attr "length" "4")
3e943b59 4191 (set_attr "type" "move,pcload,load,store")])
bc45ade3 4192
225e4f43
R
4193;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4194;; However, the d/F/c/z alternative cannot be split directly; it is converted
4195;; with special code in machine_dependent_reorg into a load of the R0_REG and
4196;; the d/m/c/X alternative, which is split later into single-precision
4197;; instructions. And when not optimizing, no splits are done before fixing
4198;; up pcloads, so we need usable length information for that.
4199(define_insn "movdf_i4"
4200 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4201 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4202 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4203 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4204 "TARGET_SH4
4205 && (arith_reg_operand (operands[0], DFmode)
4206 || arith_reg_operand (operands[1], DFmode))"
4207 "@
4208 fmov %1,%0
4209 #
4210 #
4211 fmov.d %1,%0
4212 fmov.d %1,%0
4213 #
4214 #
4215 #
4216 #
4217 #"
4218 [(set_attr_alternative "length"
4219 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4220 (const_int 4)
4221 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4222 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4223 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4224 (const_int 4)
4225 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
fa5322fa
AO
4226 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4227 ;; increment or decrement r15 explicitly.
4228 (if_then_else
4229 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4230 (const_int 10) (const_int 8))
4231 (if_then_else
4232 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233 (const_int 10) (const_int 8))])
c49439f1
R
4234 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4235 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
d64264ff
R
4236 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4237 (const_string "double")
4238 (const_string "none")))])
225e4f43
R
4239
4240;; Moving DFmode between fp/general registers through memory
4241;; (the top of the stack) is faster than moving through fpul even for
4242;; little endian. Because the type of an instruction is important for its
4243;; scheduling, it is beneficial to split these operations, rather than
4244;; emitting them in one single chunk, even if this will expose a stack
4245;; use that will prevent scheduling of other stack accesses beyond this
4246;; instruction.
4247(define_split
4248 [(set (match_operand:DF 0 "register_operand" "")
4249 (match_operand:DF 1 "register_operand" ""))
e69d1422 4250 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43
R
4251 (clobber (match_scratch:SI 3 "=X"))]
4252 "TARGET_SH4 && reload_completed
4253 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4254 [(const_int 0)]
4255 "
4256{
4257 rtx insn, tos;
4258
fa5322fa
AO
4259 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4260 {
4261 emit_move_insn (stack_pointer_rtx,
4262 plus_constant (stack_pointer_rtx, -8));
4263 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4264 }
4265 else
4266 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
225e4f43 4267 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
fa5322fa
AO
4268 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4269 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4270 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4271 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4272 else
4273 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
225e4f43 4274 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
fa5322fa
AO
4275 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4276 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4277 else
4278 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
225e4f43
R
4279 DONE;
4280}")
4281
4282;; local-alloc sometimes allocates scratch registers even when not required,
4283;; so we must be prepared to handle these.
4284
4285;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4286(define_split
4287 [(set (match_operand:DF 0 "general_movdst_operand" "")
4288 (match_operand:DF 1 "general_movsrc_operand" ""))
e69d1422
R
4289 (use (match_operand:PSI 2 "fpscr_operand" ""))
4290 (clobber (match_scratch:SI 3 ""))]
225e4f43
R
4291 "TARGET_SH4
4292 && reload_completed
4293 && true_regnum (operands[0]) < 16
4294 && true_regnum (operands[1]) < 16"
4295 [(set (match_dup 0) (match_dup 1))]
4296 "
4297{
4298 /* If this was a reg <-> mem operation with base + index reg addressing,
4299 we have to handle this in a special way. */
4300 rtx mem = operands[0];
4301 int store_p = 1;
4302 if (! memory_operand (mem, DFmode))
4303 {
4304 mem = operands[1];
4305 store_p = 0;
4306 }
ddef6bc7 4307 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
225e4f43
R
4308 mem = SUBREG_REG (mem);
4309 if (GET_CODE (mem) == MEM)
4310 {
4311 rtx addr = XEXP (mem, 0);
4312 if (GET_CODE (addr) == PLUS
4313 && GET_CODE (XEXP (addr, 0)) == REG
4314 && GET_CODE (XEXP (addr, 1)) == REG)
4315 {
4316 int offset;
4317 rtx reg0 = gen_rtx (REG, Pmode, 0);
4318 rtx regop = operands[store_p], word0 ,word1;
4319
4320 if (GET_CODE (regop) == SUBREG)
4dd8c093 4321 alter_subreg (&regop);
225e4f43
R
4322 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4323 offset = 2;
4324 else
4325 offset = 4;
4326 mem = copy_rtx (mem);
4327 PUT_MODE (mem, SImode);
4dd8c093
AO
4328 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4329 alter_subreg (&word0);
4330 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4331 alter_subreg (&word1);
18a7c2a7
AO
4332 if (store_p || ! refers_to_regno_p (REGNO (word0),
4333 REGNO (word0) + 1, addr, 0))
4334 {
4335 emit_insn (store_p
4336 ? gen_movsi_ie (mem, word0)
4337 : gen_movsi_ie (word0, mem));
4338 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4339 mem = copy_rtx (mem);
4340 emit_insn (store_p
4341 ? gen_movsi_ie (mem, word1)
4342 : gen_movsi_ie (word1, mem));
4343 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4344 }
4345 else
4346 {
4347 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4348 emit_insn (gen_movsi_ie (word1, mem));
4349 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4350 mem = copy_rtx (mem);
4351 emit_insn (gen_movsi_ie (word0, mem));
4352 }
225e4f43
R
4353 DONE;
4354 }
4355 }
4356}")
4357
4358;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4359(define_split
4360 [(set (match_operand:DF 0 "register_operand" "")
4361 (match_operand:DF 1 "memory_operand" ""))
e69d1422 4362 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4363 (clobber (reg:SI R0_REG))]
225e4f43
R
4364 "TARGET_SH4 && reload_completed"
4365 [(parallel [(set (match_dup 0) (match_dup 1))
4366 (use (match_dup 2))
4367 (clobber (scratch:SI))])]
4368 "")
4369
4370(define_expand "reload_indf"
4371 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4372 (match_operand:DF 1 "immediate_operand" "FQ"))
4773afa4 4373 (use (reg:PSI FPSCR_REG))
225e4f43 4374 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4375 "TARGET_SH1"
225e4f43
R
4376 "")
4377
4378(define_expand "reload_outdf"
4379 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4380 (match_operand:DF 1 "register_operand" "af,r"))
4381 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
fa5322fa 4382 "TARGET_SH1"
225e4f43
R
4383 "")
4384
4385;; Simplify no-op moves.
4386(define_split
4387 [(set (match_operand:SF 0 "register_operand" "")
4388 (match_operand:SF 1 "register_operand" ""))
4389 (use (match_operand:PSI 2 "fpscr_operand" ""))
4390 (clobber (match_scratch:SI 3 "X"))]
3a8699c7 4391 "TARGET_SH2E && reload_completed
225e4f43
R
4392 && true_regnum (operands[0]) == true_regnum (operands[1])"
4393 [(set (match_dup 0) (match_dup 0))]
4394 "")
4395
4396;; fmovd substitute post-reload splits
4397(define_split
4398 [(set (match_operand:DF 0 "register_operand" "")
4399 (match_operand:DF 1 "register_operand" ""))
e69d1422 4400 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43
R
4401 (clobber (match_scratch:SI 3 "X"))]
4402 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b
AO
4403 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4404 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4405 [(const_int 0)]
4406 "
4407{
4408 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4409 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4410 gen_rtx (REG, SFmode, src), operands[2]));
4411 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4412 gen_rtx (REG, SFmode, src + 1), operands[2]));
4413 DONE;
4414}")
4415
4416(define_split
4417 [(set (match_operand:DF 0 "register_operand" "")
4418 (mem:DF (match_operand:SI 1 "register_operand" "")))
e69d1422
R
4419 (use (match_operand:PSI 2 "fpscr_operand" ""))
4420 (clobber (match_scratch:SI 3 ""))]
225e4f43 4421 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
b6c02328 4422 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
225e4f43
R
4423 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4424 [(const_int 0)]
4425 "
4426{
4427 int regno = true_regnum (operands[0]);
4428 rtx insn;
4429 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4430
4431 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4432 regno + !! TARGET_LITTLE_ENDIAN),
4433 mem2, operands[2]));
4434 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4435 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4436 regno + ! TARGET_LITTLE_ENDIAN),
4437 gen_rtx (MEM, SFmode, operands[1]),
4438 operands[2]));
4439 DONE;
4440}")
4441
4442(define_split
4443 [(set (match_operand:DF 0 "register_operand" "")
4444 (match_operand:DF 1 "memory_operand" ""))
e69d1422
R
4445 (use (match_operand:PSI 2 "fpscr_operand" ""))
4446 (clobber (match_scratch:SI 3 ""))]
225e4f43 4447 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4448 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
225e4f43
R
4449 [(const_int 0)]
4450 "
4451{
4452 int regno = true_regnum (operands[0]);
4453 rtx addr, insn, adjust = NULL_RTX;
4454 rtx mem2 = copy_rtx (operands[1]);
4455 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4456 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4457
4458 PUT_MODE (mem2, SFmode);
4459 operands[1] = copy_rtx (mem2);
4460 addr = XEXP (mem2, 0);
4461 if (GET_CODE (addr) != POST_INC)
4462 {
4463 /* If we have to modify the stack pointer, the value that we have
4464 read with post-increment might be modified by an interrupt,
4465 so write it back. */
4466 if (REGNO (addr) == STACK_POINTER_REGNUM)
4467 adjust = gen_push_e (reg0);
4468 else
4469 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4470 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4471 }
4472 addr = XEXP (addr, 0);
4473 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4474 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4475 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4476 if (adjust)
4477 emit_insn (adjust);
4478 else
4479 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4480 DONE;
4481}")
4482
4483(define_split
4484 [(set (match_operand:DF 0 "memory_operand" "")
4485 (match_operand:DF 1 "register_operand" ""))
e69d1422
R
4486 (use (match_operand:PSI 2 "fpscr_operand" ""))
4487 (clobber (match_scratch:SI 3 ""))]
225e4f43 4488 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4489 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4490 [(const_int 0)]
4491 "
4492{
4493 int regno = true_regnum (operands[1]);
4494 rtx insn, addr, adjust = NULL_RTX;
4495
4496 operands[0] = copy_rtx (operands[0]);
4497 PUT_MODE (operands[0], SFmode);
4498 insn = emit_insn (gen_movsf_ie (operands[0],
4499 gen_rtx (REG, SFmode,
4500 regno + ! TARGET_LITTLE_ENDIAN),
4501 operands[2]));
4502 operands[0] = copy_rtx (operands[0]);
4503 addr = XEXP (operands[0], 0);
4504 if (GET_CODE (addr) != PRE_DEC)
4505 {
4506 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4507 emit_insn_before (adjust, insn);
4508 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4509 }
4510 addr = XEXP (addr, 0);
4511 if (! adjust)
4512 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4513 insn = emit_insn (gen_movsf_ie (operands[0],
4514 gen_rtx (REG, SFmode,
4515 regno + !! TARGET_LITTLE_ENDIAN),
4516 operands[2]));
4517 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4518 DONE;
4519}")
4520
d0aae509 4521;; If the output is a register and the input is memory or a register, we have
52702ae1 4522;; to be careful and see which word needs to be loaded first.
07a45e5c 4523
8e87e161
SC
4524(define_split
4525 [(set (match_operand:DF 0 "general_movdst_operand" "")
4526 (match_operand:DF 1 "general_movsrc_operand" ""))]
fa5322fa 4527 "TARGET_SH1 && reload_completed"
8e87e161
SC
4528 [(set (match_dup 2) (match_dup 3))
4529 (set (match_dup 4) (match_dup 5))]
4530 "
d0aae509
RK
4531{
4532 int regno;
4533
4534 if ((GET_CODE (operands[0]) == MEM
4535 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4536 || (GET_CODE (operands[1]) == MEM
4537 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4538 FAIL;
4539
4540 if (GET_CODE (operands[0]) == REG)
4541 regno = REGNO (operands[0]);
4542 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 4543 regno = subreg_regno (operands[0]);
d0aae509
RK
4544 else if (GET_CODE (operands[0]) == MEM)
4545 regno = -1;
533f5e0f
KG
4546 else
4547 abort ();
d0aae509
RK
4548
4549 if (regno == -1
4550 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
4551 {
4552 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4553 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4554 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4555 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4556 }
4557 else
4558 {
4559 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4560 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4561 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4562 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4563 }
4564
4565 if (operands[2] == 0 || operands[3] == 0
4566 || operands[4] == 0 || operands[5] == 0)
4567 FAIL;
4568}")
4569
653bd7a6
JW
4570;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4571;; used only once, let combine add in the index again.
4572
4573(define_split
4574 [(set (match_operand:SI 0 "register_operand" "")
4575 (match_operand:SI 1 "" ""))
4576 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4577 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4578 [(use (reg:SI R0_REG))]
653bd7a6
JW
4579 "
4580{
4581 rtx addr, reg, const_int;
4582
4583 if (GET_CODE (operands[1]) != MEM)
4584 FAIL;
4585 addr = XEXP (operands[1], 0);
4586 if (GET_CODE (addr) != PLUS)
4587 FAIL;
4588 reg = XEXP (addr, 0);
4589 const_int = XEXP (addr, 1);
f295bdb5
AH
4590 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4591 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4592 FAIL;
4593 emit_move_insn (operands[2], const_int);
4594 emit_move_insn (operands[0],
4595 change_address (operands[1], VOIDmode,
c5c76735 4596 gen_rtx_PLUS (SImode, reg, operands[2])));
653bd7a6
JW
4597 DONE;
4598}")
4599
4600(define_split
4601 [(set (match_operand:SI 1 "" "")
4602 (match_operand:SI 0 "register_operand" ""))
4603 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4604 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4605 [(use (reg:SI R0_REG))]
653bd7a6
JW
4606 "
4607{
4608 rtx addr, reg, const_int;
4609
4610 if (GET_CODE (operands[1]) != MEM)
4611 FAIL;
4612 addr = XEXP (operands[1], 0);
4613 if (GET_CODE (addr) != PLUS)
4614 FAIL;
4615 reg = XEXP (addr, 0);
4616 const_int = XEXP (addr, 1);
f295bdb5
AH
4617 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4618 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4619 FAIL;
4620 emit_move_insn (operands[2], const_int);
4621 emit_move_insn (change_address (operands[1], VOIDmode,
c5c76735 4622 gen_rtx_PLUS (SImode, reg, operands[2])),
653bd7a6
JW
4623 operands[0]);
4624 DONE;
4625}")
4626
bc45ade3 4627(define_expand "movdf"
0d7e008e
SC
4628 [(set (match_operand:DF 0 "general_movdst_operand" "")
4629 (match_operand:DF 1 "general_movsrc_operand" ""))]
bc45ade3 4630 ""
1245df60
R
4631 "
4632{
4633 if (prepare_move_operands (operands, DFmode)) DONE;
fa5322fa
AO
4634 if (TARGET_SHMEDIA)
4635 {
4636 if (TARGET_SHMEDIA_FPU)
4637 emit_insn (gen_movdf_media (operands[0], operands[1]));
4638 else
4639 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4640 DONE;
4641 }
225e4f43
R
4642 if (TARGET_SH4)
4643 {
4644 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
4645 DONE;
4646 }
1245df60
R
4647}")
4648
0ac78517
R
4649;;This is incompatible with the way gcc uses subregs.
4650;;(define_insn "movv2sf_i"
4651;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4652;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4653;; "TARGET_SHMEDIA_FPU
4654;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4655;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4656;; "@
4657;; #
4658;; fld%M1.p %m1, %0
4659;; fst%M0.p %m0, %1"
4660;; [(set_attr "type" "*,fload_media,fstore_media")])
4661
4662(define_insn_and_split "movv2sf_i"
4663 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
735cb76e 4664 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
0ac78517
R
4665 "TARGET_SHMEDIA_FPU"
4666 "#"
4667 "TARGET_SHMEDIA_FPU && reload_completed"
4668 [(set (match_dup 0) (match_dup 1))]
4669 "
4670{
4671 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4672 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4673}")
fa5322fa
AO
4674
4675(define_expand "movv2sf"
0ac78517
R
4676 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4677 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
fa5322fa
AO
4678 "TARGET_SHMEDIA_FPU"
4679 "
4680{
4681 if (prepare_move_operands (operands, V2SFmode))
4682 DONE;
4683}")
4684
0ac78517
R
4685(define_expand "addv2sf3"
4686 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4688 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4689 "TARGET_SHMEDIA_FPU"
4690 "
4691{
4692 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4693 DONE;
4694}")
4695
4696(define_expand "subv2sf3"
4697 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4698 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4699 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4700 "TARGET_SHMEDIA_FPU"
4701 "
4702{
4703 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4704 DONE;
4705}")
4706
4707(define_expand "mulv2sf3"
4708 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4709 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4710 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4711 "TARGET_SHMEDIA_FPU"
4712 "
4713{
4714 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4715 DONE;
4716}")
4717
4718(define_expand "divv2sf3"
4719 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4720 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4721 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4722 "TARGET_SHMEDIA_FPU"
4723 "
4724{
4725 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4726 DONE;
4727}")
4728
fa5322fa
AO
4729(define_insn_and_split "*movv4sf_i"
4730 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
735cb76e 4731 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
fa5322fa
AO
4732 "TARGET_SHMEDIA_FPU"
4733 "#"
4734 "&& reload_completed"
4735 [(const_int 0)]
4736 "
4737{
4738 int i;
4739
4740 for (i = 0; i < 4/2; i++)
4741 {
4742 rtx x, y;
4743
4744 if (GET_CODE (operands[0]) == MEM)
4745 x = gen_rtx_MEM (V2SFmode,
4746 plus_constant (XEXP (operands[0], 0),
4747 i * GET_MODE_SIZE (V2SFmode)));
4748 else
0ac78517 4749 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
fa5322fa
AO
4750
4751 if (GET_CODE (operands[1]) == MEM)
4752 y = gen_rtx_MEM (V2SFmode,
4753 plus_constant (XEXP (operands[1], 0),
4754 i * GET_MODE_SIZE (V2SFmode)));
4755 else
0ac78517 4756 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
fa5322fa
AO
4757
4758 emit_insn (gen_movv2sf_i (x, y));
4759 }
4760
4761 DONE;
4762}"
4763 [(set_attr "length" "8")])
52702ae1 4764
fa5322fa 4765(define_expand "movv4sf"
0ac78517
R
4766 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4767 (match_operand:V4SF 1 "general_operand" ""))]
fa5322fa
AO
4768 "TARGET_SHMEDIA_FPU"
4769 "
4770{
4771 if (prepare_move_operands (operands, V4SFmode))
4772 DONE;
4773}")
4774
4775(define_insn_and_split "*movv16sf_i"
4776 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4777 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4778 "TARGET_SHMEDIA_FPU"
4779 "#"
4780 "&& reload_completed"
4781 [(const_int 0)]
4782 "
4783{
4784 int i;
4785
4786 for (i = 0; i < 16/2; i++)
4787 {
4788 rtx x,y;
4789
4790 if (GET_CODE (operands[0]) == MEM)
4791 x = gen_rtx_MEM (V2SFmode,
4792 plus_constant (XEXP (operands[0], 0),
4793 i * GET_MODE_SIZE (V2SFmode)));
4794 else
4795 {
4796 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4797 alter_subreg (&x);
4798 }
4799
4800 if (GET_CODE (operands[1]) == MEM)
4801 y = gen_rtx_MEM (V2SFmode,
4802 plus_constant (XEXP (operands[1], 0),
4803 i * GET_MODE_SIZE (V2SFmode)));
4804 else
4805 {
4806 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4807 alter_subreg (&y);
4808 }
4809
4810 emit_insn (gen_movv2sf_i (x, y));
4811 }
4812
4813 DONE;
4814}"
4815 [(set_attr "length" "32")])
52702ae1 4816
fa5322fa
AO
4817(define_expand "movv16sf"
4818 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4819 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4820 "TARGET_SHMEDIA_FPU"
4821 "
4822{
4823 if (prepare_move_operands (operands, V16SFmode))
4824 DONE;
4825}")
4826
4827(define_insn "movsf_media"
4828 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 4829 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
4830 "TARGET_SHMEDIA_FPU
4831 && (register_operand (operands[0], SFmode)
d9da94a1 4832 || sh_register_operand (operands[1], SFmode))"
fa5322fa
AO
4833 "@
4834 fmov.s %1, %0
0ac78517 4835 fmov.ls %N1, %0
fa5322fa 4836 fmov.sl %1, %0
b6d33983 4837 add.l %1, r63, %0
fa5322fa
AO
4838 #
4839 fld%M1.s %m1, %0
4840 fst%M0.s %m0, %1
4841 ld%M1.l %m1, %0
d9da94a1 4842 st%M0.l %m0, %N1"
b6d33983 4843 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4844
4845(define_insn "movsf_media_nofpu"
4846 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 4847 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
4848 "TARGET_SHMEDIA
4849 && (register_operand (operands[0], SFmode)
d9da94a1 4850 || sh_register_operand (operands[1], SFmode))"
fa5322fa 4851 "@
b6d33983 4852 add.l %1, r63, %0
fa5322fa
AO
4853 #
4854 ld%M1.l %m1, %0
d9da94a1 4855 st%M0.l %m0, %N1"
b6d33983 4856 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4857
4858(define_split
4859 [(set (match_operand:SF 0 "arith_reg_operand" "")
4860 (match_operand:SF 1 "immediate_operand" ""))]
0ac78517
R
4861 "TARGET_SHMEDIA && reload_completed
4862 && ! FP_REGISTER_P (true_regnum (operands[0]))"
fa5322fa
AO
4863 [(set (match_dup 3) (match_dup 2))]
4864 "
4865{
4866 long values;
4867 REAL_VALUE_TYPE value;
4868
4869 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4870 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4871 operands[2] = GEN_INT (values);
52702ae1 4872
fa5322fa
AO
4873 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4874}")
bc45ade3 4875
bc45ade3 4876(define_insn "movsf_i"
3e943b59 4877 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
735cb76e 4878 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
fa5322fa 4879 "TARGET_SH1
3a8699c7 4880 && (! TARGET_SH2E
fa5322fa
AO
4881 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4882 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4883 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
1245df60
R
4884 && (arith_reg_operand (operands[0], SFmode)
4885 || arith_reg_operand (operands[1], SFmode))"
bc45ade3
SC
4886 "@
4887 mov %1,%0
735cb76e 4888 mov #0,%0
bc45ade3
SC
4889 mov.l %1,%0
4890 mov.l %1,%0
3e943b59 4891 mov.l %1,%0
b9654711 4892 lds %1,%0
0d7e008e 4893 sts %1,%0"
3e943b59 4894 [(set_attr "type" "move,move,pcload,load,store,move,move")])
bc45ade3 4895
4dff12bf
R
4896;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4897;; update_flow_info would not know where to put REG_EQUAL notes
4898;; when the destination changes mode.
45348d9e 4899(define_insn "movsf_ie"
7f74cc8d 4900 [(set (match_operand:SF 0 "general_movdst_operand"
a92facbb 4901 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
7f74cc8d 4902 (match_operand:SF 1 "general_movsrc_operand"
a92facbb
AO
4903 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4904 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
735cb76e 4905 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
7f74cc8d 4906
3a8699c7 4907 "TARGET_SH2E
45348d9e 4908 && (arith_reg_operand (operands[0], SFmode)
c2d10707
AO
4909 || arith_reg_operand (operands[1], SFmode)
4910 || arith_reg_operand (operands[3], SImode)
4911 || (fpul_operand (operands[0], SFmode)
4912 && memory_operand (operands[1], SFmode)
4913 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4914 || (fpul_operand (operands[1], SFmode)
4915 && memory_operand (operands[0], SFmode)
4916 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
45348d9e
JW
4917 "@
4918 fmov %1,%0
4919 mov %1,%0
4920 fldi0 %0
4921 fldi1 %0
7f74cc8d 4922 #
45348d9e
JW
4923 fmov.s %1,%0
4924 fmov.s %1,%0
4925 mov.l %1,%0
4926 mov.l %1,%0
3e943b59 4927 mov.l %1,%0
1245df60
R
4928 fsts fpul,%0
4929 flds %1,fpul
4930 lds.l %1,%0
4931 #
4dff12bf
R
4932 sts %1,%0
4933 lds %1,%0
a92facbb
AO
4934 sts.l %1,%0
4935 lds.l %1,%0
4dff12bf 4936 ! move optimized away"
c49439f1
R
4937 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4938 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
a92facbb 4939 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
d64264ff
R
4940 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4941 (const_string "single")
4942 (const_string "none")))])
79664856 4943
1245df60
R
4944(define_split
4945 [(set (match_operand:SF 0 "register_operand" "")
4946 (match_operand:SF 1 "register_operand" ""))
e69d1422 4947 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4948 (clobber (reg:SI FPUL_REG))]
fa5322fa 4949 "TARGET_SH1"
4773afa4 4950 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
225e4f43 4951 (use (match_dup 2))
1245df60 4952 (clobber (scratch:SI))])
4773afa4 4953 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
225e4f43 4954 (use (match_dup 2))
1245df60
R
4955 (clobber (scratch:SI))])]
4956 "")
4957
bc45ade3 4958(define_expand "movsf"
0d7e008e 4959 [(set (match_operand:SF 0 "general_movdst_operand" "")
3e943b59 4960 (match_operand:SF 1 "general_movsrc_operand" ""))]
bc45ade3 4961 ""
3e943b59
JR
4962 "
4963{
4964 if (prepare_move_operands (operands, SFmode))
4965 DONE;
fa5322fa
AO
4966 if (TARGET_SHMEDIA)
4967 {
4968 if (TARGET_SHMEDIA_FPU)
4969 emit_insn (gen_movsf_media (operands[0], operands[1]));
4970 else
4971 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4972 DONE;
4973 }
3a8699c7 4974 if (TARGET_SH2E)
3e943b59 4975 {
225e4f43 4976 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
3e943b59
JR
4977 DONE;
4978 }
4979}")
7f74cc8d 4980
225e4f43 4981(define_insn "mov_nop"
e69d1422 4982 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
3a8699c7 4983 "TARGET_SH2E"
225e4f43
R
4984 ""
4985 [(set_attr "length" "0")
4986 (set_attr "type" "nil")])
4987
7f74cc8d 4988(define_expand "reload_insf"
c2d10707 4989 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
7f74cc8d 4990 (match_operand:SF 1 "immediate_operand" "FQ"))
4773afa4 4991 (use (reg:PSI FPSCR_REG))
7f74cc8d 4992 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4993 "TARGET_SH1"
7f74cc8d 4994 "")
225e4f43
R
4995
4996(define_expand "reload_insi"
4997 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4998 (match_operand:SF 1 "immediate_operand" "FQ"))
4999 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 5000 "TARGET_SH1"
225e4f43
R
5001 "")
5002
5003(define_insn "*movsi_y"
5004 [(set (match_operand:SI 0 "register_operand" "=y,y")
735cb76e 5005 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
c77e04ae 5006 (clobber (match_scratch:SI 2 "=&z,r"))]
3a8699c7 5007 "TARGET_SH2E
225e4f43
R
5008 && (reload_in_progress || reload_completed)"
5009 "#"
5010 [(set_attr "length" "4")
5011 (set_attr "type" "pcload,move")])
5012
5013(define_split
997718c7
RH
5014 [(set (match_operand:SI 0 "register_operand" "")
5015 (match_operand:SI 1 "immediate_operand" ""))
5016 (clobber (match_operand:SI 2 "register_operand" ""))]
fa5322fa 5017 "TARGET_SH1"
225e4f43
R
5018 [(set (match_dup 2) (match_dup 1))
5019 (set (match_dup 0) (match_dup 2))]
5020 "")
5021
5022(define_split
997718c7
RH
5023 [(set (match_operand:SI 0 "register_operand" "")
5024 (match_operand:SI 1 "memory_operand" ""))
4773afa4 5025 (clobber (reg:SI R0_REG))]
fa5322fa 5026 "TARGET_SH1"
225e4f43
R
5027 [(set (match_dup 0) (match_dup 1))]
5028 "")
bc45ade3
SC
5029\f
5030;; ------------------------------------------------------------------------
5031;; Define the real conditional branch instructions.
5032;; ------------------------------------------------------------------------
5033
5034(define_insn "branch_true"
4773afa4 5035 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5036 (label_ref (match_operand 0 "" ""))
5037 (pc)))]
fa5322fa 5038 "TARGET_SH1"
51aea58d 5039 "* return output_branch (1, insn, operands);"
bc45ade3
SC
5040 [(set_attr "type" "cbranch")])
5041
5042(define_insn "branch_false"
4773afa4 5043 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5044 (label_ref (match_operand 0 "" ""))
5045 (pc)))]
fa5322fa 5046 "TARGET_SH1"
51aea58d 5047 "* return output_branch (0, insn, operands);"
bc45ade3
SC
5048 [(set_attr "type" "cbranch")])
5049
1245df60
R
5050;; Patterns to prevent reorg from re-combining a condbranch with a branch
5051;; which destination is too far away.
5052;; The const_int_operand is distinct for each branch target; it avoids
5053;; unwanted matches with redundant_insn.
5054(define_insn "block_branch_redirect"
e11cddec 5055 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
fa5322fa 5056 "TARGET_SH1"
1245df60
R
5057 ""
5058 [(set_attr "length" "0")])
bc45ade3 5059
1245df60
R
5060;; This one has the additional purpose to record a possible scratch register
5061;; for the following branch.
10f4f635
R
5062;; ??? Unfortunately, just setting the scratch register is not good enough,
5063;; because the insn then might be deemed dead and deleted. And we can't
5064;; make the use in the jump insn explicit because that would disable
5065;; delay slot scheduling from the target.
1245df60 5066(define_insn "indirect_jump_scratch"
e69d1422 5067 [(set (match_operand:SI 0 "register_operand" "=r")
10f4f635
R
5068 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5069 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
fa5322fa 5070 "TARGET_SH1"
1245df60
R
5071 ""
5072 [(set_attr "length" "0")])
c608a684
R
5073
5074;; This one is used to preemt an insn from beyond the bra / braf / jmp
5075;; being pulled into the delay slot of a condbranch that has been made to
5076;; jump around the unconditional jump because it was out of range.
5077(define_insn "stuff_delay_slot"
5078 [(set (pc)
5079 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5080 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5081 "TARGET_SH1"
5082 ""
5083 [(set_attr "length" "0")
5084 (set_attr "cond_delay_slot" "yes")])
bc45ade3
SC
5085\f
5086;; Conditional branch insns
5087
fa5322fa 5088(define_expand "beq_media"
1245df60 5089 [(set (pc)
fa5322fa 5090 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5091 (match_operand:DI 2 "arith_operand" "r,I06"))
fa5322fa 5092 (label_ref:DI (match_operand 0 "" ""))
bc45ade3 5093 (pc)))]
fa5322fa
AO
5094 "TARGET_SHMEDIA"
5095 "")
bc45ade3 5096
c8cc4417 5097(define_insn "*beq_media_i"
1245df60 5098 [(set (pc)
c8cc4417
R
5099 (if_then_else (match_operator 3 "equality_comparison_operator"
5100 [(match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5101 (match_operand:DI 2 "arith_operand" "r,I06")])
fa5322fa 5102 (match_operand:DI 0 "target_operand" "b,b")
1245df60 5103 (pc)))]
fa5322fa
AO
5104 "TARGET_SHMEDIA"
5105 "@
c8cc4417
R
5106 b%o3%' %1, %2, %0
5107 b%o3i%' %1, %2, %0"
5108 [(set_attr "type" "cbranch_media")])
bc45ade3 5109
fa5322fa 5110(define_expand "bne_media"
1245df60 5111 [(set (pc)
fa5322fa 5112 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5113 (match_operand:DI 2 "arith_operand" "r,I06"))
fa5322fa 5114 (label_ref:DI (match_operand 0 "" ""))
ffae286a 5115 (pc)))]
fa5322fa
AO
5116 "TARGET_SHMEDIA"
5117 "")
bc45ade3 5118
fa5322fa 5119(define_expand "bgt_media"
1245df60 5120 [(set (pc)
b6d33983
R
5121 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5122 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa 5123 (label_ref:DI (match_operand 0 "" ""))
1245df60 5124 (pc)))]
fa5322fa
AO
5125 "TARGET_SHMEDIA"
5126 "")
5127
fa5322fa
AO
5128(define_expand "bge_media"
5129 [(set (pc)
b6d33983
R
5130 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5131 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5132 (label_ref:DI (match_operand 0 "" ""))
5133 (pc)))]
5134 "TARGET_SHMEDIA"
5135 "")
5136
fa5322fa
AO
5137(define_expand "bgtu_media"
5138 [(set (pc)
b6d33983
R
5139 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5140 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5141 (label_ref:DI (match_operand 0 "" ""))
5142 (pc)))]
5143 "TARGET_SHMEDIA"
5144 "")
5145
fa5322fa
AO
5146(define_expand "bgeu_media"
5147 [(set (pc)
b6d33983
R
5148 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5149 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5150 (label_ref:DI (match_operand 0 "" ""))
5151 (pc)))]
5152 "TARGET_SHMEDIA"
5153 "")
5154
c8cc4417 5155(define_insn "*bgt_media_i"
fa5322fa 5156 [(set (pc)
c8cc4417
R
5157 (if_then_else (match_operator 3 "greater_comparison_operator"
5158 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5159 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5160 (match_operand:DI 0 "target_operand" "b")
5161 (pc)))]
5162 "TARGET_SHMEDIA"
c8cc4417
R
5163 "b%o3%' %N1, %N2, %0"
5164 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5165
5166;; These are only needed to make invert_jump() happy.
b6d33983 5167(define_insn "*blt_media_i"
fa5322fa 5168 [(set (pc)
c8cc4417 5169 (if_then_else (match_operator 3 "less_comparison_operator"
b6d33983
R
5170 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5171 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5172 (match_operand:DI 0 "target_operand" "b")
5173 (pc)))]
5174 "TARGET_SHMEDIA"
c8cc4417
R
5175 "b%o3%' %N2, %N1, %0"
5176 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5177
5178(define_expand "beq"
5179 [(set (pc)
5180 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5181 (label_ref (match_operand 0 "" ""))
5182 (pc)))]
5183 ""
5184 "
5185{
5186 if (TARGET_SHMEDIA)
5187 {
5188 if (GET_MODE (sh_compare_op0) != DImode)
5189 {
5190 rtx tmp = gen_reg_rtx (DImode);
5191
5192 emit_insn (gen_seq (tmp));
5193 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5194 DONE;
5195 }
5196
5197 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5198 emit_jump_insn (gen_beq_media (operands[0],
5199 sh_compare_op0, sh_compare_op1));
5200 DONE;
5201 }
5202
5203 from_compare (operands, EQ);
5204}")
5205
5206(define_expand "bne"
5207 [(set (pc)
5208 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5209 (label_ref (match_operand 0 "" ""))
5210 (pc)))]
5211 ""
5212 "
5213{
5214 if (TARGET_SHMEDIA)
5215 {
5216 if (GET_MODE (sh_compare_op0) != DImode)
5217 {
5218 rtx tmp = gen_reg_rtx (DImode);
5219
5220 emit_insn (gen_seq (tmp));
5221 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5222 DONE;
5223 }
5224
5225 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5226 emit_jump_insn (gen_bne_media (operands[0],
5227 sh_compare_op0, sh_compare_op1));
5228 DONE;
5229 }
5230
5231 from_compare (operands, EQ);
5232}")
5233
5234(define_expand "bgt"
5235 [(set (pc)
5236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5237 (label_ref (match_operand 0 "" ""))
5238 (pc)))]
5239 ""
5240 "
5241{
5242 if (TARGET_SHMEDIA)
5243 {
5244 if (GET_MODE (sh_compare_op0) != DImode)
5245 {
5246 rtx tmp = gen_reg_rtx (DImode);
5247
5248 emit_insn (gen_sgt (tmp));
5249 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5250 DONE;
5251 }
5252
c8cc4417
R
5253 if (sh_compare_op0 != const0_rtx)
5254 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5255 if (sh_compare_op1 != const0_rtx)
5256 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5257 emit_jump_insn (gen_bgt_media (operands[0],
5258 sh_compare_op0, sh_compare_op1));
5259 DONE;
5260 }
5261
5262 from_compare (operands, GT);
5263}")
5264
5265(define_expand "blt"
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_slt (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_bgt_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5290 DONE;
5291 }
5292
5293 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5294 {
5295 rtx tmp = sh_compare_op0;
5296 sh_compare_op0 = sh_compare_op1;
5297 sh_compare_op1 = tmp;
5298 emit_insn (gen_bgt (operands[0]));
5299 DONE;
5300 }
5301 from_compare (operands, GE);
5302}")
5303
5304(define_expand "ble"
5305 [(set (pc)
5306 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5307 (label_ref (match_operand 0 "" ""))
5308 (pc)))]
5309 ""
5310 "
5311{
5312 if (TARGET_SHMEDIA)
5313 {
5314 if (GET_MODE (sh_compare_op0) != DImode)
5315 {
5316 rtx tmp = gen_reg_rtx (DImode);
5317
5318 emit_insn (gen_sle (tmp));
5319 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5320 DONE;
5321 }
5322
c8cc4417
R
5323 if (sh_compare_op0 != const0_rtx)
5324 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5325 if (sh_compare_op1 != const0_rtx)
5326 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5327 emit_jump_insn (gen_bge_media (operands[0],
5328 sh_compare_op1, sh_compare_op0));
5329 DONE;
5330 }
5331
3a8699c7 5332 if (TARGET_SH2E
fa5322fa 5333 && TARGET_IEEE
1245df60
R
5334 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5335 {
5336 rtx tmp = sh_compare_op0;
5337 sh_compare_op0 = sh_compare_op1;
5338 sh_compare_op1 = tmp;
5339 emit_insn (gen_bge (operands[0]));
5340 DONE;
5341 }
5342 from_compare (operands, GT);
5343}")
bc45ade3
SC
5344
5345(define_expand "bge"
1245df60 5346 [(set (pc)
4773afa4 5347 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5348 (label_ref (match_operand 0 "" ""))
ffae286a 5349 (pc)))]
bc45ade3 5350 ""
45348d9e
JW
5351 "
5352{
fa5322fa
AO
5353 if (TARGET_SHMEDIA)
5354 {
5355 if (GET_MODE (sh_compare_op0) != DImode)
5356 {
5357 rtx tmp = gen_reg_rtx (DImode);
5358
5359 emit_insn (gen_sge (tmp));
5360 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5361 DONE;
5362 }
5363
c8cc4417
R
5364 if (sh_compare_op0 != const0_rtx)
5365 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5366 if (sh_compare_op1 != const0_rtx)
5367 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5368 emit_jump_insn (gen_bge_media (operands[0],
5369 sh_compare_op0, sh_compare_op1));
5370 DONE;
5371 }
5372
3a8699c7 5373 if (TARGET_SH2E
1245df60
R
5374 && ! TARGET_IEEE
5375 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e
JW
5376 {
5377 rtx tmp = sh_compare_op0;
5378 sh_compare_op0 = sh_compare_op1;
5379 sh_compare_op1 = tmp;
5380 emit_insn (gen_ble (operands[0]));
5381 DONE;
5382 }
5383 from_compare (operands, GE);
5384}")
bc45ade3
SC
5385
5386(define_expand "bgtu"
1245df60 5387 [(set (pc)
4773afa4 5388 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5389 (label_ref (match_operand 0 "" ""))
5390 (pc)))]
5391 ""
fa5322fa
AO
5392 "
5393{
5394 if (TARGET_SHMEDIA)
5395 {
c8cc4417
R
5396 if (sh_compare_op0 != const0_rtx)
5397 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5398 if (sh_compare_op1 != const0_rtx)
5399 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5400 emit_jump_insn (gen_bgtu_media (operands[0],
5401 sh_compare_op0, sh_compare_op1));
5402 DONE;
5403 }
5404
5405 from_compare (operands, GTU);
5406}")
bc45ade3
SC
5407
5408(define_expand "bltu"
1245df60 5409 [(set (pc)
4773afa4
AO
5410 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5411 (label_ref (match_operand 0 "" ""))
5412 (pc)))]
bc45ade3 5413 ""
fa5322fa
AO
5414 "
5415{
5416 if (TARGET_SHMEDIA)
5417 {
c8cc4417
R
5418 if (sh_compare_op0 != const0_rtx)
5419 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5420 if (sh_compare_op1 != const0_rtx)
5421 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5422 emit_jump_insn (gen_bgtu_media (operands[0],
5423 sh_compare_op1, sh_compare_op0));
5424 DONE;
5425 }
5426
5427 from_compare (operands, GEU);
5428}")
bc45ade3
SC
5429
5430(define_expand "bgeu"
1245df60 5431 [(set (pc)
4773afa4 5432 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5433 (label_ref (match_operand 0 "" ""))
ffae286a 5434 (pc)))]
bc45ade3 5435 ""
fa5322fa
AO
5436 "
5437{
5438 if (TARGET_SHMEDIA)
5439 {
c8cc4417
R
5440 if (sh_compare_op0 != const0_rtx)
5441 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5442 if (sh_compare_op1 != const0_rtx)
5443 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5444 emit_jump_insn (gen_bgeu_media (operands[0],
5445 sh_compare_op0, sh_compare_op1));
5446 DONE;
5447 }
5448
5449 from_compare (operands, GEU);
5450}")
bc45ade3
SC
5451
5452(define_expand "bleu"
1245df60 5453 [(set (pc)
4773afa4 5454 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1245df60
R
5455 (label_ref (match_operand 0 "" ""))
5456 (pc)))]
bc45ade3 5457 ""
fa5322fa
AO
5458 "
5459{
5460 if (TARGET_SHMEDIA)
5461 {
c8cc4417
R
5462 if (sh_compare_op0 != const0_rtx)
5463 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5464 if (sh_compare_op1 != const0_rtx)
5465 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5466 emit_jump_insn (gen_bgeu_media (operands[0],
5467 sh_compare_op1, sh_compare_op0));
5468 DONE;
5469 }
5470
5471 from_compare (operands, GTU);
5472}")
5473
5474(define_expand "bunordered"
5475 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5476 (set (pc)
5477 (if_then_else (ne (match_dup 1) (const_int 0))
5478 (label_ref:DI (match_operand 0 "" ""))
5479 (pc)))]
5480 "TARGET_SHMEDIA"
5481 "
5482{
5483 operands[1] = gen_reg_rtx (DImode);
5484 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5485 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5486}")
bc45ade3
SC
5487\f
5488;; ------------------------------------------------------------------------
5489;; Jump and linkage insns
5490;; ------------------------------------------------------------------------
5491
fa5322fa 5492(define_insn "jump_compact"
bc45ade3
SC
5493 [(set (pc)
5494 (label_ref (match_operand 0 "" "")))]
fa5322fa 5495 "TARGET_SH1"
bc45ade3
SC
5496 "*
5497{
22e1ebf1 5498 /* The length is 16 if the delay slot is unfilled. */
1245df60 5499 if (get_attr_length(insn) > 4)
51aea58d 5500 return output_far_jump(insn, operands[0]);
bc45ade3 5501 else
51aea58d 5502 return \"bra %l0%#\";
bc45ade3
SC
5503}"
5504 [(set_attr "type" "jump")
5505 (set_attr "needs_delay_slot" "yes")])
5506
10f4f635
R
5507;; ??? It would be much saner to explicitly use the scratch register
5508;; in the jump insn, and have indirect_jump_scratch only set it,
5509;; but fill_simple_delay_slots would refuse to do delay slot filling
5510;; from the target then, as it uses simplejump_p.
5511;;(define_insn "jump_compact_far"
5512;; [(set (pc)
5513;; (label_ref (match_operand 0 "" "")))
5514;; (use (match_operand 1 "register_operand" "r")]
5515;; "TARGET_SH1"
5516;; "* return output_far_jump(insn, operands[0], operands[1]);"
5517;; [(set_attr "type" "jump")
5518;; (set_attr "needs_delay_slot" "yes")])
5519
fa5322fa
AO
5520(define_insn "jump_media"
5521 [(set (pc)
5522 (match_operand:DI 0 "target_operand" "b"))]
5523 "TARGET_SHMEDIA"
2ad65b0e
SC
5524 "blink %0, r63"
5525 [(set_attr "type" "jump_media")])
fa5322fa
AO
5526
5527(define_expand "jump"
5528 [(set (pc)
5529 (label_ref (match_operand 0 "" "")))]
5530 ""
5531 "
5532{
5533 if (TARGET_SH1)
8e831557 5534 emit_jump_insn (gen_jump_compact (operands[0]));
fa5322fa
AO
5535 else if (TARGET_SHMEDIA)
5536 {
5537 if (reload_in_progress || reload_completed)
5538 FAIL;
8e831557
KK
5539 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5540 operands[0])));
fa5322fa
AO
5541 }
5542 DONE;
5543}")
5544
5545(define_insn "force_mode_for_call"
5546 [(use (reg:PSI FPSCR_REG))]
5547 "TARGET_SHCOMPACT"
5548 ""
5549 [(set_attr "length" "0")
5550 (set (attr "fp_mode")
5551 (if_then_else (eq_attr "fpu_single" "yes")
5552 (const_string "single") (const_string "double")))])
5553
bc45ade3 5554(define_insn "calli"
aa684c94 5555 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
bc45ade3 5556 (match_operand 1 "" ""))
5d00b10a 5557 (use (reg:PSI FPSCR_REG))
4773afa4 5558 (clobber (reg:SI PR_REG))]
fa5322fa 5559 "TARGET_SH1"
bc45ade3 5560 "jsr @%0%#"
ffae286a 5561 [(set_attr "type" "call")
d64264ff
R
5562 (set (attr "fp_mode")
5563 (if_then_else (eq_attr "fpu_single" "yes")
5564 (const_string "single") (const_string "double")))
ffae286a 5565 (set_attr "needs_delay_slot" "yes")])
961c4780 5566
1a66cd67
AO
5567;; This is a pc-rel call, using bsrf, for use with PIC.
5568
5569(define_insn "calli_pcrel"
5570 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5571 (match_operand 1 "" ""))
5d00b10a 5572 (use (reg:PSI FPSCR_REG))
2d01e445 5573 (use (reg:SI PIC_REG))
1a66cd67 5574 (use (match_operand 2 "" ""))
4773afa4 5575 (clobber (reg:SI PR_REG))]
eb69f95c 5576 "TARGET_SH2"
1a66cd67
AO
5577 "bsrf %0\\n%O2:%#"
5578 [(set_attr "type" "call")
5579 (set (attr "fp_mode")
5580 (if_then_else (eq_attr "fpu_single" "yes")
5581 (const_string "single") (const_string "double")))
5582 (set_attr "needs_delay_slot" "yes")])
5583
2d01e445
AO
5584(define_insn_and_split "call_pcrel"
5585 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5586 (match_operand 1 "" ""))
5587 (use (reg:PSI FPSCR_REG))
5588 (use (reg:SI PIC_REG))
5589 (clobber (reg:SI PR_REG))
5590 (clobber (match_scratch:SI 2 "=r"))]
cb51ecd2 5591 "TARGET_SH2"
2d01e445
AO
5592 "#"
5593 "reload_completed"
5594 [(const_int 0)]
5595 "
5596{
8e831557 5597 rtx lab = PATTERN (gen_call_site ());
2d01e445 5598
675ff4c7 5599 if (SYMBOL_REF_LOCAL_P (operands[0]))
2d01e445
AO
5600 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5601 else
5602 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5603 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5604 DONE;
5605}"
5606 [(set_attr "type" "call")
5607 (set (attr "fp_mode")
5608 (if_then_else (eq_attr "fpu_single" "yes")
5609 (const_string "single") (const_string "double")))
5610 (set_attr "needs_delay_slot" "yes")])
5611
fa5322fa
AO
5612(define_insn "call_compact"
5613 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5614 (match_operand 1 "" ""))
5615 (match_operand 2 "immediate_operand" "n")
5616 (use (reg:SI R0_REG))
5617 (use (reg:SI R1_REG))
5618 (use (reg:PSI FPSCR_REG))
5619 (clobber (reg:SI PR_REG))]
5620 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5621 "jsr @%0%#"
5622 [(set_attr "type" "call")
5623 (set (attr "fp_mode")
5624 (if_then_else (eq_attr "fpu_single" "yes")
5625 (const_string "single") (const_string "double")))
5626 (set_attr "needs_delay_slot" "yes")])
5627
5628(define_insn "call_compact_rettramp"
5629 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5630 (match_operand 1 "" ""))
5631 (match_operand 2 "immediate_operand" "n")
5632 (use (reg:SI R0_REG))
5633 (use (reg:SI R1_REG))
5634 (use (reg:PSI FPSCR_REG))
5635 (clobber (reg:SI R10_REG))
5636 (clobber (reg:SI PR_REG))]
5637 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5638 "jsr @%0%#"
5639 [(set_attr "type" "call")
5640 (set (attr "fp_mode")
5641 (if_then_else (eq_attr "fpu_single" "yes")
5642 (const_string "single") (const_string "double")))
5643 (set_attr "needs_delay_slot" "yes")])
5644
5645(define_insn "call_media"
5646 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5647 (match_operand 1 "" ""))
5648 (clobber (reg:DI PR_MEDIA_REG))]
5649 "TARGET_SHMEDIA"
2ad65b0e
SC
5650 "blink %0, r18"
5651 [(set_attr "type" "jump_media")])
fa5322fa 5652
bc45ade3
SC
5653(define_insn "call_valuei"
5654 [(set (match_operand 0 "" "=rf")
aa684c94 5655 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
bc45ade3 5656 (match_operand 2 "" "")))
5d00b10a 5657 (use (reg:PSI FPSCR_REG))
4773afa4 5658 (clobber (reg:SI PR_REG))]
fa5322fa 5659 "TARGET_SH1"
bc45ade3 5660 "jsr @%1%#"
ffae286a 5661 [(set_attr "type" "call")
d64264ff
R
5662 (set (attr "fp_mode")
5663 (if_then_else (eq_attr "fpu_single" "yes")
5664 (const_string "single") (const_string "double")))
ffae286a 5665 (set_attr "needs_delay_slot" "yes")])
bc45ade3 5666
1a66cd67
AO
5667(define_insn "call_valuei_pcrel"
5668 [(set (match_operand 0 "" "=rf")
5669 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5670 (match_operand 2 "" "")))
5d00b10a 5671 (use (reg:PSI FPSCR_REG))
2d01e445 5672 (use (reg:SI PIC_REG))
1a66cd67 5673 (use (match_operand 3 "" ""))
4773afa4 5674 (clobber (reg:SI PR_REG))]
eb69f95c 5675 "TARGET_SH2"
1a66cd67
AO
5676 "bsrf %1\\n%O3:%#"
5677 [(set_attr "type" "call")
5678 (set (attr "fp_mode")
5679 (if_then_else (eq_attr "fpu_single" "yes")
5680 (const_string "single") (const_string "double")))
5681 (set_attr "needs_delay_slot" "yes")])
5682
2d01e445
AO
5683(define_insn_and_split "call_value_pcrel"
5684 [(set (match_operand 0 "" "=rf")
5685 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5686 (match_operand 2 "" "")))
5687 (use (reg:PSI FPSCR_REG))
5688 (use (reg:SI PIC_REG))
5689 (clobber (reg:SI PR_REG))
5690 (clobber (match_scratch:SI 3 "=r"))]
cb51ecd2 5691 "TARGET_SH2"
2d01e445
AO
5692 "#"
5693 "reload_completed"
5694 [(const_int 0)]
5695 "
5696{
8e831557 5697 rtx lab = PATTERN (gen_call_site ());
2d01e445 5698
675ff4c7 5699 if (SYMBOL_REF_LOCAL_P (operands[1]))
2d01e445
AO
5700 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5701 else
5702 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5703 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5704 operands[2], lab));
5705 DONE;
5706}"
5707 [(set_attr "type" "call")
5708 (set (attr "fp_mode")
5709 (if_then_else (eq_attr "fpu_single" "yes")
5710 (const_string "single") (const_string "double")))
5711 (set_attr "needs_delay_slot" "yes")])
5712
fa5322fa
AO
5713(define_insn "call_value_compact"
5714 [(set (match_operand 0 "" "=rf")
5715 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5716 (match_operand 2 "" "")))
5717 (match_operand 3 "immediate_operand" "n")
5718 (use (reg:SI R0_REG))
5719 (use (reg:SI R1_REG))
5720 (use (reg:PSI FPSCR_REG))
5721 (clobber (reg:SI PR_REG))]
5722 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5723 "jsr @%1%#"
5724 [(set_attr "type" "call")
5725 (set (attr "fp_mode")
5726 (if_then_else (eq_attr "fpu_single" "yes")
5727 (const_string "single") (const_string "double")))
5728 (set_attr "needs_delay_slot" "yes")])
5729
5730(define_insn "call_value_compact_rettramp"
5731 [(set (match_operand 0 "" "=rf")
5732 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5733 (match_operand 2 "" "")))
5734 (match_operand 3 "immediate_operand" "n")
5735 (use (reg:SI R0_REG))
5736 (use (reg:SI R1_REG))
5737 (use (reg:PSI FPSCR_REG))
5738 (clobber (reg:SI R10_REG))
5739 (clobber (reg:SI PR_REG))]
5740 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5741 "jsr @%1%#"
5742 [(set_attr "type" "call")
5743 (set (attr "fp_mode")
5744 (if_then_else (eq_attr "fpu_single" "yes")
5745 (const_string "single") (const_string "double")))
5746 (set_attr "needs_delay_slot" "yes")])
5747
5748(define_insn "call_value_media"
5749 [(set (match_operand 0 "" "=rf")
5750 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5751 (match_operand 2 "" "")))
5752 (clobber (reg:DI PR_MEDIA_REG))]
5753 "TARGET_SHMEDIA"
2ad65b0e
SC
5754 "blink %1, r18"
5755 [(set_attr "type" "jump_media")])
fa5322fa 5756
bc45ade3 5757(define_expand "call"
51aea58d
JW
5758 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5759 (match_operand 1 "" ""))
fa5322fa 5760 (match_operand 2 "" "")
5d00b10a 5761 (use (reg:PSI FPSCR_REG))
4773afa4 5762 (clobber (reg:SI PR_REG))])]
bc45ade3 5763 ""
1a66cd67 5764 "
827bdee4 5765{
fa5322fa
AO
5766 if (TARGET_SHMEDIA)
5767 {
5768 operands[0] = XEXP (operands[0], 0);
5769 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5770 {
675ff4c7 5771 if (! SYMBOL_REF_LOCAL_P (operands[0]))
fa5322fa
AO
5772 {
5773 rtx reg = gen_reg_rtx (Pmode);
52702ae1 5774
fa5322fa
AO
5775 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5776 operands[0] = reg;
5777 }
5778 else
5779 {
5780 operands[0] = gen_sym2PIC (operands[0]);
5781 PUT_MODE (operands[0], Pmode);
5782 }
5783 }
5784 if (GET_MODE (operands[0]) == SImode)
5785 {
5786 if (GET_CODE (operands[0]) == REG)
5787 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5788 else if (GET_CODE (operands[0]) == SUBREG)
5789 {
5790 operands[0] = SUBREG_REG (operands[0]);
5791 if (GET_MODE (operands[0]) != DImode)
5792 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5793 }
5794 else
5795 {
5796 operands[0] = shallow_copy_rtx (operands[0]);
5797 PUT_MODE (operands[0], DImode);
5798 }
5799 }
5800 if (! target_reg_operand (operands[0], DImode))
5801 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5802 emit_call_insn (gen_call_media (operands[0], operands[1]));
5803 DONE;
5804 }
5805 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5806 {
5807 rtx cookie_rtx = operands[2];
5808 long cookie = INTVAL (cookie_rtx);
5809 rtx func = XEXP (operands[0], 0);
5810 rtx r0, r1;
5811
5812 if (flag_pic)
5813 {
675ff4c7 5814 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
5815 {
5816 rtx reg = gen_reg_rtx (Pmode);
5817
5818 emit_insn (gen_symGOTPLT2reg (reg, func));
5819 func = reg;
5820 }
5821 else
5822 func = legitimize_pic_address (func, Pmode, 0);
5823 }
5824
5825 r0 = gen_rtx_REG (SImode, R0_REG);
5826 r1 = gen_rtx_REG (SImode, R1_REG);
5827
5828 /* Since such a call function may use all call-clobbered
5829 registers, we force a mode switch earlier, so that we don't
5830 run out of registers when adjusting fpscr for the call. */
5831 emit_insn (gen_force_mode_for_call ());
5832
90534361 5833 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
5834 if (flag_pic)
5835 {
5836 rtx reg = gen_reg_rtx (Pmode);
5837
5838 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5839 operands[0] = reg;
5840 }
5841 operands[0] = force_reg (SImode, operands[0]);
5842
5843 emit_move_insn (r0, func);
5844 emit_move_insn (r1, cookie_rtx);
5845
5846 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5847 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5848 operands[2]));
5849 else
5850 emit_call_insn (gen_call_compact (operands[0], operands[1],
5851 operands[2]));
5852
5853 DONE;
5854 }
5855 else if (TARGET_SHCOMPACT && flag_pic
5856 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 5857 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
5858 {
5859 rtx reg = gen_reg_rtx (Pmode);
5860
5861 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5862 XEXP (operands[0], 0) = reg;
5863 }
cb51ecd2 5864 if (flag_pic && TARGET_SH2
827bdee4
AO
5865 && GET_CODE (operands[0]) == MEM
5866 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5867 {
2d01e445 5868 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
827bdee4
AO
5869 DONE;
5870 }
5871 else
61f71b34 5872 {
827bdee4 5873 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
61f71b34
DD
5874 operands[1] = operands[2];
5875 }
fa5322fa
AO
5876
5877 emit_call_insn (gen_calli (operands[0], operands[1]));
5878 DONE;
5879}")
5880
5881(define_insn "call_pop_compact"
5882 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5883 (match_operand 1 "" ""))
5884 (match_operand 2 "immediate_operand" "n")
5885 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5886 (match_operand 3 "immediate_operand" "n")))
5887 (use (reg:SI R0_REG))
5888 (use (reg:SI R1_REG))
5889 (use (reg:PSI FPSCR_REG))
5890 (clobber (reg:SI PR_REG))]
5891 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5892 "jsr @%0%#"
5893 [(set_attr "type" "call")
5894 (set (attr "fp_mode")
5895 (if_then_else (eq_attr "fpu_single" "yes")
5896 (const_string "single") (const_string "double")))
5897 (set_attr "needs_delay_slot" "yes")])
5898
5899(define_insn "call_pop_compact_rettramp"
5900 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5901 (match_operand 1 "" ""))
5902 (match_operand 2 "immediate_operand" "n")
5903 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5904 (match_operand 3 "immediate_operand" "n")))
5905 (use (reg:SI R0_REG))
5906 (use (reg:SI R1_REG))
5907 (use (reg:PSI FPSCR_REG))
5908 (clobber (reg:SI R10_REG))
5909 (clobber (reg:SI PR_REG))]
5910 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5911 "jsr @%0%#"
5912 [(set_attr "type" "call")
5913 (set (attr "fp_mode")
5914 (if_then_else (eq_attr "fpu_single" "yes")
5915 (const_string "single") (const_string "double")))
5916 (set_attr "needs_delay_slot" "yes")])
5917
5918(define_expand "call_pop"
5919 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5920 (match_operand 1 "" ""))
5921 (match_operand 2 "" "")
5922 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5923 (match_operand 3 "" "")))])]
5924 "TARGET_SHCOMPACT"
5925 "
5926{
5927 if (operands[2] && INTVAL (operands[2]))
5928 {
5929 rtx cookie_rtx = operands[2];
5930 long cookie = INTVAL (cookie_rtx);
5931 rtx func = XEXP (operands[0], 0);
5932 rtx r0, r1;
5933
5934 if (flag_pic)
5935 {
675ff4c7 5936 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
5937 {
5938 rtx reg = gen_reg_rtx (Pmode);
5939
5940 emit_insn (gen_symGOTPLT2reg (reg, func));
5941 func = reg;
5942 }
5943 else
5944 func = legitimize_pic_address (func, Pmode, 0);
5945 }
5946
5947 r0 = gen_rtx_REG (SImode, R0_REG);
5948 r1 = gen_rtx_REG (SImode, R1_REG);
5949
5950 /* Since such a call function may use all call-clobbered
5951 registers, we force a mode switch earlier, so that we don't
5952 run out of registers when adjusting fpscr for the call. */
5953 emit_insn (gen_force_mode_for_call ());
5954
90534361 5955 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
5956 if (flag_pic)
5957 {
5958 rtx reg = gen_reg_rtx (Pmode);
5959
5960 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5961 operands[0] = reg;
5962 }
5963 operands[0] = force_reg (SImode, operands[0]);
5964
5965 emit_move_insn (r0, func);
5966 emit_move_insn (r1, cookie_rtx);
5967
5968 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5969 emit_call_insn (gen_call_pop_compact_rettramp
5970 (operands[0], operands[1], operands[2], operands[3]));
5971 else
5972 emit_call_insn (gen_call_pop_compact
5973 (operands[0], operands[1], operands[2], operands[3]));
5974
5975 DONE;
5976 }
5977
5978 abort ();
827bdee4 5979}")
bc45ade3
SC
5980
5981(define_expand "call_value"
51aea58d
JW
5982 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5983 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5984 (match_operand 2 "" "")))
fa5322fa 5985 (match_operand 3 "" "")
5d00b10a 5986 (use (reg:PSI FPSCR_REG))
4773afa4 5987 (clobber (reg:SI PR_REG))])]
bc45ade3 5988 ""
1a66cd67 5989 "
827bdee4 5990{
fa5322fa
AO
5991 if (TARGET_SHMEDIA)
5992 {
5993 operands[1] = XEXP (operands[1], 0);
5994 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5995 {
675ff4c7 5996 if (! SYMBOL_REF_LOCAL_P (operands[1]))
fa5322fa
AO
5997 {
5998 rtx reg = gen_reg_rtx (Pmode);
52702ae1 5999
fa5322fa
AO
6000 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6001 operands[1] = reg;
6002 }
6003 else
6004 {
6005 operands[1] = gen_sym2PIC (operands[1]);
6006 PUT_MODE (operands[1], Pmode);
6007 }
6008 }
6009 if (GET_MODE (operands[1]) == SImode)
6010 {
6011 if (GET_CODE (operands[1]) == REG)
6012 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6013 else if (GET_CODE (operands[1]) == SUBREG)
6014 {
6015 operands[1] = SUBREG_REG (operands[1]);
6016 if (GET_MODE (operands[1]) != DImode)
6017 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6018 }
6019 else
6020 {
6021 operands[1] = shallow_copy_rtx (operands[1]);
6022 PUT_MODE (operands[1], DImode);
6023 }
6024 }
6025 if (! target_reg_operand (operands[1], DImode))
6026 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6027 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6028 operands[2]));
6029 DONE;
6030 }
6031 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6032 {
6033 rtx cookie_rtx = operands[3];
6034 long cookie = INTVAL (cookie_rtx);
6035 rtx func = XEXP (operands[1], 0);
6036 rtx r0, r1;
6037
6038 if (flag_pic)
6039 {
675ff4c7 6040 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6041 {
6042 rtx reg = gen_reg_rtx (Pmode);
6043
6044 emit_insn (gen_symGOTPLT2reg (reg, func));
6045 func = reg;
6046 }
6047 else
6048 func = legitimize_pic_address (func, Pmode, 0);
6049 }
6050
6051 r0 = gen_rtx_REG (SImode, R0_REG);
6052 r1 = gen_rtx_REG (SImode, R1_REG);
6053
6054 /* Since such a call function may use all call-clobbered
6055 registers, we force a mode switch earlier, so that we don't
6056 run out of registers when adjusting fpscr for the call. */
6057 emit_insn (gen_force_mode_for_call ());
6058
90534361 6059 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6060 if (flag_pic)
6061 {
6062 rtx reg = gen_reg_rtx (Pmode);
6063
6064 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6065 operands[1] = reg;
6066 }
6067 operands[1] = force_reg (SImode, operands[1]);
6068
6069 emit_move_insn (r0, func);
6070 emit_move_insn (r1, cookie_rtx);
6071
6072 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6073 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6074 operands[1],
6075 operands[2],
6076 operands[3]));
6077 else
6078 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6079 operands[2], operands[3]));
6080
6081 DONE;
6082 }
6083 else if (TARGET_SHCOMPACT && flag_pic
6084 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
675ff4c7 6085 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
fa5322fa
AO
6086 {
6087 rtx reg = gen_reg_rtx (Pmode);
6088
6089 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6090 XEXP (operands[1], 0) = reg;
6091 }
cb51ecd2 6092 if (flag_pic && TARGET_SH2
827bdee4
AO
6093 && GET_CODE (operands[1]) == MEM
6094 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6095 {
2d01e445
AO
6096 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6097 operands[2]));
827bdee4
AO
6098 DONE;
6099 }
6100 else
6101 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
fa5322fa
AO
6102
6103 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6104 DONE;
827bdee4 6105}")
bc45ade3 6106
5db5a888 6107(define_insn "sibcalli"
cb51ecd2 6108 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5db5a888
AO
6109 (match_operand 1 "" ""))
6110 (use (reg:PSI FPSCR_REG))
6111 (return)]
fa5322fa 6112 "TARGET_SH1"
5db5a888
AO
6113 "jmp @%0%#"
6114 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6115 (set (attr "fp_mode")
6116 (if_then_else (eq_attr "fpu_single" "yes")
6117 (const_string "single") (const_string "double")))
5db5a888
AO
6118 (set_attr "type" "jump_ind")])
6119
6120(define_insn "sibcalli_pcrel"
cb51ecd2 6121 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5db5a888
AO
6122 (match_operand 1 "" ""))
6123 (use (match_operand 2 "" ""))
6124 (use (reg:PSI FPSCR_REG))
6125 (return)]
6126 "TARGET_SH2"
6127 "braf %0\\n%O2:%#"
6128 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6129 (set (attr "fp_mode")
6130 (if_then_else (eq_attr "fpu_single" "yes")
6131 (const_string "single") (const_string "double")))
5db5a888
AO
6132 (set_attr "type" "jump_ind")])
6133
6134(define_insn_and_split "sibcall_pcrel"
6135 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6136 (match_operand 1 "" ""))
6137 (use (reg:PSI FPSCR_REG))
cb51ecd2 6138 (clobber (match_scratch:SI 2 "=k"))
5db5a888 6139 (return)]
cb51ecd2 6140 "TARGET_SH2"
5db5a888
AO
6141 "#"
6142 "reload_completed"
6143 [(const_int 0)]
6144 "
6145{
8e831557 6146 rtx lab = PATTERN (gen_call_site ());
5db5a888
AO
6147 rtx call_insn;
6148
fa5322fa
AO
6149 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6150 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6151 lab));
6152 SIBLING_CALL_P (call_insn) = 1;
6153 DONE;
6154}"
6155 [(set_attr "needs_delay_slot" "yes")
6156 (set (attr "fp_mode")
6157 (if_then_else (eq_attr "fpu_single" "yes")
6158 (const_string "single") (const_string "double")))
6159 (set_attr "type" "jump_ind")])
6160
6161(define_insn "sibcall_compact"
6162 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6163 (match_operand 1 "" ""))
6164 (return)
e69d1422 6165 (use (match_operand:SI 2 "register_operand" "z,x"))
fa5322fa
AO
6166 (use (reg:SI R1_REG))
6167 (use (reg:PSI FPSCR_REG))
6168 ;; We want to make sure the `x' above will only match MACH_REG
6169 ;; because sibcall_epilogue may clobber MACL_REG.
6170 (clobber (reg:SI MACL_REG))]
6171 "TARGET_SHCOMPACT"
6172 "@
6173 jmp @%0%#
6174 jmp @%0\\n sts %2, r0"
6175 [(set_attr "needs_delay_slot" "yes,no")
6176 (set_attr "length" "2,4")
6177 (set (attr "fp_mode") (const_string "single"))
6178 (set_attr "type" "jump_ind")])
6179
6180(define_insn "sibcall_media"
6181 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6182 (match_operand 1 "" ""))
7d73a2ba 6183 (use (reg:SI PR_MEDIA_REG))
fa5322fa
AO
6184 (return)]
6185 "TARGET_SHMEDIA"
2ad65b0e
SC
6186 "blink %0, r63"
6187 [(set_attr "type" "jump_media")])
fa5322fa
AO
6188
6189(define_expand "sibcall"
6190 [(parallel
6191 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6192 (match_operand 1 "" ""))
6193 (match_operand 2 "" "")
6194 (use (reg:PSI FPSCR_REG))
6195 (return)])]
6196 ""
6197 "
6198{
6199 if (TARGET_SHMEDIA)
6200 {
6201 operands[0] = XEXP (operands[0], 0);
6202 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6203 {
675ff4c7 6204 if (! SYMBOL_REF_LOCAL_P (operands[0]))
fa5322fa
AO
6205 {
6206 rtx reg = gen_reg_rtx (Pmode);
52702ae1 6207
fa5322fa
AO
6208 /* We must not use GOTPLT for sibcalls, because PIC_REG
6209 must be restored before the PLT code gets to run. */
6210 emit_insn (gen_symGOT2reg (reg, operands[0]));
6211 operands[0] = reg;
6212 }
6213 else
6214 {
6215 operands[0] = gen_sym2PIC (operands[0]);
6216 PUT_MODE (operands[0], Pmode);
6217 }
6218 }
6219 if (GET_MODE (operands[0]) == SImode)
6220 {
6221 if (GET_CODE (operands[0]) == REG)
6222 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6223 else if (GET_CODE (operands[0]) == SUBREG)
6224 {
6225 operands[0] = SUBREG_REG (operands[0]);
6226 if (GET_MODE (operands[0]) != DImode)
6227 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6228 }
6229 else
6230 {
6231 operands[0] = shallow_copy_rtx (operands[0]);
6232 PUT_MODE (operands[0], DImode);
6233 }
6234 }
6235 if (! target_reg_operand (operands[0], DImode))
6236 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6237 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6238 DONE;
6239 }
6240 else if (TARGET_SHCOMPACT && operands[2]
6241 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6242 {
6243 rtx cookie_rtx = operands[2];
6244 long cookie = INTVAL (cookie_rtx);
6245 rtx func = XEXP (operands[0], 0);
6246 rtx mach, r1;
6247
6248 if (flag_pic)
6249 {
675ff4c7 6250 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6251 {
6252 rtx reg = gen_reg_rtx (Pmode);
6253
6254 emit_insn (gen_symGOT2reg (reg, func));
6255 func = reg;
6256 }
6257 else
6258 func = legitimize_pic_address (func, Pmode, 0);
6259 }
5db5a888 6260
fa5322fa
AO
6261 /* FIXME: if we could tell whether all argument registers are
6262 already taken, we could decide whether to force the use of
6263 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6264 simple way to tell. We could use the CALL_COOKIE, but we
6265 can't currently tell a register used for regular argument
6266 passing from one that is unused. If we leave it up to reload
6267 to decide which register to use, it seems to always choose
6268 R0_REG, which leaves no available registers in SIBCALL_REGS
6269 to hold the address of the trampoline. */
6270 mach = gen_rtx_REG (SImode, MACH_REG);
6271 r1 = gen_rtx_REG (SImode, R1_REG);
6272
6273 /* Since such a call function may use all call-clobbered
6274 registers, we force a mode switch earlier, so that we don't
6275 run out of registers when adjusting fpscr for the call. */
6276 emit_insn (gen_force_mode_for_call ());
6277
90534361 6278 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6279 if (flag_pic)
6280 {
6281 rtx reg = gen_reg_rtx (Pmode);
6282
6283 emit_insn (gen_symGOT2reg (reg, operands[0]));
6284 operands[0] = reg;
6285 }
6286 operands[0] = force_reg (SImode, operands[0]);
6287
6288 /* We don't need a return trampoline, since the callee will
6289 return directly to the upper caller. */
6290 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6291 {
6292 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6293 cookie_rtx = GEN_INT (cookie);
6294 }
6295
6296 emit_move_insn (mach, func);
6297 emit_move_insn (r1, cookie_rtx);
6298
6299 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6300 DONE;
6301 }
6302 else if (TARGET_SHCOMPACT && flag_pic
6303 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 6304 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
6305 {
6306 rtx reg = gen_reg_rtx (Pmode);
6307
6308 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6309 XEXP (operands[0], 0) = reg;
6310 }
cb51ecd2 6311 if (flag_pic && TARGET_SH2
5db5a888
AO
6312 && GET_CODE (operands[0]) == MEM
6313 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6314 /* The PLT needs the PIC register, but the epilogue would have
6315 to restore it, so we can only use PC-relative PIC calls for
6316 static functions. */
675ff4c7 6317 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5db5a888
AO
6318 {
6319 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6320 DONE;
6321 }
6322 else
6323 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
fa5322fa
AO
6324
6325 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6326 DONE;
5db5a888
AO
6327}")
6328
6329(define_expand "sibcall_value"
6330 [(set (match_operand 0 "" "")
6331 (call (match_operand 1 "" "")
fa5322fa
AO
6332 (match_operand 2 "" "")))
6333 (match_operand 3 "" "")]
5db5a888
AO
6334 ""
6335 "
6336{
fa5322fa 6337 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5db5a888
AO
6338 DONE;
6339}")
6340
fa5322fa
AO
6341(define_insn "call_value_pop_compact"
6342 [(set (match_operand 0 "" "=rf")
6343 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6344 (match_operand 2 "" "")))
6345 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6346 (match_operand 4 "immediate_operand" "n")))
6347 (match_operand 3 "immediate_operand" "n")
6348 (use (reg:SI R0_REG))
6349 (use (reg:SI R1_REG))
6350 (use (reg:PSI FPSCR_REG))
6351 (clobber (reg:SI PR_REG))]
6352 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6353 "jsr @%1%#"
6354 [(set_attr "type" "call")
6355 (set (attr "fp_mode")
6356 (if_then_else (eq_attr "fpu_single" "yes")
6357 (const_string "single") (const_string "double")))
6358 (set_attr "needs_delay_slot" "yes")])
6359
6360(define_insn "call_value_pop_compact_rettramp"
6361 [(set (match_operand 0 "" "=rf")
6362 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6363 (match_operand 2 "" "")))
6364 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6365 (match_operand 4 "immediate_operand" "n")))
6366 (match_operand 3 "immediate_operand" "n")
6367 (use (reg:SI R0_REG))
6368 (use (reg:SI R1_REG))
6369 (use (reg:PSI FPSCR_REG))
6370 (clobber (reg:SI R10_REG))
6371 (clobber (reg:SI PR_REG))]
6372 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6373 "jsr @%1%#"
6374 [(set_attr "type" "call")
6375 (set (attr "fp_mode")
6376 (if_then_else (eq_attr "fpu_single" "yes")
6377 (const_string "single") (const_string "double")))
6378 (set_attr "needs_delay_slot" "yes")])
6379
6380(define_expand "call_value_pop"
6381 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6382 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6383 (match_operand 2 "" "")))
6384 (match_operand 3 "" "")
6385 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6386 (match_operand 4 "" "")))])]
6387 "TARGET_SHCOMPACT"
6388 "
6389{
6390 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6391 {
6392 rtx cookie_rtx = operands[3];
6393 long cookie = INTVAL (cookie_rtx);
6394 rtx func = XEXP (operands[1], 0);
6395 rtx r0, r1;
6396
6397 if (flag_pic)
6398 {
675ff4c7 6399 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6400 {
6401 rtx reg = gen_reg_rtx (Pmode);
6402
6403 emit_insn (gen_symGOTPLT2reg (reg, func));
6404 func = reg;
6405 }
6406 else
6407 func = legitimize_pic_address (func, Pmode, 0);
6408 }
6409
6410 r0 = gen_rtx_REG (SImode, R0_REG);
6411 r1 = gen_rtx_REG (SImode, R1_REG);
6412
6413 /* Since such a call function may use all call-clobbered
6414 registers, we force a mode switch earlier, so that we don't
6415 run out of registers when adjusting fpscr for the call. */
6416 emit_insn (gen_force_mode_for_call ());
6417
90534361 6418 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6419 if (flag_pic)
6420 {
6421 rtx reg = gen_reg_rtx (Pmode);
6422
6423 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6424 operands[1] = reg;
6425 }
6426 operands[1] = force_reg (SImode, operands[1]);
6427
6428 emit_move_insn (r0, func);
6429 emit_move_insn (r1, cookie_rtx);
6430
6431 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6432 emit_call_insn (gen_call_value_pop_compact_rettramp
6433 (operands[0], operands[1], operands[2],
6434 operands[3], operands[4]));
6435 else
6436 emit_call_insn (gen_call_value_pop_compact
6437 (operands[0], operands[1], operands[2],
6438 operands[3], operands[4]));
6439
6440 DONE;
6441 }
6442
6443 abort ();
6444}")
6445
5db5a888
AO
6446(define_expand "sibcall_epilogue"
6447 [(return)]
6448 ""
6449 "
6450{
6451 sh_expand_epilogue ();
fa5322fa
AO
6452 if (TARGET_SHCOMPACT)
6453 {
6454 rtx insn, set;
6455
6456 /* If epilogue clobbers r0, preserve it in macl. */
6457 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6458 if ((set = single_set (insn))
6459 && GET_CODE (SET_DEST (set)) == REG
6460 && REGNO (SET_DEST (set)) == R0_REG)
6461 {
6462 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6463 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6464 rtx i;
6465
6466 /* We can't tell at this point whether the sibcall is a
6467 sibcall_compact and, if it is, whether it uses r0 or
6468 mach as operand 2, so let the instructions that
6469 preserve r0 be optimized away if r0 turns out to be
6470 dead. */
6471 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6472 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6473 REG_NOTES (i));
6474 i = emit_move_insn (r0, tmp);
6475 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6476 REG_NOTES (i));
6477 break;
6478 }
6479 }
5db5a888
AO
6480 DONE;
6481}")
6482
fa5322fa 6483(define_insn "indirect_jump_compact"
bc45ade3 6484 [(set (pc)
aa684c94 6485 (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 6486 "TARGET_SH1"
b9654711 6487 "jmp @%0%#"
1245df60
R
6488 [(set_attr "needs_delay_slot" "yes")
6489 (set_attr "type" "jump_ind")])
a1a0806a 6490
fa5322fa
AO
6491(define_expand "indirect_jump"
6492 [(set (pc)
6493 (match_operand 0 "register_operand" ""))]
6494 ""
6495 "
6496{
6497 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6498 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6499}")
6500
1245df60 6501;; The use of operand 1 / 2 helps us distinguish case table jumps
f1ffca1c
JW
6502;; which can be present in structured code from indirect jumps which can not
6503;; be present in structured code. This allows -fprofile-arcs to work.
6504
1245df60
R
6505;; For SH1 processors.
6506(define_insn "casesi_jump_1"
f1ffca1c 6507 [(set (pc)
1245df60 6508 (match_operand:SI 0 "register_operand" "r"))
f1ffca1c 6509 (use (label_ref (match_operand 1 "" "")))]
fa5322fa 6510 "TARGET_SH1"
1245df60
R
6511 "jmp @%0%#"
6512 [(set_attr "needs_delay_slot" "yes")
6513 (set_attr "type" "jump_ind")])
6514
6515;; For all later processors.
6516(define_insn "casesi_jump_2"
6517 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
eb3881bf 6518 (label_ref (match_operand 1 "" ""))))
1245df60 6519 (use (label_ref (match_operand 2 "" "")))]
e6dfd05f
AO
6520 "TARGET_SH2
6521 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
1245df60
R
6522 "braf %0%#"
6523 [(set_attr "needs_delay_slot" "yes")
6524 (set_attr "type" "jump_ind")])
6525
fa5322fa
AO
6526(define_insn "casesi_jump_media"
6527 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6528 (use (label_ref (match_operand 1 "" "")))]
6529 "TARGET_SHMEDIA"
2ad65b0e
SC
6530 "blink %0, r63"
6531 [(set_attr "type" "jump_media")])
52702ae1 6532
a1a0806a
JW
6533;; Call subroutine returning any type.
6534;; ??? This probably doesn't work.
6535
6536(define_expand "untyped_call"
6537 [(parallel [(call (match_operand 0 "" "")
6538 (const_int 0))
6539 (match_operand 1 "" "")
6540 (match_operand 2 "" "")])]
3a8699c7 6541 "TARGET_SH2E || TARGET_SHMEDIA"
a1a0806a
JW
6542 "
6543{
6544 int i;
6545
fa5322fa 6546 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
a1a0806a
JW
6547
6548 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6549 {
6550 rtx set = XVECEXP (operands[2], 0, i);
6551 emit_move_insn (SET_DEST (set), SET_SRC (set));
6552 }
6553
6554 /* The optimizer does not know that the call sets the function value
6555 registers we stored in the result block. We avoid problems by
6556 claiming that all hard registers are used and clobbered at this
6557 point. */
6558 emit_insn (gen_blockage ());
6559
6560 DONE;
6561}")
bc45ade3
SC
6562\f
6563;; ------------------------------------------------------------------------
6564;; Misc insns
6565;; ------------------------------------------------------------------------
6566
51bd623f 6567(define_insn "dect"
4773afa4 6568 [(set (reg:SI T_REG)
aff48e32
JR
6569 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6570 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
51bd623f 6571 "TARGET_SH2"
1245df60
R
6572 "dt %0"
6573 [(set_attr "type" "arith")])
bc45ade3
SC
6574
6575(define_insn "nop"
6576 [(const_int 0)]
6577 ""
51bd623f 6578 "nop")
0d7e008e 6579
1245df60
R
6580;; Load address of a label. This is only generated by the casesi expand,
6581;; and by machine_dependent_reorg (fixing up fp moves).
6582;; This must use unspec, because this only works for labels that are
6583;; within range,
0d7e008e
SC
6584
6585(define_insn "mova"
4773afa4 6586 [(set (reg:SI R0_REG)
e69d1422 6587 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
fa5322fa 6588 "TARGET_SH1"
0d7e008e 6589 "mova %O0,r0"
1245df60
R
6590 [(set_attr "in_delay_slot" "no")
6591 (set_attr "type" "arith")])
0d7e008e 6592
18dbd950 6593;; machine_dependent_reorg will make this a `mova'.
43c05634
AO
6594(define_insn "mova_const"
6595 [(set (reg:SI R0_REG)
e69d1422 6596 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
fa5322fa 6597 "TARGET_SH1"
43c05634
AO
6598 "#"
6599 [(set_attr "in_delay_slot" "no")
6600 (set_attr "type" "arith")])
6601
1a66cd67 6602(define_expand "GOTaddr2picreg"
4773afa4 6603 [(set (reg:SI R0_REG)
e69d1422
R
6604 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6605 UNSPEC_MOVA))
615cd49b 6606 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
4773afa4 6607 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
1a66cd67
AO
6608 "" "
6609{
fa5322fa 6610 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
1a66cd67 6611 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
fa5322fa
AO
6612
6613 if (TARGET_SH5)
6614 operands[1] = gen_datalabel_ref (operands[1]);
6615
6616 if (TARGET_SHMEDIA)
6617 {
6618 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6619 rtx dipic = operands[0];
8e831557 6620 rtx lab = PATTERN (gen_call_site ());
fa5322fa
AO
6621 rtx insn, equiv;
6622
6623 equiv = operands[1];
6624 operands[1] = gen_rtx_MINUS (DImode,
6625 operands[1],
6626 gen_rtx_CONST
6627 (DImode,
6628 gen_rtx_MINUS (DImode,
6629 gen_rtx_CONST (DImode,
6630 lab),
6631 pc_rtx)));
6632 operands[1] = gen_sym2PIC (operands[1]);
6633 PUT_MODE (operands[1], DImode);
6634
6635 if (GET_MODE (dipic) != DImode)
6636 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6637
6638 if (TARGET_SHMEDIA64)
6639 emit_insn (gen_movdi_const (dipic, operands[1]));
6640 else
6641 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6642
6643 emit_insn (gen_ptrel (tr, dipic, lab));
6644
6645 if (GET_MODE (operands[0]) != GET_MODE (tr))
90534361 6646 tr = gen_lowpart (GET_MODE (operands[0]), tr);
fa5322fa
AO
6647
6648 insn = emit_move_insn (operands[0], tr);
52702ae1 6649
fa5322fa
AO
6650 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6651 REG_NOTES (insn));
6652
6653 DONE;
6654 }
1a66cd67
AO
6655}
6656")
6657
fa5322fa 6658(define_insn "*ptb"
b6d33983 6659 [(set (match_operand:DI 0 "target_reg_operand" "=b")
735cb76e 6660 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
fa5322fa
AO
6661 UNSPEC_DATALABEL)))]
6662 "TARGET_SHMEDIA && flag_pic
735cb76e 6663 && EXTRA_CONSTRAINT_Csy (operands[1])"
fa5322fa 6664 "ptb/u datalabel %1, %0"
2ad65b0e 6665 [(set_attr "type" "pt_media")
fa5322fa
AO
6666 (set_attr "length" "*")])
6667
6668(define_insn "ptrel"
e69d1422
R
6669 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6670 (plus:DI (match_operand:DI 1 "register_operand" "r")
fa5322fa
AO
6671 (pc)))
6672 (match_operand:DI 2 "" "")]
6673 "TARGET_SHMEDIA"
6674 "%O2: ptrel/u %1, %0"
2ad65b0e 6675 [(set_attr "type" "ptabs_media")])
fa5322fa 6676
001643af
KK
6677(define_expand "builtin_setjmp_receiver"
6678 [(match_operand 0 "" "")]
6679 "flag_pic"
6680 "
6681{
6682 emit_insn (gen_GOTaddr2picreg ());
6683 DONE;
6684}")
6685
2d01e445
AO
6686(define_expand "call_site"
6687 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
fa5322fa 6688 "TARGET_SH1"
2d01e445
AO
6689 "
6690{
6691 static HOST_WIDE_INT i = 0;
6692 operands[0] = GEN_INT (i);
6693 i++;
6694}")
6695
1a66cd67
AO
6696(define_expand "sym_label2reg"
6697 [(set (match_operand:SI 0 "" "")
a4f76ef9
AO
6698 (const:SI (minus:SI
6699 (const:SI
6700 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6701 (const:SI
6702 (plus:SI
6703 (match_operand:SI 2 "" "")
6704 (const_int 2))))))]
fa5322fa 6705 "TARGET_SH1" "")
1a66cd67 6706
e1d71275
AO
6707(define_expand "symGOT_load"
6708 [(set (match_dup 2) (match_operand 1 "" ""))
6709 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6710 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6711 ""
6712 "
6713{
6714 rtx insn;
6715
6716 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6717 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6718
fa5322fa
AO
6719 if (TARGET_SHMEDIA)
6720 {
6721 rtx reg = operands[2];
52702ae1 6722
fa5322fa
AO
6723 if (GET_MODE (reg) != DImode)
6724 reg = gen_rtx_SUBREG (DImode, reg, 0);
52702ae1 6725
fa5322fa
AO
6726 if (flag_pic > 1)
6727 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6728 else
6729 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6730 }
6731 else
6732 emit_move_insn (operands[2], operands[1]);
e1d71275
AO
6733
6734 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6735 operands[2],
6736 gen_rtx_REG (Pmode, PIC_REG)));
6737
6738 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6739
6740 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6741 0), 0, 0),
6742 REG_NOTES (insn));
52702ae1 6743
e1d71275
AO
6744 DONE;
6745}")
6746
6747(define_expand "sym2GOT"
6748 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6749 ""
6750 "")
6751
1a66cd67 6752(define_expand "symGOT2reg"
e1d71275 6753 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6754 ""
6755 "
6756{
e1d71275
AO
6757 rtx gotsym, insn;
6758
6759 gotsym = gen_sym2GOT (operands[1]);
6760 PUT_MODE (gotsym, Pmode);
6761 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6762
6763 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6764
6765 DONE;
1a66cd67
AO
6766}")
6767
fa5322fa
AO
6768(define_expand "sym2GOTPLT"
6769 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6770 ""
6771 "")
6772
6773(define_expand "symGOTPLT2reg"
6774 [(match_operand 0 "" "") (match_operand 1 "" "")]
6775 ""
6776 "
6777{
6778 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6779 DONE;
6780}")
6781
e1d71275
AO
6782(define_expand "sym2GOTOFF"
6783 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6784 ""
6785 "")
6786
1a66cd67 6787(define_expand "symGOTOFF2reg"
e1d71275 6788 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6789 ""
6790 "
6791{
e1d71275
AO
6792 rtx gotoffsym, insn;
6793 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6794
6795 gotoffsym = gen_sym2GOTOFF (operands[1]);
6796 PUT_MODE (gotoffsym, Pmode);
6797 emit_move_insn (t, gotoffsym);
6798 insn = emit_move_insn (operands[0],
6799 gen_rtx_PLUS (Pmode, t,
6800 gen_rtx_REG (Pmode, PIC_REG)));
6801
6802 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6803 REG_NOTES (insn));
6804
6805 DONE;
1a66cd67
AO
6806}")
6807
6808(define_expand "symPLT_label2reg"
6809 [(set (match_operand:SI 0 "" "")
e1d71275
AO
6810 (const:SI (minus:SI
6811 (const:SI
6812 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6813 (const:SI
6814 (minus:SI
6815 (const:SI (plus:SI
6816 (match_operand:SI 2 "" "")
6817 (const_int 2)))
6818 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6915629f
AO
6819 ;; Even though the PIC register is not really used by the call
6820 ;; sequence in which this is expanded, the PLT code assumes the PIC
6821 ;; register is set, so we must not skip its initialization. Since
6822 ;; we only use this expand as part of calling sequences, and never
6823 ;; to take the address of a function, this is the best point to
6824 ;; insert the (use). Using the PLT to take the address of a
6825 ;; function would be wrong, not only because the PLT entry could
6826 ;; then be called from a function that doesn't initialize the PIC
6827 ;; register to the proper GOT, but also because pointers to the
6828 ;; same function might not compare equal, should they be set by
6829 ;; different shared libraries.
6830 (use (reg:SI PIC_REG))]
fa5322fa
AO
6831 "TARGET_SH1"
6832 "")
6833
6834(define_expand "sym2PIC"
6835 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6915629f
AO
6836 ""
6837 "")
1a66cd67 6838
463f02cd
KK
6839;; TLS code generation.
6840;; ??? this should be a define_insn_and_split
6841;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6842;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6843;; for details.
6844
6845(define_insn "tls_global_dynamic"
6846 [(set (match_operand:SI 0 "register_operand" "=&z")
6847 (unspec:SI [(match_operand:SI 1 "" "")]
6848 UNSPEC_TLSGD))
6849 (use (reg:PSI FPSCR_REG))
6850 (use (reg:SI PIC_REG))
6851 (clobber (reg:SI PR_REG))
6852 (clobber (scratch:SI))]
6853 "TARGET_SH1"
6854 "*
6855{
6856 return \"\\
6857mov.l\\t1f,r4\\n\\
6858\\tmova\\t2f,r0\\n\\
6859\\tmov.l\\t2f,r1\\n\\
6860\\tadd\\tr0,r1\\n\\
6861\\tjsr\\t@r1\\n\\
6862\\tadd\\tr12,r4\\n\\
6863\\tbra\\t3f\\n\\
6864\\tnop\\n\\
6865\\t.align\\t2\\n\\
68661:\\t.long\\t%a1@TLSGD\\n\\
68672:\\t.long\\t__tls_get_addr@PLT\\n\\
68683:\";
6869}"
6870 [(set_attr "type" "tls_load")
6871 (set_attr "length" "26")])
6872
6873(define_insn "tls_local_dynamic"
6874 [(set (match_operand:SI 0 "register_operand" "=&z")
6875 (unspec:SI [(match_operand:SI 1 "" "")]
6876 UNSPEC_TLSLDM))
6877 (use (reg:PSI FPSCR_REG))
6878 (use (reg:SI PIC_REG))
6879 (clobber (reg:SI PR_REG))
6880 (clobber (scratch:SI))]
6881 "TARGET_SH1"
6882 "*
6883{
6884 return \"\\
6885mov.l\\t1f,r4\\n\\
6886\\tmova\\t2f,r0\\n\\
6887\\tmov.l\\t2f,r1\\n\\
6888\\tadd\\tr0,r1\\n\\
6889\\tjsr\\t@r1\\n\\
6890\\tadd\\tr12,r4\\n\\
6891\\tbra\\t3f\\n\\
6892\\tnop\\n\\
6893\\t.align\\t2\\n\\
68941:\\t.long\\t%a1@TLSLDM\\n\\
68952:\\t.long\\t__tls_get_addr@PLT\\n\\
68963:\";
6897}"
6898 [(set_attr "type" "tls_load")
6899 (set_attr "length" "26")])
6900
6901(define_expand "sym2DTPOFF"
6902 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6903 ""
6904 "")
6905
6906(define_expand "symDTPOFF2reg"
6907 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6908 ""
6909 "
6910{
6911 rtx dtpoffsym, insn;
6912 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6913
6914 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6915 PUT_MODE (dtpoffsym, Pmode);
6916 emit_move_insn (t, dtpoffsym);
6917 insn = emit_move_insn (operands[0],
6918 gen_rtx_PLUS (Pmode, t, operands[2]));
6919 DONE;
6920}")
6921
6922(define_expand "sym2GOTTPOFF"
6923 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6924 ""
6925 "")
6926
6927(define_insn "tls_initial_exec"
6928 [(set (match_operand:SI 0 "register_operand" "=&r")
6929 (unspec:SI [(match_operand:SI 1 "" "")]
6930 UNSPEC_TLSIE))
6931 (use (reg:SI GBR_REG))
6932 (use (reg:SI PIC_REG))
6933 (clobber (reg:SI R0_REG))]
6934 ""
6935 "*
6936{
6937 return \"\\
6938mov.l\\t1f,r0\\n\\
6939\\tstc\\tgbr,%0\\n\\
6940\\tmov.l\\t@(r0,r12),r0\\n\\
6941\\tbra\\t2f\\n\\
6942\\tadd\\tr0,%0\\n\\
6943\\t.align\\t2\\n\\
69441:\\t.long\\t%a1\\n\\
69452:\";
6946}"
6947 [(set_attr "type" "tls_load")
6948 (set_attr "length" "16")])
6949
6950(define_expand "sym2TPOFF"
6951 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6952 ""
6953 "")
6954
6955(define_expand "symTPOFF2reg"
6956 [(match_operand 0 "" "") (match_operand 1 "" "")]
6957 ""
6958 "
6959{
6960 rtx tpoffsym, insn;
6961
6962 tpoffsym = gen_sym2TPOFF (operands[1]);
6963 PUT_MODE (tpoffsym, Pmode);
6964 insn = emit_move_insn (operands[0], tpoffsym);
6965 DONE;
6966}")
6967
6968(define_insn "load_gbr"
6969 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6970 (use (reg:SI GBR_REG))]
6971 ""
6972 "stc gbr,%0"
6973 [(set_attr "type" "tls_load")])
6974
0d7e008e
SC
6975;; case instruction for switch statements.
6976
6977;; Operand 0 is index
6978;; operand 1 is the minimum bound
6979;; operand 2 is the maximum bound - minimum bound + 1
6980;; operand 3 is CODE_LABEL for the table;
6981;; operand 4 is the CODE_LABEL to go to if index out of range.
6982
6983(define_expand "casesi"
1245df60
R
6984 [(match_operand:SI 0 "arith_reg_operand" "")
6985 (match_operand:SI 1 "arith_reg_operand" "")
6986 (match_operand:SI 2 "arith_reg_operand" "")
6987 (match_operand 3 "" "") (match_operand 4 "" "")]
6988 ""
6989 "
6990{
6991 rtx reg = gen_reg_rtx (SImode);
6992 rtx reg2 = gen_reg_rtx (SImode);
fa5322fa
AO
6993 if (TARGET_SHMEDIA)
6994 {
6995 rtx reg = gen_reg_rtx (DImode);
6996 rtx reg2 = gen_reg_rtx (DImode);
6997 rtx reg3 = gen_reg_rtx (DImode);
6998 rtx reg4 = gen_reg_rtx (DImode);
6999 rtx reg5 = gen_reg_rtx (DImode);
7000
7001 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7002 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7003 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7004
7005 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7006 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7007 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7008 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7009 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7010 (DImode, operands[3])));
7011 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7012 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7013 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7014 emit_barrier ();
7015 DONE;
7016 }
1245df60
R
7017 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7018 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7019 /* If optimizing, casesi_worker depends on the mode of the instruction
7020 before label it 'uses' - operands[3]. */
7021 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7022 reg));
7023 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7024 if (TARGET_SH2)
eb3881bf 7025 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
1245df60 7026 else
eb3881bf 7027 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
1245df60
R
7028 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7029 operands[3], but to lab. We will fix this up in
7030 machine_dependent_reorg. */
7031 emit_barrier ();
7032 DONE;
7033}")
7034
7035(define_expand "casesi_0"
7036 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7037 (set (match_dup 4) (minus:SI (match_dup 4)
0d7e008e 7038 (match_operand:SI 1 "arith_operand" "")))
4773afa4 7039 (set (reg:SI T_REG)
1245df60 7040 (gtu:SI (match_dup 4)
22e1ebf1 7041 (match_operand:SI 2 "arith_reg_operand" "")))
0d7e008e 7042 (set (pc)
4773afa4 7043 (if_then_else (ne (reg:SI T_REG)
7c225e88 7044 (const_int 0))
1245df60
R
7045 (label_ref (match_operand 3 "" ""))
7046 (pc)))]
fa5322fa 7047 "TARGET_SH1"
1245df60 7048 "")
0d7e008e 7049
1245df60
R
7050;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7051;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7052;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7053
7054(define_insn "casesi_worker_0"
7055 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422 7056 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
4773afa4 7057 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7058 (clobber (match_scratch:SI 3 "=X,1"))
7059 (clobber (match_scratch:SI 4 "=&z,z"))]
fa5322fa 7060 "TARGET_SH1"
1245df60
R
7061 "#")
7062
7063(define_split
7064 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
7065 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7066 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7067 (clobber (match_scratch:SI 3 ""))
7068 (clobber (match_scratch:SI 4 ""))]
fa5322fa 7069 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
e69d1422 7070 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 7071 (parallel [(set (match_dup 0)
e69d1422
R
7072 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7073 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 7074 (clobber (match_dup 3))])
4773afa4 7075 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
b6d33983 7076 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
7077
7078(define_split
7079 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
7080 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7081 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7082 (clobber (match_scratch:SI 3 ""))
7083 (clobber (match_scratch:SI 4 ""))]
7084 "TARGET_SH2 && reload_completed"
e69d1422 7085 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 7086 (parallel [(set (match_dup 0)
615cd49b 7087 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
e69d1422 7088 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 7089 (clobber (match_dup 3))])]
b6d33983 7090 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
7091
7092(define_insn "*casesi_worker"
7093 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422
R
7094 (unspec:SI [(reg:SI R0_REG)
7095 (match_operand:SI 1 "register_operand" "0,r")
7096 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60 7097 (clobber (match_scratch:SI 3 "=X,1"))]
fa5322fa 7098 "TARGET_SH1"
4fdd1f85 7099 "*
ffae286a 7100{
33f7f353
JR
7101 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7102
7103 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7104 abort ();
7105
7106 switch (GET_MODE (diff_vec))
1245df60
R
7107 {
7108 case SImode:
7109 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7110 case HImode:
7111 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7112 case QImode:
33f7f353 7113 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
1245df60 7114 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
33f7f353 7115 return \"mov.b @(r0,%1),%0\";
1245df60
R
7116 default:
7117 abort ();
7118 }
ffae286a 7119}"
51bd623f 7120 [(set_attr "length" "4")])
0d7e008e 7121
fa5322fa 7122(define_insn "casesi_shift_media"
51214775
R
7123 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7124 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7125 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7126 UNSPEC_CASESI)))]
fa5322fa
AO
7127 "TARGET_SHMEDIA"
7128 "*
7129{
7130 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7131
7132 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7133 abort ();
7134
7135 switch (GET_MODE (diff_vec))
7136 {
7137 case SImode:
7138 return \"shlli %1, 2, %0\";
7139 case HImode:
7140 return \"shlli %1, 1, %0\";
7141 case QImode:
7142 if (rtx_equal_p (operands[0], operands[1]))
7143 return \"\";
7144 return \"add %1, r63, %0\";
7145 default:
7146 abort ();
7147 }
2ad65b0e
SC
7148}"
7149 [(set_attr "type" "arith_media")])
fa5322fa
AO
7150
7151(define_insn "casesi_load_media"
7152 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7153 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7154 (match_operand 2 "arith_reg_operand" "r")
7155 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7156 "TARGET_SHMEDIA"
7157 "*
7158{
7159 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7160
7161 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7162 abort ();
7163
7164 switch (GET_MODE (diff_vec))
7165 {
7166 case SImode:
7167 return \"ldx.l %1, %2, %0\";
7168 case HImode:
7169#if 0
7170 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7171 return \"ldx.uw %1, %2, %0\";
7172#endif
7173 return \"ldx.w %1, %2, %0\";
7174 case QImode:
7175 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7176 return \"ldx.ub %1, %2, %0\";
7177 return \"ldx.b %1, %2, %0\";
7178 default:
7179 abort ();
7180 }
2ad65b0e
SC
7181}"
7182 [(set_attr "type" "load_media")])
fa5322fa 7183
afbc2905
R
7184(define_expand "return"
7185 [(return)]
7186 "reload_completed && ! sh_need_epilogue ()"
fa5322fa
AO
7187 "
7188{
7189 if (TARGET_SHMEDIA)
7190 {
7191 emit_jump_insn (gen_return_media ());
7192 DONE;
7193 }
7194
7195 if (TARGET_SHCOMPACT
7196 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7197 {
7198 emit_jump_insn (gen_shcompact_return_tramp ());
7199 DONE;
7200 }
7201}")
afbc2905
R
7202
7203(define_insn "*return_i"
0d7e008e 7204 [(return)]
fa5322fa
AO
7205 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7206 && (current_function_args_info.call_cookie
7207 & CALL_COOKIE_RET_TRAMP (1)))
7208 && reload_completed"
961c4780 7209 "%@ %#"
51bd623f
JW
7210 [(set_attr "type" "return")
7211 (set_attr "needs_delay_slot" "yes")])
b9654711 7212
fa5322fa
AO
7213(define_expand "shcompact_return_tramp"
7214 [(return)]
7215 "TARGET_SHCOMPACT
7216 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7217 "
7218{
7219 rtx reg = gen_rtx_REG (Pmode, R0_REG);
90534361 7220 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
fa5322fa
AO
7221
7222 if (flag_pic)
7223 emit_insn (gen_symGOTPLT2reg (reg, sym));
7224 else
7225 emit_move_insn (reg, sym);
7226
7227 emit_jump_insn (gen_shcompact_return_tramp_i ());
7228 DONE;
7229}")
7230
7231(define_insn "shcompact_return_tramp_i"
7232 [(parallel [(return) (use (reg:SI R0_REG))])]
7233 "TARGET_SHCOMPACT
7234 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7235 "jmp @r0%#"
7236 [(set_attr "type" "jump_ind")
7237 (set_attr "needs_delay_slot" "yes")])
7238
7239(define_insn "return_media_i"
7240 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7241 "TARGET_SHMEDIA && reload_completed"
2ad65b0e
SC
7242 "blink %0, r63"
7243 [(set_attr "type" "jump_media")])
fa5322fa 7244
1bf93c14
R
7245(define_insn "return_media_rte"
7246 [(return)]
7247 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7248 "rte"
7249 [(set_attr "type" "jump_media")])
7250
fa5322fa
AO
7251(define_expand "return_media"
7252 [(return)]
7253 "TARGET_SHMEDIA && reload_completed"
7254 "
7255{
7256 int tr_regno = sh_media_register_for_return ();
7257 rtx tr;
7258
1bf93c14
R
7259 if (current_function_interrupt)
7260 {
7261 emit_jump_insn (gen_return_media_rte ());
7262 DONE;
7263 }
fa5322fa
AO
7264 if (tr_regno < 0)
7265 {
7266 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7267
fada1961
R
7268 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7269 abort ();
fa5322fa
AO
7270 tr_regno = TR0_REG;
7271 tr = gen_rtx_REG (DImode, tr_regno);
7272 emit_move_insn (tr, r18);
7273 }
7274 else
7275 tr = gen_rtx_REG (DImode, tr_regno);
7276
7277 emit_jump_insn (gen_return_media_i (tr));
7278 DONE;
7279}")
7280
7281(define_insn "shcompact_preserve_incoming_args"
e69d1422
R
7282 [(set (match_operand:SI 0 "register_operand" "+r")
7283 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
fa5322fa
AO
7284 "TARGET_SHCOMPACT"
7285 ""
7286 [(set_attr "length" "0")])
7287
7288(define_insn "shcompact_incoming_args"
e69d1422
R
7289 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7290 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7291 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7292 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7293 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7294 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7295 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7296 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa 7297 (set (mem:BLK (reg:SI MACL_REG))
e69d1422 7298 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa
AO
7299 (use (reg:SI R0_REG))
7300 (clobber (reg:SI R0_REG))
7301 (clobber (reg:SI MACL_REG))
7302 (clobber (reg:SI MACH_REG))
7303 (clobber (reg:SI PR_REG))]
7304 "TARGET_SHCOMPACT"
7305 "jsr @r0%#"
7306 [(set_attr "needs_delay_slot" "yes")])
7307
7308(define_insn "shmedia_save_restore_regs_compact"
7309 [(set (reg:SI SP_REG)
7310 (plus:SI (reg:SI SP_REG)
7311 (match_operand:SI 0 "immediate_operand" "i")))
7312 (use (reg:SI R0_REG))
7313 (clobber (reg:SI PR_REG))]
7314 "TARGET_SHCOMPACT
7315 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7316 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7317 "jsr @r0%#"
7318 [(set_attr "needs_delay_slot" "yes")])
7319
b9654711
SC
7320(define_expand "prologue"
7321 [(const_int 0)]
7322 ""
7323 "sh_expand_prologue (); DONE;")
7324
7325(define_expand "epilogue"
7326 [(return)]
7327 ""
fa5322fa
AO
7328 "
7329{
7330 sh_expand_epilogue ();
7331 emit_jump_insn (gen_return ());
7332 DONE;
7333}")
b9654711 7334
4977bab6 7335(define_expand "eh_return"
34dc173c 7336 [(use (match_operand 0 "register_operand" ""))]
4977bab6
ZW
7337 ""
7338{
34dc173c 7339 rtx tmp, ra = operands[0];
4977bab6
ZW
7340
7341 if (TARGET_SHMEDIA64)
7342 emit_insn (gen_eh_set_ra_di (ra));
7343 else
7344 emit_insn (gen_eh_set_ra_si (ra));
7345
4977bab6
ZW
7346 DONE;
7347})
7348
7349;; Clobber the return address on the stack. We can't expand this
7350;; until we know where it will be put in the stack frame.
7351
7352(define_insn "eh_set_ra_si"
7353 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7354 (clobber (match_scratch:SI 1 "=&r"))]
7355 "! TARGET_SHMEDIA64"
7356 "#")
7357
7358(define_insn "eh_set_ra_di"
7359 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7360 (clobber (match_scratch:DI 1 "=&r"))]
7361 "TARGET_SHMEDIA64"
7362 "#")
7363
7364(define_split
7365 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7366 (clobber (match_scratch 1 ""))]
7367 "reload_completed"
7368 [(const_int 0)]
7369 "
7370{
7371 sh_set_return_address (operands[0], operands[1]);
7372 DONE;
7373}")
7374
b9654711 7375(define_insn "blockage"
4773afa4 7376 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
b9654711
SC
7377 ""
7378 ""
7379 [(set_attr "length" "0")])
bc45ade3
SC
7380\f
7381;; ------------------------------------------------------------------------
7382;; Scc instructions
7383;; ------------------------------------------------------------------------
7384
0d7e008e 7385(define_insn "movt"
aa684c94 7386 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 7387 (eq:SI (reg:SI T_REG) (const_int 1)))]
fa5322fa 7388 "TARGET_SH1"
1245df60
R
7389 "movt %0"
7390 [(set_attr "type" "arith")])
bc45ade3
SC
7391
7392(define_expand "seq"
aa684c94 7393 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7394 (match_dup 1))]
7395 ""
fa5322fa
AO
7396 "
7397{
7398 if (TARGET_SHMEDIA)
7399 {
7400 if (GET_MODE (operands[0]) != DImode)
7401 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7402 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7403 if (sh_compare_op1 != const0_rtx)
7404 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7405 ? GET_MODE (sh_compare_op0)
7406 : GET_MODE (sh_compare_op1),
7407 sh_compare_op1);
7408
7409 switch (GET_MODE (sh_compare_op0))
7410 {
7411 case DImode:
7412 emit_insn (gen_cmpeqdi_media (operands[0],
7413 sh_compare_op0, sh_compare_op1));
7414 break;
7415
7416 case SFmode:
7417 if (! TARGET_SHMEDIA_FPU)
7418 FAIL;
7419 emit_insn (gen_cmpeqsf_media (operands[0],
7420 sh_compare_op0, sh_compare_op1));
7421 break;
7422
7423 case DFmode:
7424 if (! TARGET_SHMEDIA_FPU)
7425 FAIL;
7426 emit_insn (gen_cmpeqdf_media (operands[0],
7427 sh_compare_op0, sh_compare_op1));
7428 break;
7429
7430 default:
7431 FAIL;
7432 }
7433 DONE;
7434 }
7435 operands[1] = prepare_scc_operands (EQ);
7436}")
bc45ade3
SC
7437
7438(define_expand "slt"
aa684c94 7439 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7440 (match_dup 1))]
7441 ""
fa5322fa
AO
7442 "
7443{
7444 if (TARGET_SHMEDIA)
7445 {
7446 if (GET_MODE (operands[0]) != DImode)
7447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7448 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7449 if (sh_compare_op1 != const0_rtx)
7450 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7451 ? GET_MODE (sh_compare_op0)
7452 : GET_MODE (sh_compare_op1),
7453 sh_compare_op1);
7454
7455 switch (GET_MODE (sh_compare_op0))
7456 {
7457 case DImode:
7458 emit_insn (gen_cmpgtdi_media (operands[0],
7459 sh_compare_op1, sh_compare_op0));
7460 break;
7461
7462 case SFmode:
7463 if (! TARGET_SHMEDIA_FPU)
7464 FAIL;
7465 emit_insn (gen_cmpgtsf_media (operands[0],
7466 sh_compare_op1, sh_compare_op0));
7467 break;
7468
7469 case DFmode:
7470 if (! TARGET_SHMEDIA_FPU)
7471 FAIL;
7472 emit_insn (gen_cmpgtdf_media (operands[0],
7473 sh_compare_op1, sh_compare_op0));
7474 break;
7475
7476 default:
7477 FAIL;
7478 }
7479 DONE;
7480 }
7481 operands[1] = prepare_scc_operands (LT);
7482}")
bc45ade3
SC
7483
7484(define_expand "sle"
1245df60 7485 [(match_operand:SI 0 "arith_reg_operand" "")]
bc45ade3 7486 ""
45348d9e
JW
7487 "
7488{
1245df60 7489 rtx tmp = sh_compare_op0;
fa5322fa
AO
7490
7491 if (TARGET_SHMEDIA)
7492 {
7493 if (GET_MODE (operands[0]) != DImode)
7494 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7495 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7496 if (sh_compare_op1 != const0_rtx)
7497 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7498 ? GET_MODE (sh_compare_op0)
7499 : GET_MODE (sh_compare_op1),
7500 sh_compare_op1);
7501
7502 switch (GET_MODE (sh_compare_op0))
7503 {
7504 case DImode:
7505 {
7506 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7507
7508 emit_insn (gen_cmpgtdi_media (tmp,
7509 sh_compare_op0, sh_compare_op1));
7510 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7511 break;
7512 }
7513
7514 case SFmode:
7515 if (! TARGET_SHMEDIA_FPU)
7516 FAIL;
7517 emit_insn (gen_cmpgesf_media (operands[0],
7518 sh_compare_op1, sh_compare_op0));
7519 break;
7520
7521 case DFmode:
7522 if (! TARGET_SHMEDIA_FPU)
7523 FAIL;
7524 emit_insn (gen_cmpgedf_media (operands[0],
7525 sh_compare_op1, sh_compare_op0));
7526 break;
7527
7528 default:
7529 FAIL;
7530 }
7531 DONE;
7532 }
7533
1245df60
R
7534 sh_compare_op0 = sh_compare_op1;
7535 sh_compare_op1 = tmp;
7536 emit_insn (gen_sge (operands[0]));
7537 DONE;
45348d9e 7538}")
bc45ade3
SC
7539
7540(define_expand "sgt"
aa684c94 7541 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7542 (match_dup 1))]
7543 ""
fa5322fa
AO
7544 "
7545{
7546 if (TARGET_SHMEDIA)
7547 {
7548 if (GET_MODE (operands[0]) != DImode)
7549 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7550 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7551 if (sh_compare_op1 != const0_rtx)
7552 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7553 ? GET_MODE (sh_compare_op0)
7554 : GET_MODE (sh_compare_op1),
7555 sh_compare_op1);
7556
7557 switch (GET_MODE (sh_compare_op0))
7558 {
7559 case DImode:
7560 emit_insn (gen_cmpgtdi_media (operands[0],
7561 sh_compare_op0, sh_compare_op1));
7562 break;
7563
7564 case SFmode:
7565 if (! TARGET_SHMEDIA_FPU)
7566 FAIL;
7567 emit_insn (gen_cmpgtsf_media (operands[0],
7568 sh_compare_op0, sh_compare_op1));
7569 break;
7570
7571 case DFmode:
7572 if (! TARGET_SHMEDIA_FPU)
7573 FAIL;
7574 emit_insn (gen_cmpgtdf_media (operands[0],
7575 sh_compare_op0, sh_compare_op1));
7576 break;
7577
7578 default:
7579 FAIL;
7580 }
7581 DONE;
7582 }
7583 operands[1] = prepare_scc_operands (GT);
7584}")
bc45ade3
SC
7585
7586(define_expand "sge"
aa684c94 7587 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7588 (match_dup 1))]
7589 ""
45348d9e
JW
7590 "
7591{
fa5322fa
AO
7592 if (TARGET_SHMEDIA)
7593 {
7594 if (GET_MODE (operands[0]) != DImode)
7595 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7596 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7597 if (sh_compare_op1 != const0_rtx)
7598 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7599 ? GET_MODE (sh_compare_op0)
7600 : GET_MODE (sh_compare_op1),
7601 sh_compare_op1);
7602
7603 switch (GET_MODE (sh_compare_op0))
7604 {
7605 case DImode:
7606 {
7607 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7608
7609 emit_insn (gen_cmpgtdi_media (tmp,
7610 sh_compare_op1, sh_compare_op0));
7611 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7612 break;
7613 }
7614
7615 case SFmode:
7616 if (! TARGET_SHMEDIA_FPU)
7617 FAIL;
7618 emit_insn (gen_cmpgesf_media (operands[0],
7619 sh_compare_op0, sh_compare_op1));
7620 break;
7621
7622 case DFmode:
7623 if (! TARGET_SHMEDIA_FPU)
7624 FAIL;
7625 emit_insn (gen_cmpgedf_media (operands[0],
7626 sh_compare_op0, sh_compare_op1));
7627 break;
7628
7629 default:
7630 FAIL;
7631 }
7632 DONE;
7633 }
7634
225e4f43 7635 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e 7636 {
1245df60
R
7637 if (TARGET_IEEE)
7638 {
1245df60 7639 rtx lab = gen_label_rtx ();
225e4f43 7640 prepare_scc_operands (EQ);
1245df60 7641 emit_jump_insn (gen_branch_true (lab));
225e4f43 7642 prepare_scc_operands (GT);
1245df60
R
7643 emit_label (lab);
7644 emit_insn (gen_movt (operands[0]));
7645 }
7646 else
7647 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
45348d9e
JW
7648 DONE;
7649 }
7650 operands[1] = prepare_scc_operands (GE);
7651}")
bc45ade3
SC
7652
7653(define_expand "sgtu"
aa684c94 7654 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7655 (match_dup 1))]
7656 ""
fa5322fa
AO
7657 "
7658{
7659 if (TARGET_SHMEDIA)
7660 {
7661 if (GET_MODE (operands[0]) != DImode)
7662 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7663 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7664 if (sh_compare_op1 != const0_rtx)
7665 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7666 ? GET_MODE (sh_compare_op0)
7667 : GET_MODE (sh_compare_op1),
7668 sh_compare_op1);
7669
7670 emit_insn (gen_cmpgtudi_media (operands[0],
7671 sh_compare_op0, sh_compare_op1));
7672 DONE;
7673 }
7674 operands[1] = prepare_scc_operands (GTU);
7675}")
bc45ade3
SC
7676
7677(define_expand "sltu"
aa684c94 7678 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7679 (match_dup 1))]
7680 ""
fa5322fa
AO
7681 "
7682{
7683 if (TARGET_SHMEDIA)
7684 {
7685 if (GET_MODE (operands[0]) != DImode)
7686 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7687 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7688 if (sh_compare_op1 != const0_rtx)
7689 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7690 ? GET_MODE (sh_compare_op0)
7691 : GET_MODE (sh_compare_op1),
7692 sh_compare_op1);
7693
7694 emit_insn (gen_cmpgtudi_media (operands[0],
7695 sh_compare_op1, sh_compare_op0));
7696 DONE;
7697 }
7698 operands[1] = prepare_scc_operands (LTU);
7699}")
bc45ade3
SC
7700
7701(define_expand "sleu"
aa684c94 7702 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7703 (match_dup 1))]
7704 ""
fa5322fa
AO
7705 "
7706{
7707 if (TARGET_SHMEDIA)
7708 {
7709 rtx tmp;
7710
7711 if (GET_MODE (operands[0]) != DImode)
7712 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7713 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7714 if (sh_compare_op1 != const0_rtx)
7715 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7716 ? GET_MODE (sh_compare_op0)
7717 : GET_MODE (sh_compare_op1),
7718 sh_compare_op1);
7719
7720 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7721
7722 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7723 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7724
7725 DONE;
7726 }
7727 operands[1] = prepare_scc_operands (LEU);
7728}")
bc45ade3
SC
7729
7730(define_expand "sgeu"
aa684c94 7731 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7732 (match_dup 1))]
7733 ""
fa5322fa
AO
7734 "
7735{
7736 if (TARGET_SHMEDIA)
7737 {
7738 rtx tmp;
7739
7740 if (GET_MODE (operands[0]) != DImode)
7741 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7742 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7743 if (sh_compare_op1 != const0_rtx)
7744 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7745 ? GET_MODE (sh_compare_op0)
7746 : GET_MODE (sh_compare_op1),
7747 sh_compare_op1);
7748
7749 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7750
7751 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7752 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7753
7754 DONE;
7755 }
7756
7757 operands[1] = prepare_scc_operands (GEU);
7758}")
bc45ade3 7759
8bca10f4
JW
7760;; sne moves the complement of the T reg to DEST like this:
7761;; cmp/eq ...
7762;; mov #-1,temp
7763;; negc temp,dest
7764;; This is better than xoring compare result with 1 because it does
7765;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7766;; loop.
7767
bc45ade3 7768(define_expand "sne"
8bca10f4
JW
7769 [(set (match_dup 2) (const_int -1))
7770 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7771 (neg:SI (plus:SI (match_dup 1)
7772 (match_dup 2))))
4773afa4 7773 (set (reg:SI T_REG)
8bca10f4 7774 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
52702ae1 7775 (const_int 0)))])]
8bca10f4
JW
7776 ""
7777 "
7778{
fa5322fa
AO
7779 if (TARGET_SHMEDIA)
7780 {
7781 rtx tmp;
7782
7783 if (GET_MODE (operands[0]) != DImode)
7784 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7785
7786 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7787 FAIL;
7788
7789 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7790 if (sh_compare_op1 != const0_rtx)
7791 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7792 ? GET_MODE (sh_compare_op0)
7793 : GET_MODE (sh_compare_op1),
7794 sh_compare_op1);
7795
7796 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7797
7798 emit_insn (gen_seq (tmp));
7799 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7800
7801 DONE;
7802 }
7803
8bca10f4
JW
7804 operands[1] = prepare_scc_operands (EQ);
7805 operands[2] = gen_reg_rtx (SImode);
7806}")
7807
fa5322fa
AO
7808(define_expand "sunordered"
7809 [(set (match_operand:DI 0 "arith_reg_operand" "")
7810 (unordered:DI (match_dup 1) (match_dup 2)))]
7811 "TARGET_SHMEDIA_FPU"
7812 "
7813{
7814 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7815 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7816}")
7817
1245df60
R
7818;; Use the same trick for FP sle / sge
7819(define_expand "movnegt"
7820 [(set (match_dup 2) (const_int -1))
7821 (parallel [(set (match_operand 0 "" "")
7822 (neg:SI (plus:SI (match_dup 1)
7823 (match_dup 2))))
4773afa4 7824 (set (reg:SI T_REG)
1245df60 7825 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
52702ae1 7826 (const_int 0)))])]
fa5322fa 7827 "TARGET_SH1"
1245df60
R
7828 "operands[2] = gen_reg_rtx (SImode);")
7829
8bca10f4 7830;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
956d6950 7831;; This prevents a regression that occurred when we switched from xor to
8bca10f4
JW
7832;; mov/neg for sne.
7833
7834(define_split
aa684c94 7835 [(set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 7836 (plus:SI (reg:SI T_REG)
8bca10f4 7837 (const_int -1)))]
fa5322fa 7838 "TARGET_SH1"
4773afa4 7839 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
8bca10f4
JW
7840 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7841 "")
bc45ade3 7842
0d7e008e
SC
7843;; -------------------------------------------------------------------------
7844;; Instructions to cope with inline literal tables
7845;; -------------------------------------------------------------------------
7846
7847; 2 byte integer in line
b9654711 7848
0d7e008e 7849(define_insn "consttable_2"
b91455de
KK
7850 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7851 (match_operand 1 "" "")]
4773afa4 7852 UNSPECV_CONST2)]
0d7e008e
SC
7853 ""
7854 "*
7855{
b91455de 7856 if (operands[1] != const0_rtx)
c8af3574 7857 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
0d7e008e
SC
7858 return \"\";
7859}"
7860 [(set_attr "length" "2")
7861 (set_attr "in_delay_slot" "no")])
7862
7863; 4 byte integer in line
7864
7865(define_insn "consttable_4"
b91455de
KK
7866 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7867 (match_operand 1 "" "")]
4773afa4 7868 UNSPECV_CONST4)]
0d7e008e
SC
7869 ""
7870 "*
7871{
b91455de 7872 if (operands[1] != const0_rtx)
c8af3574 7873 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
0d7e008e
SC
7874 return \"\";
7875}"
7876 [(set_attr "length" "4")
7877 (set_attr "in_delay_slot" "no")])
7878
7879; 8 byte integer in line
7880
7881(define_insn "consttable_8"
b91455de
KK
7882 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7883 (match_operand 1 "" "")]
4773afa4 7884 UNSPECV_CONST8)]
0d7e008e
SC
7885 ""
7886 "*
7887{
b91455de 7888 if (operands[1] != const0_rtx)
c8af3574 7889 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
0d7e008e
SC
7890 return \"\";
7891}"
7892 [(set_attr "length" "8")
7893 (set_attr "in_delay_slot" "no")])
7894
3e943b59
JR
7895; 4 byte floating point
7896
7897(define_insn "consttable_sf"
b91455de
KK
7898 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7899 (match_operand 1 "" "")]
4773afa4 7900 UNSPECV_CONST4)]
3e943b59
JR
7901 ""
7902 "*
7903{
b91455de
KK
7904 if (operands[1] != const0_rtx)
7905 {
85654444
ZW
7906 REAL_VALUE_TYPE d;
7907 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7908 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
b91455de 7909 }
3e943b59
JR
7910 return \"\";
7911}"
7912 [(set_attr "length" "4")
7913 (set_attr "in_delay_slot" "no")])
7914
7915; 8 byte floating point
7916
7917(define_insn "consttable_df"
b91455de
KK
7918 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7919 (match_operand 1 "" "")]
4773afa4 7920 UNSPECV_CONST8)]
3e943b59
JR
7921 ""
7922 "*
7923{
b91455de
KK
7924 if (operands[1] != const0_rtx)
7925 {
85654444
ZW
7926 REAL_VALUE_TYPE d;
7927 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7928 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
b91455de 7929 }
3e943b59
JR
7930 return \"\";
7931}"
7932 [(set_attr "length" "8")
7933 (set_attr "in_delay_slot" "no")])
7934
1245df60
R
7935;; Alignment is needed for some constant tables; it may also be added for
7936;; Instructions at the start of loops, or after unconditional branches.
7937;; ??? We would get more accurate lengths if we did instruction
7938;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7939;; here is too conservative.
7940
0d7e008e
SC
7941; align to a two byte boundary
7942
33f7f353 7943(define_expand "align_2"
4773afa4 7944 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
0d7e008e 7945 ""
33f7f353 7946 "")
0d7e008e
SC
7947
7948; align to a four byte boundary
1245df60
R
7949;; align_4 and align_log are instructions for the starts of loops, or
7950;; after unconditional branches, which may take up extra room.
7951
7952(define_expand "align_4"
4773afa4 7953 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
1245df60
R
7954 ""
7955 "")
7956
7957; align to a cache line boundary
0d7e008e 7958
1245df60 7959(define_insn "align_log"
4773afa4 7960 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
0d7e008e 7961 ""
33f7f353
JR
7962 ""
7963 [(set_attr "length" "0")
1245df60 7964 (set_attr "in_delay_slot" "no")])
0d7e008e
SC
7965
7966; emitted at the end of the literal table, used to emit the
7967; 32bit branch labels if needed.
7968
7969(define_insn "consttable_end"
4773afa4 7970 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
0d7e008e
SC
7971 ""
7972 "* return output_jump_label_table ();"
7973 [(set_attr "in_delay_slot" "no")])
7974
b91455de
KK
7975; emitted at the end of the window in the literal table.
7976
7977(define_insn "consttable_window_end"
7978 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7979 ""
7980 ""
7981 [(set_attr "length" "0")
7982 (set_attr "in_delay_slot" "no")])
7983
0d7e008e
SC
7984;; -------------------------------------------------------------------------
7985;; Misc
7986;; -------------------------------------------------------------------------
7987
07a45e5c 7988;; String/block move insn.
0d7e008e
SC
7989
7990(define_expand "movstrsi"
7991 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7992 (mem:BLK (match_operand:BLK 1 "" "")))
7993 (use (match_operand:SI 2 "nonmemory_operand" ""))
7994 (use (match_operand:SI 3 "immediate_operand" ""))
4773afa4
AO
7995 (clobber (reg:SI PR_REG))
7996 (clobber (reg:SI R4_REG))
7997 (clobber (reg:SI R5_REG))
7998 (clobber (reg:SI R0_REG))])]
fa5322fa 7999 "TARGET_SH1 && ! TARGET_SH5"
0d7e008e
SC
8000 "
8001{
8002 if(expand_block_move (operands))
8003 DONE;
8004 else FAIL;
8005}")
8006
8007(define_insn "block_move_real"
4773afa4
AO
8008 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8009 (mem:BLK (reg:SI R5_REG)))
0d7e008e 8010 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8011 (clobber (reg:SI PR_REG))
8012 (clobber (reg:SI R0_REG))])]
fa5322fa 8013 "TARGET_SH1 && ! TARGET_HARD_SH4"
0d7e008e 8014 "jsr @%0%#"
22e1ebf1 8015 [(set_attr "type" "sfunc")
0d7e008e
SC
8016 (set_attr "needs_delay_slot" "yes")])
8017
8018(define_insn "block_lump_real"
4773afa4
AO
8019 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8020 (mem:BLK (reg:SI R5_REG)))
0d7e008e 8021 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8022 (use (reg:SI R6_REG))
8023 (clobber (reg:SI PR_REG))
8024 (clobber (reg:SI T_REG))
8025 (clobber (reg:SI R4_REG))
8026 (clobber (reg:SI R5_REG))
8027 (clobber (reg:SI R6_REG))
8028 (clobber (reg:SI R0_REG))])]
fa5322fa 8029 "TARGET_SH1 && ! TARGET_HARD_SH4"
225e4f43
R
8030 "jsr @%0%#"
8031 [(set_attr "type" "sfunc")
8032 (set_attr "needs_delay_slot" "yes")])
8033
8034(define_insn "block_move_real_i4"
4773afa4
AO
8035 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8036 (mem:BLK (reg:SI R5_REG)))
225e4f43 8037 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8038 (clobber (reg:SI PR_REG))
8039 (clobber (reg:SI R0_REG))
8040 (clobber (reg:SI R1_REG))
8041 (clobber (reg:SI R2_REG))])]
225e4f43
R
8042 "TARGET_HARD_SH4"
8043 "jsr @%0%#"
8044 [(set_attr "type" "sfunc")
8045 (set_attr "needs_delay_slot" "yes")])
8046
8047(define_insn "block_lump_real_i4"
4773afa4
AO
8048 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8049 (mem:BLK (reg:SI R5_REG)))
225e4f43 8050 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8051 (use (reg:SI R6_REG))
8052 (clobber (reg:SI PR_REG))
8053 (clobber (reg:SI T_REG))
8054 (clobber (reg:SI R4_REG))
8055 (clobber (reg:SI R5_REG))
8056 (clobber (reg:SI R6_REG))
8057 (clobber (reg:SI R0_REG))
8058 (clobber (reg:SI R1_REG))
8059 (clobber (reg:SI R2_REG))
8060 (clobber (reg:SI R3_REG))])]
225e4f43 8061 "TARGET_HARD_SH4"
0d7e008e 8062 "jsr @%0%#"
22e1ebf1 8063 [(set_attr "type" "sfunc")
0d7e008e 8064 (set_attr "needs_delay_slot" "yes")])
45348d9e
JW
8065\f
8066;; -------------------------------------------------------------------------
8067;; Floating point instructions.
8068;; -------------------------------------------------------------------------
8069
8070;; ??? All patterns should have a type attribute.
8071
225e4f43 8072(define_expand "fpu_switch0"
8845e874
AO
8073 [(set (match_operand:SI 0 "" "") (match_dup 2))
8074 (set (match_dup 1) (mem:PSI (match_dup 0)))]
ecfdeaeb 8075 "TARGET_SH4"
225e4f43
R
8076 "
8077{
8845e874
AO
8078 operands[1] = get_fpscr_rtx ();
8079 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
8080 if (flag_pic)
8081 operands[2] = legitimize_pic_address (operands[2], SImode,
8082 no_new_pseudos ? operands[0] : 0);
225e4f43
R
8083}")
8084
8085(define_expand "fpu_switch1"
8845e874
AO
8086 [(set (match_operand:SI 0 "" "") (match_dup 2))
8087 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8088 (set (match_dup 1) (mem:PSI (match_dup 3)))]
ecfdeaeb 8089 "TARGET_SH4"
225e4f43
R
8090 "
8091{
8845e874
AO
8092 operands[1] = get_fpscr_rtx ();
8093 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
8094 if (flag_pic)
8095 operands[2] = legitimize_pic_address (operands[2], SImode,
8096 no_new_pseudos ? operands[0] : 0);
8845e874 8097 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
225e4f43
R
8098}")
8099
8100(define_expand "movpsi"
8101 [(set (match_operand:PSI 0 "register_operand" "")
8102 (match_operand:PSI 1 "general_movsrc_operand" ""))]
ecfdeaeb 8103 "TARGET_SH4"
225e4f43
R
8104 "")
8105
8106;; The c / m alternative is a fake to guide reload to load directly into
8107;; fpscr, since reload doesn't know how to use post-increment.
8108;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8109;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8110;; predicate after reload.
c49439f1
R
8111;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8112;; like a mac -> gpr move.
225e4f43 8113(define_insn "fpu_switch"
7144b2d8
DD
8114 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8115 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
603ff6b5 8116 "TARGET_SH2E
ecfdeaeb
AO
8117 && (! reload_completed
8118 || true_regnum (operands[0]) != FPSCR_REG
8119 || GET_CODE (operands[1]) != MEM
8120 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
225e4f43
R
8121 "@
8122 ! precision stays the same
8123 lds.l %1,fpscr
8124 mov.l %1,%0
8125 #
8126 lds %1,fpscr
8127 mov %1,%0
8128 mov.l %1,%0
7144b2d8
DD
8129 sts fpscr,%0
8130 sts.l fpscr,%0"
8131 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8132 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
225e4f43
R
8133
8134(define_split
4773afa4 8135 [(set (reg:PSI FPSCR_REG)
c1b92d09 8136 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 8137 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
225e4f43
R
8138 [(set (match_dup 0) (match_dup 0))]
8139 "
8140{
8141 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8142 gen_rtx (MEM, PSImode,
8143 gen_rtx (POST_INC, Pmode,
8144 operands[0]))));
8145 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8146}")
8147
8148(define_split
4773afa4 8149 [(set (reg:PSI FPSCR_REG)
c1b92d09 8150 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 8151 "TARGET_SH4"
225e4f43
R
8152 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8153 "
8154{
8155 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8156 gen_rtx (MEM, PSImode,
8157 gen_rtx (POST_INC, Pmode,
8158 operands[0]))));
8159 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8160}")
8161
8162;; ??? This uses the fp unit, but has no type indicating that.
8163;; If we did that, this would either give a bogus latency or introduce
8164;; a bogus FIFO constraint.
8165;; Since this insn is currently only used for prologues/epilogues,
8166;; it is probably best to claim no function unit, which matches the
8167;; current setting.
8168(define_insn "toggle_sz"
4773afa4
AO
8169 [(set (reg:PSI FPSCR_REG)
8170 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
225e4f43
R
8171 "TARGET_SH4"
8172 "fschg")
8173
8174(define_expand "addsf3"
fa5322fa
AO
8175 [(set (match_operand:SF 0 "arith_reg_operand" "")
8176 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8177 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 8178 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8179 "
8180{
3a8699c7 8181 if (TARGET_SH2E)
fa5322fa
AO
8182 {
8183 expand_sf_binop (&gen_addsf3_i, operands);
8184 DONE;
8185 }
8186}")
8187
8188(define_insn "*addsf3_media"
8189 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8190 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8191 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8192 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8193 "fadd.s %1, %2, %0"
8194 [(set_attr "type" "fparith_media")])
225e4f43 8195
0ac78517
R
8196(define_insn_and_split "unary_sf_op"
8197 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8198 (vec_select:V2SF
8199 (vec_concat:V2SF
8200 (vec_select:SF
8201 (match_dup 0)
8202 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8203 (match_operator:SF 2 "unary_float_operator"
8204 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8205 (parallel [(match_operand 4
8206 "const_int_operand" "n")]))]))
8207 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8208 "TARGET_SHMEDIA_FPU"
8209 "#"
8210 "TARGET_SHMEDIA_FPU && reload_completed"
8211 [(set (match_dup 5) (match_dup 6))]
8212 "
8213{
8214 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8215 rtx op1 = gen_rtx_REG (SFmode,
8216 (true_regnum (operands[1])
8217 + (INTVAL (operands[4]) ^ endian)));
8218
8219 operands[7] = gen_rtx_REG (SFmode,
8220 (true_regnum (operands[0])
8221 + (INTVAL (operands[3]) ^ endian)));
8222 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8223}"
8224 [(set_attr "type" "fparith_media")])
8225
8226(define_insn_and_split "binary_sf_op"
8227 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8228 (vec_select:V2SF
8229 (vec_concat:V2SF
8230 (vec_select:SF
8231 (match_dup 0)
a93d1ba2 8232 (parallel [(match_operand 7 "const_int_operand" "n")]))
0ac78517
R
8233 (match_operator:SF 3 "binary_float_operator"
8234 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8235 (parallel [(match_operand 5
8236 "const_int_operand" "n")]))
8237 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8238 (parallel [(match_operand 6
8239 "const_int_operand" "n")]))]))
a93d1ba2
R
8240 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8241 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
0ac78517 8242 "#"
a93d1ba2
R
8243 "&& reload_completed"
8244 [(set (match_dup 8) (match_dup 9))]
0ac78517
R
8245 "
8246{
8247 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8248 rtx op1 = gen_rtx_REG (SFmode,
8249 (true_regnum (operands[1])
8250 + (INTVAL (operands[5]) ^ endian)));
8251 rtx op2 = gen_rtx_REG (SFmode,
8252 (true_regnum (operands[2])
8253 + (INTVAL (operands[6]) ^ endian)));
8254
a93d1ba2 8255 operands[8] = gen_rtx_REG (SFmode,
0ac78517
R
8256 (true_regnum (operands[0])
8257 + (INTVAL (operands[4]) ^ endian)));
a93d1ba2 8258 operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
0ac78517
R
8259}"
8260 [(set_attr "type" "fparith_media")])
8261
225e4f43 8262(define_insn "addsf3_i"
45348d9e
JW
8263 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8264 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
225e4f43
R
8265 (match_operand:SF 2 "arith_reg_operand" "f")))
8266 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8267 "TARGET_SH2E"
c1aef54d 8268 "fadd %2,%0"
d64264ff
R
8269 [(set_attr "type" "fp")
8270 (set_attr "fp_mode" "single")])
45348d9e 8271
225e4f43 8272(define_expand "subsf3"
fa5322fa
AO
8273 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8274 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8275 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 8276 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8277 "
8278{
3a8699c7 8279 if (TARGET_SH2E)
fa5322fa
AO
8280 {
8281 expand_sf_binop (&gen_subsf3_i, operands);
8282 DONE;
8283 }
8284}")
8285
8286(define_insn "*subsf3_media"
8287 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8288 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8289 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8290 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8291 "fsub.s %1, %2, %0"
8292 [(set_attr "type" "fparith_media")])
225e4f43
R
8293
8294(define_insn "subsf3_i"
66c0b347
R
8295 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8296 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8297 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8298 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8299 "TARGET_SH2E"
c1aef54d 8300 "fsub %2,%0"
d64264ff
R
8301 [(set_attr "type" "fp")
8302 (set_attr "fp_mode" "single")])
45348d9e 8303
225e4f43
R
8304;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8305;; register in feeding fp instructions. Thus, we cannot generate fmac for
8306;; mixed-precision SH4 targets. To allow it to be still generated for the
8307;; SH3E, we use a separate insn for SH3E mulsf3.
8308
8309(define_expand "mulsf3"
fa5322fa
AO
8310 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8311 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8312 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 8313 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8314 "
8315{
8316 if (TARGET_SH4)
8317 expand_sf_binop (&gen_mulsf3_i4, operands);
3a8699c7 8318 else if (TARGET_SH2E)
225e4f43 8319 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
fa5322fa
AO
8320 if (! TARGET_SHMEDIA)
8321 DONE;
225e4f43
R
8322}")
8323
fa5322fa
AO
8324(define_insn "*mulsf3_media"
8325 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8326 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8327 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8328 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8329 "fmul.s %1, %2, %0"
8330 [(set_attr "type" "fparith_media")])
fa5322fa 8331
225e4f43 8332(define_insn "mulsf3_i4"
4b9580a5
R
8333 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8334 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8335 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8336 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8337 "TARGET_SH2E"
c1aef54d 8338 "fmul %2,%0"
d64264ff
R
8339 [(set_attr "type" "fp")
8340 (set_attr "fp_mode" "single")])
45348d9e 8341
225e4f43 8342(define_insn "mulsf3_ie"
4b9580a5
R
8343 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8344 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8345 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
3a8699c7 8346 "TARGET_SH2E && ! TARGET_SH4"
225e4f43
R
8347 "fmul %2,%0"
8348 [(set_attr "type" "fp")])
8349
fa5322fa
AO
8350(define_insn "*mac_media"
8351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8352 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8353 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8354 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8355 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8356 "fmac.s %1, %2, %0"
8357 [(set_attr "type" "fparith_media")])
fa5322fa 8358
45348d9e 8359(define_insn "*macsf3"
4b9580a5
R
8360 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8361 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8362 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
225e4f43
R
8363 (match_operand:SF 3 "arith_reg_operand" "0")))
8364 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
3a8699c7 8365 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8366 "fmac fr0,%2,%0"
d64264ff
R
8367 [(set_attr "type" "fp")
8368 (set_attr "fp_mode" "single")])
45348d9e 8369
225e4f43 8370(define_expand "divsf3"
fa5322fa
AO
8371 [(set (match_operand:SF 0 "arith_reg_operand" "")
8372 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8373 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 8374 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8375 "
8376{
3a8699c7 8377 if (TARGET_SH2E)
fa5322fa
AO
8378 {
8379 expand_sf_binop (&gen_divsf3_i, operands);
8380 DONE;
8381 }
8382}")
8383
8384(define_insn "*divsf3_media"
8385 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8386 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8387 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8388 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8389 "fdiv.s %1, %2, %0"
8390 [(set_attr "type" "fdiv_media")])
225e4f43
R
8391
8392(define_insn "divsf3_i"
45348d9e
JW
8393 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8394 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
225e4f43
R
8395 (match_operand:SF 2 "arith_reg_operand" "f")))
8396 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8397 "TARGET_SH2E"
c1aef54d 8398 "fdiv %2,%0"
d64264ff
R
8399 [(set_attr "type" "fdiv")
8400 (set_attr "fp_mode" "single")])
45348d9e 8401
fa5322fa
AO
8402(define_insn "floatdisf2"
8403 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8404 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8406 "float.qs %1, %0"
8407 [(set_attr "type" "fpconv_media")])
fa5322fa 8408
1245df60 8409(define_expand "floatsisf2"
4b9580a5
R
8410 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8411 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
3a8699c7 8412 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8413 "
8414{
8415 if (TARGET_SH4)
8416 {
0c4c9b16 8417 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8418 DONE;
8419 }
225e4f43
R
8420}")
8421
fa5322fa
AO
8422(define_insn "*floatsisf2_media"
8423 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8424 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8425 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8426 "float.ls %1, %0"
8427 [(set_attr "type" "fpconv_media")])
fa5322fa 8428
225e4f43 8429(define_insn "floatsisf2_i4"
4b9580a5
R
8430 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8431 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8432 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
0f805606 8433 "TARGET_SH4"
0c4c9b16 8434 "float %1,%0"
d64264ff
R
8435 [(set_attr "type" "fp")
8436 (set_attr "fp_mode" "single")])
45348d9e 8437
0f805606 8438(define_insn "*floatsisf2_ie"
4b9580a5
R
8439 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8440 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
3a8699c7 8441 "TARGET_SH2E && ! TARGET_SH4"
0f805606
BS
8442 "float %1,%0"
8443 [(set_attr "type" "fp")])
45348d9e 8444
fa5322fa
AO
8445(define_insn "fix_truncsfdi2"
8446 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8447 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8448 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8449 "ftrc.sq %1, %0"
8450 [(set_attr "type" "fpconv_media")])
fa5322fa 8451
1245df60 8452(define_expand "fix_truncsfsi2"
4b9580a5
R
8453 [(set (match_operand:SI 0 "fpul_operand" "=y")
8454 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8455 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8456 "
8457{
8458 if (TARGET_SH4)
8459 {
0c4c9b16 8460 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8461 DONE;
8462 }
8463}")
8464
fa5322fa
AO
8465(define_insn "*fix_truncsfsi2_media"
8466 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8467 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8468 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8469 "ftrc.sl %1, %0"
8470 [(set_attr "type" "fpconv_media")])
fa5322fa 8471
225e4f43 8472(define_insn "fix_truncsfsi2_i4"
4b9580a5
R
8473 [(set (match_operand:SI 0 "fpul_operand" "=y")
8474 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8475 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8476 "TARGET_SH4"
0c4c9b16 8477 "ftrc %1,%0"
c49439f1 8478 [(set_attr "type" "ftrc_s")
d64264ff 8479 (set_attr "fp_mode" "single")])
225e4f43 8480
0c4c9b16
BS
8481;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8482;; fix_truncsfsi2_i4.
8483;; (define_insn "fix_truncsfsi2_i4_2"
8484;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8485;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
5d00b10a 8486;; (use (reg:PSI FPSCR_REG))
4773afa4 8487;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8488;; "TARGET_SH4"
8489;; "#"
8490;; [(set_attr "length" "4")
8491;; (set_attr "fp_mode" "single")])
8492
8493;;(define_split
8494;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8495;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8496;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8497;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8498;; "TARGET_SH4"
4773afa4 8499;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8500;; (use (match_dup 2))])
4773afa4 8501;; (set (match_dup 0) (reg:SI FPUL_REG))])
45348d9e 8502
1245df60 8503(define_insn "*fixsfsi"
4b9580a5
R
8504 [(set (match_operand:SI 0 "fpul_operand" "=y")
8505 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8506 "TARGET_SH2E && ! TARGET_SH4"
0c4c9b16 8507 "ftrc %1,%0"
1245df60 8508 [(set_attr "type" "fp")])
45348d9e 8509
1245df60 8510(define_insn "cmpgtsf_t"
4773afa4
AO
8511 [(set (reg:SI T_REG)
8512 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8513 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8514 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8515 "fcmp/gt %1,%0"
d64264ff
R
8516 [(set_attr "type" "fp")
8517 (set_attr "fp_mode" "single")])
45348d9e 8518
1245df60 8519(define_insn "cmpeqsf_t"
4773afa4
AO
8520 [(set (reg:SI T_REG)
8521 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8522 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8523 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8524 "fcmp/eq %1,%0"
d64264ff
R
8525 [(set_attr "type" "fp")
8526 (set_attr "fp_mode" "single")])
45348d9e 8527
1245df60 8528(define_insn "ieee_ccmpeqsf_t"
4773afa4
AO
8529 [(set (reg:SI T_REG)
8530 (ior:SI (reg:SI T_REG)
4b9580a5
R
8531 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8532 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
3a8699c7 8533 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
1245df60
R
8534 "* return output_ieee_ccmpeq (insn, operands);"
8535 [(set_attr "length" "4")])
8536
8537
225e4f43 8538(define_insn "cmpgtsf_t_i4"
4773afa4
AO
8539 [(set (reg:SI T_REG)
8540 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8541 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8542 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8543 "TARGET_SH4"
8544 "fcmp/gt %1,%0"
d64264ff
R
8545 [(set_attr "type" "fp")
8546 (set_attr "fp_mode" "single")])
225e4f43
R
8547
8548(define_insn "cmpeqsf_t_i4"
4773afa4
AO
8549 [(set (reg:SI T_REG)
8550 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8551 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8552 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8553 "TARGET_SH4"
8554 "fcmp/eq %1,%0"
d64264ff
R
8555 [(set_attr "type" "fp")
8556 (set_attr "fp_mode" "single")])
225e4f43
R
8557
8558(define_insn "*ieee_ccmpeqsf_t_4"
4773afa4
AO
8559 [(set (reg:SI T_REG)
8560 (ior:SI (reg:SI T_REG)
4b9580a5
R
8561 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8562 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
225e4f43
R
8563 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8564 "TARGET_IEEE && TARGET_SH4"
8565 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8566 [(set_attr "length" "4")
8567 (set_attr "fp_mode" "single")])
225e4f43 8568
fa5322fa
AO
8569(define_insn "cmpeqsf_media"
8570 [(set (match_operand:DI 0 "register_operand" "=r")
8571 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8572 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8573 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8574 "fcmpeq.s %1, %2, %0"
8575 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8576
8577(define_insn "cmpgtsf_media"
8578 [(set (match_operand:DI 0 "register_operand" "=r")
8579 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8580 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8581 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8582 "fcmpgt.s %1, %2, %0"
8583 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8584
8585(define_insn "cmpgesf_media"
8586 [(set (match_operand:DI 0 "register_operand" "=r")
8587 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8588 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8589 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8590 "fcmpge.s %1, %2, %0"
8591 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8592
8593(define_insn "cmpunsf_media"
8594 [(set (match_operand:DI 0 "register_operand" "=r")
8595 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8596 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8597 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8598 "fcmpun.s %1, %2, %0"
8599 [(set_attr "type" "fcmp_media")])
fa5322fa 8600
45348d9e 8601(define_expand "cmpsf"
4773afa4
AO
8602 [(set (reg:SI T_REG)
8603 (compare (match_operand:SF 0 "arith_operand" "")
8604 (match_operand:SF 1 "arith_operand" "")))]
3a8699c7 8605 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
45348d9e
JW
8606 "
8607{
8608 sh_compare_op0 = operands[0];
8609 sh_compare_op1 = operands[1];
8610 DONE;
8611}")
b9654711 8612
225e4f43 8613(define_expand "negsf2"
fa5322fa
AO
8614 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8615 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 8616 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8617 "
8618{
3a8699c7 8619 if (TARGET_SH2E)
fa5322fa
AO
8620 {
8621 expand_sf_unop (&gen_negsf2_i, operands);
8622 DONE;
8623 }
8624}")
8625
8626(define_insn "*negsf2_media"
8627 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8628 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8629 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8630 "fneg.s %1, %0"
8631 [(set_attr "type" "fmove_media")])
225e4f43
R
8632
8633(define_insn "negsf2_i"
4b9580a5
R
8634 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8635 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8636 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 8637 "TARGET_SH2E"
c1aef54d 8638 "fneg %0"
d64264ff
R
8639 [(set_attr "type" "fmove")
8640 (set_attr "fp_mode" "single")])
45348d9e 8641
225e4f43 8642(define_expand "sqrtsf2"
fa5322fa
AO
8643 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8644 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8645 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8646 "
8647{
8648 if (TARGET_SH3E)
8649 {
8650 expand_sf_unop (&gen_sqrtsf2_i, operands);
8651 DONE;
8652 }
8653}")
8654
8655(define_insn "*sqrtsf2_media"
8656 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8657 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8658 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8659 "fsqrt.s %1, %0"
8660 [(set_attr "type" "fdiv_media")])
225e4f43
R
8661
8662(define_insn "sqrtsf2_i"
4b9580a5
R
8663 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8664 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8665 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 8666 "TARGET_SH3E"
c1aef54d 8667 "fsqrt %0"
d64264ff
R
8668 [(set_attr "type" "fdiv")
8669 (set_attr "fp_mode" "single")])
45348d9e 8670
225e4f43 8671(define_expand "abssf2"
fa5322fa
AO
8672 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8673 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 8674 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8675 "
8676{
3a8699c7 8677 if (TARGET_SH2E)
fa5322fa
AO
8678 {
8679 expand_sf_unop (&gen_abssf2_i, operands);
8680 DONE;
8681 }
8682}")
8683
8684(define_insn "*abssf2_media"
8685 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8686 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8687 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8688 "fabs.s %1, %0"
8689 [(set_attr "type" "fmove_media")])
225e4f43
R
8690
8691(define_insn "abssf2_i"
4b9580a5
R
8692 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8693 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8694 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 8695 "TARGET_SH2E"
c1aef54d 8696 "fabs %0"
d64264ff
R
8697 [(set_attr "type" "fmove")
8698 (set_attr "fp_mode" "single")])
225e4f43
R
8699
8700(define_expand "adddf3"
fa5322fa
AO
8701 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8702 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8703 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8704 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8705 "
8706{
8707 if (TARGET_SH4)
8708 {
8709 expand_df_binop (&gen_adddf3_i, operands);
8710 DONE;
8711 }
8712}")
8713
8714(define_insn "*adddf3_media"
8715 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8716 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8717 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8718 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8719 "fadd.d %1, %2, %0"
8720 [(set_attr "type" "dfparith_media")])
225e4f43
R
8721
8722(define_insn "adddf3_i"
4b9580a5
R
8723 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8724 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8725 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8726 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8727 "TARGET_SH4"
8728 "fadd %2,%0"
d64264ff
R
8729 [(set_attr "type" "dfp_arith")
8730 (set_attr "fp_mode" "double")])
225e4f43
R
8731
8732(define_expand "subdf3"
fa5322fa
AO
8733 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8734 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8735 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8736 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8737 "
8738{
8739 if (TARGET_SH4)
8740 {
8741 expand_df_binop (&gen_subdf3_i, operands);
8742 DONE;
8743 }
8744}")
8745
8746(define_insn "*subdf3_media"
8747 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8748 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8749 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8750 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8751 "fsub.d %1, %2, %0"
8752 [(set_attr "type" "dfparith_media")])
225e4f43
R
8753
8754(define_insn "subdf3_i"
4b9580a5
R
8755 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8756 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8757 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8758 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8759 "TARGET_SH4"
8760 "fsub %2,%0"
d64264ff
R
8761 [(set_attr "type" "dfp_arith")
8762 (set_attr "fp_mode" "double")])
225e4f43
R
8763
8764(define_expand "muldf3"
fa5322fa
AO
8765 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8766 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8767 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8768 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8769 "
8770{
8771 if (TARGET_SH4)
8772 {
8773 expand_df_binop (&gen_muldf3_i, operands);
8774 DONE;
8775 }
8776}")
8777
8778(define_insn "*muldf3_media"
8779 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8780 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8781 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8782 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8783 "fmul.d %1, %2, %0"
8784 [(set_attr "type" "dfmul_media")])
225e4f43
R
8785
8786(define_insn "muldf3_i"
4b9580a5
R
8787 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8788 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8789 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8790 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8791 "TARGET_SH4"
8792 "fmul %2,%0"
d64264ff
R
8793 [(set_attr "type" "dfp_arith")
8794 (set_attr "fp_mode" "double")])
225e4f43
R
8795
8796(define_expand "divdf3"
fa5322fa
AO
8797 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8798 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8799 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8800 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8801 "
8802{
8803 if (TARGET_SH4)
8804 {
8805 expand_df_binop (&gen_divdf3_i, operands);
8806 DONE;
8807 }
8808}")
8809
8810(define_insn "*divdf3_media"
8811 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8812 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8813 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8814 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8815 "fdiv.d %1, %2, %0"
8816 [(set_attr "type" "dfdiv_media")])
225e4f43
R
8817
8818(define_insn "divdf3_i"
4b9580a5
R
8819 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8820 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8821 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8822 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8823 "TARGET_SH4"
8824 "fdiv %2,%0"
d64264ff
R
8825 [(set_attr "type" "dfdiv")
8826 (set_attr "fp_mode" "double")])
225e4f43 8827
fa5322fa
AO
8828(define_insn "floatdidf2"
8829 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8830 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8831 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8832 "float.qd %1, %0"
8833 [(set_attr "type" "dfpconv_media")])
fa5322fa 8834
225e4f43 8835(define_expand "floatsidf2"
fa5322fa
AO
8836 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8837 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8838 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8839 "
8840{
fa5322fa
AO
8841 if (TARGET_SH4)
8842 {
8843 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8844 get_fpscr_rtx ()));
8845 DONE;
8846 }
225e4f43
R
8847}")
8848
fa5322fa
AO
8849(define_insn "*floatsidf2_media"
8850 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8851 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8852 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8853 "float.ld %1, %0"
8854 [(set_attr "type" "dfpconv_media")])
fa5322fa 8855
225e4f43 8856(define_insn "floatsidf2_i"
4b9580a5
R
8857 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8858 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8859 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8860 "TARGET_SH4"
0c4c9b16 8861 "float %1,%0"
d64264ff
R
8862 [(set_attr "type" "dfp_conv")
8863 (set_attr "fp_mode" "double")])
225e4f43 8864
fa5322fa
AO
8865(define_insn "fix_truncdfdi2"
8866 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8867 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8868 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8869 "ftrc.dq %1, %0"
8870 [(set_attr "type" "dfpconv_media")])
fa5322fa 8871
225e4f43 8872(define_expand "fix_truncdfsi2"
fa5322fa
AO
8873 [(set (match_operand:SI 0 "fpul_operand" "")
8874 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8875 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8876 "
8877{
fa5322fa
AO
8878 if (TARGET_SH4)
8879 {
8880 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8881 get_fpscr_rtx ()));
8882 DONE;
8883 }
225e4f43
R
8884}")
8885
fa5322fa
AO
8886(define_insn "*fix_truncdfsi2_media"
8887 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8888 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8889 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8890 "ftrc.dl %1, %0"
8891 [(set_attr "type" "dfpconv_media")])
fa5322fa 8892
225e4f43 8893(define_insn "fix_truncdfsi2_i"
4b9580a5
R
8894 [(set (match_operand:SI 0 "fpul_operand" "=y")
8895 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8896 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8897 "TARGET_SH4"
0c4c9b16
BS
8898 "ftrc %1,%0"
8899 [(set_attr "type" "dfp_conv")
c49439f1 8900 (set_attr "dfp_comp" "no")
d64264ff 8901 (set_attr "fp_mode" "double")])
225e4f43 8902
0c4c9b16
BS
8903;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8904;; fix_truncdfsi2_i.
8905;; (define_insn "fix_truncdfsi2_i4"
8906;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8907;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8908;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8909;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8910;; "TARGET_SH4"
8911;; "#"
8912;; [(set_attr "length" "4")
8913;; (set_attr "fp_mode" "double")])
52702ae1 8914;;
0c4c9b16
BS
8915;; (define_split
8916;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8917;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8918;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8919;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8920;; "TARGET_SH4"
4773afa4 8921;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8922;; (use (match_dup 2))])
4773afa4 8923;; (set (match_dup 0) (reg:SI FPUL_REG))])
225e4f43
R
8924
8925(define_insn "cmpgtdf_t"
4773afa4
AO
8926 [(set (reg:SI T_REG)
8927 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8928 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
8929 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8930 "TARGET_SH4"
8931 "fcmp/gt %1,%0"
d64264ff
R
8932 [(set_attr "type" "dfp_cmp")
8933 (set_attr "fp_mode" "double")])
225e4f43
R
8934
8935(define_insn "cmpeqdf_t"
4773afa4
AO
8936 [(set (reg:SI T_REG)
8937 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8938 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
8939 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8940 "TARGET_SH4"
8941 "fcmp/eq %1,%0"
d64264ff
R
8942 [(set_attr "type" "dfp_cmp")
8943 (set_attr "fp_mode" "double")])
225e4f43
R
8944
8945(define_insn "*ieee_ccmpeqdf_t"
4773afa4
AO
8946 [(set (reg:SI T_REG)
8947 (ior:SI (reg:SI T_REG)
8948 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8949 (match_operand:DF 1 "arith_reg_operand" "f"))))
225e4f43
R
8950 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8951 "TARGET_IEEE && TARGET_SH4"
8952 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8953 [(set_attr "length" "4")
8954 (set_attr "fp_mode" "double")])
52702ae1 8955
fa5322fa
AO
8956(define_insn "cmpeqdf_media"
8957 [(set (match_operand:DI 0 "register_operand" "=r")
8958 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8959 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8960 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8961 "fcmpeq.d %1,%2,%0"
8962 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8963
8964(define_insn "cmpgtdf_media"
8965 [(set (match_operand:DI 0 "register_operand" "=r")
8966 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8967 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8968 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8969 "fcmpgt.d %1,%2,%0"
8970 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8971
8972(define_insn "cmpgedf_media"
8973 [(set (match_operand:DI 0 "register_operand" "=r")
8974 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8975 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8976 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8977 "fcmpge.d %1,%2,%0"
8978 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8979
8980(define_insn "cmpundf_media"
8981 [(set (match_operand:DI 0 "register_operand" "=r")
8982 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8983 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8984 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8985 "fcmpun.d %1,%2,%0"
8986 [(set_attr "type" "fcmp_media")])
fa5322fa 8987
225e4f43 8988(define_expand "cmpdf"
4773afa4
AO
8989 [(set (reg:SI T_REG)
8990 (compare (match_operand:DF 0 "arith_operand" "")
8991 (match_operand:DF 1 "arith_operand" "")))]
fa5322fa 8992 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8993 "
8994{
8995 sh_compare_op0 = operands[0];
8996 sh_compare_op1 = operands[1];
8997 DONE;
8998}")
8999
9000(define_expand "negdf2"
fa5322fa
AO
9001 [(set (match_operand:DF 0 "arith_reg_operand" "")
9002 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9003 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9004 "
9005{
9006 if (TARGET_SH4)
9007 {
9008 expand_df_unop (&gen_negdf2_i, operands);
9009 DONE;
9010 }
9011}")
9012
9013(define_insn "*negdf2_media"
9014 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9015 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9016 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9017 "fneg.d %1, %0"
9018 [(set_attr "type" "fmove_media")])
225e4f43
R
9019
9020(define_insn "negdf2_i"
9021 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9022 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9023 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9024 "TARGET_SH4"
9025 "fneg %0"
d64264ff
R
9026 [(set_attr "type" "fmove")
9027 (set_attr "fp_mode" "double")])
225e4f43
R
9028
9029(define_expand "sqrtdf2"
fa5322fa
AO
9030 [(set (match_operand:DF 0 "arith_reg_operand" "")
9031 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9032 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9033 "
9034{
9035 if (TARGET_SH4)
9036 {
9037 expand_df_unop (&gen_sqrtdf2_i, operands);
9038 DONE;
9039 }
9040}")
9041
9042(define_insn "*sqrtdf2_media"
9043 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9044 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9045 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9046 "fsqrt.d %1, %0"
9047 [(set_attr "type" "dfdiv_media")])
225e4f43
R
9048
9049(define_insn "sqrtdf2_i"
9050 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9051 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9052 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9053 "TARGET_SH4"
9054 "fsqrt %0"
d64264ff
R
9055 [(set_attr "type" "dfdiv")
9056 (set_attr "fp_mode" "double")])
225e4f43
R
9057
9058(define_expand "absdf2"
fa5322fa
AO
9059 [(set (match_operand:DF 0 "arith_reg_operand" "")
9060 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9061 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9062 "
9063{
9064 if (TARGET_SH4)
9065 {
9066 expand_df_unop (&gen_absdf2_i, operands);
9067 DONE;
9068 }
9069}")
9070
9071(define_insn "*absdf2_media"
9072 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9073 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9074 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9075 "fabs.d %1, %0"
9076 [(set_attr "type" "fmove_media")])
225e4f43
R
9077
9078(define_insn "absdf2_i"
9079 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9080 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9081 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9082 "TARGET_SH4"
9083 "fabs %0"
d64264ff
R
9084 [(set_attr "type" "fmove")
9085 (set_attr "fp_mode" "double")])
225e4f43
R
9086
9087(define_expand "extendsfdf2"
fa5322fa
AO
9088 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9089 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9090 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9091 "
9092{
fa5322fa
AO
9093 if (TARGET_SH4)
9094 {
9095 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9096 get_fpscr_rtx ()));
9097 DONE;
9098 }
225e4f43
R
9099}")
9100
fa5322fa
AO
9101(define_insn "*extendsfdf2_media"
9102 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9103 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9104 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9105 "fcnv.sd %1, %0"
9106 [(set_attr "type" "dfpconv_media")])
fa5322fa 9107
225e4f43 9108(define_insn "extendsfdf2_i4"
4b9580a5
R
9109 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9110 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
0c4c9b16 9111 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 9112 "TARGET_SH4"
0c4c9b16 9113 "fcnvsd %1,%0"
d64264ff
R
9114 [(set_attr "type" "fp")
9115 (set_attr "fp_mode" "double")])
225e4f43
R
9116
9117(define_expand "truncdfsf2"
fa5322fa
AO
9118 [(set (match_operand:SF 0 "fpul_operand" "")
9119 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9120 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9121 "
9122{
fa5322fa
AO
9123 if (TARGET_SH4)
9124 {
9125 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9126 get_fpscr_rtx ()));
9127 DONE;
9128 }
225e4f43
R
9129}")
9130
fa5322fa
AO
9131(define_insn "*truncdfsf2_media"
9132 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9133 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9134 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9135 "fcnv.ds %1, %0"
9136 [(set_attr "type" "dfpconv_media")])
fa5322fa 9137
225e4f43 9138(define_insn "truncdfsf2_i4"
4b9580a5
R
9139 [(set (match_operand:SF 0 "fpul_operand" "=y")
9140 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 9141 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 9142 "TARGET_SH4"
0c4c9b16 9143 "fcnvds %1,%0"
d64264ff
R
9144 [(set_attr "type" "fp")
9145 (set_attr "fp_mode" "double")])
45348d9e 9146\f
725de644
JW
9147;; Bit field extract patterns. These give better code for packed bitfields,
9148;; because they allow auto-increment addresses to be generated.
9149
9150(define_expand "insv"
9151 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9152 (match_operand:SI 1 "immediate_operand" "")
9153 (match_operand:SI 2 "immediate_operand" ""))
9154 (match_operand:SI 3 "general_operand" ""))]
fa5322fa 9155 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
725de644
JW
9156 "
9157{
a7f52356
R
9158 rtx addr_target, orig_address, shift_reg, qi_val;
9159 HOST_WIDE_INT bitsize, size, v;
9160 rtx x = operands[3];
725de644
JW
9161
9162 /* ??? expmed doesn't care for non-register predicates. */
9163 if (! memory_operand (operands[0], VOIDmode)
9164 || ! immediate_operand (operands[1], VOIDmode)
9165 || ! immediate_operand (operands[2], VOIDmode)
a7f52356 9166 || ! general_operand (x, VOIDmode))
725de644
JW
9167 FAIL;
9168 /* If this isn't a 16 / 24 / 32 bit field, or if
9169 it doesn't start on a byte boundary, then fail. */
a7f52356
R
9170 bitsize = INTVAL (operands[1]);
9171 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
725de644
JW
9172 || (INTVAL (operands[2]) % 8) != 0)
9173 FAIL;
9174
a7f52356 9175 size = bitsize / 8;
725de644 9176 orig_address = XEXP (operands[0], 0);
725de644 9177 shift_reg = gen_reg_rtx (SImode);
a7f52356
R
9178 if (GET_CODE (x) == CONST_INT)
9179 {
9180 v = INTVAL (x);
9181 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9182 }
9183 else
9184 {
9185 emit_insn (gen_movsi (shift_reg, operands[3]));
9186 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9187 }
ea3cbda5 9188 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
725de644 9189
792760b9 9190 operands[0] = replace_equiv_address (operands[0], addr_target);
a7f52356 9191 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9192
9193 while (size -= 1)
9194 {
a7f52356
R
9195 if (GET_CODE (x) == CONST_INT)
9196 qi_val
9197 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9198 else
9199 {
9200 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9201 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9202 }
725de644 9203 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
a7f52356 9204 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9205 }
9206
9207 DONE;
9208}")
9209\f
51bd623f
JW
9210;; -------------------------------------------------------------------------
9211;; Peepholes
9212;; -------------------------------------------------------------------------
961c4780 9213
51bd623f
JW
9214;; This matches cases where a stack pointer increment at the start of the
9215;; epilogue combines with a stack slot read loading the return value.
aa684c94 9216
07a45e5c 9217(define_peephole
51bd623f
JW
9218 [(set (match_operand:SI 0 "arith_reg_operand" "")
9219 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9220 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
fa5322fa 9221 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
51bd623f 9222 "mov.l @%1+,%0")
00f8ff66 9223
51bd623f 9224;; See the comment on the dt combiner pattern above.
00f8ff66 9225
07a45e5c
JW
9226(define_peephole
9227 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
00f8ff66
SC
9228 (plus:SI (match_dup 0)
9229 (const_int -1)))
4773afa4 9230 (set (reg:SI T_REG)
00f8ff66
SC
9231 (eq:SI (match_dup 0)
9232 (const_int 0)))]
9233 "TARGET_SH2"
9234 "dt %0")
e4931540
RK
9235
9236;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9237;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9238;; reload when the constant is too large for a reg+offset address.
9239
9240;; ??? We would get much better code if this was done in reload. This would
9241;; require modifying find_reloads_address to recognize that if the constant
9242;; is out-of-range for an immediate add, then we get better code by reloading
9243;; the constant into a register than by reloading the sum into a register,
9244;; since the former is one instruction shorter if the address does not need
9245;; to be offsettable. Unfortunately this does not work, because there is
9246;; only one register, r0, that can be used as an index register. This register
9247;; is also the function return value register. So, if we try to force reload
9248;; to use double-reg addresses, then we end up with some instructions that
9249;; need to use r0 twice. The only way to fix this is to change the calling
9250;; convention so that r0 is not used to return values.
9251
9252(define_peephole
9253 [(set (match_operand:SI 0 "register_operand" "=r")
9254 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9255 (set (mem:SI (match_dup 0))
9256 (match_operand:SI 2 "general_movsrc_operand" ""))]
fa5322fa 9257 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9258 "mov.l %2,@(%0,%1)")
9259
9260(define_peephole
9261 [(set (match_operand:SI 0 "register_operand" "=r")
9262 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9263 (set (match_operand:SI 2 "general_movdst_operand" "")
9264 (mem:SI (match_dup 0)))]
fa5322fa 9265 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9266 "mov.l @(%0,%1),%2")
9267
9268(define_peephole
9269 [(set (match_operand:SI 0 "register_operand" "=r")
9270 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9271 (set (mem:HI (match_dup 0))
9272 (match_operand:HI 2 "general_movsrc_operand" ""))]
fa5322fa 9273 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9274 "mov.w %2,@(%0,%1)")
9275
9276(define_peephole
9277 [(set (match_operand:SI 0 "register_operand" "=r")
9278 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9279 (set (match_operand:HI 2 "general_movdst_operand" "")
9280 (mem:HI (match_dup 0)))]
fa5322fa 9281 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9282 "mov.w @(%0,%1),%2")
9283
9284(define_peephole
9285 [(set (match_operand:SI 0 "register_operand" "=r")
9286 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9287 (set (mem:QI (match_dup 0))
9288 (match_operand:QI 2 "general_movsrc_operand" ""))]
fa5322fa 9289 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9290 "mov.b %2,@(%0,%1)")
9291
9292(define_peephole
9293 [(set (match_operand:SI 0 "register_operand" "=r")
9294 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9295 (set (match_operand:QI 2 "general_movdst_operand" "")
9296 (mem:QI (match_dup 0)))]
fa5322fa 9297 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9298 "mov.b @(%0,%1),%2")
9299
9300(define_peephole
9301 [(set (match_operand:SI 0 "register_operand" "=r")
9302 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9303 (set (mem:SF (match_dup 0))
9304 (match_operand:SF 2 "general_movsrc_operand" ""))]
fa5322fa 9305 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9306 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9307 || (GET_CODE (operands[2]) == SUBREG
9308 && REGNO (SUBREG_REG (operands[2])) < 16))
9309 && reg_unused_after (operands[0], insn)"
e4931540
RK
9310 "mov.l %2,@(%0,%1)")
9311
9312(define_peephole
9313 [(set (match_operand:SI 0 "register_operand" "=r")
9314 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9315 (set (match_operand:SF 2 "general_movdst_operand" "")
9316
9317 (mem:SF (match_dup 0)))]
fa5322fa 9318 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9319 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9320 || (GET_CODE (operands[2]) == SUBREG
9321 && REGNO (SUBREG_REG (operands[2])) < 16))
9322 && reg_unused_after (operands[0], insn)"
e4931540 9323 "mov.l @(%0,%1),%2")
45348d9e
JW
9324
9325(define_peephole
9326 [(set (match_operand:SI 0 "register_operand" "=r")
9327 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9328 (set (mem:SF (match_dup 0))
9329 (match_operand:SF 2 "general_movsrc_operand" ""))]
3a8699c7 9330 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
9331 && ((GET_CODE (operands[2]) == REG
9332 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9333 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9334 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9335 && reg_unused_after (operands[0], insn)"
1245df60 9336 "fmov{.s|} %2,@(%0,%1)")
45348d9e
JW
9337
9338(define_peephole
9339 [(set (match_operand:SI 0 "register_operand" "=r")
9340 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9341 (set (match_operand:SF 2 "general_movdst_operand" "")
9342
9343 (mem:SF (match_dup 0)))]
3a8699c7 9344 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
9345 && ((GET_CODE (operands[2]) == REG
9346 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9347 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9348 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9349 && reg_unused_after (operands[0], insn)"
1245df60 9350 "fmov{.s|} @(%0,%1),%2")
4408efce
JL
9351
9352;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9353(define_insn "sp_switch_1"
9354 [(const_int 1)]
fa5322fa 9355 "TARGET_SH1"
4408efce
JL
9356 "*
9357{
9358 rtx xoperands[1];
9359
9360 xoperands[0] = sp_switch;
9361 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9362 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9363 return \"mov r0,r15\";
9364}"
9365 [(set_attr "length" "10")])
4408efce 9366
956d6950 9367;; Switch back to the original stack for interrupt functions with the
4408efce
JL
9368;; sp_switch attribute. */
9369(define_insn "sp_switch_2"
9370 [(const_int 2)]
fa5322fa 9371 "TARGET_SH1"
4408efce
JL
9372 "mov.l @r15+,r15\;mov.l @r15+,r0"
9373 [(set_attr "length" "4")])
fae15c93 9374
c1b92d09
R
9375;; Integer vector moves
9376
9377(define_expand "movv8qi"
9378 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9379 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9380 "TARGET_SHMEDIA"
9381 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9382
9383(define_insn "movv8qi_i"
9384 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9385 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9386 "TARGET_SHMEDIA
9387 && (register_operand (operands[0], V8QImode)
d9da94a1 9388 || sh_register_operand (operands[1], V8QImode))"
c1b92d09
R
9389 "@
9390 add %1, r63, %0
9391 movi %1, %0
9392 #
9393 ld%M1.q %m1, %0
d9da94a1 9394 st%M0.q %m0, %N1"
c1b92d09
R
9395 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9396 (set_attr "length" "4,4,16,4,4")])
9397
9398(define_split
9399 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9400 (subreg:V8QI (const_int 0) 0))]
9401 "TARGET_SHMEDIA"
9402 [(set (match_dup 0)
9403 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9404 (const_int 0) (const_int 0) (const_int 0)
9405 (const_int 0) (const_int 0)]))])
9406
9407(define_split
9408 [(set (match_operand 0 "arith_reg_dest" "")
9409 (match_operand 1 "sh_rep_vec" ""))]
9410 "TARGET_SHMEDIA && reload_completed
9411 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9412 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9413 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9414 && (XVECEXP (operands[1], 0, 0) != const0_rtx
c034672a
R
9415 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9416 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9417 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
c1b92d09
R
9418 [(set (match_dup 0) (match_dup 1))
9419 (match_dup 2)]
9420 "
9421{
9422 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9423 rtx elt1 = XVECEXP (operands[1], 0, 1);
9424
9425 if (unit_size > 2)
9426 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9427 else
750afc12
R
9428 {
9429 if (unit_size < 2)
9430 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9431 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9432 }
c1b92d09
R
9433 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9434 operands[1] = XVECEXP (operands[1], 0, 0);
9435 if (unit_size < 2)
9436 {
9437 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9438 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9439 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9440 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9441 else
9442 {
9443 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9444 operands[1]
9445 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9446 }
9447 }
9448}")
9449
9450(define_split
9451 [(set (match_operand 0 "arith_reg_dest" "")
9452 (match_operand 1 "sh_const_vec" ""))]
9453 "TARGET_SHMEDIA && reload_completed
9454 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9455 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
0ac78517 9456 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
c1b92d09
R
9457 [(set (match_dup 0) (match_dup 1))]
9458 "
9459{
9460 rtx v = operands[1];
9461 enum machine_mode new_mode
9462 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9463
9464 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9465 operands[1]
52702ae1 9466 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
c1b92d09
R
9467}")
9468
9469(define_expand "movv2hi"
9470 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9471 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9472 "TARGET_SHMEDIA"
9473 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9474
9475(define_insn "movv2hi_i"
9476 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9477 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9478 "TARGET_SHMEDIA
9479 && (register_operand (operands[0], V2HImode)
d9da94a1 9480 || sh_register_operand (operands[1], V2HImode))"
c1b92d09
R
9481 "@
9482 addz.l %1, r63, %0
9483 movi %1, %0
9484 #
9485 ld%M1.l %m1, %0
d9da94a1 9486 st%M0.l %m0, %N1"
c1b92d09
R
9487 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9488 (set_attr "length" "4,4,16,4,4")])
9489
9490(define_expand "movv4hi"
9491 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9492 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9493 "TARGET_SHMEDIA"
9494 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9495
9496(define_insn "movv4hi_i"
9497 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9498 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9499 "TARGET_SHMEDIA
9500 && (register_operand (operands[0], V4HImode)
d9da94a1 9501 || sh_register_operand (operands[1], V4HImode))"
c1b92d09
R
9502 "@
9503 add %1, r63, %0
9504 movi %1, %0
9505 #
9506 ld%M1.q %m1, %0
d9da94a1 9507 st%M0.q %m0, %N1"
c1b92d09
R
9508 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9509 (set_attr "length" "4,4,16,4,4")])
9510
9511(define_expand "movv2si"
9512 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9513 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9514 "TARGET_SHMEDIA"
9515 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9516
9517(define_insn "movv2si_i"
9518 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9519 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9520 "TARGET_SHMEDIA
9521 && (register_operand (operands[0], V2SImode)
d9da94a1 9522 || sh_register_operand (operands[1], V2SImode))"
c1b92d09
R
9523 "@
9524 add %1, r63, %0
52702ae1 9525 #
c1b92d09
R
9526 #
9527 ld%M1.q %m1, %0
d9da94a1 9528 st%M0.q %m0, %N1"
c1b92d09
R
9529 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9530 (set_attr "length" "4,4,16,4,4")])
9531
9532;; Multimedia Intrinsics
9533
9534(define_insn "absv2si2"
9535 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9536 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9537 "TARGET_SHMEDIA"
9538 "mabs.l %1, %0"
9539 [(set_attr "type" "mcmp_media")])
9540
9541(define_insn "absv4hi2"
9542 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9543 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9544 "TARGET_SHMEDIA"
9545 "mabs.w %1, %0"
9546 [(set_attr "type" "mcmp_media")])
9547
9548(define_insn "addv2si3"
9549 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9550 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9551 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9552 "TARGET_SHMEDIA"
9553 "madd.l %1, %2, %0"
9554 [(set_attr "type" "arith_media")])
9555
9556(define_insn "addv4hi3"
9557 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9558 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9559 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9560 "TARGET_SHMEDIA"
9561 "madd.w %1, %2, %0"
9562 [(set_attr "type" "arith_media")])
9563
9564(define_insn "ssaddv2si3"
9565 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9566 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9567 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9568 "TARGET_SHMEDIA"
9569 "madds.l %1, %2, %0"
9570 [(set_attr "type" "mcmp_media")])
9571
9572(define_insn "usaddv8qi3"
9573 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9574 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9575 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9576 "TARGET_SHMEDIA"
9577 "madds.ub %1, %2, %0"
9578 [(set_attr "type" "mcmp_media")])
9579
9580(define_insn "ssaddv4hi3"
9581 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9582 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9583 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9584 "TARGET_SHMEDIA"
9585 "madds.w %1, %2, %0"
9586 [(set_attr "type" "mcmp_media")])
9587
9588(define_insn "negcmpeqv8qi"
9589 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
9590 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9591 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9592 "TARGET_SHMEDIA"
9593 "mcmpeq.b %N1, %N2, %0"
9594 [(set_attr "type" "mcmp_media")])
9595
9596(define_insn "negcmpeqv2si"
9597 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
9598 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9599 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9600 "TARGET_SHMEDIA"
9601 "mcmpeq.l %N1, %N2, %0"
9602 [(set_attr "type" "mcmp_media")])
9603
9604(define_insn "negcmpeqv4hi"
9605 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
9606 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9607 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9608 "TARGET_SHMEDIA"
9609 "mcmpeq.w %N1, %N2, %0"
9610 [(set_attr "type" "mcmp_media")])
9611
9612(define_insn "negcmpgtuv8qi"
9613 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
9614 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9615 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9616 "TARGET_SHMEDIA"
9617 "mcmpgt.ub %N1, %N2, %0"
9618 [(set_attr "type" "mcmp_media")])
9619
9620(define_insn "negcmpgtv2si"
9621 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
9622 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9623 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9624 "TARGET_SHMEDIA"
9625 "mcmpgt.l %N1, %N2, %0"
9626 [(set_attr "type" "mcmp_media")])
9627
9628(define_insn "negcmpgtv4hi"
9629 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
9630 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9631 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9632 "TARGET_SHMEDIA"
9633 "mcmpgt.w %N1, %N2, %0"
9634 [(set_attr "type" "mcmp_media")])
9635
9636(define_insn "mcmv"
9637 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9638 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9639 (match_operand:DI 2 "arith_reg_operand" "r"))
9640 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9641 (not:DI (match_dup 2)))))]
9642 "TARGET_SHMEDIA"
9643 "mcmv %N1, %2, %0"
9644 [(set_attr "type" "arith_media")])
9645
9646(define_insn "mcnvs_lw"
9647 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9648 (vec_concat:V4HI
735cb76e
R
9649 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9650 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9651 "TARGET_SHMEDIA"
9652 "mcnvs.lw %N1, %N2, %0"
9653 [(set_attr "type" "mcmp_media")])
9654
9655(define_insn "mcnvs_wb"
9656 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9657 (vec_concat:V8QI
735cb76e
R
9658 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9659 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9660 "TARGET_SHMEDIA"
9661 "mcnvs.wb %N1, %N2, %0"
9662 [(set_attr "type" "mcmp_media")])
9663
9664(define_insn "mcnvs_wub"
9665 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9666 (vec_concat:V8QI
735cb76e
R
9667 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9668 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9669 "TARGET_SHMEDIA"
9670 "mcnvs.wub %N1, %N2, %0"
9671 [(set_attr "type" "mcmp_media")])
9672
9673(define_insn "mextr_rl"
9674 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9675 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 9676 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 9677 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9678 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9679 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9680 "*
9681{
9682 static char templ[16];
9683
9684 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9685 (int) INTVAL (operands[3]) >> 3);
9686 return templ;
9687}"
9688 [(set_attr "type" "arith_media")])
9689
9690(define_insn "*mextr_lr"
9691 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9692 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 9693 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 9694 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9695 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9696 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9697 "*
9698{
9699 static char templ[16];
9700
9701 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9702 (int) INTVAL (operands[4]) >> 3);
9703 return templ;
9704}"
9705 [(set_attr "type" "arith_media")])
9706
9707; mextrN can be modelled with vec_select / vec_concat, but the selection
9708; vector then varies depending on endianness.
9709(define_expand "mextr1"
0ac78517 9710 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9711 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9712 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9713 "TARGET_SHMEDIA"
9714 "
9715{
0ac78517 9716 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9717 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9718 DONE;
9719}")
9720
9721(define_expand "mextr2"
0ac78517 9722 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9723 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9724 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9725 "TARGET_SHMEDIA"
9726 "
9727{
0ac78517 9728 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9729 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9730 DONE;
9731}")
9732
9733(define_expand "mextr3"
0ac78517 9734 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9735 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9736 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9737 "TARGET_SHMEDIA"
9738 "
9739{
0ac78517 9740 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9741 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9742 DONE;
9743}")
9744
9745(define_expand "mextr4"
0ac78517 9746 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9747 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9748 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9749 "TARGET_SHMEDIA"
9750 "
9751{
0ac78517 9752 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9753 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9754 DONE;
9755}")
9756
9757(define_expand "mextr5"
0ac78517 9758 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9759 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9760 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9761 "TARGET_SHMEDIA"
9762 "
9763{
0ac78517 9764 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9765 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9766 DONE;
9767}")
9768
9769(define_expand "mextr6"
0ac78517 9770 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9771 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9772 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9773 "TARGET_SHMEDIA"
9774 "
9775{
0ac78517 9776 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9777 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9778 DONE;
9779}")
9780
9781(define_expand "mextr7"
0ac78517 9782 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9783 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9784 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9785 "TARGET_SHMEDIA"
9786 "
9787{
0ac78517 9788 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9789 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9790 DONE;
9791}")
9792
9793(define_expand "mmacfx_wl"
9794 [(match_operand:V2SI 0 "arith_reg_dest" "")
9795 (match_operand:V2HI 1 "extend_reg_operand" "")
9796 (match_operand:V2HI 2 "extend_reg_operand" "")
9797 (match_operand:V2SI 3 "arith_reg_operand" "")]
9798 "TARGET_SHMEDIA"
9799 "
9800{
9801 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9802 operands[1], operands[2]));
9803 DONE;
9804}")
9805
9806(define_insn "mmacfx_wl_i"
9807 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9808 (ss_plus:V2SI
9809 (match_operand:V2SI 1 "arith_reg_operand" "0")
9810 (ss_truncate:V2SI
9811 (ashift:V2DI
9812 (sign_extend:V2DI
9813 (mult:V2SI
9814 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9815 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9816 (const_int 1)))))]
9817 "TARGET_SHMEDIA"
9818 "mmacfx.wl %2, %3, %0"
9819 [(set_attr "type" "mac_media")])
9820
9821(define_expand "mmacnfx_wl"
9822 [(match_operand:V2SI 0 "arith_reg_dest" "")
9823 (match_operand:V2HI 1 "extend_reg_operand" "")
9824 (match_operand:V2HI 2 "extend_reg_operand" "")
9825 (match_operand:V2SI 3 "arith_reg_operand" "")]
9826 "TARGET_SHMEDIA"
9827 "
9828{
9829 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9830 operands[1], operands[2]));
9831 DONE;
9832}")
9833
9834(define_insn "mmacnfx_wl_i"
9835 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9836 (ss_minus:V2SI
9837 (match_operand:V2SI 1 "arith_reg_operand" "0")
9838 (ss_truncate:V2SI
9839 (ashift:V2DI
9840 (sign_extend:V2DI
9841 (mult:V2SI
9842 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9843 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9844 (const_int 1)))))]
9845 "TARGET_SHMEDIA"
9846 "mmacnfx.wl %2, %3, %0"
9847 [(set_attr "type" "mac_media")])
9848
9849(define_insn "mulv2si3"
9850 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9851 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9852 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9853 "TARGET_SHMEDIA"
9854 "mmul.l %1, %2, %0"
9855 [(set_attr "type" "d2mpy_media")])
9856
9857(define_insn "mulv4hi3"
9858 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9859 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9860 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9861 "TARGET_SHMEDIA"
9862 "mmul.w %1, %2, %0"
9863 [(set_attr "type" "dmpy_media")])
9864
9865(define_insn "mmulfx_l"
9866 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9867 (ss_truncate:V2SI
9868 (ashiftrt:V2DI
9869 (mult:V2DI
9870 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9871 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9872 (const_int 31))))]
9873 "TARGET_SHMEDIA"
9874 "mmulfx.l %1, %2, %0"
9875 [(set_attr "type" "d2mpy_media")])
9876
9877(define_insn "mmulfx_w"
9878 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9879 (ss_truncate:V4HI
9880 (ashiftrt:V4SI
9881 (mult:V4SI
9882 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9883 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9884 (const_int 15))))]
9885 "TARGET_SHMEDIA"
9886 "mmulfx.w %1, %2, %0"
9887 [(set_attr "type" "dmpy_media")])
9888
9889(define_insn "mmulfxrp_w"
9890 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9891 (ss_truncate:V4HI
9892 (ashiftrt:V4SI
9893 (plus:V4SI
9894 (mult:V4SI
9895 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9896 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9897 (const_int 16384))
9898 (const_int 15))))]
9899 "TARGET_SHMEDIA"
9900 "mmulfxrp.w %1, %2, %0"
9901 [(set_attr "type" "dmpy_media")])
9902
9903(define_expand "mmulhi_wl"
9904 [(match_operand:V2SI 0 "arith_reg_dest" "")
9905 (match_operand:V4HI 1 "arith_reg_operand" "")
9906 (match_operand:V4HI 2 "arith_reg_operand" "")]
9907 "TARGET_SHMEDIA"
9908 "
9909{
9910 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9911 (operands[0], operands[1], operands[2]));
9912 DONE;
9913}")
9914
9915(define_expand "mmullo_wl"
9916 [(match_operand:V2SI 0 "arith_reg_dest" "")
9917 (match_operand:V4HI 1 "arith_reg_operand" "")
9918 (match_operand:V4HI 2 "arith_reg_operand" "")]
9919 "TARGET_SHMEDIA"
9920 "
9921{
9922 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9923 (operands[0], operands[1], operands[2]));
9924 DONE;
9925}")
9926
9927(define_insn "mmul23_wl"
9928 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9929 (vec_select:V2SI
9930 (mult:V4SI
9931 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9932 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 9933 (parallel [(const_int 2) (const_int 3)])))]
c1b92d09
R
9934 "TARGET_SHMEDIA"
9935 "* return (TARGET_LITTLE_ENDIAN
9936 ? \"mmulhi.wl %1, %2, %0\"
9937 : \"mmullo.wl %1, %2, %0\");"
9938 [(set_attr "type" "dmpy_media")])
9939
9940(define_insn "mmul01_wl"
9941 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9942 (vec_select:V2SI
9943 (mult:V4SI
9944 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9945 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 9946 (parallel [(const_int 0) (const_int 1)])))]
c1b92d09
R
9947 "TARGET_SHMEDIA"
9948 "* return (TARGET_LITTLE_ENDIAN
9949 ? \"mmullo.wl %1, %2, %0\"
9950 : \"mmulhi.wl %1, %2, %0\");"
9951 [(set_attr "type" "dmpy_media")])
9952
9953(define_expand "mmulsum_wq"
9954 [(match_operand:DI 0 "arith_reg_dest" "")
9955 (match_operand:V4HI 1 "arith_reg_operand" "")
9956 (match_operand:V4HI 2 "arith_reg_operand" "")
9957 (match_operand:DI 3 "arith_reg_operand" "")]
9958 "TARGET_SHMEDIA"
9959 "
9960{
9961 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9962 operands[1], operands[2]));
9963 DONE;
9964}")
9965
9966(define_insn "mmulsum_wq_i"
9967 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9968 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9969 (plus:DI
9970 (plus:DI
9971 (vec_select:DI
9972 (mult:V4DI
9973 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9974 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
0ac78517 9975 (parallel [(const_int 0)]))
c1b92d09
R
9976 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9977 (sign_extend:V4DI (match_dup 3)))
0ac78517 9978 (parallel [(const_int 1)])))
c1b92d09
R
9979 (plus:DI
9980 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9981 (sign_extend:V4DI (match_dup 3)))
0ac78517 9982 (parallel [(const_int 2)]))
c1b92d09
R
9983 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9984 (sign_extend:V4DI (match_dup 3)))
0ac78517 9985 (parallel [(const_int 3)]))))))]
c1b92d09
R
9986 "TARGET_SHMEDIA"
9987 "mmulsum.wq %2, %3, %0"
9988 [(set_attr "type" "mac_media")])
9989
9990(define_expand "mperm_w"
9991 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9992 (match_operand:V4HI 1 "arith_reg_operand" "r")
735cb76e 9993 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
c1b92d09
R
9994 "TARGET_SHMEDIA"
9995 "
9996{
9997 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9998 (operands[0], operands[1], operands[2]));
c49439f1 9999 DONE;
c1b92d09
R
10000}")
10001
10002; This use of vec_select isn't exactly correct according to rtl.texi
10003; (because not constant), but it seems a straightforward extension.
10004(define_insn "mperm_w_little"
10005 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10006 (vec_select:V4HI
10007 (match_operand:V4HI 1 "arith_reg_operand" "r")
10008 (parallel
735cb76e 10009 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
502e6d5a
R
10010 (const_int 2) (const_int 0))
10011 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10012 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10013 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
c1b92d09
R
10014 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10015 "mperm.w %1, %N2, %0"
10016 [(set_attr "type" "arith_media")])
10017
10018(define_insn "mperm_w_big"
10019 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10020 (vec_select:V4HI
10021 (match_operand:V4HI 1 "arith_reg_operand" "r")
10022 (parallel
502e6d5a 10023 [(zero_extract:QI (not:QI (match_operand:QI 2
735cb76e 10024 "extend_reg_or_0_operand" "rZ"))
502e6d5a
R
10025 (const_int 2) (const_int 0))
10026 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10027 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10028 (zero_extract:QI (not:QI (match_dup 2))
10029 (const_int 2) (const_int 6))])))]
c1b92d09
R
10030 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10031 "mperm.w %1, %N2, %0"
10032 [(set_attr "type" "arith_media")])
10033
10034(define_insn "mperm_w0"
10035 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10036 (vec_duplicate:V4HI (truncate:HI (match_operand 1
e69d1422 10037 "trunc_hi_operand" "r"))))]
c1b92d09
R
10038 "TARGET_SHMEDIA"
10039 "mperm.w %1, r63, %0"
10040 [(set_attr "type" "arith_media")])
10041
10042(define_expand "msad_ubq"
10043 [(match_operand:DI 0 "arith_reg_dest" "")
10044 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10045 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10046 (match_operand:DI 3 "arith_reg_operand" "")]
10047 "TARGET_SHMEDIA"
10048 "
10049{
10050 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10051 operands[1], operands[2]));
10052 DONE;
10053}")
10054
10055(define_insn "msad_ubq_i"
10056 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10057 (plus:DI
10058 (plus:DI
10059 (plus:DI
10060 (plus:DI
10061 (match_operand:DI 1 "arith_reg_operand" "0")
10062 (abs:DI (vec_select:DI
10063 (minus:V8DI
10064 (zero_extend:V8DI
735cb76e 10065 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
c1b92d09 10066 (zero_extend:V8DI
735cb76e 10067 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
0ac78517 10068 (parallel [(const_int 0)]))))
c1b92d09
R
10069 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10070 (zero_extend:V8DI (match_dup 3)))
0ac78517 10071 (parallel [(const_int 1)]))))
c1b92d09
R
10072 (plus:DI
10073 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10074 (zero_extend:V8DI (match_dup 3)))
0ac78517 10075 (parallel [(const_int 2)])))
c1b92d09
R
10076 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10077 (zero_extend:V8DI (match_dup 3)))
0ac78517 10078 (parallel [(const_int 3)])))))
c1b92d09
R
10079 (plus:DI
10080 (plus:DI
10081 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10082 (zero_extend:V8DI (match_dup 3)))
0ac78517 10083 (parallel [(const_int 4)])))
c1b92d09
R
10084 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10085 (zero_extend:V8DI (match_dup 3)))
0ac78517 10086 (parallel [(const_int 5)]))))
c1b92d09
R
10087 (plus:DI
10088 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10089 (zero_extend:V8DI (match_dup 3)))
0ac78517 10090 (parallel [(const_int 6)])))
c1b92d09
R
10091 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10092 (zero_extend:V8DI (match_dup 3)))
0ac78517 10093 (parallel [(const_int 7)])))))))]
c1b92d09
R
10094 "TARGET_SHMEDIA"
10095 "msad.ubq %N2, %N3, %0"
10096 [(set_attr "type" "mac_media")])
10097
10098(define_insn "mshalds_l"
10099 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10100 (ss_truncate:V2SI
10101 (ashift:V2DI
10102 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10103 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10104 (const_int 31)))))]
10105 "TARGET_SHMEDIA"
10106 "mshalds.l %1, %2, %0"
10107 [(set_attr "type" "mcmp_media")])
10108
10109(define_insn "mshalds_w"
10110 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10111 (ss_truncate:V4HI
10112 (ashift:V4SI
10113 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10114 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10115 (const_int 15)))))]
10116 "TARGET_SHMEDIA"
10117 "mshalds.w %1, %2, %0"
10118 [(set_attr "type" "mcmp_media")])
10119
10120(define_insn "ashrv2si3"
10121 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10122 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10123 (match_operand:DI 2 "arith_reg_operand" "r")))]
10124 "TARGET_SHMEDIA"
10125 "mshard.l %1, %2, %0"
10126 [(set_attr "type" "arith_media")])
10127
10128(define_insn "ashrv4hi3"
10129 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10130 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10131 (match_operand:DI 2 "arith_reg_operand" "r")))]
10132 "TARGET_SHMEDIA"
10133 "mshard.w %1, %2, %0"
10134 [(set_attr "type" "arith_media")])
10135
10136(define_insn "mshards_q"
10137 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10138 (ss_truncate:HI
10139 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
735cb76e 10140 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
10141 "TARGET_SHMEDIA"
10142 "mshards.q %1, %N2, %0"
10143 [(set_attr "type" "mcmp_media")])
10144
10145(define_expand "mshfhi_b"
10146 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
10147 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10148 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10149 "TARGET_SHMEDIA"
10150 "
10151{
10152 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10153 (operands[0], operands[1], operands[2]));
8721e3df 10154 DONE;
c1b92d09
R
10155}")
10156
10157(define_expand "mshflo_b"
10158 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
10159 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10160 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10161 "TARGET_SHMEDIA"
10162 "
10163{
10164 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10165 (operands[0], operands[1], operands[2]));
8721e3df 10166 DONE;
c1b92d09
R
10167}")
10168
10169(define_insn "mshf4_b"
10170 [(set
10171 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10172 (vec_select:V8QI
735cb76e
R
10173 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10174 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
10175 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10176 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
c1b92d09
R
10177 "TARGET_SHMEDIA"
10178 "* return (TARGET_LITTLE_ENDIAN
10179 ? \"mshfhi.b %N1, %N2, %0\"
10180 : \"mshflo.b %N1, %N2, %0\");"
10181 [(set_attr "type" "arith_media")])
10182
10183(define_insn "mshf0_b"
10184 [(set
10185 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10186 (vec_select:V8QI
735cb76e
R
10187 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10188 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
10189 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10190 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
c1b92d09
R
10191 "TARGET_SHMEDIA"
10192 "* return (TARGET_LITTLE_ENDIAN
10193 ? \"mshflo.b %N1, %N2, %0\"
10194 : \"mshfhi.b %N1, %N2, %0\");"
10195 [(set_attr "type" "arith_media")])
10196
10197(define_expand "mshfhi_l"
10198 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
10199 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10200 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10201 "TARGET_SHMEDIA"
10202 "
10203{
10204 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10205 (operands[0], operands[1], operands[2]));
8721e3df 10206 DONE;
c1b92d09
R
10207}")
10208
10209(define_expand "mshflo_l"
10210 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
10211 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10212 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10213 "TARGET_SHMEDIA"
10214 "
10215{
10216 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10217 (operands[0], operands[1], operands[2]));
8721e3df 10218 DONE;
c1b92d09
R
10219}")
10220
10221(define_insn "mshf4_l"
10222 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10223 (vec_select:V2SI
735cb76e
R
10224 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10225 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10226 (parallel [(const_int 1) (const_int 3)])))]
c1b92d09
R
10227 "TARGET_SHMEDIA"
10228 "* return (TARGET_LITTLE_ENDIAN
10229 ? \"mshfhi.l %N1, %N2, %0\"
10230 : \"mshflo.l %N1, %N2, %0\");"
10231 [(set_attr "type" "arith_media")])
10232
10233(define_insn "mshf0_l"
10234 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10235 (vec_select:V2SI
735cb76e
R
10236 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10237 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10238 (parallel [(const_int 0) (const_int 2)])))]
c1b92d09
R
10239 "TARGET_SHMEDIA"
10240 "* return (TARGET_LITTLE_ENDIAN
10241 ? \"mshflo.l %N1, %N2, %0\"
10242 : \"mshfhi.l %N1, %N2, %0\");"
10243 [(set_attr "type" "arith_media")])
10244
10245(define_expand "mshfhi_w"
10246 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
10247 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10248 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10249 "TARGET_SHMEDIA"
10250 "
10251{
10252 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10253 (operands[0], operands[1], operands[2]));
8721e3df 10254 DONE;
c1b92d09
R
10255}")
10256
10257(define_expand "mshflo_w"
10258 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
10259 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10260 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10261 "TARGET_SHMEDIA"
10262 "
10263{
10264 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10265 (operands[0], operands[1], operands[2]));
8721e3df 10266 DONE;
c1b92d09
R
10267}")
10268
10269(define_insn "mshf4_w"
10270 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10271 (vec_select:V4HI
735cb76e
R
10272 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10273 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10274 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
c1b92d09
R
10275 "TARGET_SHMEDIA"
10276 "* return (TARGET_LITTLE_ENDIAN
10277 ? \"mshfhi.w %N1, %N2, %0\"
10278 : \"mshflo.w %N1, %N2, %0\");"
10279 [(set_attr "type" "arith_media")])
10280
10281(define_insn "mshf0_w"
10282 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10283 (vec_select:V4HI
735cb76e
R
10284 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10285 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10286 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
c1b92d09
R
10287 "TARGET_SHMEDIA"
10288 "* return (TARGET_LITTLE_ENDIAN
10289 ? \"mshflo.w %N1, %N2, %0\"
10290 : \"mshfhi.w %N1, %N2, %0\");"
10291 [(set_attr "type" "arith_media")])
10292
0ac78517
R
10293(define_insn "mshflo_w_x"
10294 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10295 (vec_select:V4HI
735cb76e
R
10296 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10297 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
08c43ea7 10298 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
0ac78517
R
10299 "TARGET_SHMEDIA"
10300 "mshflo.w %N1, %N2, %0"
10301 [(set_attr "type" "arith_media")])
10302
c1b92d09 10303/* These are useful to expand ANDs and as combiner patterns. */
0ac78517
R
10304(define_insn_and_split "mshfhi_l_di"
10305 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
735cb76e 10306 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
c1b92d09 10307 (const_int 32))
735cb76e 10308 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
c1b92d09
R
10309 (const_int -4294967296))))]
10310 "TARGET_SHMEDIA"
0ac78517
R
10311 "@
10312 mshfhi.l %N1, %N2, %0
10313 #"
10314 "TARGET_SHMEDIA && reload_completed
10315 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10316 [(set (match_dup 3) (match_dup 4))
10317 (set (match_dup 5) (match_dup 6))]
10318 "
10319{
10320 operands[3] = gen_lowpart (SImode, operands[0]);
10321 operands[4] = gen_highpart (SImode, operands[1]);
10322 operands[5] = gen_highpart (SImode, operands[0]);
10323 operands[6] = gen_highpart (SImode, operands[2]);
10324}"
c1b92d09
R
10325 [(set_attr "type" "arith_media")])
10326
10327(define_insn "*mshfhi_l_di_rev"
10328 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10329 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10330 (const_int -4294967296))
735cb76e 10331 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10332 (const_int 32))))]
10333 "TARGET_SHMEDIA"
10334 "mshfhi.l %N2, %N1, %0"
10335 [(set_attr "type" "arith_media")])
10336
52702ae1
R
10337(define_split
10338 [(set (match_operand:DI 0 "arith_reg_dest" "")
10339 (ior:DI (zero_extend:DI (match_operand:SI 1
10340 "extend_reg_or_0_operand" ""))
10341 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10342 (const_int -4294967296))))
10343 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10344 "TARGET_SHMEDIA"
10345 [(const_int 0)]
10346 "
10347{
10348 emit_insn (gen_ashldi3_media (operands[3],
10349 simplify_gen_subreg (DImode, operands[1],
10350 SImode, 0),
10351 GEN_INT (32)));
10352 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10353 DONE;
10354}")
10355
c1b92d09
R
10356(define_insn "mshflo_l_di"
10357 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10358 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10359 (const_int 4294967295))
735cb76e 10360 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10361 (const_int 32))))]
10362
10363 "TARGET_SHMEDIA"
10364 "mshflo.l %N1, %N2, %0"
10365 [(set_attr "type" "arith_media")])
10366
10367(define_insn "*mshflo_l_di_rev"
10368 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10369 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10370 (const_int 32))
735cb76e 10371 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10372 (const_int 4294967295))))]
10373
10374 "TARGET_SHMEDIA"
10375 "mshflo.l %N2, %N1, %0"
10376 [(set_attr "type" "arith_media")])
10377
ca903bba
R
10378;; Combiner pattern for trampoline initialization.
10379(define_insn_and_split "*double_shori"
10380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10381 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10382 (const_int 32))
10383 (match_operand:DI 2 "const_int_operand" "n")))]
10384 "TARGET_SHMEDIA
10385 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10386 "#"
10387 "rtx_equal_p (operands[0], operands[1])"
10388 [(const_int 0)]
10389 "
10390{
10391 HOST_WIDE_INT v = INTVAL (operands[2]);
10392
10393 emit_insn (gen_shori_media (operands[0], operands[0],
10394 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10395 emit_insn (gen_shori_media (operands[0], operands[0],
10396 gen_int_mode (v, HImode)));
10397 DONE;
10398}")
10399
10400
c1b92d09
R
10401(define_insn "*mshflo_l_di_x"
10402 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
0ac78517 10403 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
735cb76e
R
10404 "rZ"))
10405 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10406 (const_int 32))))]
10407
10408 "TARGET_SHMEDIA"
10409 "mshflo.l %N1, %N2, %0"
10410 [(set_attr "type" "arith_media")])
10411
0ac78517
R
10412(define_insn_and_split "concat_v2sf"
10413 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
735cb76e
R
10414;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10415 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10416 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
0ac78517
R
10417
10418 "TARGET_SHMEDIA"
10419 "@
10420 mshflo.l %N1, %N2, %0
10421 #
10422 #"
10423 "TARGET_SHMEDIA && reload_completed
10424 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10425 [(set (match_dup 3) (match_dup 1))
10426 (set (match_dup 4) (match_dup 2))]
10427 "
10428{
10429 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10430 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10431}"
10432 [(set_attr "type" "arith_media")])
10433
c1b92d09
R
10434(define_insn "*mshflo_l_di_x_rev"
10435 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10436 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10437 (const_int 32))
735cb76e 10438 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
c1b92d09
R
10439
10440 "TARGET_SHMEDIA"
10441 "mshflo.l %N2, %N1, %0"
10442 [(set_attr "type" "arith_media")])
10443
10444(define_insn "ashlv2si3"
10445 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10446 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10447 (match_operand:DI 2 "arith_reg_operand" "r")))]
10448 "TARGET_SHMEDIA"
10449 "mshlld.l %1, %2, %0"
10450 [(set_attr "type" "arith_media")])
10451
10452(define_insn "ashlv4hi3"
10453 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10454 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10455 (match_operand:DI 2 "arith_reg_operand" "r")))]
10456 "TARGET_SHMEDIA"
10457 "mshlld.w %1, %2, %0"
10458 [(set_attr "type" "arith_media")])
10459
10460(define_insn "lshrv2si3"
10461 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10462 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10463 (match_operand:DI 2 "arith_reg_operand" "r")))]
10464 "TARGET_SHMEDIA"
10465 "mshlrd.l %1, %2, %0"
10466 [(set_attr "type" "arith_media")])
10467
10468(define_insn "lshrv4hi3"
10469 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10470 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10471 (match_operand:DI 2 "arith_reg_operand" "r")))]
10472 "TARGET_SHMEDIA"
10473 "mshlrd.w %1, %2, %0"
10474 [(set_attr "type" "arith_media")])
10475
10476(define_insn "subv2si3"
10477 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 10478 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10479 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10480 "TARGET_SHMEDIA"
10481 "msub.l %N1, %2, %0"
10482 [(set_attr "type" "arith_media")])
10483
10484(define_insn "subv4hi3"
10485 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 10486 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10487 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10488 "TARGET_SHMEDIA"
10489 "msub.w %N1, %2, %0"
10490 [(set_attr "type" "arith_media")])
10491
10492(define_insn "sssubv2si3"
10493 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 10494 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10495 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10496 "TARGET_SHMEDIA"
10497 "msubs.l %N1, %2, %0"
10498 [(set_attr "type" "mcmp_media")])
10499
10500(define_insn "ussubv8qi3"
10501 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10502 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10503 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10504 "TARGET_SHMEDIA"
10505 "msubs.ub %1, %2, %0"
10506 [(set_attr "type" "mcmp_media")])
10507
10508(define_insn "sssubv4hi3"
10509 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 10510 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10511 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10512 "TARGET_SHMEDIA"
10513 "msubs.w %N1, %2, %0"
10514 [(set_attr "type" "mcmp_media")])
10515
10516;; Floating Point Intrinsics
10517
10518(define_insn "fcosa_s"
10519 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10520 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10521 UNSPEC_FCOSA))]
10522 "TARGET_SHMEDIA"
10523 "fcosa.s %1, %0"
10524 [(set_attr "type" "atrans_media")])
10525
10526(define_insn "fsina_s"
10527 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10528 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10529 UNSPEC_FSINA))]
10530 "TARGET_SHMEDIA"
10531 "fsina.s %1, %0"
10532 [(set_attr "type" "atrans_media")])
10533
10534(define_insn "fipr"
10535 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10537 "fp_arith_reg_operand" "f")
10538 (match_operand:V4SF 2
10539 "fp_arith_reg_operand" "f"))
0ac78517 10540 (parallel [(const_int 0)]))
c1b92d09 10541 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10542 (parallel [(const_int 1)])))
c1b92d09 10543 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10544 (parallel [(const_int 2)]))
c1b92d09 10545 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10546 (parallel [(const_int 3)])))))]
c1b92d09
R
10547 "TARGET_SHMEDIA"
10548 "fipr %1, %2, %0"
10549 [(set_attr "type" "fparith_media")])
10550
10551(define_insn "fsrra_s"
10552 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10553 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10554 UNSPEC_FSRRA))]
10555 "TARGET_SHMEDIA"
10556 "fsrra.s %1, %0"
10557 [(set_attr "type" "atrans_media")])
10558
10559(define_insn "ftrv"
10560 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10561 (plus:V4SF
10562 (plus:V4SF
10563 (mult:V4SF
10564 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
0ac78517
R
10565 (parallel [(const_int 0) (const_int 5)
10566 (const_int 10) (const_int 15)]))
c1b92d09
R
10567 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10568 (mult:V4SF
10569 (vec_select:V4SF (match_dup 1)
0ac78517
R
10570 (parallel [(const_int 4) (const_int 9)
10571 (const_int 14) (const_int 3)]))
c1b92d09 10572 (vec_select:V4SF (match_dup 2)
0ac78517
R
10573 (parallel [(const_int 1) (const_int 2)
10574 (const_int 3) (const_int 0)]))))
c1b92d09
R
10575 (plus:V4SF
10576 (mult:V4SF
10577 (vec_select:V4SF (match_dup 1)
0ac78517
R
10578 (parallel [(const_int 8) (const_int 13)
10579 (const_int 2) (const_int 7)]))
c1b92d09 10580 (vec_select:V4SF (match_dup 2)
0ac78517
R
10581 (parallel [(const_int 2) (const_int 3)
10582 (const_int 0) (const_int 1)])))
c1b92d09
R
10583 (mult:V4SF
10584 (vec_select:V4SF (match_dup 1)
0ac78517
R
10585 (parallel [(const_int 12) (const_int 1)
10586 (const_int 6) (const_int 11)]))
c1b92d09 10587 (vec_select:V4SF (match_dup 2)
0ac78517
R
10588 (parallel [(const_int 3) (const_int 0)
10589 (const_int 1) (const_int 2)]))))))]
c1b92d09
R
10590 "TARGET_SHMEDIA"
10591 "ftrv %1, %2, %0"
10592 [(set_attr "type" "fparith_media")])
10593
b6d33983
R
10594(define_insn "nsb"
10595 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10596 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10597 UNSPEC_NSB))]
10598 "TARGET_SHMEDIA"
10599 "nsb %1, %0"
10600 [(set_attr "type" "arith_media")])
10601
10602(define_insn "nsbsi"
10603 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10604 (zero_extend:SI
10605 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10606 UNSPEC_NSB)))]
10607 "TARGET_SHMEDIA"
10608 "nsb %1, %0"
10609 [(set_attr "type" "arith_media")])
10610
10611(define_insn "nsbdi"
10612 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10613 (zero_extend:DI
10614 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10615 UNSPEC_NSB)))]
10616 "TARGET_SHMEDIA"
10617 "nsb %1, %0"
10618 [(set_attr "type" "arith_media")])
10619
10620(define_expand "ffsdi2"
10621 [(set (match_operand:DI 0 "arith_reg_dest" "")
10622 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10623 "TARGET_SHMEDIA"
10624 "
10625{
10626 rtx scratch = gen_reg_rtx (DImode);
10627 rtx last;
10628
10629 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10630 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10631 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10632 emit_insn (gen_nsbdi (scratch, scratch));
10633 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10634 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10635 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10636 REG_NOTES (last)
10637 = gen_rtx_EXPR_LIST (REG_EQUAL,
10638 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10639 DONE;
10640}")
10641
10642(define_expand "ffssi2"
10643 [(set (match_operand:SI 0 "arith_reg_dest" "")
10644 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10645 "TARGET_SHMEDIA"
10646 "
10647{
10648 rtx scratch = gen_reg_rtx (SImode);
10649 rtx discratch = gen_reg_rtx (DImode);
10650 rtx last;
10651
e3c62520
R
10652 emit_insn (gen_adddi3 (discratch,
10653 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10654 GEN_INT (-1)));
10655 emit_insn (gen_andcdi3 (discratch,
10656 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10657 discratch));
b6d33983
R
10658 emit_insn (gen_nsbsi (scratch, discratch));
10659 last = emit_insn (gen_subsi3 (operands[0],
e3c62520 10660 force_reg (SImode, GEN_INT (63)), scratch));
b6d33983
R
10661 REG_NOTES (last)
10662 = gen_rtx_EXPR_LIST (REG_EQUAL,
10663 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10664 DONE;
10665}")
10666
10667(define_insn "byterev"
10668 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10669 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10670 (parallel [(const_int 7) (const_int 6) (const_int 5)
10671 (const_int 4) (const_int 3) (const_int 2)
10672 (const_int 1) (const_int 0)])))]
10673 "TARGET_SHMEDIA"
10674 "byterev %1, %0"
10675 [(set_attr "type" "arith_media")])
10676
fae15c93
VM
10677;; The following description models the
10678;; SH4 pipeline using the DFA based scheduler.
10679;; The DFA based description is better way to model
10680;; a superscalar pipeline as compared to function unit
10681;; reservation model.
10682;; 1. The function unit based model is oriented to describe at most one
10683;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10684;; pipeline units by same insn. This can be done using DFA based description.
10685;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10686;; 3. Writing all unit reservations for an instruction class is more natural description
10687;; of the pipeline and makes interface of the hazard recognizer simpler than the
10688;; old function unit based model.
10689;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10690
10691
10692;; Two automata are defined to reduce number of states
10693;; which a single large automaton will have.(Factoring)
10694
10695(define_automaton "inst_pipeline,fpu_pipe")
10696
10697;; This unit is basically the decode unit of the processor.
10698;; Since SH4 is a dual issue machine,it is as if there are two
10699;; units so that any insn can be processed by either one
10700;; of the decoding unit.
10701
10702(define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10703
10704
10705;; The fixed point arithmetic calculator(?? EX Unit).
10706
10707(define_cpu_unit "int" "inst_pipeline")
10708
10709;; f1_1 and f1_2 are floating point units.Actually there is
10710;; a f1 unit which can overlap with other f1 unit but
10711;; not another F1 unit.It is as though there were two
10712;; f1 units.
10713
10714(define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10715
c49439f1 10716;; The floating point units (except FS - F2 always precedes it.)
fae15c93 10717
c49439f1 10718(define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
fae15c93
VM
10719
10720;; This is basically the MA unit of SH4
10721;; used in LOAD/STORE pipeline.
10722
10723(define_cpu_unit "memory" "inst_pipeline")
10724
c49439f1
R
10725;; However, there are LS group insns that don't use it, even ones that
10726;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10727(define_cpu_unit "load_store" "inst_pipeline")
10728
fae15c93 10729;; The address calculator used for branch instructions.
c49439f1
R
10730;; This will be reserved after "issue" of branch instructions
10731;; and this is to make sure that no two branch instructions
fae15c93
VM
10732;; can be issued in parallel.
10733
10734(define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10735
10736;; ----------------------------------------------------
10737;; This reservation is to simplify the dual issue description.
10738
10739(define_reservation "issue" "pipe_01|pipe_02")
10740
10741;; This is to express the locking of D stage.
c49439f1 10742;; Note that the issue of a CO group insn also effectively locks the D stage.
fae15c93
VM
10743
10744(define_reservation "d_lock" "pipe_01+pipe_02")
10745
c49439f1
R
10746;; Every FE instruction but fipr / ftrv starts with issue and this.
10747(define_reservation "F01" "F0+F1")
10748
fae15c93
VM
10749;; This is to simplify description where F1,F2,FS
10750;; are used simultaneously.
10751
c49439f1 10752(define_reservation "fpu" "F1+F2")
fae15c93
VM
10753
10754;; This is to highlight the fact that f1
10755;; cannot overlap with F1.
10756
10757(exclusion_set "f1_1,f1_2" "F1")
10758
c49439f1
R
10759(define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10760
fae15c93
VM
10761;; Although reg moves have a latency of zero
10762;; we need to highlight that they use D stage
10763;; for one cycle.
10764
c49439f1
R
10765;; Group: MT
10766
fae15c93 10767(define_insn_reservation "reg_mov" 0
c49439f1
R
10768 (and (eq_attr "pipe_model" "sh4")
10769 (eq_attr "type" "move"))
10770 "issue")
10771
10772;; Group: LS
10773
10774(define_insn_reservation "freg_mov" 0
10775 (and (eq_attr "pipe_model" "sh4")
10776 (eq_attr "type" "fmove"))
10777 "issue+load_store")
10778
10779;; We don't model all pipeline stages; we model the issue ('D') stage
825db093
KH
10780;; inasmuch as we allow only two instructions to issue simultaneously,
10781;; and CO instructions prevent any simultaneous issue of another instruction.
c49439f1
R
10782;; (This uses pipe_01 and pipe_02).
10783;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10784;; Double issue of EX / BR insns is prevented by using the int unit /
10785;; pcr_addrcalc unit in the EX stage.
10786;; Double issue of BR / LS instructions is prevented by using the
10787;; pcr_addrcalc / load_store unit in the issue cycle.
10788;; Double issue of FE instructions is prevented by using F0 in the first
10789;; pipeline stage after the first D stage.
10790;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10791;; (except in the cases outlined above), nor to describe the FS stage after
10792;; the F2 stage.
fae15c93 10793
825db093 10794;; Other MT group instructions(1 step operations)
fae15c93
VM
10795;; Group: MT
10796;; Latency: 1
10797;; Issue Rate: 1
10798
10799(define_insn_reservation "mt" 1
c49439f1
R
10800 (and (eq_attr "pipe_model" "sh4")
10801 (eq_attr "type" "mt_group"))
10802 "issue")
fae15c93
VM
10803
10804;; Fixed Point Arithmetic Instructions(1 step operations)
10805;; Group: EX
10806;; Latency: 1
10807;; Issue Rate: 1
10808
c49439f1
R
10809(define_insn_reservation "sh4_simple_arith" 1
10810 (and (eq_attr "pipe_model" "sh4")
10811 (eq_attr "insn_class" "ex_group"))
10812 "issue,int")
10813
10814;; Load and store instructions have no alignment peculiarities for the SH4,
10815;; but they use the load-store unit, which they share with the fmove type
10816;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10817;; Loads have a latency of two.
10818;; However, call insns can only paired with a preceding insn, and have
10819;; a delay slot, so that we want two more insns to be scheduled between the
10820;; load of the function address and the call. This is equivalent to a
10821;; latency of three.
10822;; ADJUST_COST can only properly handle reductions of the cost, so we
10823;; use a latency of three here, which gets multiplied by 10 to yield 30.
10824;; We only do this for SImode loads of general registers, to make the work
10825;; for ADJUST_COST easier.
fae15c93
VM
10826
10827;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10828;; Group: LS
10829;; Latency: 2
10830;; Issue Rate: 1
10831
c49439f1
R
10832(define_insn_reservation "sh4_load" 2
10833 (and (eq_attr "pipe_model" "sh4")
10834 (eq_attr "type" "load,pcload"))
10835 "issue+load_store,nothing,memory")
10836
10837;; calls / sfuncs need an extra instruction for their delay slot.
10838;; Moreover, estimating the latency for SImode loads as 3 will also allow
10839;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10840;; count of a dynamic shift.
10841(define_insn_reservation "sh4_load_si" 3
10842 (and (eq_attr "pipe_model" "sh4")
10843 (eq_attr "type" "load_si,pcload_si"))
10844 "issue+load_store,nothing,memory")
10845
10846;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10847
10848;; The load latency is upped to three higher if the dependent insn does
10849;; double precision computation. We want the 'default' latency to reflect
10850;; that increased latency because otherwise the insn priorities won't
10851;; allow proper scheduling.
10852(define_insn_reservation "sh4_fload" 3
10853 (and (eq_attr "pipe_model" "sh4")
10854 (eq_attr "type" "fload,pcfload"))
10855 "issue+load_store,nothing,memory")
10856
10857;; (define_bypass 2 "sh4_fload" "!")
10858
10859(define_insn_reservation "sh4_store" 1
10860 (and (eq_attr "pipe_model" "sh4")
10861 (eq_attr "type" "store"))
10862 "issue+load_store,nothing,memory")
10863
10864;; Load Store instructions.
10865;; Group: LS
10866;; Latency: 1
10867;; Issue Rate: 1
10868
10869(define_insn_reservation "sh4_gp_fpul" 1
10870 (and (eq_attr "pipe_model" "sh4")
10871 (eq_attr "type" "gp_fpul"))
10872 "issue+load_store")
10873
10874;; Load Store instructions.
10875;; Group: LS
10876;; Latency: 3
10877;; Issue Rate: 1
10878
10879(define_insn_reservation "sh4_fpul_gp" 3
10880 (and (eq_attr "pipe_model" "sh4")
10881 (eq_attr "type" "fpul_gp"))
10882 "issue+load_store")
fae15c93
VM
10883
10884;; Branch (BF,BF/S,BT,BT/S,BRA)
10885;; Group: BR
c49439f1 10886;; Latency when taken: 2 (or 1)
fae15c93
VM
10887;; Issue Rate: 1
10888;; The latency is 1 when displacement is 0.
c49439f1
R
10889;; We can't really do much with the latency, even if we could express it,
10890;; but the pairing restrictions are useful to take into account.
10891;; ??? If the branch is likely, we might want to fill the delay slot;
10892;; if the branch is likely, but not very likely, should we pretend to use
10893;; a resource that CO instructions use, to get a pairable delay slot insn?
fae15c93 10894
c49439f1
R
10895(define_insn_reservation "sh4_branch" 1
10896 (and (eq_attr "pipe_model" "sh4")
10897 (eq_attr "type" "cbranch,jump"))
10898 "issue+pcr_addrcalc")
fae15c93
VM
10899
10900;; Branch Far (JMP,RTS,BRAF)
10901;; Group: CO
10902;; Latency: 3
10903;; Issue Rate: 2
c49439f1
R
10904;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10905;; can't be distinguished from bra for the "jump" pattern.
fae15c93 10906
c49439f1
R
10907(define_insn_reservation "sh4_return" 3
10908 (and (eq_attr "pipe_model" "sh4")
10909 (eq_attr "type" "return,jump_ind"))
10910 "d_lock*2")
fae15c93
VM
10911
10912;; RTE
10913;; Group: CO
c49439f1 10914;; Latency: 5
fae15c93
VM
10915;; Issue Rate: 5
10916;; this instruction can be executed in any of the pipelines
10917;; and blocks the pipeline for next 4 stages.
10918
c49439f1
R
10919(define_insn_reservation "sh4_return_from_exp" 5
10920 (and (eq_attr "pipe_model" "sh4")
10921 (eq_attr "type" "rte"))
10922 "d_lock*5")
fae15c93
VM
10923
10924;; OCBP, OCBWB
10925;; Group: CO
c49439f1 10926;; Latency: 1-5
fae15c93
VM
10927;; Issue Rate: 1
10928
c49439f1
R
10929;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10930;; ocbwb on its own would be "d_lock,nothing,memory*5"
10931(define_insn_reservation "ocbwb" 6
10932 (and (eq_attr "pipe_model" "sh4")
10933 (eq_attr "type" "cwb"))
10934 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
fae15c93
VM
10935
10936;; LDS to PR,JSR
10937;; Group: CO
10938;; Latency: 3
10939;; Issue Rate: 2
10940;; The SX stage is blocked for last 2 cycles.
c49439f1
R
10941;; OTOH, the only time that has an effect for insns generated by the compiler
10942;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10943;; or when we are doing a function call - and we don't do inter-function
10944;; scheduling. For the function call case, it's really best that we end with
10945;; something that models an rts.
fae15c93 10946
c49439f1
R
10947(define_insn_reservation "sh4_lds_to_pr" 3
10948 (and (eq_attr "pipe_model" "sh4")
10949 (eq_attr "type" "prset") )
10950 "d_lock*2")
10951
10952;; calls introduce a longisch delay that is likely to flush the pipelines
10953;; of the caller's instructions. Ordinary functions tend to end with a
10954;; load to restore a register (in the delay slot of rts), while sfuncs
10955;; tend to end with an EX or MT insn. But that is not actually relevant,
10956;; since there are no instructions that contend for memory access early.
10957;; We could, of course, provide exact scheduling information for specific
10958;; sfuncs, if that should prove useful.
10959
10960(define_insn_reservation "sh4_call" 16
10961 (and (eq_attr "pipe_model" "sh4")
10962 (eq_attr "type" "call,sfunc"))
10963 "d_lock*16")
fae15c93
VM
10964
10965;; LDS.L to PR
10966;; Group: CO
10967;; Latency: 3
10968;; Issue Rate: 2
10969;; The SX unit is blocked for last 2 cycles.
10970
10971(define_insn_reservation "ldsmem_to_pr" 3
c49439f1
R
10972 (and (eq_attr "pipe_model" "sh4")
10973 (eq_attr "type" "pload"))
10974 "d_lock*2")
fae15c93
VM
10975
10976;; STS from PR
10977;; Group: CO
10978;; Latency: 2
10979;; Issue Rate: 2
10980;; The SX unit in second and third cycles.
10981
10982(define_insn_reservation "sts_from_pr" 2
c49439f1
R
10983 (and (eq_attr "pipe_model" "sh4")
10984 (eq_attr "type" "prget"))
10985 "d_lock*2")
fae15c93
VM
10986
10987;; STS.L from PR
10988;; Group: CO
10989;; Latency: 2
10990;; Issue Rate: 2
10991
c49439f1
R
10992(define_insn_reservation "sh4_prstore_mem" 2
10993 (and (eq_attr "pipe_model" "sh4")
10994 (eq_attr "type" "pstore"))
10995 "d_lock*2,nothing,memory")
fae15c93
VM
10996
10997;; LDS to FPSCR
10998;; Group: CO
10999;; Latency: 4
11000;; Issue Rate: 1
11001;; F1 is blocked for last three cycles.
11002
c49439f1
R
11003(define_insn_reservation "fpscr_load" 4
11004 (and (eq_attr "pipe_model" "sh4")
11005 (eq_attr "type" "gp_fpscr"))
11006 "d_lock,nothing,F1*3")
fae15c93
VM
11007
11008;; LDS.L to FPSCR
11009;; Group: CO
11010;; Latency: 1 / 4
11011;; Latency to update Rn is 1 and latency to update FPSCR is 4
11012;; Issue Rate: 1
11013;; F1 is blocked for last three cycles.
11014
c49439f1
R
11015(define_insn_reservation "fpscr_load_mem" 4
11016 (and (eq_attr "pipe_model" "sh4")
11017 (eq_attr "type" "mem_fpscr"))
11018 "d_lock,nothing,(F1+memory),F1*2")
fae15c93
VM
11019
11020\f
11021;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11022;; Group: CO
11023;; Latency: 4 / 4
11024;; Issue Rate: 1
11025
11026(define_insn_reservation "multi" 4
c49439f1
R
11027 (and (eq_attr "pipe_model" "sh4")
11028 (eq_attr "type" "smpy,dmpy"))
11029 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11030
11031;; Fixed STS from MACL / MACH
11032;; Group: CO
11033;; Latency: 3
11034;; Issue Rate: 1
11035
11036(define_insn_reservation "sh4_mac_gp" 3
11037 (and (eq_attr "pipe_model" "sh4")
11038 (eq_attr "type" "mac_gp"))
11039 "d_lock")
fae15c93
VM
11040
11041
11042;; Single precision floating point computation FCMP/EQ,
c49439f1 11043;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
fae15c93 11044;; Group: FE
c49439f1 11045;; Latency: 3/4
fae15c93
VM
11046;; Issue Rate: 1
11047
c49439f1
R
11048(define_insn_reservation "fp_arith" 3
11049 (and (eq_attr "pipe_model" "sh4")
11050 (eq_attr "type" "fp"))
11051 "issue,F01,F2")
11052
11053(define_insn_reservation "fp_arith_ftrc" 3
11054 (and (eq_attr "pipe_model" "sh4")
11055 (eq_attr "type" "ftrc_s"))
11056 "issue,F01,F2")
11057
11058(define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
fae15c93
VM
11059
11060;; Single Precision FDIV/SQRT
11061;; Group: FE
c49439f1 11062;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
fae15c93 11063;; Issue Rate: 1
c49439f1 11064;; We describe fdiv here; fsqrt is actually one cycle faster.
fae15c93 11065
c49439f1
R
11066(define_insn_reservation "fp_div" 12
11067 (and (eq_attr "pipe_model" "sh4")
11068 (eq_attr "type" "fdiv"))
11069 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
fae15c93
VM
11070
11071;; Double Precision floating point computation
11072;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11073;; Group: FE
11074;; Latency: (3,4)/5
11075;; Issue Rate: 1
11076
c49439f1
R
11077(define_insn_reservation "dp_float" 4
11078 (and (eq_attr "pipe_model" "sh4")
11079 (eq_attr "type" "dfp_conv"))
11080 "issue,F01,F1+F2,F2")
fae15c93 11081
c49439f1 11082;; Double-precision floating-point (FADD,FMUL,FSUB)
fae15c93
VM
11083;; Group: FE
11084;; Latency: (7,8)/9
11085;; Issue Rate: 1
11086
c49439f1
R
11087(define_insn_reservation "fp_double_arith" 8
11088 (and (eq_attr "pipe_model" "sh4")
11089 (eq_attr "type" "dfp_arith"))
11090 "issue,F01,F1+F2,fpu*4,F2")
fae15c93
VM
11091
11092;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
c49439f1 11093;; Group: CO
fae15c93
VM
11094;; Latency: 3/5
11095;; Issue Rate: 2
11096
c49439f1
R
11097(define_insn_reservation "fp_double_cmp" 3
11098 (and (eq_attr "pipe_model" "sh4")
11099 (eq_attr "type" "dfp_cmp"))
11100 "d_lock,(d_lock+F01),F1+F2,F2")
fae15c93
VM
11101
11102;; Double precision FDIV/SQRT
11103;; Group: FE
11104;; Latency: (24,25)/26
11105;; Issue Rate: 1
11106
c49439f1
R
11107(define_insn_reservation "dp_div" 25
11108 (and (eq_attr "pipe_model" "sh4")
11109 (eq_attr "type" "dfdiv"))
11110 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11111
fae15c93 11112
c49439f1
R
11113;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11114;; case, we'd get a d_lock instead of issue at the end.
11115(define_insn_reservation "arith3" 3
11116 (and (eq_attr "pipe_model" "sh4")
11117 (eq_attr "type" "arith3"))
11118 "issue,d_lock+pcr_addrcalc,issue")
11119
11120;; arith3b insns schedule the same no matter if the branch is taken or not.
11121(define_insn_reservation "arith3b" 2
11122 (and (eq_attr "pipe_model" "sh4")
11123 (eq_attr "type" "arith3"))
11124 "issue,d_lock+pcr_addrcalc")