]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/sh.md
superh.opt: New file.
[thirdparty/gcc.git] / gcc / config / sh / sh.md
CommitLineData
c8f0269d 1;;- Machine description for Renesas / SuperH SH.
68d2b0bb 2;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
42201282 3;; 2003, 2004, 2005, 2006 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
39d14dda
KC
21;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22;; Boston, MA 02110-1301, 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)
73a4d10b
R
146 (UNSPEC_DIV_INV_M0 30)
147 (UNSPEC_DIV_INV_M1 31)
148 (UNSPEC_DIV_INV_M2 32)
149 (UNSPEC_DIV_INV_M3 33)
150 (UNSPEC_DIV_INV20 34)
151 (UNSPEC_ASHIFTRT 35)
152 (UNSPEC_THUNK 36)
50b69666
KK
153 (UNSPEC_SP_SET 40)
154 (UNSPEC_SP_TEST 41)
4773afa4
AO
155
156 ;; These are used with unspec_volatile.
157 (UNSPECV_BLOCKAGE 0)
b927e8c7 158 (UNSPECV_ALIGN 1)
4773afa4
AO
159 (UNSPECV_CONST2 2)
160 (UNSPECV_CONST4 4)
161 (UNSPECV_CONST8 6)
b91455de 162 (UNSPECV_WINDOW_END 10)
4773afa4 163 (UNSPECV_CONST_END 11)
73774972 164])
4773afa4 165
bc45ade3
SC
166;; -------------------------------------------------------------------------
167;; Attributes
168;; -------------------------------------------------------------------------
169
eeb531d5 170;; Target CPU.
b9654711 171
1245df60 172(define_attr "cpu"
157371cf 173 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
07a45e5c 174 (const (symbol_ref "sh_cpu_attr")))
961c4780 175
1245df60
R
176(define_attr "endian" "big,little"
177 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178 (const_string "little") (const_string "big"))))
179
d64264ff
R
180;; Indicate if the default fpu mode is single precision.
181(define_attr "fpu_single" "yes,no"
182 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183 (const_string "yes") (const_string "no"))))
184
225e4f43
R
185(define_attr "fmovd" "yes,no"
186 (const (if_then_else (symbol_ref "TARGET_FMOVD")
187 (const_string "yes") (const_string "no"))))
2ad65b0e
SC
188;; pipeline model
189(define_attr "pipe_model" "sh1,sh4,sh5media"
190 (const
191 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193 (const_string "sh1"))))
225e4f43 194
0d7e008e
SC
195;; cbranch conditional branch instructions
196;; jump unconditional jumps
197;; arith ordinary arithmetic
956d6950 198;; arith3 a compound insn that behaves similarly to a sequence of
1245df60
R
199;; three insns of type arith
200;; arith3b like above, but might end with a redirected branch
0d7e008e 201;; load from memory
1245df60 202;; load_si Likewise, SImode variant for general register.
c49439f1 203;; fload Likewise, but load to fp register.
0d7e008e 204;; store to memory
c49439f1
R
205;; move general purpose register to register
206;; mt_group other sh4 mt instructions
1245df60 207;; fmove register to register, floating point
51bd623f
JW
208;; smpy word precision integer multiply
209;; dmpy longword or doublelongword precision integer multiply
0d7e008e 210;; return rts
ffae286a 211;; pload load of pr reg, which can't be put into delay slot of rts
99e87c10 212;; prset copy register to pr reg, ditto
ffae286a 213;; pstore store of pr reg, which can't be put into delay slot of jsr
99e87c10 214;; prget copy pr to register, ditto
22e1ebf1 215;; pcload pc relative load of constant value
c49439f1 216;; pcfload Likewise, but load to fp register.
1245df60 217;; pcload_si Likewise, SImode variant for general register.
0d7e008e
SC
218;; rte return from exception
219;; sfunc special function call with known used registers
ffae286a 220;; call function call
c1aef54d
ILT
221;; fp floating point
222;; fdiv floating point divide (or square root)
c49439f1
R
223;; gp_fpul move from general purpose register to fpul
224;; fpul_gp move from fpul to general purpose register
225;; mac_gp move from mac[lh] to general purpose register
225e4f43 226;; dfp_arith, dfp_cmp,dfp_conv
c49439f1 227;; ftrc_s fix_truncsfsi2_i4
225e4f43 228;; dfdiv double precision floating point divide (or square root)
c49439f1 229;; cwb ic_invalidate_line_i
312209c6
AO
230;; movua SH4a unaligned load
231;; fsrra square root reciprocal approximate
232;; fsca sine and cosine approximate
73774972 233;; tls_load load TLS related address
2ad65b0e
SC
234;; arith_media SHmedia arithmetic, logical, and shift instructions
235;; cbranch_media SHmedia conditional branch instructions
236;; cmp_media SHmedia compare instructions
237;; dfdiv_media SHmedia double precision divide and square root
238;; dfmul_media SHmedia double precision multiply instruction
239;; dfparith_media SHmedia double precision floating point arithmetic
240;; dfpconv_media SHmedia double precision floating point conversions
241;; dmpy_media SHmedia longword multiply
242;; fcmp_media SHmedia floating point compare instructions
243;; fdiv_media SHmedia single precision divide and square root
244;; fload_media SHmedia floating point register load instructions
245;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
246;; fparith_media SHmedia single precision floating point arithmetic
247;; fpconv_media SHmedia single precision floating point conversions
248;; fstore_media SHmedia floating point register store instructions
249;; gettr_media SHmedia gettr instruction
825db093 250;; invalidate_line_media SHmedia invalidate_line sequence
2ad65b0e
SC
251;; jump_media SHmedia unconditional branch instructions
252;; load_media SHmedia general register load instructions
253;; pt_media SHmedia pt instruction (expanded by assembler)
254;; ptabs_media SHmedia ptabs instruction
255;; store_media SHmedia general register store instructions
256;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
257;; mac_media SHmedia mac-style fixed point operations
258;; d2mpy_media SHmedia: two 32 bit integer multiplies
73a4d10b 259;; atrans_media SHmedia approximate transcendental functions
2ad65b0e 260;; ustore_media SHmedia unaligned stores
4dff12bf 261;; nil no-op move, will be deleted.
0d7e008e 262
07a45e5c 263(define_attr "type"
312209c6 264 "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,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
bc45ade3
SC
265 (const_string "other"))
266
fae15c93 267;; We define a new attribute namely "insn_class".We use
c49439f1 268;; this for the DFA based pipeline description.
fae15c93
VM
269;;
270;; mt_group SH4 "mt" group instructions.
271;;
c49439f1
R
272;; ex_group SH4 "ex" group instructions.
273;;
274;; ls_group SH4 "ls" group instructions.
fae15c93 275;;
fae15c93
VM
276
277(define_attr "insn_class"
c49439f1
R
278 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282 (eq_attr "type" "cbranch,jump") (const_string "br_group")
283 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284 (const_string "fe_group")
285 (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")]
286 (const_string "none")))
287;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288;; so these do not belong in an insn group, although they are modeled
289;; with their own define_insn_reservations.
fae15c93 290
d64264ff
R
291;; Indicate what precision must be selected in fpscr for this insn, if any.
292
293(define_attr "fp_mode" "single,double,none" (const_string "none"))
294
73774972
EC
295;; Indicate if the fpu mode is set by this instruction
296;; "unknown" must have the value as "none" in fp_mode, and means
297;; that the instruction/abi has left the processor in an unknown
298;; state.
299;; "none" means that nothing has changed and no mode is set.
300;; This attribute is only used for the Renesas ABI.
301(define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
302
07a45e5c 303; If a conditional branch destination is within -252..258 bytes away
bc45ade3 304; from the instruction it can be 2 bytes long. Something in the
22e1ebf1 305; range -4090..4100 bytes can be 6 bytes long. All other conditional
1245df60
R
306; branches are initially assumed to be 16 bytes long.
307; In machine_dependent_reorg, we split all branches that are longer than
308; 2 bytes.
bc45ade3 309
536fe39c 310;; The maximum range used for SImode constant pool entries is 1018. A final
33f7f353
JR
311;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
313;; instruction around the pool table, 2 bytes of alignment before the table,
314;; and 30 bytes of alignment after the table. That gives a maximum total
315;; pool size of 1058 bytes.
316;; Worst case code/pool content size ratio is 1:2 (using asms).
317;; Thus, in the worst case, there is one instruction in front of a maximum
318;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
320;; If we have a forward branch, the initial table will be put after the
321;; unconditional branch.
322;;
323;; ??? We could do much better by keeping track of the actual pcloads within
324;; the branch range and in the pcload range in front of the branch range.
325
326;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
327;; inside an le.
328(define_attr "short_cbranch_p" "no,yes"
329 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
330 (const_string "no")
331 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
332 (const_string "yes")
333 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
334 (const_string "no")
335 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
336 (const_string "yes")
337 ] (const_string "no")))
338
339(define_attr "med_branch_p" "no,yes"
340 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
341 (const_int 1988))
342 (const_string "yes")
343 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344 (const_string "no")
345 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
346 (const_int 8186))
347 (const_string "yes")
348 ] (const_string "no")))
349
350(define_attr "med_cbranch_p" "no,yes"
351 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
352 (const_int 1986))
353 (const_string "yes")
354 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
355 (const_string "no")
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
357 (const_int 8184))
358 (const_string "yes")
359 ] (const_string "no")))
360
361(define_attr "braf_branch_p" "no,yes"
362 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
363 (const_string "no")
364 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
365 (const_int 20660))
366 (const_string "yes")
367 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
368 (const_string "no")
369 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
370 (const_int 65530))
371 (const_string "yes")
372 ] (const_string "no")))
373
374(define_attr "braf_cbranch_p" "no,yes"
375 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
376 (const_string "no")
377 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
378 (const_int 20658))
379 (const_string "yes")
380 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
381 (const_string "no")
382 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
383 (const_int 65528))
384 (const_string "yes")
385 ] (const_string "no")))
386
22e1ebf1 387; An unconditional jump in the range -4092..4098 can be 2 bytes long.
1245df60
R
388; For wider ranges, we need a combination of a code and a data part.
389; If we can get a scratch register for a long range jump, the code
390; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391; If the jump is in the range -32764..32770, the data part can be 2 bytes
392; long; otherwise, it must be 6 bytes long.
bc45ade3
SC
393
394; All other instructions are two bytes long by default.
395
33f7f353
JR
396;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397;; but getattrtab doesn't understand this.
07a45e5c 398(define_attr "length" ""
bc45ade3 399 (cond [(eq_attr "type" "cbranch")
33f7f353 400 (cond [(eq_attr "short_cbranch_p" "yes")
1245df60 401 (const_int 2)
33f7f353 402 (eq_attr "med_cbranch_p" "yes")
1245df60 403 (const_int 6)
33f7f353 404 (eq_attr "braf_cbranch_p" "yes")
1245df60 405 (const_int 12)
33f7f353
JR
406;; ??? using pc is not computed transitively.
407 (ne (match_dup 0) (match_dup 0))
408 (const_int 14)
e6dfd05f
AO
409 (ne (symbol_ref ("flag_pic")) (const_int 0))
410 (const_int 24)
1245df60 411 ] (const_int 16))
bc45ade3 412 (eq_attr "type" "jump")
33f7f353 413 (cond [(eq_attr "med_branch_p" "yes")
1245df60 414 (const_int 2)
10f4f635 415 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
c0311627
R
416 (symbol_ref "INSN"))
417 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
418 (symbol_ref "code_for_indirect_jump_scratch")))
419 (cond [(eq_attr "braf_branch_p" "yes")
420 (const_int 6)
421 (eq (symbol_ref "flag_pic") (const_int 0))
422 (const_int 10)
423 (ne (symbol_ref "TARGET_SH2") (const_int 0))
424 (const_int 10)] (const_int 18))
33f7f353 425 (eq_attr "braf_branch_p" "yes")
1245df60 426 (const_int 10)
33f7f353
JR
427;; ??? using pc is not computed transitively.
428 (ne (match_dup 0) (match_dup 0))
1245df60 429 (const_int 12)
e6dfd05f
AO
430 (ne (symbol_ref ("flag_pic")) (const_int 0))
431 (const_int 22)
1245df60 432 ] (const_int 14))
2ad65b0e 433 (eq_attr "type" "pt_media")
fa5322fa
AO
434 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
435 (const_int 20) (const_int 12))
73a4d10b
R
436 (and (eq_attr "type" "jump_media")
437 (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
438 (const_int 8)
fa5322fa
AO
439 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
440 (const_int 4)
441 (const_int 2))))
b9654711 442
2de7ffa7 443;; DFA descriptions for the pipelines
2ad65b0e 444
2de7ffa7
PB
445(include "sh1.md")
446(include "shmedia.md")
447(include "sh4.md")
2ad65b0e 448
73a4d10b
R
449(include "predicates.md")
450
2de7ffa7 451;; Definitions for filling delay slots
bc45ade3 452
51bd623f
JW
453(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
454
225e4f43
R
455;; ??? This should be (nil) instead of (const_int 0)
456(define_attr "hit_stack" "yes,no"
4773afa4
AO
457 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
458 (const_int 0))
225e4f43
R
459 (const_string "no")]
460 (const_string "yes")))
51bd623f
JW
461
462(define_attr "interrupt_function" "no,yes"
552ecbd9 463 (const (symbol_ref "current_function_interrupt")))
51bd623f 464
07a45e5c 465(define_attr "in_delay_slot" "yes,no"
51bd623f 466 (cond [(eq_attr "type" "cbranch") (const_string "no")
1245df60 467 (eq_attr "type" "pcload,pcload_si") (const_string "no")
51bd623f
JW
468 (eq_attr "needs_delay_slot" "yes") (const_string "no")
469 (eq_attr "length" "2") (const_string "yes")
470 ] (const_string "no")))
471
c608a684
R
472(define_attr "cond_delay_slot" "yes,no"
473 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474 ] (const_string "no")))
475
0603a39d
R
476(define_attr "is_sfunc" ""
477 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
478
2ad65b0e
SC
479(define_attr "is_mac_media" ""
480 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
481
c49439f1
R
482(define_attr "branch_zero" "yes,no"
483 (cond [(eq_attr "type" "!cbranch") (const_string "no")
484 (ne (symbol_ref "(next_active_insn (insn)\
485 == (prev_active_insn\
486 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
487 && get_attr_length (next_active_insn (insn)) == 2")
488 (const_int 0))
489 (const_string "yes")]
490 (const_string "no")))
491
492;; SH4 Double-precision computation with double-precision result -
493;; the two halves are ready at different times.
494(define_attr "dfp_comp" "yes,no"
495 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
496 (const_string "no")))
497
498;; Insns for which the latency of a preceding fp insn is decreased by one.
499(define_attr "late_fp_use" "yes,no" (const_string "no"))
500;; And feeding insns for which this relevant.
501(define_attr "any_fp_comp" "yes,no"
502 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
503 (const_string "yes")]
504 (const_string "no")))
505
506(define_attr "any_int_load" "yes,no"
507 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
508 (const_string "yes")]
509 (const_string "no")))
510
73a4d10b
R
511(define_attr "highpart" "user, ignore, extend, depend, must_split"
512 (const_string "user"))
513
51bd623f 514(define_delay
0d7e008e 515 (eq_attr "needs_delay_slot" "yes")
b9654711
SC
516 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
517
51aea58d
JW
518;; On the SH and SH2, the rte instruction reads the return pc from the stack,
519;; and thus we can't put a pop instruction in its delay slot.
6b005b88
JW
520;; ??? On the SH3, the rte instruction does not use the stack, so a pop
521;; instruction can go in the delay slot.
51aea58d 522
ffae286a
JW
523;; Since a normal return (rts) implicitly uses the PR register,
524;; we can't allow PR register loads in an rts delay slot.
525
07a45e5c 526(define_delay
961c4780 527 (eq_attr "type" "return")
07a45e5c 528 [(and (eq_attr "in_delay_slot" "yes")
ffae286a 529 (ior (and (eq_attr "interrupt_function" "no")
99e87c10 530 (eq_attr "type" "!pload,prset"))
ffae286a 531 (and (eq_attr "interrupt_function" "yes")
552ecbd9
AH
532 (ior
533 (ne (symbol_ref "TARGET_SH3") (const_int 0))
534 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
ffae286a
JW
535
536;; Since a call implicitly uses the PR register, we can't allow
537;; a PR register store in a jsr delay slot.
538
539(define_delay
540 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
541 [(and (eq_attr "in_delay_slot" "yes")
99e87c10 542 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
ffae286a
JW
543
544;; Say that we have annulled true branches, since this gives smaller and
545;; faster code when branches are predicted as not taken.
546
68fe56fc
R
547;; ??? The non-annulled condition should really be "in_delay_slot",
548;; but insns that can be filled in non-annulled get priority over insns
549;; that can only be filled in anulled.
550
07a45e5c
JW
551(define_delay
552 (and (eq_attr "type" "cbranch")
1245df60 553 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
3a8699c7
AO
554 ;; SH2e has a hardware bug that pretty much prohibits the use of
555 ;; annuled delay slots.
68fe56fc 556 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
73a4d10b 557 (not (eq_attr "cpu" "sh2e"))) (nil)])
bc45ade3
SC
558\f
559;; -------------------------------------------------------------------------
560;; SImode signed integer comparisons
561;; -------------------------------------------------------------------------
562
51bd623f 563(define_insn ""
4773afa4 564 [(set (reg:SI T_REG)
51bd623f 565 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
735cb76e 566 (match_operand:SI 1 "arith_operand" "K08,r"))
51bd623f 567 (const_int 0)))]
fa5322fa 568 "TARGET_SH1"
fae15c93 569 "tst %1,%0"
c49439f1 570 [(set_attr "type" "mt_group")])
0d7e008e 571
07a45e5c
JW
572;; ??? Perhaps should only accept reg/constant if the register is reg 0.
573;; That would still allow reload to create cmpi instructions, but would
574;; perhaps allow forcing the constant into a register when that is better.
ffae286a
JW
575;; Probably should use r0 for mem/imm compares, but force constant into a
576;; register for pseudo/imm compares.
07a45e5c 577
0d7e008e 578(define_insn "cmpeqsi_t"
4773afa4
AO
579 [(set (reg:SI T_REG)
580 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
735cb76e 581 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
fa5322fa 582 "TARGET_SH1"
0d7e008e 583 "@
51bd623f 584 tst %0,%0
0d7e008e 585 cmp/eq %1,%0
fae15c93 586 cmp/eq %1,%0"
c49439f1 587 [(set_attr "type" "mt_group")])
bc45ade3
SC
588
589(define_insn "cmpgtsi_t"
4773afa4
AO
590 [(set (reg:SI T_REG)
591 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
592 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 593 "TARGET_SH1"
0d7e008e 594 "@
22e1ebf1 595 cmp/gt %1,%0
fae15c93 596 cmp/pl %0"
c49439f1 597 [(set_attr "type" "mt_group")])
bc45ade3
SC
598
599(define_insn "cmpgesi_t"
4773afa4
AO
600 [(set (reg:SI T_REG)
601 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
602 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 603 "TARGET_SH1"
0d7e008e 604 "@
22e1ebf1 605 cmp/ge %1,%0
fae15c93 606 cmp/pz %0"
c49439f1 607 [(set_attr "type" "mt_group")])
fae15c93 608
bc45ade3
SC
609;; -------------------------------------------------------------------------
610;; SImode unsigned integer comparisons
611;; -------------------------------------------------------------------------
612
613(define_insn "cmpgeusi_t"
4773afa4
AO
614 [(set (reg:SI T_REG)
615 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
616 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 617 "TARGET_SH1"
fae15c93 618 "cmp/hs %1,%0"
c49439f1 619 [(set_attr "type" "mt_group")])
bc45ade3
SC
620
621(define_insn "cmpgtusi_t"
4773afa4
AO
622 [(set (reg:SI T_REG)
623 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
624 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 625 "TARGET_SH1"
fae15c93 626 "cmp/hi %1,%0"
c49439f1 627 [(set_attr "type" "mt_group")])
bc45ade3
SC
628
629;; We save the compare operands in the cmpxx patterns and use them when
630;; we generate the branch.
631
632(define_expand "cmpsi"
4773afa4 633 [(set (reg:SI T_REG)
3db1b434 634 (compare (match_operand:SI 0 "cmpsi_operand" "")
4773afa4 635 (match_operand:SI 1 "arith_operand" "")))]
73a4d10b 636 "TARGET_SH1 || TARGET_SHMEDIA"
bc45ade3 637 "
0d7e008e 638{
3db1b434
R
639 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
640 && GET_CODE (operands[1]) != CONST_INT)
641 operands[0] = copy_to_mode_reg (SImode, operands[0]);
0d7e008e 642 sh_compare_op0 = operands[0];
bc45ade3
SC
643 sh_compare_op1 = operands[1];
644 DONE;
645}")
bc45ade3
SC
646\f
647;; -------------------------------------------------------------------------
1245df60
R
648;; DImode signed integer comparisons
649;; -------------------------------------------------------------------------
650
651;; ??? Could get better scheduling by splitting the initial test from the
652;; rest of the insn after reload. However, the gain would hardly justify
653;; the sh.md size increase necessary to do that.
654
655(define_insn ""
4773afa4 656 [(set (reg:SI T_REG)
1245df60
R
657 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
658 (match_operand:DI 1 "arith_operand" "r"))
659 (const_int 0)))]
fa5322fa 660 "TARGET_SH1"
1245df60
R
661 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
662 insn, operands);"
663 [(set_attr "length" "6")
664 (set_attr "type" "arith3b")])
665
666(define_insn "cmpeqdi_t"
4773afa4
AO
667 [(set (reg:SI T_REG)
668 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
669 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
fa5322fa 670 "TARGET_SH1"
712646d0 671 "@
4c0d0505
JR
672 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
673 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
1245df60
R
674 [(set_attr "length" "6")
675 (set_attr "type" "arith3b")])
676
1987b7bc 677(define_split
4773afa4 678 [(set (reg:SI T_REG)
e69d1422
R
679 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
680 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
712646d0
R
681;; If we applied this split when not optimizing, it would only be
682;; applied during the machine-dependent reorg, when no new basic blocks
683;; may be created.
fa5322fa 684 "TARGET_SH1 && reload_completed && optimize"
4773afa4
AO
685 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
686 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
712646d0
R
687 (label_ref (match_dup 6))
688 (pc)))
4773afa4 689 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
712646d0 690 (match_dup 6)]
1987b7bc
R
691 "
692{
693 operands[2]
694 = gen_rtx_REG (SImode,
695 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
696 operands[3]
697 = (operands[1] == const0_rtx
698 ? const0_rtx
699 : gen_rtx_REG (SImode,
700 true_regnum (operands[1])
701 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
702 operands[4] = gen_lowpart (SImode, operands[0]);
703 operands[5] = gen_lowpart (SImode, operands[1]);
712646d0 704 operands[6] = gen_label_rtx ();
1987b7bc
R
705}")
706
1245df60 707(define_insn "cmpgtdi_t"
4773afa4
AO
708 [(set (reg:SI T_REG)
709 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
710 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
711 "TARGET_SH2"
712 "@
713 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
714 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
715 [(set_attr "length" "8")
716 (set_attr "type" "arith3")])
717
718(define_insn "cmpgedi_t"
4773afa4
AO
719 [(set (reg:SI T_REG)
720 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
722 "TARGET_SH2"
723 "@
724 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
725 cmp/pz\\t%S0"
726 [(set_attr "length" "8,2")
c49439f1 727 (set_attr "type" "arith3,mt_group")])
1245df60
R
728\f
729;; -------------------------------------------------------------------------
730;; DImode unsigned integer comparisons
731;; -------------------------------------------------------------------------
732
733(define_insn "cmpgeudi_t"
4773afa4
AO
734 [(set (reg:SI T_REG)
735 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
736 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
737 "TARGET_SH2"
738 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
739 [(set_attr "length" "8")
740 (set_attr "type" "arith3")])
741
742(define_insn "cmpgtudi_t"
4773afa4
AO
743 [(set (reg:SI T_REG)
744 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
745 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
746 "TARGET_SH2"
747 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
748 [(set_attr "length" "8")
749 (set_attr "type" "arith3")])
750
73a4d10b
R
751(define_insn "cmpeqsi_media"
752 [(set (match_operand:DI 0 "register_operand" "=r")
753 (eq:DI (match_operand:SI 1 "logical_operand" "%r")
754 (match_operand:SI 2 "cmp_operand" "Nr")))]
755 "TARGET_SHMEDIA"
756 "cmpeq %1, %N2, %0"
757 [(set_attr "type" "cmp_media")])
758
fa5322fa 759(define_insn "cmpeqdi_media"
b6d33983
R
760 [(set (match_operand:DI 0 "register_operand" "=r")
761 (eq:DI (match_operand:DI 1 "register_operand" "%r")
73a4d10b 762 (match_operand:DI 2 "cmp_operand" "Nr")))]
fa5322fa 763 "TARGET_SHMEDIA"
b6d33983
R
764 "cmpeq %1, %N2, %0"
765 [(set_attr "type" "cmp_media")])
fa5322fa 766
73a4d10b
R
767(define_insn "cmpgtsi_media"
768 [(set (match_operand:DI 0 "register_operand" "=r")
769 (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
770 (match_operand:SI 2 "cmp_operand" "rN")))]
771 "TARGET_SHMEDIA"
772 "cmpgt %N1, %N2, %0"
773 [(set_attr "type" "cmp_media")])
774
fa5322fa 775(define_insn "cmpgtdi_media"
b6d33983
R
776 [(set (match_operand:DI 0 "register_operand" "=r")
777 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
778 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 779 "TARGET_SHMEDIA"
b6d33983
R
780 "cmpgt %N1, %N2, %0"
781 [(set_attr "type" "cmp_media")])
fa5322fa 782
73a4d10b
R
783(define_insn "cmpgtusi_media"
784 [(set (match_operand:DI 0 "register_operand" "=r")
785 (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
786 (match_operand:SI 2 "cmp_operand" "rN")))]
787 "TARGET_SHMEDIA"
788 "cmpgtu %N1, %N2, %0"
789 [(set_attr "type" "cmp_media")])
790
fa5322fa 791(define_insn "cmpgtudi_media"
b6d33983
R
792 [(set (match_operand:DI 0 "register_operand" "=r")
793 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
794 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 795 "TARGET_SHMEDIA"
68cef009 796 "cmpgtu %N1, %N2, %0"
b6d33983 797 [(set_attr "type" "cmp_media")])
fa5322fa 798
73a4d10b
R
799(define_insn "cmpsieqsi_media"
800 [(set (match_operand:SI 0 "register_operand" "=r")
801 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
802 (match_operand:SI 2 "cmp_operand" "Nr")))]
803 "TARGET_SHMEDIA"
804 "cmpeq %1, %N2, %0"
805 [(set_attr "type" "cmp_media")])
806
807(define_insn "cmpsieqdi_media"
808 [(set (match_operand:SI 0 "register_operand" "=r")
809 (eq:SI (match_operand:DI 1 "register_operand" "%r")
810 (match_operand:DI 2 "cmp_operand" "Nr")))]
811 "TARGET_SHMEDIA"
812 "cmpeq %1, %N2, %0"
813 [(set_attr "type" "cmp_media")])
814
815(define_insn "cmpsigtsi_media"
816 [(set (match_operand:SI 0 "register_operand" "=r")
817 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
818 (match_operand:SI 2 "cmp_operand" "rN")))]
819 "TARGET_SHMEDIA"
820 "cmpgt %N1, %N2, %0"
821 [(set_attr "type" "cmp_media")])
822
823(define_insn "cmpsigtdi_media"
824 [(set (match_operand:SI 0 "register_operand" "=r")
825 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
826 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827 "TARGET_SHMEDIA"
828 "cmpgt %N1, %N2, %0"
829 [(set_attr "type" "cmp_media")])
830
831(define_insn "cmpsigtusi_media"
832 [(set (match_operand:SI 0 "register_operand" "=r")
833 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
834 (match_operand:SI 2 "cmp_operand" "rN")))]
835 "TARGET_SHMEDIA"
836 "cmpgtu %N1, %N2, %0"
837 [(set_attr "type" "cmp_media")])
838
839(define_insn "cmpsigtudi_media"
840 [(set (match_operand:SI 0 "register_operand" "=r")
841 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
842 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
843 "TARGET_SHMEDIA"
844 "cmpgtu %N1, %N2, %0"
845 [(set_attr "type" "cmp_media")])
846
847; These two patterns are for combine.
848(define_insn "*cmpne0si_media"
849 [(set (match_operand:DI 0 "register_operand" "=r")
850 (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
851 "TARGET_SHMEDIA"
852 "cmpgtu %1,r63,%0"
853 [(set_attr "type" "cmp_media")])
854
855(define_insn "*cmpne0sisi_media"
856 [(set (match_operand:SI 0 "register_operand" "=r")
857 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
858 "TARGET_SHMEDIA"
859 "cmpgtu %1,r63,%0"
860 [(set_attr "type" "cmp_media")])
861
1245df60
R
862;; We save the compare operands in the cmpxx patterns and use them when
863;; we generate the branch.
864
865(define_expand "cmpdi"
4773afa4
AO
866 [(set (reg:SI T_REG)
867 (compare (match_operand:DI 0 "arith_operand" "")
868 (match_operand:DI 1 "arith_operand" "")))]
fa5322fa 869 "TARGET_SH2 || TARGET_SHMEDIA"
1245df60
R
870 "
871{
872 sh_compare_op0 = operands[0];
873 sh_compare_op1 = operands[1];
874 DONE;
875}")
fa5322fa
AO
876;; -------------------------------------------------------------------------
877;; Conditional move instructions
878;; -------------------------------------------------------------------------
879
880;; The insn names may seem reversed, but note that cmveq performs the move
881;; if op1 == 0, and cmvne does it if op1 != 0.
882
883(define_insn "movdicc_false"
b6d33983
R
884 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
885 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 886 (const_int 0))
b6d33983
R
887 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
888 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 889 "TARGET_SHMEDIA"
b6d33983
R
890 "cmveq %1, %N2, %0"
891 [(set_attr "type" "arith_media")])
fa5322fa
AO
892
893(define_insn "movdicc_true"
b6d33983
R
894 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
895 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 896 (const_int 0))
b6d33983
R
897 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
898 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 899 "TARGET_SHMEDIA"
b6d33983
R
900 "cmvne %1, %N2, %0"
901 [(set_attr "type" "arith_media")])
fa5322fa 902
73a4d10b
R
903(define_peephole2
904 [(set (match_operand:DI 0 "arith_reg_dest" "")
905 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
906 [(match_operand:DI 1 "arith_reg_operand" "")
907 (const_int 0)])
908 (match_operand:DI 2 "arith_reg_dest" "")
909 (match_dup 0)))
910 (set (match_dup 2) (match_dup 0))]
911 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
912 [(set (match_dup 2)
913 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
914 "
915{
916 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917 VOIDmode, operands[1], CONST0_RTX (DImode));
918}")
919
920(define_peephole2
921 [(set (match_operand:DI 0 "general_movdst_operand" "")
922 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
923 (set (match_operand:DI 2 "arith_reg_dest" "")
924 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
925 [(match_operand:DI 3 "arith_reg_operand" "")
926 (const_int 0)])
927 (match_dup 0)
928 (match_dup 2)))]
929 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
930 [(set (match_dup 2)
931 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
932 "")
933
fa5322fa
AO
934(define_expand "movdicc"
935 [(set (match_operand:DI 0 "register_operand" "")
936 (if_then_else:DI (match_operand 1 "comparison_operator" "")
937 (match_operand:DI 2 "register_operand" "")
938 (match_operand:DI 3 "register_operand" "")))]
939 "TARGET_SHMEDIA"
940 "
941{
942 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
943 && GET_MODE (sh_compare_op0) == DImode
944 && sh_compare_op1 == const0_rtx)
1c563bed 945 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
0f4c242b 946 sh_compare_op0, sh_compare_op1);
fa5322fa
AO
947 else
948 {
949 rtx tmp;
950
951 if (no_new_pseudos)
952 FAIL;
953
954 tmp = gen_reg_rtx (DImode);
955
956 switch (GET_CODE (operands[1]))
957 {
958 case EQ:
959 emit_insn (gen_seq (tmp));
c0d4e710 960 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
961 break;
962
963 case NE:
964 emit_insn (gen_seq (tmp));
c0d4e710 965 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
966 break;
967
968 case GT:
969 emit_insn (gen_sgt (tmp));
c0d4e710 970 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
971 break;
972
973 case LT:
974 emit_insn (gen_slt (tmp));
c0d4e710 975 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
976 break;
977
978 case GE:
979 emit_insn (gen_slt (tmp));
c0d4e710 980 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
981 break;
982
983 case LE:
984 emit_insn (gen_sgt (tmp));
c0d4e710 985 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
986 break;
987
988 case GTU:
989 emit_insn (gen_sgtu (tmp));
c0d4e710 990 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
991 break;
992
993 case LTU:
994 emit_insn (gen_sltu (tmp));
c0d4e710 995 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
996 break;
997
998 case GEU:
999 emit_insn (gen_sltu (tmp));
c0d4e710 1000 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
1001 break;
1002
1003 case LEU:
1004 emit_insn (gen_sgtu (tmp));
c0d4e710 1005 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
1006 break;
1007
1008 case UNORDERED:
1009 emit_insn (gen_sunordered (tmp));
c0d4e710 1010 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
1011 break;
1012
1013 case ORDERED:
1014 emit_insn (gen_sunordered (tmp));
c0d4e710 1015 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
fa5322fa
AO
1016 break;
1017
1018 case UNEQ:
1019 case UNGE:
1020 case UNGT:
1021 case UNLE:
1022 case UNLT:
1023 case LTGT:
1024 FAIL;
1025
1026 default:
f5b9e7c9 1027 gcc_unreachable ();
fa5322fa
AO
1028 }
1029 }
1030}")
73a4d10b
R
1031
1032;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1033;; SImode to DImode.
1034(define_insn "movsicc_false"
1035 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1036 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1037 (const_int 0))
1038 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1039 (match_operand:SI 3 "arith_reg_operand" "0")))]
1040 "TARGET_SHMEDIA"
1041 "cmveq %1, %N2, %0"
1042 [(set_attr "type" "arith_media")])
1043
1044(define_insn "movsicc_true"
1045 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1046 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1047 (const_int 0))
1048 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1049 (match_operand:SI 3 "arith_reg_operand" "0")))]
1050 "TARGET_SHMEDIA"
1051 "cmvne %1, %N2, %0"
1052 [(set_attr "type" "arith_media")])
1053
1054(define_peephole2
1055 [(set (match_operand:SI 0 "arith_reg_dest" "")
1056 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1057 [(match_operand:SI 1 "arith_reg_operand" "")
1058 (const_int 0)])
1059 (match_operand:SI 2 "arith_reg_dest" "")
1060 (match_dup 0)))
1061 (set (match_dup 2) (match_dup 0))]
1062 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1063 [(set (match_dup 2)
1064 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1065 "
1066{
1067 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068 VOIDmode, operands[1], CONST0_RTX (SImode));
1069}")
1070
1071(define_peephole2
1072 [(set (match_operand:SI 0 "general_movdst_operand" "")
1073 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1074 (set (match_operand:SI 2 "arith_reg_dest" "")
1075 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1076 [(match_operand:SI 3 "arith_reg_operand" "")
1077 (const_int 0)])
1078 (match_dup 0)
1079 (match_dup 2)))]
1080 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1081 && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1082 [(set (match_dup 2)
1083 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1084 "
1085{
1086 replace_rtx (operands[4], operands[0], operands[1]);
1087}")
1088
1089(define_peephole2
1090 [(set (match_operand 0 "any_register_operand" "")
1091 (match_operand 1 "any_register_operand" ""))
1092 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1093 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1094 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1095 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1096 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1097 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1098 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1099 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1100 && (REGNO_REG_CLASS (REGNO (operands[0]))
1101 == REGNO_REG_CLASS (REGNO (operands[2])))
1102 && (REGNO_REG_CLASS (REGNO (operands[1]))
1103 == REGNO_REG_CLASS (REGNO (operands[0])))"
1104 [(set (match_dup 0) (match_dup 3))
1105 (set (match_dup 4) (match_dup 5))]
1106 "
1107{
1108 rtx set1, set2;
1109 rtx replacements[4];
1110
0fa2e4df 1111 /* We want to replace occurrences of operands[0] with operands[1] and
73a4d10b 1112 operands[2] with operands[0] in operands[4]/operands[5].
30dc60c7 1113 Doing just two replace_rtx calls naively would result in the second
73a4d10b
R
1114 replacement undoing all that the first did if operands[1] and operands[2]
1115 are identical, so we must do this simultaneously. */
1116 replacements[0] = operands[0];
1117 replacements[1] = operands[1];
1118 replacements[2] = operands[2];
1119 replacements[3] = operands[0];
1120 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1121 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1122 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1123 FAIL;
1124
1125 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1126 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1127 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1128 /* The operands array is aliased to recog_data.operand, which gets
1129 clobbered by extract_insn, so finish with it now. */
1130 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1131 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1132 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1133 always uses emit_insn. */
1134 /* Check that we don't violate matching constraints or earlyclobbers. */
1135 extract_insn (emit_insn (set1));
1136 if (! constrain_operands (1))
1137 goto failure;
1138 extract_insn (emit (set2));
1139 if (! constrain_operands (1))
1140 {
1141 rtx tmp;
1142 failure:
1143 tmp = replacements[0];
1144 replacements[0] = replacements[1];
1145 replacements[1] = tmp;
1146 tmp = replacements[2];
1147 replacements[2] = replacements[3];
1148 replacements[3] = tmp;
1149 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1150 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1151 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1152 FAIL;
1153 }
1154 DONE;
1155}")
1156
1157;; The register allocator is rather clumsy in handling multi-way conditional
1158;; moves, so allow the combiner to make them, and we split them up after
1159;; reload. */
1160(define_insn_and_split "*movsicc_umin"
1161 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1162 (umin:SI (if_then_else:SI
1163 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1164 (const_int 0))
1165 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1166 (match_operand:SI 3 "register_operand" "0"))
1167 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1168 (clobber (match_scratch:SI 5 "=&r"))]
1169 "TARGET_SHMEDIA && no_new_pseudos"
1170 "#"
1171 "TARGET_SHMEDIA && reload_completed"
1172 [(pc)]
1173 "
1174{
1175 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1176 operands[3]));
1177 emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1178 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1179 operands[0]));
1180 DONE;
1181}")
1182
25e651ca
AS
1183(define_insn "*movsicc_t_false"
1184 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1185 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1186 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1187 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1188 "TARGET_PRETEND_CMOVE
1189 && (arith_reg_operand (operands[1], SImode)
1190 || (immediate_operand (operands[1], SImode)
1191 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1192 "bt 0f\;mov %1,%0\\n0:"
1193 [(set_attr "type" "mt_group,arith") ;; poor approximation
1194 (set_attr "length" "4")])
1195
1196(define_insn "*movsicc_t_true"
1197 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1198 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1199 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1200 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1201 "TARGET_PRETEND_CMOVE
1202 && (arith_reg_operand (operands[1], SImode)
1203 || (immediate_operand (operands[1], SImode)
1204 && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1205 "bf 0f\;mov %1,%0\\n0:"
1206 [(set_attr "type" "mt_group,arith") ;; poor approximation
1207 (set_attr "length" "4")])
1208
73a4d10b 1209(define_expand "movsicc"
25e651ca 1210 [(set (match_operand:SI 0 "arith_reg_dest" "")
73a4d10b 1211 (if_then_else:SI (match_operand 1 "comparison_operator" "")
25e651ca
AS
1212 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1213 (match_operand:SI 3 "arith_reg_operand" "")))]
1214 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
73a4d10b
R
1215 "
1216{
1217 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1218 && GET_MODE (sh_compare_op0) == SImode
25e651ca
AS
1219 && (TARGET_SHMEDIA
1220 || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
73a4d10b
R
1221 && sh_compare_op1 == const0_rtx)
1222 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1223 sh_compare_op0, sh_compare_op1);
25e651ca
AS
1224 else if (TARGET_PRETEND_CMOVE)
1225 {
1226 enum rtx_code code = GET_CODE (operands[1]);
1227 enum rtx_code new_code = code;
1228 rtx tmp;
1229
1230 if (! currently_expanding_to_rtl)
1231 FAIL;
1232 switch (code)
1233 {
1234 case LT: case LE: case LEU: case LTU:
1235 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1236 break;
1237 case NE:
1238 new_code = reverse_condition (code);
1239 break;
1240 case EQ: case GT: case GE: case GEU: case GTU:
1241 break;
1242 default:
1243 FAIL;
1244 }
1245 tmp = prepare_scc_operands (new_code);
1246 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1247 tmp, const0_rtx);
1248 }
73a4d10b
R
1249 else
1250 {
1251 rtx tmp;
1252
1253 if (no_new_pseudos)
1254 FAIL;
1255
1256 tmp = gen_reg_rtx (SImode);
1257
1258 switch (GET_CODE (operands[1]))
1259 {
1260 case EQ:
1261 emit_insn (gen_seq (tmp));
1262 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1263 break;
1264
1265 case NE:
1266 emit_insn (gen_seq (tmp));
1267 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1268 break;
1269
1270 case GT:
1271 emit_insn (gen_sgt (tmp));
1272 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1273 break;
1274
1275 case LT:
1276 emit_insn (gen_slt (tmp));
1277 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1278 break;
1279
1280 case GE:
1281 emit_insn (gen_slt (tmp));
1282 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1283 break;
1284
1285 case LE:
1286 emit_insn (gen_sgt (tmp));
1287 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1288 break;
1289
1290 case GTU:
1291 emit_insn (gen_sgtu (tmp));
1292 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1293 break;
1294
1295 case LTU:
1296 emit_insn (gen_sltu (tmp));
1297 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1298 break;
1299
1300 case GEU:
1301 emit_insn (gen_sltu (tmp));
1302 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1303 break;
1304
1305 case LEU:
1306 emit_insn (gen_sgtu (tmp));
1307 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1308 break;
1309
1310 case UNORDERED:
1311 emit_insn (gen_sunordered (tmp));
1312 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1313 break;
1314
1315 case ORDERED:
1316 emit_insn (gen_sunordered (tmp));
1317 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1318 break;
1319
1320 case UNEQ:
1321 case UNGE:
1322 case UNGT:
1323 case UNLE:
1324 case UNLT:
1325 case LTGT:
1326 FAIL;
1327
1328 default:
1329 abort ();
1330 }
1331 }
1332}")
1333
1334(define_expand "movqicc"
1335 [(set (match_operand:QI 0 "register_operand" "")
1336 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1337 (match_operand:QI 2 "register_operand" "")
1338 (match_operand:QI 3 "register_operand" "")))]
1339 "TARGET_SHMEDIA"
1340 "
1341{
1342 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1343 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1344 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1345 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1346 DONE;
1347}")
1245df60
R
1348\f
1349;; -------------------------------------------------------------------------
bc45ade3
SC
1350;; Addition instructions
1351;; -------------------------------------------------------------------------
1352
fa5322fa
AO
1353(define_expand "adddi3"
1354 [(set (match_operand:DI 0 "arith_reg_operand" "")
1355 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1356 (match_operand:DI 2 "arith_operand" "")))]
1357 ""
1358 "
1359{
1360 if (TARGET_SH1)
1361 {
1362 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1363 FAIL;
1364 operands[2] = force_reg (DImode, operands[2]);
1365 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1366 DONE;
1367 }
1368}")
0d7e008e 1369
fa5322fa 1370(define_insn "*adddi3_media"
73a4d10b 1371 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
fa5322fa 1372 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 1373 (match_operand:DI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1374 "TARGET_SHMEDIA"
1375 "@
1376 add %1, %2, %0
2ad65b0e
SC
1377 addi %1, %2, %0"
1378 [(set_attr "type" "arith_media")])
fa5322fa 1379
73a4d10b
R
1380(define_insn "*adddisi3_media"
1381 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1382 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1383 (match_operand:DI 2 "arith_operand" "r,I10")))]
1384 "TARGET_SHMEDIA"
1385 "@
1386 add.l %1, %2, %0
1387 addi.l %1, %2, %0"
1388 [(set_attr "type" "arith_media")
1389 (set_attr "highpart" "ignore")])
1390
b6d33983 1391(define_insn "adddi3z_media"
73a4d10b 1392 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
fa5322fa 1393 (zero_extend:DI
b6d33983
R
1394 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1395 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
fa5322fa 1396 "TARGET_SHMEDIA"
b6d33983 1397 "addz.l %1, %N2, %0"
73a4d10b
R
1398 [(set_attr "type" "arith_media")
1399 (set_attr "highpart" "ignore")])
52702ae1 1400
fa5322fa 1401(define_insn "adddi3_compact"
73a4d10b 1402 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
07a45e5c
JW
1403 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1404 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1405 (clobber (reg:SI T_REG))]
fa5322fa 1406 "TARGET_SH1"
1245df60 1407 "#"
4fdd1f85 1408 [(set_attr "length" "6")])
961c4780 1409
1245df60 1410(define_split
73a4d10b 1411 [(set (match_operand:DI 0 "arith_reg_dest" "")
e69d1422
R
1412 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1413 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1414 (clobber (reg:SI T_REG))]
fa5322fa 1415 "TARGET_SH1 && reload_completed"
1245df60
R
1416 [(const_int 0)]
1417 "
1418{
1419 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1420 high0 = gen_rtx_REG (SImode,
1421 true_regnum (operands[0])
1422 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1423 high2 = gen_rtx_REG (SImode,
1424 true_regnum (operands[2])
1425 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1426 emit_insn (gen_clrt ());
1427 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1428 emit_insn (gen_addc1 (high0, high0, high2));
1429 DONE;
1430}")
1431
1432(define_insn "addc"
73a4d10b 1433 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1245df60
R
1434 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1435 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1436 (reg:SI T_REG)))
1437 (set (reg:SI T_REG)
1245df60 1438 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1439 "TARGET_SH1"
1245df60 1440 "addc %2,%0"
c49439f1 1441 [(set_attr "type" "arith")])
1245df60
R
1442
1443(define_insn "addc1"
73a4d10b 1444 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1245df60
R
1445 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1446 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1447 (reg:SI T_REG)))
1448 (clobber (reg:SI T_REG))]
fa5322fa 1449 "TARGET_SH1"
1245df60 1450 "addc %2,%0"
c49439f1 1451 [(set_attr "type" "arith")])
1245df60 1452
fa5322fa
AO
1453(define_expand "addsi3"
1454 [(set (match_operand:SI 0 "arith_reg_operand" "")
1455 (plus:SI (match_operand:SI 1 "arith_operand" "")
1456 (match_operand:SI 2 "arith_operand" "")))]
1457 ""
1458 "
1459{
1460 if (TARGET_SHMEDIA)
1461 operands[1] = force_reg (SImode, operands[1]);
1462}")
1463
1464(define_insn "addsi3_media"
73a4d10b 1465 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
b6d33983 1466 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
735cb76e 1467 (match_operand:SI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1468 "TARGET_SHMEDIA"
1469 "@
1470 add.l %1, %2, %0
b6d33983 1471 addi.l %1, %2, %0"
73a4d10b
R
1472 [(set_attr "type" "arith_media")
1473 (set_attr "highpart" "ignore")])
1474
1475(define_insn "addsidi3_media"
1476 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1477 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1478 "%r,r")
1479 (match_operand:SI 2 "arith_operand"
1480 "r,I10"))))]
1481 "TARGET_SHMEDIA"
1482 "@
1483 add.l %1, %2, %0
1484 addi.l %1, %2, %0"
1485 [(set_attr "type" "arith_media")
1486 (set_attr "highpart" "ignore")])
52702ae1 1487
fa5322fa 1488(define_insn "*addsi3_compact"
73a4d10b 1489 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
51bd623f 1490 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
735cb76e 1491 (match_operand:SI 2 "arith_operand" "rI08")))]
fa5322fa 1492 "TARGET_SH1"
bc45ade3 1493 "add %2,%0"
c49439f1 1494 [(set_attr "type" "arith")])
fae15c93 1495
bc45ade3
SC
1496;; -------------------------------------------------------------------------
1497;; Subtraction instructions
1498;; -------------------------------------------------------------------------
1499
fa5322fa
AO
1500(define_expand "subdi3"
1501 [(set (match_operand:DI 0 "arith_reg_operand" "")
52702ae1 1502 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
fa5322fa
AO
1503 (match_operand:DI 2 "arith_reg_operand" "")))]
1504 ""
1505 "
1506{
1507 if (TARGET_SH1)
1508 {
52702ae1 1509 operands[1] = force_reg (DImode, operands[1]);
fa5322fa
AO
1510 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1511 DONE;
1512 }
1513}")
52702ae1 1514
fa5322fa 1515(define_insn "*subdi3_media"
73a4d10b 1516 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
52702ae1 1517 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
fa5322fa
AO
1518 (match_operand:DI 2 "arith_reg_operand" "r")))]
1519 "TARGET_SHMEDIA"
2ad65b0e
SC
1520 "sub %N1, %2, %0"
1521 [(set_attr "type" "arith_media")])
73a4d10b
R
1522
1523(define_insn "subdisi3_media"
1524 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1525 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1526 (match_operand:DI 2 "arith_reg_operand" "r")))]
1527 "TARGET_SHMEDIA"
1528 "sub.l %N1, %2, %0"
1529 [(set_attr "type" "arith_media")
1530 (set_attr "highpart" "ignore")])
52702ae1 1531
fa5322fa 1532(define_insn "subdi3_compact"
73a4d10b 1533 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
07a45e5c
JW
1534 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1535 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1536 (clobber (reg:SI T_REG))]
fa5322fa 1537 "TARGET_SH1"
1245df60 1538 "#"
4fdd1f85 1539 [(set_attr "length" "6")])
bc45ade3 1540
1245df60 1541(define_split
73a4d10b 1542 [(set (match_operand:DI 0 "arith_reg_dest" "")
e69d1422
R
1543 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1544 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1545 (clobber (reg:SI T_REG))]
fa5322fa 1546 "TARGET_SH1 && reload_completed"
1245df60
R
1547 [(const_int 0)]
1548 "
1549{
1550 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1551 high0 = gen_rtx_REG (SImode,
1552 true_regnum (operands[0])
1553 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1554 high2 = gen_rtx_REG (SImode,
1555 true_regnum (operands[2])
1556 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1557 emit_insn (gen_clrt ());
1558 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1559 emit_insn (gen_subc1 (high0, high0, high2));
1560 DONE;
1561}")
1562
1563(define_insn "subc"
73a4d10b 1564 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1245df60
R
1565 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1566 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1567 (reg:SI T_REG)))
1568 (set (reg:SI T_REG)
3db1b434
R
1569 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1570 (reg:SI T_REG))
1571 (match_dup 1)))]
fa5322fa 1572 "TARGET_SH1"
1245df60 1573 "subc %2,%0"
c49439f1 1574 [(set_attr "type" "arith")])
1245df60
R
1575
1576(define_insn "subc1"
73a4d10b 1577 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1245df60
R
1578 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1579 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1580 (reg:SI T_REG)))
1581 (clobber (reg:SI T_REG))]
fa5322fa 1582 "TARGET_SH1"
1245df60 1583 "subc %2,%0"
c49439f1 1584 [(set_attr "type" "arith")])
1245df60 1585
73a4d10b
R
1586;; life_analysis thinks rn is live before subc rn,rn, so make a special
1587;; pattern for this case. This helps multimedia applications that compute
1588;; the sum of absolute differences.
1589(define_insn "mov_neg_si_t"
1590 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1591 "TARGET_SH1"
1592 "subc %0,%0"
1593 [(set_attr "type" "arith")])
1594
caca3c8a 1595(define_insn "*subsi3_internal"
73a4d10b 1596 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
0d7e008e 1597 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1598 (match_operand:SI 2 "arith_reg_operand" "r")))]
fa5322fa 1599 "TARGET_SH1"
0d7e008e 1600 "sub %2,%0"
c49439f1 1601 [(set_attr "type" "arith")])
caca3c8a 1602
73a4d10b
R
1603(define_insn_and_split "*subsi3_media"
1604 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1605 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
b6d33983 1606 (match_operand:SI 2 "extend_reg_operand" "r")))]
73a4d10b
R
1607 "TARGET_SHMEDIA
1608 && (operands[1] != constm1_rtx
1609 || (GET_CODE (operands[2]) != TRUNCATE
1610 && GET_CODE (operands[2]) != SUBREG))"
b6d33983 1611 "sub.l %N1, %2, %0"
73a4d10b
R
1612 "operands[1] == constm1_rtx"
1613 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1614 ""
1615 [(set_attr "type" "arith_media")
1616 (set_attr "highpart" "ignore")])
fa5322fa 1617
73a4d10b
R
1618(define_split
1619 [(set (match_operand:SI 0 "arith_reg_dest" "")
1620 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1621 "general_extend_operand"
1622 "") 0)) 0)))]
1623 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1624 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1625 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1626 "")
1627
1628(define_split
1629 [(set (match_operand:SI 0 "arith_reg_dest" "")
1630 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1631 "general_extend_operand"
1632 "") 0)) 3)))]
1633 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1634 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1635 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1636 "")
caca3c8a
JW
1637;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1638;; will sometimes save one instruction. Otherwise we might get
1639;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1640;; are the same.
1641
1642(define_expand "subsi3"
1643 [(set (match_operand:SI 0 "arith_reg_operand" "")
1644 (minus:SI (match_operand:SI 1 "arith_operand" "")
1645 (match_operand:SI 2 "arith_reg_operand" "")))]
1646 ""
1647 "
1648{
fa5322fa 1649 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
caca3c8a
JW
1650 {
1651 emit_insn (gen_negsi2 (operands[0], operands[2]));
1652 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1653 DONE;
1654 }
fa5322fa
AO
1655 if (TARGET_SHMEDIA)
1656 {
b6d33983 1657 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
fa5322fa 1658 FAIL;
73a4d10b 1659 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
b6d33983 1660 operands[1] = force_reg (SImode, operands[1]);
fa5322fa 1661 }
caca3c8a 1662}")
bc45ade3
SC
1663\f
1664;; -------------------------------------------------------------------------
0d7e008e 1665;; Division instructions
bc45ade3
SC
1666;; -------------------------------------------------------------------------
1667
ffae286a 1668;; We take advantage of the library routines which don't clobber as many
0d7e008e
SC
1669;; registers as a normal function call would.
1670
1245df60 1671;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
956d6950 1672;; also has an effect on the register that holds the address of the sfunc.
e69d1422 1673;; To make this work, we have an extra dummy insn that shows the use
1245df60
R
1674;; of this register for reorg.
1675
1676(define_insn "use_sfunc_addr"
4773afa4 1677 [(set (reg:SI PR_REG)
e69d1422 1678 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
07d7d2f4 1679 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1245df60
R
1680 ""
1681 [(set_attr "length" "0")])
1682
157371cf 1683(define_insn "udivsi3_sh2a"
73a4d10b 1684 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
157371cf
AO
1685 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1686 (match_operand:SI 2 "arith_reg_operand" "z")))]
1687 "TARGET_SH2A"
1688 "divu %2,%1"
98e20ffd
NC
1689 [(set_attr "type" "arith")
1690 (set_attr "in_delay_slot" "no")])
157371cf 1691
ddd5a7c1 1692;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
e96a50cc
JW
1693;; hard register 0. If we used hard register 0, then the next instruction
1694;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1695;; gets allocated to a stack slot that needs its address reloaded, then
1696;; there is nothing to prevent reload from using r0 to reload the address.
1697;; This reload would clobber the value in r0 we are trying to store.
1698;; If we let reload allocate r0, then this problem can never happen.
0d7e008e 1699
a512fa97 1700(define_insn "udivsi3_i1"
1245df60 1701 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1702 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1703 (clobber (reg:SI T_REG))
1704 (clobber (reg:SI PR_REG))
1705 (clobber (reg:SI R4_REG))
1245df60 1706 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1707 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1708 "jsr @%1%#"
1709 [(set_attr "type" "sfunc")
1710 (set_attr "needs_delay_slot" "yes")])
1711
9e96203d
R
1712; Since shmedia-nofpu code could be linked against shcompact code, and
1713; the udivsi3 libcall has the same name, we must consider all registers
1714; clobbered that are in the union of the registers clobbered by the
1715; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1716; implementation actually used shcompact code, we'd need to clobber
9e96203d 1717; also r23 and fr23.
fa5322fa
AO
1718(define_insn "udivsi3_i1_media"
1719 [(set (match_operand:SI 0 "register_operand" "=z")
1720 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1721 (clobber (reg:SI T_MEDIA_REG))
1722 (clobber (reg:SI PR_MEDIA_REG))
9e96203d
R
1723 (clobber (reg:SI R20_REG))
1724 (clobber (reg:SI R21_REG))
1725 (clobber (reg:SI R22_REG))
fa5322fa
AO
1726 (clobber (reg:DI TR0_REG))
1727 (clobber (reg:DI TR1_REG))
1728 (clobber (reg:DI TR2_REG))
73a4d10b
R
1729 (use (match_operand 1 "target_operand" "b"))]
1730 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
fa5322fa
AO
1731 "blink %1, r18"
1732 [(set_attr "type" "sfunc")
1733 (set_attr "needs_delay_slot" "yes")])
1734
1735(define_expand "udivsi3_i4_media"
b6d33983
R
1736 [(set (match_dup 3)
1737 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1738 (set (match_dup 4)
1739 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
fa5322fa 1740 (set (match_dup 5) (float:DF (match_dup 3)))
b6d33983
R
1741 (set (match_dup 6) (float:DF (match_dup 4)))
1742 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1743 (set (match_dup 8) (fix:DI (match_dup 7)))
0ac78517
R
1744 (set (match_operand:SI 0 "register_operand" "")
1745 (truncate:SI (match_dup 8)))]
fa5322fa
AO
1746 "TARGET_SHMEDIA_FPU"
1747 "
1748{
fa5322fa 1749 operands[3] = gen_reg_rtx (DImode);
b6d33983 1750 operands[4] = gen_reg_rtx (DImode);
fa5322fa
AO
1751 operands[5] = gen_reg_rtx (DFmode);
1752 operands[6] = gen_reg_rtx (DFmode);
b6d33983
R
1753 operands[7] = gen_reg_rtx (DFmode);
1754 operands[8] = gen_reg_rtx (DImode);
fa5322fa
AO
1755}")
1756
225e4f43
R
1757(define_insn "udivsi3_i4"
1758 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1759 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1760 (clobber (reg:SI T_REG))
4773afa4
AO
1761 (clobber (reg:SI PR_REG))
1762 (clobber (reg:DF DR0_REG))
1763 (clobber (reg:DF DR2_REG))
1764 (clobber (reg:DF DR4_REG))
1765 (clobber (reg:SI R0_REG))
1766 (clobber (reg:SI R1_REG))
1767 (clobber (reg:SI R4_REG))
1768 (clobber (reg:SI R5_REG))
1769 (use (reg:PSI FPSCR_REG))
225e4f43
R
1770 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1771 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1772 "jsr @%1%#"
1773 [(set_attr "type" "sfunc")
d64264ff 1774 (set_attr "fp_mode" "double")
225e4f43
R
1775 (set_attr "needs_delay_slot" "yes")])
1776
1777(define_insn "udivsi3_i4_single"
1778 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1779 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1780 (clobber (reg:SI T_REG))
4773afa4
AO
1781 (clobber (reg:SI PR_REG))
1782 (clobber (reg:DF DR0_REG))
1783 (clobber (reg:DF DR2_REG))
1784 (clobber (reg:DF DR4_REG))
1785 (clobber (reg:SI R0_REG))
1786 (clobber (reg:SI R1_REG))
1787 (clobber (reg:SI R4_REG))
1788 (clobber (reg:SI R5_REG))
225e4f43 1789 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1790 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1791 "jsr @%1%#"
0d7e008e 1792 [(set_attr "type" "sfunc")
0d7e008e
SC
1793 (set_attr "needs_delay_slot" "yes")])
1794
b368d6b8
R
1795(define_insn "udivsi3_i4_int"
1796 [(set (match_operand:SI 0 "register_operand" "=z")
1797 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1798 (clobber (reg:SI T_REG))
1799 (clobber (reg:SI R1_REG))
1800 (clobber (reg:SI PR_REG))
1801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1802 "TARGET_SH1"
1803 "jsr @%1%#"
1804 [(set_attr "type" "sfunc")
1805 (set_attr "needs_delay_slot" "yes")])
1806
1807
0d7e008e 1808(define_expand "udivsi3"
a512fa97 1809 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
4773afa4
AO
1810 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1811 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1812 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1813 (udiv:SI (reg:SI R4_REG)
1814 (reg:SI R5_REG)))
1815 (clobber (reg:SI T_REG))
1816 (clobber (reg:SI PR_REG))
1817 (clobber (reg:SI R4_REG))
ffae286a 1818 (use (match_dup 3))])]
0d7e008e 1819 ""
225e4f43
R
1820 "
1821{
4392ebd3 1822 rtx first, last;
a512fa97 1823
fa5322fa 1824 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1825 /* Emit the move of the address to a pseudo outside of the libcall. */
b368d6b8
R
1826 if (TARGET_DIVIDE_CALL_TABLE)
1827 {
1828 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1829 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1830 }
1831 else if (TARGET_DIVIDE_CALL_FP)
225e4f43 1832 {
73a4d10b 1833 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
225e4f43 1834 if (TARGET_FPU_SINGLE)
a512fa97 1835 last = gen_udivsi3_i4_single (operands[0], operands[3]);
225e4f43 1836 else
a512fa97 1837 last = gen_udivsi3_i4 (operands[0], operands[3]);
225e4f43 1838 }
fa5322fa 1839 else if (TARGET_SHMEDIA_FPU)
b6d33983
R
1840 {
1841 operands[1] = force_reg (SImode, operands[1]);
1842 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1843 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1844 DONE;
b6d33983 1845 }
157371cf
AO
1846 else if (TARGET_SH2A)
1847 {
1848 operands[1] = force_reg (SImode, operands[1]);
1849 operands[2] = force_reg (SImode, operands[2]);
1850 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1851 DONE;
1852 }
fa5322fa
AO
1853 else if (TARGET_SH5)
1854 {
73a4d10b
R
1855 function_symbol (operands[3],
1856 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1857 SFUNC_STATIC);
fa5322fa
AO
1858
1859 if (TARGET_SHMEDIA)
73a4d10b 1860 last = gen_udivsi3_i1_media (operands[0], operands[3]);
fa5322fa
AO
1861 else if (TARGET_FPU_ANY)
1862 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1863 else
1864 last = gen_udivsi3_i1 (operands[0], operands[3]);
1865 }
a512fa97
R
1866 else
1867 {
73a4d10b 1868 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
a512fa97
R
1869 last = gen_udivsi3_i1 (operands[0], operands[3]);
1870 }
4392ebd3
RS
1871 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1872 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1873 last = emit_insn (last);
1874 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1875 invariant code motion can move it. */
1876 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1877 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1878 DONE;
225e4f43 1879}")
0d7e008e 1880
157371cf 1881(define_insn "divsi3_sh2a"
73a4d10b 1882 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
157371cf
AO
1883 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1884 (match_operand:SI 2 "arith_reg_operand" "z")))]
1885 "TARGET_SH2A"
1886 "divs %2,%1"
98e20ffd
NC
1887 [(set_attr "type" "arith")
1888 (set_attr "in_delay_slot" "no")])
157371cf 1889
a512fa97 1890(define_insn "divsi3_i1"
1245df60 1891 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1892 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1893 (clobber (reg:SI T_REG))
1894 (clobber (reg:SI PR_REG))
1895 (clobber (reg:SI R1_REG))
1896 (clobber (reg:SI R2_REG))
1897 (clobber (reg:SI R3_REG))
1245df60 1898 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1899 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1900 "jsr @%1%#"
1901 [(set_attr "type" "sfunc")
1902 (set_attr "needs_delay_slot" "yes")])
1903
fa5322fa
AO
1904(define_insn "divsi3_i1_media"
1905 [(set (match_operand:SI 0 "register_operand" "=z")
1906 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1907 (clobber (reg:SI T_MEDIA_REG))
1908 (clobber (reg:SI PR_MEDIA_REG))
1909 (clobber (reg:SI R1_REG))
9e96203d
R
1910 (clobber (reg:SI R20_REG))
1911 (clobber (reg:SI R21_REG))
73a4d10b
R
1912 (clobber (reg:SI TR0_REG))
1913 (use (match_operand 1 "target_operand" "b"))]
1914 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
2ad65b0e
SC
1915 "blink %1, r18"
1916 [(set_attr "type" "sfunc")])
fa5322fa 1917
73a4d10b
R
1918(define_insn "divsi3_media_2"
1919 [(set (match_operand:SI 0 "register_operand" "=z")
1920 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1921 (clobber (reg:SI T_MEDIA_REG))
1922 (clobber (reg:SI PR_MEDIA_REG))
1923 (clobber (reg:SI R1_REG))
1924 (clobber (reg:SI R21_REG))
1925 (clobber (reg:SI TR0_REG))
1926 (use (reg:SI R20_REG))
1927 (use (match_operand 1 "target_operand" "b"))]
1928 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1929 "blink %1, r18"
1930 [(set_attr "type" "sfunc")])
1931
1932;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1933;; hard reg clobbers and data dependencies that we need when we want
1934;; to rematerialize the division into a call.
1935(define_insn_and_split "divsi_inv_call"
1936 [(set (match_operand:SI 0 "register_operand" "=r")
1937 (div:SI (match_operand:SI 1 "register_operand" "r")
1938 (match_operand:SI 2 "register_operand" "r")))
1939 (clobber (reg:SI R4_REG))
1940 (clobber (reg:SI R5_REG))
1941 (clobber (reg:SI T_MEDIA_REG))
1942 (clobber (reg:SI PR_MEDIA_REG))
1943 (clobber (reg:SI R1_REG))
1944 (clobber (reg:SI R21_REG))
1945 (clobber (reg:SI TR0_REG))
1946 (clobber (reg:SI R20_REG))
1947 (use (match_operand:SI 3 "register_operand" "r"))]
1948 "TARGET_SHMEDIA"
1949 "#"
1950 "&& (high_life_started || reload_completed)"
1951 [(set (match_dup 0) (match_dup 3))]
1952 ""
1953 [(set_attr "highpart" "must_split")])
1954
1955;; This is the combiner pattern for -mdiv=inv:call .
1956(define_insn_and_split "*divsi_inv_call_combine"
1957 [(set (match_operand:SI 0 "register_operand" "=z")
1958 (div:SI (match_operand:SI 1 "register_operand" "r")
1959 (match_operand:SI 2 "register_operand" "r")))
1960 (clobber (reg:SI R4_REG))
1961 (clobber (reg:SI R5_REG))
1962 (clobber (reg:SI T_MEDIA_REG))
1963 (clobber (reg:SI PR_MEDIA_REG))
1964 (clobber (reg:SI R1_REG))
1965 (clobber (reg:SI R21_REG))
1966 (clobber (reg:SI TR0_REG))
1967 (clobber (reg:SI R20_REG))
1968 (use (unspec:SI [(match_dup 1)
1969 (match_operand:SI 3 "" "")
1970 (unspec:SI [(match_operand:SI 4 "" "")
1971 (match_dup 3)
1972 (match_operand:DI 5 "" "")]
1973 UNSPEC_DIV_INV_M2)
1974 (match_operand:DI 6 "" "")
1975 (const_int 0)
1976 (const_int 0)]
1977 UNSPEC_DIV_INV_M3))]
1978 "TARGET_SHMEDIA"
1979 "#"
1980 "&& (high_life_started || reload_completed)"
1981 [(pc)]
1982 "
1983{
1984 const char *name = sh_divsi3_libfunc;
1985 enum sh_function_kind kind = SFUNC_GOT;
1986 rtx sym;
1987
1988 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1989 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1990 while (TARGET_DIVIDE_INV_CALL2)
1991 {
1992 rtx x = operands[3];
1993
1994 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1995 break;
1996 x = XVECEXP (x, 0, 0);
1997 name = \"__sdivsi3_2\";
1998 kind = SFUNC_STATIC;
1999 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2000 break;
2001 }
2002 sym = function_symbol (NULL, name, kind);
2003 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2004 DONE;
2005}"
2006 [(set_attr "highpart" "must_split")])
2007
fa5322fa 2008(define_expand "divsi3_i4_media"
51214775
R
2009 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2010 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2011 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
fa5322fa 2012 (set (match_operand:SI 0 "register_operand" "=r")
51214775 2013 (fix:SI (match_dup 5)))]
fa5322fa
AO
2014 "TARGET_SHMEDIA_FPU"
2015 "
2016{
51214775 2017 operands[3] = gen_reg_rtx (DFmode);
fa5322fa
AO
2018 operands[4] = gen_reg_rtx (DFmode);
2019 operands[5] = gen_reg_rtx (DFmode);
fa5322fa
AO
2020}")
2021
225e4f43
R
2022(define_insn "divsi3_i4"
2023 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
2024 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2025 (clobber (reg:SI PR_REG))
2026 (clobber (reg:DF DR0_REG))
2027 (clobber (reg:DF DR2_REG))
2028 (use (reg:PSI FPSCR_REG))
225e4f43
R
2029 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2030 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2031 "jsr @%1%#"
2032 [(set_attr "type" "sfunc")
d64264ff 2033 (set_attr "fp_mode" "double")
225e4f43
R
2034 (set_attr "needs_delay_slot" "yes")])
2035
2036(define_insn "divsi3_i4_single"
2037 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
2038 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2039 (clobber (reg:SI PR_REG))
2040 (clobber (reg:DF DR0_REG))
2041 (clobber (reg:DF DR2_REG))
2042 (clobber (reg:SI R2_REG))
225e4f43 2043 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 2044 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 2045 "jsr @%1%#"
0d7e008e 2046 [(set_attr "type" "sfunc")
0d7e008e
SC
2047 (set_attr "needs_delay_slot" "yes")])
2048
b368d6b8
R
2049(define_insn "divsi3_i4_int"
2050 [(set (match_operand:SI 0 "register_operand" "=z")
2051 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2052 (clobber (reg:SI T_REG))
2053 (clobber (reg:SI PR_REG))
2054 (clobber (reg:SI R1_REG))
2055 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2056 "TARGET_SH1"
2057 "jsr @%1%#"
2058 [(set_attr "type" "sfunc")
2059 (set_attr "needs_delay_slot" "yes")])
2060
0d7e008e 2061(define_expand "divsi3"
a512fa97 2062 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
4773afa4
AO
2063 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2064 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 2065 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
2066 (div:SI (reg:SI R4_REG)
2067 (reg:SI R5_REG)))
2068 (clobber (reg:SI T_REG))
2069 (clobber (reg:SI PR_REG))
2070 (clobber (reg:SI R1_REG))
2071 (clobber (reg:SI R2_REG))
2072 (clobber (reg:SI R3_REG))
ffae286a 2073 (use (match_dup 3))])]
0d7e008e 2074 ""
225e4f43
R
2075 "
2076{
4392ebd3 2077 rtx first, last;
a512fa97 2078
fa5322fa 2079 operands[3] = gen_reg_rtx (Pmode);
a512fa97 2080 /* Emit the move of the address to a pseudo outside of the libcall. */
b368d6b8
R
2081 if (TARGET_DIVIDE_CALL_TABLE)
2082 {
2083 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2084 last = gen_divsi3_i4_int (operands[0], operands[3]);
2085 }
2086 else if (TARGET_DIVIDE_CALL_FP)
225e4f43 2087 {
73a4d10b 2088 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
225e4f43 2089 if (TARGET_FPU_SINGLE)
a512fa97 2090 last = gen_divsi3_i4_single (operands[0], operands[3]);
225e4f43 2091 else
a512fa97 2092 last = gen_divsi3_i4 (operands[0], operands[3]);
225e4f43 2093 }
157371cf
AO
2094 else if (TARGET_SH2A)
2095 {
2096 operands[1] = force_reg (SImode, operands[1]);
2097 operands[2] = force_reg (SImode, operands[2]);
2098 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2099 DONE;
2100 }
73a4d10b
R
2101 else if (TARGET_DIVIDE_INV)
2102 {
2103 rtx dividend = operands[1];
2104 rtx divisor = operands[2];
2105 rtx tab_base;
2106 rtx nsb_res = gen_reg_rtx (DImode);
2107 rtx norm64 = gen_reg_rtx (DImode);
2108 rtx tab_ix = gen_reg_rtx (DImode);
2109 rtx norm32 = gen_reg_rtx (SImode);
2110 rtx i92 = force_reg (DImode, GEN_INT (92));
2111 rtx scratch0a = gen_reg_rtx (DImode);
2112 rtx scratch0b = gen_reg_rtx (DImode);
2113 rtx inv0 = gen_reg_rtx (SImode);
2114 rtx scratch1a = gen_reg_rtx (DImode);
2115 rtx scratch1b = gen_reg_rtx (DImode);
2116 rtx shift = gen_reg_rtx (DImode);
2117 rtx i2p27, i43;
2118 rtx inv1 = gen_reg_rtx (SImode);
2119 rtx scratch2a = gen_reg_rtx (DImode);
2120 rtx scratch2b = gen_reg_rtx (SImode);
2121 rtx inv2 = gen_reg_rtx (SImode);
2122 rtx scratch3a = gen_reg_rtx (DImode);
2123 rtx scratch3b = gen_reg_rtx (DImode);
2124 rtx scratch3c = gen_reg_rtx (DImode);
2125 rtx scratch3d = gen_reg_rtx (SImode);
2126 rtx scratch3e = gen_reg_rtx (DImode);
2127 rtx result = gen_reg_rtx (SImode);
2128
2129 if (! arith_reg_or_0_operand (dividend, SImode))
2130 dividend = force_reg (SImode, dividend);
2131 if (! arith_reg_operand (divisor, SImode))
2132 divisor = force_reg (SImode, divisor);
2133 if (flag_pic && Pmode != DImode)
2134 {
2135 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2136 tab_base = gen_datalabel_ref (tab_base);
2137 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2138 }
2139 else
2140 {
2141 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2142 tab_base = gen_datalabel_ref (tab_base);
2143 tab_base = force_reg (DImode, tab_base);
2144 }
2145 if (TARGET_DIVIDE_INV20U)
2146 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2147 else
2148 i2p27 = GEN_INT (0);
2149 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2150 i43 = force_reg (DImode, GEN_INT (43));
2151 else
2152 i43 = GEN_INT (0);
2153 emit_insn (gen_nsbdi (nsb_res,
2154 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2155 emit_insn (gen_ashldi3_media (norm64,
2156 gen_rtx_SUBREG (DImode, divisor, 0),
2157 nsb_res));
2158 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2159 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2160 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2161 inv0, scratch0a, scratch0b,
2162 scratch1a, scratch1b));
2163 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2164 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2165 scratch2a));
2166 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2167 i2p27, i43,
2168 scratch3a, scratch3b, scratch3c,
2169 scratch2a, scratch2b, scratch3d, scratch3e));
2170 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2171 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2172 else if (TARGET_DIVIDE_INV_FP)
2173 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2174 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2175 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2176 gen_reg_rtx (DFmode)));
2177 else
2178 emit_move_insn (operands[0], result);
2179 DONE;
2180 }
2181 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
51214775
R
2182 {
2183 operands[1] = force_reg (SImode, operands[1]);
2184 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
2185 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2186 DONE;
51214775 2187 }
fa5322fa
AO
2188 else if (TARGET_SH5)
2189 {
73a4d10b
R
2190 if (TARGET_DIVIDE_CALL2)
2191 {
2192 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2193 tab_base = gen_datalabel_ref (tab_base);
2194 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2195 }
2196 if (TARGET_FPU_ANY && TARGET_SH1)
2197 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2198 else if (TARGET_DIVIDE_CALL2)
2199 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2200 else
2201 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
fa5322fa
AO
2202
2203 if (TARGET_SHMEDIA)
73a4d10b
R
2204 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2205 (operands[0], operands[3]));
fa5322fa
AO
2206 else if (TARGET_FPU_ANY)
2207 last = gen_divsi3_i4_single (operands[0], operands[3]);
2208 else
2209 last = gen_divsi3_i1 (operands[0], operands[3]);
2210 }
a512fa97
R
2211 else
2212 {
73a4d10b 2213 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
a512fa97
R
2214 last = gen_divsi3_i1 (operands[0], operands[3]);
2215 }
4392ebd3
RS
2216 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2217 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
2218 last = emit_insn (last);
2219 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2220 invariant code motion can move it. */
2221 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2222 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2223 DONE;
225e4f43 2224}")
73a4d10b
R
2225
2226;; operands: inv0, tab_base, tab_ix, norm32
2227;; scratch equiv in sdivsi3_2: r19, r21
2228(define_expand "divsi_inv_m0"
2229 [(set (match_operand:SI 0 "register_operand" "=r")
2230 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2231 (match_operand:DI 2 "register_operand" "r")
2232 (match_operand:SI 3 "register_operand" "r")]
2233 UNSPEC_DIV_INV_M0))
2234 (clobber (match_operand:DI 4 "register_operand" "=r"))
2235 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2236 "TARGET_SHMEDIA"
2237 "
2238{
2239/*
2240tab_base: r20
2241tab_ix: r21
2242norm32: r25
2243 ldx.ub r20, r21, r19 // u0.8
2244 shlli r21, 1, r21
2245 muls.l r25, r19, r19 // s2.38
2246 ldx.w r20, r21, r21 // s2.14
2247 shari r19, 24, r19 // truncate to s2.14
2248 sub r21, r19, r19 // some 11 bit inverse in s1.14
2249*/
2250
2251 rtx inv0 = operands[0];
2252 rtx tab_base = operands[1];
2253 rtx tab_ix = operands[2];
2254 rtx norm32 = operands[3];
2255 rtx scratch0 = operands[4];
2256 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2257 rtx scratch1 = operands[5];
2258 rtx mem;
2259
57d38024 2260 mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
73a4d10b
R
2261 emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2262 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2263 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
57d38024 2264 mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
73a4d10b
R
2265 emit_insn (gen_extendhidi2 (scratch1, mem));
2266 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2267 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2268 DONE;
2269}")
2270
2271;; operands: inv1, tab_base, tab_ix, norm32
2272(define_insn_and_split "divsi_inv_m1"
2273 [(set (match_operand:SI 0 "register_operand" "=r")
2274 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2275 (match_operand:DI 2 "register_operand" "r")
2276 (match_operand:SI 3 "register_operand" "r")]
2277 UNSPEC_DIV_INV_M1))
2278 (clobber (match_operand:SI 4 "register_operand" "=r"))
2279 (clobber (match_operand:DI 5 "register_operand" "=r"))
2280 (clobber (match_operand:DI 6 "register_operand" "=r"))
2281 (clobber (match_operand:DI 7 "register_operand" "=r"))
2282 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2283 "TARGET_SHMEDIA"
2284 "#"
2285 "&& no_new_pseudos"
2286 [(pc)]
2287 "
2288{
2289/* inv0: r19
2290 muls.l r19, r19, r18 // u0.28
2291 muls.l r25, r18, r18 // s2.58
2292 shlli r19, 45, r0 // multiply by two and convert to s2.58
2293 sub r0, r18, r18
2294 shari r18, 28, r18 // some 18 bit inverse in s1.30
2295*/
2296
2297 rtx inv1 = operands[0];
2298 rtx tab_base = operands[1];
2299 rtx tab_ix = operands[2];
2300 rtx norm32 = operands[3];
2301 rtx inv0 = operands[4];
2302 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2303 rtx scratch0a = operands[5];
2304 rtx scratch0b = operands[6];
2305 rtx scratch0 = operands[7];
2306 rtx scratch1 = operands[8];
2307 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2308
2309 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2310 scratch0a, scratch0b));
2311 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2312 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2313 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2314 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2315 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2316 DONE;
2317}")
2318
2319;; operands: inv2, norm32, inv1, i92
2320(define_insn_and_split "divsi_inv_m2"
2321 [(set (match_operand:SI 0 "register_operand" "=r")
2322 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2323 (match_operand:SI 2 "register_operand" "r")
2324 (match_operand:DI 3 "register_operand" "r")]
2325 UNSPEC_DIV_INV_M2))
2326 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2327 "TARGET_SHMEDIA"
2328 "#"
2329 "&& no_new_pseudos"
2330 [(pc)]
2331 "
2332{
2333/*
2334 muls.l r18, r25, r0 // s2.60
2335 shari r0, 16, r0 // s-16.44
2336 sub
2337 muls.l r0, r18, r19 // s-16.74
2338 shari r19, 30, r19 // s-16.44
2339*/
2340 rtx inv2 = operands[0];
2341 rtx norm32 = operands[1];
2342 rtx inv1 = operands[2];
2343 rtx i92 = operands[3];
2344 rtx scratch0 = operands[4];
2345 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2346
2347 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2348 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2349 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2350 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2351 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2352 DONE;
2353}")
2354
2355(define_insn_and_split "divsi_inv_m3"
2356 [(set (match_operand:SI 0 "register_operand" "=r")
2357 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2358 (match_operand:SI 2 "register_operand" "r")
2359 (match_operand:SI 3 "register_operand" "r")
2360 (match_operand:DI 4 "register_operand" "r")
2361 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2362 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2363 UNSPEC_DIV_INV_M3))
2364 (clobber (match_operand:DI 7 "register_operand" "=r"))
2365 (clobber (match_operand:DI 8 "register_operand" "=r"))
2366 (clobber (match_operand:DI 9 "register_operand" "=r"))
2367 (clobber (match_operand:DI 10 "register_operand" "=r"))
2368 (clobber (match_operand:SI 11 "register_operand" "=r"))
2369 (clobber (match_operand:SI 12 "register_operand" "=r"))
2370 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2371 "TARGET_SHMEDIA"
2372 "#"
2373 "&& no_new_pseudos"
2374 [(pc)]
2375 "
2376{
2377/*
2378 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2379 r0: scratch0 r19: scratch1 r21: scratch2
2380
2381 muls.l r18, r4, r25 // s32.30
2382 muls.l r19, r4, r19 // s15.30
2383 shari r25, 63, r21
2384 shari r19, 14, r19 // s18.-14
2385 sub r25, r19, r0
2386 shard r0, r1, r0
2387 sub r0, r21, r0
2388*/
2389
2390 rtx result = operands[0];
2391 rtx dividend = operands[1];
2392 rtx inv1 = operands[2];
2393 rtx inv2 = operands[3];
2394 rtx shift = operands[4];
2395 rtx scratch0 = operands[7];
2396 rtx scratch1 = operands[8];
2397 rtx scratch2 = operands[9];
2398
2399 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2400 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2401 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2402 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2403 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2404 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2405 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2406 DONE;
2407}")
2408
2409;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2410;; inv1: tab_base, tab_ix, norm32
2411;; inv2: norm32, inv1, i92
2412(define_insn_and_split "divsi_inv_m1_3"
2413 [(set (match_operand:SI 0 "register_operand" "=r")
2414 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2415 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2416 (match_operand:DI 3 "register_operand" "r")
2417 (match_operand:SI 4 "register_operand" "r")]
2418 UNSPEC_DIV_INV_M1)
2419 (unspec:SI [(match_dup 4)
2420 (unspec:SI [(match_dup 2)
2421 (match_dup 3)
2422 (match_dup 4)] UNSPEC_DIV_INV_M1)
2423 (match_operand:SI 5 "" "")]
2424 UNSPEC_DIV_INV_M2)
2425 (match_operand:DI 6 "register_operand" "r")
2426 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2427 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2428 UNSPEC_DIV_INV_M3))
2429 (clobber (match_operand:DI 9 "register_operand" "=r"))
2430 (clobber (match_operand:DI 10 "register_operand" "=r"))
2431 (clobber (match_operand:DI 11 "register_operand" "=r"))
2432 (clobber (match_operand:DI 12 "register_operand" "=r"))
2433 (clobber (match_operand:SI 13 "register_operand" "=r"))
2434 (clobber (match_operand:SI 14 "register_operand" "=r"))
2435 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2436 "TARGET_SHMEDIA
2437 && (TARGET_DIVIDE_INV_MINLAT
2438 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2439 "#"
2440 "&& no_new_pseudos"
2441 [(pc)]
2442 "
2443{
2444 rtx result = operands[0];
2445 rtx dividend = operands[1];
2446 rtx tab_base = operands[2];
2447 rtx tab_ix = operands[3];
2448 rtx norm32 = operands[4];
2449 /* rtx i92 = operands[5]; */
2450 rtx shift = operands[6];
2451 rtx i2p27 = operands[7];
2452 rtx i43 = operands[8];
2453 rtx scratch0 = operands[9];
2454 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2455 rtx scratch1 = operands[10];
2456 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2457 rtx scratch2 = operands[11];
2458 rtx scratch3 = operands[12];
2459 rtx scratch4 = operands[13];
2460 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2461 rtx scratch5 = operands[14];
2462 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2463 rtx scratch6 = operands[15];
2464
2465 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2466 scratch0, scratch1));
2467 /* inv0 == scratch4 */
2468 if (! TARGET_DIVIDE_INV20U)
2469 {
2470 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2471 i2p27 = scratch0;
2472 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2473 }
2474 else
2475 {
2476 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2477 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2478 }
2479 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2480 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2481 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2482 /* inv1 == scratch4 */
2483
2484 if (TARGET_DIVIDE_INV_MINLAT)
2485 {
2486 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2487 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2488 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2489 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2490 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2491 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2492 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2493 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2494 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2495 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2496 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2497 }
2498 else
2499 {
2500 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2501 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2502 emit_insn (gen_nsbdi (scratch6,
2503 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2504 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2505 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2506 emit_insn (gen_divsi_inv20 (scratch2,
2507 norm32, scratch4, dividend,
2508 scratch6, scratch3, i43,
2509 /* scratch0 may be shared with i2p27. */
2510 scratch0, scratch1, scratch5,
2511 label, label, i2p27));
2512 }
2513 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2514 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2515 DONE;
2516}")
2517
2518(define_insn "divsi_inv20"
2519 [(set (match_operand:DI 0 "register_operand" "=&r")
2520 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2521 (match_operand:SI 2 "register_operand" "r")
2522 (match_operand:SI 3 "register_operand" "r")
2523 (match_operand:DI 4 "register_operand" "r")
2524 (match_operand:DI 5 "register_operand" "r")
2525 (match_operand:DI 6 "register_operand" "r")
2526 (match_operand:DI 12 "register_operand" "r")
2527 (match_operand 10 "target_operand" "b")
2528 (match_operand 11 "immediate_operand" "i")]
2529 UNSPEC_DIV_INV20))
2530 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2531 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2532 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2533 "TARGET_SHMEDIA
2534 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2535 "*
2536{
2537/* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2538 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2539 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2540 %10 label (tr), %11 label (imm)
2541
2542 muls.l inv1, norm32, scratch0 // s2.60
2543 muls.l inv1, dividend, result // s32.30
2544 xor i2p27, result_sign, round_scratch
2545 bge/u dividend_nsb, i43, tr.. (label)
2546 shari scratch0, 16, scratch0 // s-16.44
2547 muls.l sratch0_si, inv1, scratch0 // s-16.74
2548 sub result, round_scratch, result
2549 shari dividend, 14, scratch1 // s19.-14
2550 shari scratch0, 30, scratch0 // s-16.44
2551 muls.l scratch0, scratch1, round_scratch // s15.30
2552label:
2553 sub result, round_scratch, result */
2554
2555 int likely = TARGET_DIVIDE_INV20L;
2556
2557 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2558 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2559 output_asm_insn (likely
2560 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2561 : \"bge/u\t%4, %6, %10\", operands);
2562 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2563 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2564 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2565 return (likely
2566 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2567 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2568}")
2569
2570(define_insn_and_split "divsi_inv_fp"
2571 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2572 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2573 (match_operand:SI 2 "register_operand" "rf")))
2574 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2575 (clobber (match_operand:SI 4 "register_operand" "=r"))
2576 (clobber (match_operand:SI 5 "register_operand" "=r"))
2577 (clobber (match_operand:DF 6 "register_operand" "=r"))
2578 (clobber (match_operand:DF 7 "register_operand" "=r"))
2579 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2580 "TARGET_SHMEDIA_FPU"
2581 "#"
2582 "&& (high_life_started || reload_completed)"
2583 [(set (match_dup 0) (match_dup 3))]
2584 ""
2585 [(set_attr "highpart" "must_split")])
2586
2587;; If a matching group of divide-by-inverse instructions is in the same
2588;; basic block after gcse & loop optimizations, we want to transform them
2589;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2590(define_insn_and_split "*divsi_inv_fp_combine"
2591 [(set (match_operand:SI 0 "register_operand" "=f")
2592 (div:SI (match_operand:SI 1 "register_operand" "f")
2593 (match_operand:SI 2 "register_operand" "f")))
2594 (use (unspec:SI [(match_dup 1)
2595 (match_operand:SI 3 "" "")
2596 (unspec:SI [(match_operand:SI 4 "" "")
2597 (match_dup 3)
2598 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2599 (match_operand:DI 6 "" "")
2600 (const_int 0)
2601 (const_int 0)] UNSPEC_DIV_INV_M3))
2602 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2603 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2604 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2605 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2606 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2607 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2608 "#"
2609 "&& 1"
2610 [(set (match_dup 9) (float:DF (match_dup 1)))
2611 (set (match_dup 10) (float:DF (match_dup 2)))
2612 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2613 (set (match_dup 8)
2614 (fix:SI (match_dup 11)))
2615 (set (match_dup 0) (match_dup 8))]
2616 "
2617{
2618 if (! fp_arith_reg_operand (operands[1], SImode))
2619 {
2620 emit_move_insn (operands[7], operands[1]);
2621 operands[1] = operands[7];
2622 }
2623 if (! fp_arith_reg_operand (operands[2], SImode))
2624 {
2625 emit_move_insn (operands[8], operands[2]);
2626 operands[2] = operands[8];
2627 }
2628}"
2629 [(set_attr "highpart" "must_split")])
0d7e008e
SC
2630\f
2631;; -------------------------------------------------------------------------
2632;; Multiplication instructions
2633;; -------------------------------------------------------------------------
2634
a512fa97 2635(define_insn "umulhisi3_i"
4773afa4
AO
2636 [(set (reg:SI MACL_REG)
2637 (mult:SI (zero_extend:SI
2638 (match_operand:HI 0 "arith_reg_operand" "r"))
2639 (zero_extend:SI
2640 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 2641 "TARGET_SH1"
e9a9e960 2642 "mulu.w %1,%0"
b9654711 2643 [(set_attr "type" "smpy")])
bc45ade3 2644
a512fa97 2645(define_insn "mulhisi3_i"
4773afa4 2646 [(set (reg:SI MACL_REG)
bc45ade3 2647 (mult:SI (sign_extend:SI
af55dae3 2648 (match_operand:HI 0 "arith_reg_operand" "r"))
bc45ade3 2649 (sign_extend:SI
af55dae3 2650 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 2651 "TARGET_SH1"
e9a9e960 2652 "muls.w %1,%0"
b9654711 2653 [(set_attr "type" "smpy")])
bc45ade3
SC
2654
2655(define_expand "mulhisi3"
4773afa4 2656 [(set (reg:SI MACL_REG)
bc45ade3 2657 (mult:SI (sign_extend:SI
51aea58d 2658 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 2659 (sign_extend:SI
51aea58d
JW
2660 (match_operand:HI 2 "arith_reg_operand" ""))))
2661 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 2662 (reg:SI MACL_REG))]
fa5322fa 2663 "TARGET_SH1"
a512fa97
R
2664 "
2665{
2666 rtx first, last;
2667
2668 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
4773afa4 2669 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
2670 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2671 invariant code motion can move it. */
2672 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2673 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
2674 /* expand_binop can't find a suitable code in umul_widen_optab to
2675 make a REG_EQUAL note from, so make one here.
2676 See also smulsi3_highpart.
2677 ??? Alternatively, we could put this at the calling site of expand_binop,
2678 i.e. expand_expr. */
2679 REG_NOTES (last)
2680 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2681 REG_NOTES (last));
a512fa97
R
2682 DONE;
2683}")
bc45ade3
SC
2684
2685(define_expand "umulhisi3"
4773afa4 2686 [(set (reg:SI MACL_REG)
bc45ade3 2687 (mult:SI (zero_extend:SI
51aea58d 2688 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 2689 (zero_extend:SI
51aea58d
JW
2690 (match_operand:HI 2 "arith_reg_operand" ""))))
2691 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 2692 (reg:SI MACL_REG))]
fa5322fa 2693 "TARGET_SH1"
a512fa97
R
2694 "
2695{
2696 rtx first, last;
2697
2698 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
4773afa4 2699 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
2700 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2701 invariant code motion can move it. */
2702 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2703 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
2704 /* expand_binop can't find a suitable code in umul_widen_optab to
2705 make a REG_EQUAL note from, so make one here.
2706 See also smulsi3_highpart.
2707 ??? Alternatively, we could put this at the calling site of expand_binop,
2708 i.e. expand_expr. */
2709 REG_NOTES (last)
2710 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2711 REG_NOTES (last));
a512fa97
R
2712 DONE;
2713}")
bc45ade3 2714
0d7e008e
SC
2715;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2716;; a call to a routine which clobbers known registers.
2717
2718(define_insn ""
e96a50cc 2719 [(set (match_operand:SI 1 "register_operand" "=z")
4773afa4
AO
2720 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2721 (clobber (reg:SI MACL_REG))
2722 (clobber (reg:SI T_REG))
2723 (clobber (reg:SI PR_REG))
2724 (clobber (reg:SI R3_REG))
2725 (clobber (reg:SI R2_REG))
2726 (clobber (reg:SI R1_REG))
07a45e5c 2727 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 2728 "TARGET_SH1"
0d7e008e
SC
2729 "jsr @%0%#"
2730 [(set_attr "type" "sfunc")
0d7e008e
SC
2731 (set_attr "needs_delay_slot" "yes")])
2732
2733(define_expand "mulsi3_call"
4773afa4
AO
2734 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2735 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
51aea58d 2736 (parallel[(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
2737 (mult:SI (reg:SI R4_REG)
2738 (reg:SI R5_REG)))
2739 (clobber (reg:SI MACL_REG))
2740 (clobber (reg:SI T_REG))
2741 (clobber (reg:SI PR_REG))
2742 (clobber (reg:SI R3_REG))
2743 (clobber (reg:SI R2_REG))
2744 (clobber (reg:SI R1_REG))
225e4f43 2745 (use (match_operand:SI 3 "register_operand" ""))])]
fa5322fa 2746 "TARGET_SH1"
225e4f43 2747 "")
07a45e5c 2748
157371cf 2749(define_insn "mul_r"
73a4d10b 2750 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
157371cf
AO
2751 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2752 (match_operand:SI 2 "arith_reg_operand" "z")))]
2753 "TARGET_SH2A"
2754 "mulr %2,%0"
2755 [(set_attr "type" "dmpy")])
2756
0d7e008e 2757(define_insn "mul_l"
4773afa4 2758 [(set (reg:SI MACL_REG)
0d7e008e
SC
2759 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2760 (match_operand:SI 1 "arith_reg_operand" "r")))]
2761 "TARGET_SH2"
2762 "mul.l %1,%0"
51bd623f 2763 [(set_attr "type" "dmpy")])
0d7e008e
SC
2764
2765(define_expand "mulsi3"
4773afa4 2766 [(set (reg:SI MACL_REG)
51aea58d
JW
2767 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2768 (match_operand:SI 2 "arith_reg_operand" "")))
2769 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 2770 (reg:SI MACL_REG))]
fa5322fa 2771 "TARGET_SH1"
51bd623f
JW
2772 "
2773{
225e4f43
R
2774 rtx first, last;
2775
51bd623f
JW
2776 if (!TARGET_SH2)
2777 {
225e4f43
R
2778 /* The address must be set outside the libcall,
2779 since it goes into a pseudo. */
73a4d10b 2780 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
a6f463a0
AO
2781 rtx addr = force_reg (SImode, sym);
2782 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2783 operands[2], addr);
fa60f36d
R
2784 first = insns;
2785 last = emit_insn (insns);
51bd623f 2786 }
225e4f43
R
2787 else
2788 {
2789 rtx macl = gen_rtx_REG (SImode, MACL_REG);
aa4778b6 2790
225e4f43 2791 first = emit_insn (gen_mul_l (operands[1], operands[2]));
aa4778b6
R
2792 /* consec_sets_giv can only recognize the first insn that sets a
2793 giv as the giv insn. So we must tag this also with a REG_EQUAL
2794 note. */
78d114ef 2795 last = emit_insn (gen_movsi_i ((operands[0]), macl));
225e4f43
R
2796 }
2797 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2798 invariant code motion can move it. */
2799 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2800 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2801 DONE;
51bd623f 2802}")
00f8ff66 2803
af55dae3 2804(define_insn "mulsidi3_i"
4773afa4 2805 [(set (reg:SI MACH_REG)
a512fa97 2806 (truncate:SI
4773afa4
AO
2807 (lshiftrt:DI
2808 (mult:DI
2809 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2810 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2811 (const_int 32))))
2812 (set (reg:SI MACL_REG)
a512fa97
R
2813 (mult:SI (match_dup 0)
2814 (match_dup 1)))]
06e1bace 2815 "TARGET_SH2"
af55dae3 2816 "dmuls.l %1,%0"
0d7e008e
SC
2817 [(set_attr "type" "dmpy")])
2818
fa5322fa
AO
2819(define_expand "mulsidi3"
2820 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2821 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2822 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2823 "TARGET_SH2 || TARGET_SHMEDIA"
2824 "
2825{
2826 if (TARGET_SH2)
2827 {
2828 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2829 operands[2]));
2830 DONE;
2831 }
2832}")
2833
2834(define_insn "mulsidi3_media"
73a4d10b 2835 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
b6d33983
R
2836 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2837 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 2838 "TARGET_SHMEDIA"
b6d33983 2839 "muls.l %1, %2, %0"
73a4d10b
R
2840 [(set_attr "type" "dmpy_media")
2841 (set_attr "highpart" "ignore")])
52702ae1 2842
fa5322fa 2843(define_insn "mulsidi3_compact"
73a4d10b 2844 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4773afa4
AO
2845 (mult:DI
2846 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2847 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
2848 (clobber (reg:SI MACH_REG))
2849 (clobber (reg:SI MACL_REG))]
a512fa97
R
2850 "TARGET_SH2"
2851 "#")
2852
2853(define_split
73a4d10b 2854 [(set (match_operand:DI 0 "arith_reg_dest" "")
4773afa4
AO
2855 (mult:DI
2856 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2857 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
2858 (clobber (reg:SI MACH_REG))
2859 (clobber (reg:SI MACL_REG))]
06e1bace 2860 "TARGET_SH2"
a512fa97 2861 [(const_int 0)]
af55dae3
JW
2862 "
2863{
a512fa97
R
2864 rtx low_dst = gen_lowpart (SImode, operands[0]);
2865 rtx high_dst = gen_highpart (SImode, operands[0]);
0d7e008e 2866
a512fa97 2867 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
af55dae3 2868
4773afa4
AO
2869 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2870 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
2871 /* We need something to tag the possible REG_EQUAL notes on to. */
2872 emit_move_insn (operands[0], operands[0]);
2873 DONE;
af55dae3
JW
2874}")
2875
2876(define_insn "umulsidi3_i"
4773afa4 2877 [(set (reg:SI MACH_REG)
a512fa97 2878 (truncate:SI
4773afa4
AO
2879 (lshiftrt:DI
2880 (mult:DI
2881 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2882 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2883 (const_int 32))))
2884 (set (reg:SI MACL_REG)
a512fa97
R
2885 (mult:SI (match_dup 0)
2886 (match_dup 1)))]
06e1bace 2887 "TARGET_SH2"
af55dae3 2888 "dmulu.l %1,%0"
0d7e008e
SC
2889 [(set_attr "type" "dmpy")])
2890
fa5322fa
AO
2891(define_expand "umulsidi3"
2892 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2893 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2894 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2895 "TARGET_SH2 || TARGET_SHMEDIA"
2896 "
2897{
2898 if (TARGET_SH2)
2899 {
2900 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2901 operands[2]));
2902 DONE;
2903 }
2904}")
2905
2906(define_insn "umulsidi3_media"
73a4d10b 2907 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
b6d33983
R
2908 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2909 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 2910 "TARGET_SHMEDIA"
b6d33983 2911 "mulu.l %1, %2, %0"
73a4d10b
R
2912 [(set_attr "type" "dmpy_media")
2913 (set_attr "highpart" "ignore")])
52702ae1 2914
fa5322fa 2915(define_insn "umulsidi3_compact"
73a4d10b 2916 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4773afa4
AO
2917 (mult:DI
2918 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2919 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
2920 (clobber (reg:SI MACH_REG))
2921 (clobber (reg:SI MACL_REG))]
a512fa97
R
2922 "TARGET_SH2"
2923 "#")
2924
2925(define_split
73a4d10b 2926 [(set (match_operand:DI 0 "arith_reg_dest" "")
51aea58d
JW
2927 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2928 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
2929 (clobber (reg:SI MACH_REG))
2930 (clobber (reg:SI MACL_REG))]
06e1bace 2931 "TARGET_SH2"
a512fa97 2932 [(const_int 0)]
af55dae3
JW
2933 "
2934{
a512fa97
R
2935 rtx low_dst = gen_lowpart (SImode, operands[0]);
2936 rtx high_dst = gen_highpart (SImode, operands[0]);
af55dae3 2937
a512fa97 2938 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
af55dae3 2939
4773afa4
AO
2940 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2941 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
2942 /* We need something to tag the possible REG_EQUAL notes on to. */
2943 emit_move_insn (operands[0], operands[0]);
2944 DONE;
af55dae3 2945}")
06e1bace 2946
a512fa97 2947(define_insn "smulsi3_highpart_i"
4773afa4 2948 [(set (reg:SI MACH_REG)
06e1bace 2949 (truncate:SI
4773afa4
AO
2950 (lshiftrt:DI
2951 (mult:DI
2952 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2953 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2954 (const_int 32))))
2955 (clobber (reg:SI MACL_REG))]
06e1bace 2956 "TARGET_SH2"
af55dae3 2957 "dmuls.l %1,%0"
06e1bace
RK
2958 [(set_attr "type" "dmpy")])
2959
2960(define_expand "smulsi3_highpart"
4773afa4
AO
2961 [(parallel
2962 [(set (reg:SI MACH_REG)
2963 (truncate:SI
2964 (lshiftrt:DI
2965 (mult:DI
2966 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2967 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2968 (const_int 32))))
2969 (clobber (reg:SI MACL_REG))])
06e1bace 2970 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 2971 (reg:SI MACH_REG))]
06e1bace 2972 "TARGET_SH2"
a512fa97
R
2973 "
2974{
2975 rtx first, last;
06e1bace 2976
a512fa97 2977 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
4773afa4 2978 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
2979 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2980 invariant code motion can move it. */
2981 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2982 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
22d05f60
R
2983 /* expand_binop can't find a suitable code in mul_highpart_optab to
2984 make a REG_EQUAL note from, so make one here.
c49439f1 2985 See also {,u}mulhisi.
22d05f60
R
2986 ??? Alternatively, we could put this at the calling site of expand_binop,
2987 i.e. expand_mult_highpart. */
2988 REG_NOTES (last)
2989 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2990 REG_NOTES (last));
a512fa97
R
2991 DONE;
2992}")
2993
2994(define_insn "umulsi3_highpart_i"
4773afa4 2995 [(set (reg:SI MACH_REG)
06e1bace 2996 (truncate:SI
4773afa4
AO
2997 (lshiftrt:DI
2998 (mult:DI
2999 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3000 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3001 (const_int 32))))
3002 (clobber (reg:SI MACL_REG))]
06e1bace 3003 "TARGET_SH2"
af55dae3 3004 "dmulu.l %1,%0"
06e1bace
RK
3005 [(set_attr "type" "dmpy")])
3006
3007(define_expand "umulsi3_highpart"
4773afa4
AO
3008 [(parallel
3009 [(set (reg:SI MACH_REG)
3010 (truncate:SI
3011 (lshiftrt:DI
3012 (mult:DI
3013 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3014 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3015 (const_int 32))))
3016 (clobber (reg:SI MACL_REG))])
06e1bace 3017 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 3018 (reg:SI MACH_REG))]
06e1bace 3019 "TARGET_SH2"
a512fa97
R
3020 "
3021{
3022 rtx first, last;
3023
3024 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
4773afa4 3025 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
3026 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3027 invariant code motion can move it. */
3028 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3029 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3030 DONE;
3031}")
73a4d10b
R
3032
3033(define_insn_and_split "muldi3"
3034 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3035 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3036 (match_operand:DI 2 "arith_reg_operand" "r")))
3037 (clobber (match_scratch:DI 3 "=&r"))
3038 (clobber (match_scratch:DI 4 "=r"))]
3039 "TARGET_SHMEDIA"
3040 "#"
3041 "reload_completed"
3042 [(const_int 0)]
3043 "
3044{
3045 rtx op3_v2si, op2_v2si;
3046
3047 op3_v2si = operands[3];
3048 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3049 {
3050 op3_v2si = XEXP (op3_v2si, 0);
3051 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3052 }
3053 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3054 op2_v2si = operands[2];
3055 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3056 {
3057 op2_v2si = XEXP (op2_v2si, 0);
3058 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3059 }
3060 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3061 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3062 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3063 emit_insn (gen_umulsidi3_media (operands[4],
3064 sh_gen_truncate (SImode, operands[1], 0),
3065 sh_gen_truncate (SImode, operands[2], 0)));
3066 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3067 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3068 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3069 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3070 DONE;
3071}")
3072
bc45ade3
SC
3073\f
3074;; -------------------------------------------------------------------------
3075;; Logical operations
3076;; -------------------------------------------------------------------------
3077
b6d33983 3078(define_insn "*andsi3_compact"
73a4d10b 3079 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
aa684c94 3080 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 3081 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 3082 "TARGET_SH1"
bc45ade3 3083 "and %2,%0"
c49439f1 3084 [(set_attr "type" "arith")])
bc45ade3 3085
73a4d10b
R
3086(define_insn "*andsi3_media"
3087 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3088 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3089 (match_operand:SI 2 "logical_operand" "r,I10")))]
3090 "TARGET_SHMEDIA"
3091 "@
3092 and %1, %2, %0
3093 andi %1, %2, %0"
3094 [(set_attr "type" "arith_media")])
3095
43aa4e05 3096;; If the constant is 255, then emit an extu.b instruction instead of an
51bd623f
JW
3097;; and, since that will give better code.
3098
0d7e008e
SC
3099(define_expand "andsi3"
3100 [(set (match_operand:SI 0 "arith_reg_operand" "")
73a4d10b 3101 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
0d7e008e 3102 (match_operand:SI 2 "logical_operand" "")))]
73a4d10b 3103 ""
51bd623f
JW
3104 "
3105{
73a4d10b
R
3106 if (TARGET_SH1
3107 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
51bd623f
JW
3108 {
3109 emit_insn (gen_zero_extendqisi2 (operands[0],
3110 gen_lowpart (QImode, operands[1])));
3111 DONE;
3112 }
3113}")
0d7e008e 3114
c1b92d09 3115(define_insn_and_split "anddi3"
73a4d10b 3116 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
c1b92d09 3117 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
735cb76e 3118 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
fa5322fa
AO
3119 "TARGET_SHMEDIA"
3120 "@
3121 and %1, %2, %0
c1b92d09
R
3122 andi %1, %2, %0
3123 #"
3124 "reload_completed
3125 && ! logical_operand (operands[2], DImode)"
3126 [(const_int 0)]
3127 "
3128{
f5b9e7c9 3129 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
c1b92d09
R
3130 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3131 else
3132 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3133 DONE;
2ad65b0e
SC
3134}"
3135 [(set_attr "type" "arith_media")])
fa5322fa 3136
73a4d10b
R
3137(define_insn "andcsi3"
3138 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3139 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3140 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3141 "TARGET_SHMEDIA"
3142 "andc %1,%2,%0"
3143 [(set_attr "type" "arith_media")])
3144
b6d33983 3145(define_insn "andcdi3"
73a4d10b 3146 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
fa5322fa
AO
3147 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3148 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3149 "TARGET_SHMEDIA"
2ad65b0e
SC
3150 "andc %1,%2,%0"
3151 [(set_attr "type" "arith_media")])
fa5322fa 3152
73a4d10b
R
3153(define_expand "iorsi3"
3154 [(set (match_operand:SI 0 "arith_reg_operand" "")
3155 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3156 (match_operand:SI 2 "logical_operand" "")))]
3157 ""
3158 "")
3159
3160(define_insn "*iorsi3_compact"
3161 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
aa684c94 3162 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 3163 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 3164 "TARGET_SH1"
1245df60 3165 "or %2,%0"
c49439f1 3166 [(set_attr "type" "arith")])
bc45ade3 3167
73a4d10b
R
3168(define_insn "*iorsi3_media"
3169 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3170 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3171 (match_operand:SI 2 "logical_operand" "r,I10")))]
3172 "TARGET_SHMEDIA"
3173 "@
3174 or %1, %2, %0
3175 ori %1, %2, %0"
3176 [(set_attr "type" "arith_media")])
3177
fa5322fa 3178(define_insn "iordi3"
73a4d10b 3179 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
fa5322fa 3180 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 3181 (match_operand:DI 2 "logical_operand" "r,I10")))]
fa5322fa
AO
3182 "TARGET_SHMEDIA"
3183 "@
3184 or %1, %2, %0
2ad65b0e
SC
3185 ori %1, %2, %0"
3186 [(set_attr "type" "arith_media")])
fa5322fa 3187
73a4d10b
R
3188(define_insn_and_split "*logical_sidi3"
3189 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3190 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3191 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3192 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3193 "TARGET_SHMEDIA"
3194 "#"
3195 "&& reload_completed"
3196 [(set (match_dup 0) (match_dup 3))]
3197 "
3198{
3199 operands[3]
3200 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3201 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3202 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3203}")
3204
3205(define_insn_and_split "*logical_sidisi3"
3206 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3207 (truncate:SI (sign_extend:DI
3208 (match_operator:SI 3 "logical_operator"
3209 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3210 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3211 "TARGET_SHMEDIA"
3212 "#"
3213 "&& 1"
3214 [(set (match_dup 0) (match_dup 3))])
3215
3216(define_insn_and_split "*logical_sidi3_2"
3217 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3218 (sign_extend:DI (truncate:SI (sign_extend:DI
3219 (match_operator:SI 3 "logical_operator"
3220 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3221 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3222 "TARGET_SHMEDIA"
3223 "#"
3224 "&& 1"
3225 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3226
3227(define_expand "xorsi3"
3228 [(set (match_operand:SI 0 "arith_reg_operand" "")
3229 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3230 (match_operand:SI 2 "xor_operand" "")))]
3231 ""
3232 "")
3233
3234(define_insn "*xorsi3_compact"
3235 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
aa684c94 3236 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 3237 (match_operand:SI 2 "logical_operand" "K08,r")))]
fa5322fa 3238 "TARGET_SH1"
bc45ade3 3239 "xor %2,%0"
c49439f1 3240 [(set_attr "type" "arith")])
fa5322fa 3241
73a4d10b
R
3242(define_insn "*xorsi3_media"
3243 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3244 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3245 (match_operand:SI 2 "xor_operand" "r,I06")))]
3246 "TARGET_SHMEDIA"
3247 "@
3248 xor %1, %2, %0
3249 xori %1, %2, %0"
3250 [(set_attr "type" "arith_media")])
3251
fa5322fa 3252(define_insn "xordi3"
73a4d10b 3253 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
fa5322fa 3254 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
73a4d10b 3255 (match_operand:DI 2 "xor_operand" "r,I06")))]
fa5322fa
AO
3256 "TARGET_SHMEDIA"
3257 "@
3258 xor %1, %2, %0
2ad65b0e
SC
3259 xori %1, %2, %0"
3260 [(set_attr "type" "arith_media")])
ff881d52
R
3261
3262;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3263;; converts 2 * sign extend -> logical op into logical op -> sign extend
3264(define_split
73a4d10b 3265 [(set (match_operand:DI 0 "arith_reg_dest" "")
ff881d52
R
3266 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3267 [(match_operand 1 "any_register_operand" "")
3268 (match_operand 2 "any_register_operand" "")])))]
3269 "TARGET_SHMEDIA"
3270 [(set (match_dup 5) (match_dup 4))
3271 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3272"
3273{
3274 enum machine_mode inmode = GET_MODE (operands[1]);
fada1961 3275 int offset = 0;
ff881d52
R
3276
3277 if (GET_CODE (operands[0]) == SUBREG)
3278 {
3279 offset = SUBREG_BYTE (operands[0]);
3280 operands[0] = SUBREG_REG (operands[0]);
3281 }
f5b9e7c9 3282 gcc_assert (GET_CODE (operands[0]) == REG);
ff881d52
R
3283 if (! TARGET_LITTLE_ENDIAN)
3284 offset += 8 - GET_MODE_SIZE (inmode);
3285 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3286}")
bc45ade3
SC
3287\f
3288;; -------------------------------------------------------------------------
3289;; Shifts and rotates
3290;; -------------------------------------------------------------------------
3291
b6d33983
R
3292(define_expand "rotldi3"
3293 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3294 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3295 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3296 "TARGET_SHMEDIA"
3297 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3298
3299(define_insn "rotldi3_mextr"
3300 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3301 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3302 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3303 "TARGET_SHMEDIA"
3304 "*
3305{
3306 static char templ[16];
3307
3308 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3309 8 - (int) (INTVAL (operands[2]) >> 3));
3310 return templ;
3311}"
3312 [(set_attr "type" "arith_media")])
3313
3314(define_expand "rotrdi3"
3315 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3316 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3317 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3318 "TARGET_SHMEDIA"
3319 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3320
3321(define_insn "rotrdi3_mextr"
3322 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3323 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3324 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3325 "TARGET_SHMEDIA"
3326 "*
3327{
3328 static char templ[16];
3329
3330 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3331 return templ;
3332}"
3333 [(set_attr "type" "arith_media")])
3334
73a4d10b
R
3335(define_split
3336 [(set (match_operand:DI 0 "arith_reg_dest" "")
3337 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3338 "ua_address_operand" "")))
3339 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3340 (const_int 8))))
3341 (clobber (match_operand:DI 3 "register_operand" ""))]
3342 "TARGET_SHMEDIA"
3343 [(match_dup 4) (match_dup 5)]
3344 "
3345{
3346 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3347 (operands[3], operands[1]));
3348 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3349 GEN_INT (56), GEN_INT (8));
3350}")
3351
51bd623f 3352(define_insn "rotlsi3_1"
73a4d10b 3353 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
b9654711
SC
3354 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3355 (const_int 1)))
4773afa4 3356 (set (reg:SI T_REG)
51aea58d 3357 (lshiftrt:SI (match_dup 1) (const_int 31)))]
fa5322fa 3358 "TARGET_SH1"
1245df60 3359 "rotl %0"
c49439f1 3360 [(set_attr "type" "arith")])
b9654711 3361
51bd623f 3362(define_insn "rotlsi3_31"
73a4d10b 3363 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
51bd623f
JW
3364 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3365 (const_int 31)))
4773afa4 3366 (clobber (reg:SI T_REG))]
fa5322fa 3367 "TARGET_SH1"
1245df60 3368 "rotr %0"
c49439f1 3369 [(set_attr "type" "arith")])
b9654711 3370
1245df60 3371(define_insn "rotlsi3_16"
73a4d10b 3372 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
51bd623f
JW
3373 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3374 (const_int 16)))]
fa5322fa 3375 "TARGET_SH1"
1245df60 3376 "swap.w %1,%0"
c49439f1 3377 [(set_attr "type" "arith")])
b9654711 3378
51bd623f 3379(define_expand "rotlsi3"
73a4d10b 3380 [(set (match_operand:SI 0 "arith_reg_dest" "")
51bd623f
JW
3381 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3382 (match_operand:SI 2 "immediate_operand" "")))]
fa5322fa 3383 "TARGET_SH1"
51bd623f
JW
3384 "
3385{
0139adca 3386 static const char rot_tab[] = {
1245df60
R
3387 000, 000, 000, 000, 000, 000, 010, 001,
3388 001, 001, 011, 013, 003, 003, 003, 003,
3389 003, 003, 003, 003, 003, 013, 012, 002,
3390 002, 002, 010, 000, 000, 000, 000, 000,
3391 };
3392
3393 int count, choice;
3394
51bd623f
JW
3395 if (GET_CODE (operands[2]) != CONST_INT)
3396 FAIL;
1245df60
R
3397 count = INTVAL (operands[2]);
3398 choice = rot_tab[count];
3399 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3400 FAIL;
3401 choice &= 7;
3402 switch (choice)
51bd623f 3403 {
1245df60
R
3404 case 0:
3405 emit_move_insn (operands[0], operands[1]);
3406 count -= (count & 16) * 2;
3407 break;
3408 case 3:
3409 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3410 count -= 16;
3411 break;
3412 case 1:
3413 case 2:
3414 {
3415 rtx parts[2];
3416 parts[0] = gen_reg_rtx (SImode);
3417 parts[1] = gen_reg_rtx (SImode);
3418 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
4fbf3498 3419 emit_move_insn (parts[choice-1], operands[1]);
1245df60
R
3420 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3421 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3422 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3423 count = (count & ~16) - 8;
3424 }
51bd623f 3425 }
1245df60
R
3426
3427 for (; count > 0; count--)
3428 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3429 for (; count < 0; count++)
3430 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3431
3432 DONE;
51bd623f
JW
3433}")
3434
1245df60 3435(define_insn "*rotlhi3_8"
73a4d10b 3436 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
51bd623f
JW
3437 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3438 (const_int 8)))]
fa5322fa 3439 "TARGET_SH1"
1245df60 3440 "swap.b %1,%0"
c49439f1 3441 [(set_attr "type" "arith")])
51bd623f
JW
3442
3443(define_expand "rotlhi3"
3444 [(set (match_operand:HI 0 "arith_reg_operand" "")
3445 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3446 (match_operand:HI 2 "immediate_operand" "")))]
fa5322fa 3447 "TARGET_SH1"
51bd623f
JW
3448 "
3449{
3450 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3451 FAIL;
3452}")
0d7e008e
SC
3453
3454;;
3455;; shift left
3456
157371cf 3457(define_insn "ashlsi3_sh2a"
73a4d10b 3458 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
157371cf
AO
3459 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3460 (match_operand:SI 2 "arith_reg_operand" "r")))]
3461 "TARGET_SH2A"
3462 "shad %2,%0"
3463 [(set_attr "type" "arith")
3464 (set_attr "length" "4")])
3465
7e2fda6e
BS
3466;; This pattern is used by init_expmed for computing the costs of shift
3467;; insns.
3468
3469(define_insn_and_split "ashlsi3_std"
73a4d10b 3470 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
7e2fda6e 3471 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
735cb76e 3472 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
7e2fda6e
BS
3473 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3474 "TARGET_SH3
fa5322fa 3475 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
735cb76e 3476 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
0d7e008e 3477 "@
7e2fda6e
BS
3478 shld %2,%0
3479 add %0,%0
3480 shll%O2 %0
3481 #"
3482 "TARGET_SH3
615cd49b 3483 && reload_completed
7e2fda6e 3484 && GET_CODE (operands[2]) == CONST_INT
735cb76e 3485 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
7e2fda6e
BS
3486 [(set (match_dup 3) (match_dup 2))
3487 (parallel
3488 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3489 (clobber (match_dup 4))])]
3490 "operands[4] = gen_rtx_SCRATCH (SImode);"
3491 [(set_attr "length" "*,*,*,4")
c49439f1 3492 (set_attr "type" "dyn_shift,arith,arith,arith")])
0d7e008e 3493
98e819b9 3494(define_insn "ashlhi3_k"
73a4d10b 3495 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
98e819b9 3496 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
735cb76e
R
3497 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3498 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
98e819b9
JW
3499 "@
3500 add %0,%0
1245df60 3501 shll%O2 %0"
c49439f1 3502 [(set_attr "type" "arith")])
98e819b9 3503
0d7e008e 3504(define_insn "ashlsi3_n"
73a4d10b 3505 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
0d7e008e 3506 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 3507 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 3508 (clobber (reg:SI T_REG))]
fa5322fa 3509 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
3510 "#"
3511 [(set (attr "length")
3512 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3513 (const_string "2")
3514 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3515 (const_string "4")
3516 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3517 (const_string "6")]
3518 (const_string "8")))
c49439f1 3519 (set_attr "type" "arith")])
bc45ade3 3520
07a45e5c 3521(define_split
73a4d10b 3522 [(set (match_operand:SI 0 "arith_reg_dest" "")
07a45e5c 3523 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 3524 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 3525 (clobber (reg:SI T_REG))]
fa5322fa 3526 "TARGET_SH1 && reload_completed"
4773afa4 3527 [(use (reg:SI R0_REG))]
07a45e5c
JW
3528 "
3529{
3530 gen_shifty_op (ASHIFT, operands);
3531 DONE;
3532}")
3533
fa5322fa 3534(define_insn "ashlsi3_media"
73a4d10b 3535 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
b6d33983 3536 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
73a4d10b 3537 (match_operand:SI 2 "shift_count_operand" "r,n")))]
fa5322fa
AO
3538 "TARGET_SHMEDIA"
3539 "@
3540 shlld.l %1, %2, %0
b6d33983 3541 shlli.l %1, %2, %0"
73a4d10b
R
3542 [(set_attr "type" "arith_media")
3543 (set_attr "highpart" "ignore")])
fa5322fa 3544
bc45ade3 3545(define_expand "ashlsi3"
ffae286a
JW
3546 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3547 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3548 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 3549 (clobber (reg:SI T_REG))])]
bc45ade3 3550 ""
d2f09a2f
JW
3551 "
3552{
fa5322fa
AO
3553 if (TARGET_SHMEDIA)
3554 {
3555 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3556 DONE;
3557 }
1245df60
R
3558 if (GET_CODE (operands[2]) == CONST_INT
3559 && sh_dynamicalize_shift_p (operands[2]))
3560 operands[2] = force_reg (SImode, operands[2]);
7e2fda6e 3561 if (TARGET_SH3)
6b005b88 3562 {
7e2fda6e 3563 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
6b005b88
JW
3564 DONE;
3565 }
d2f09a2f
JW
3566 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3567 FAIL;
3568}")
0d7e008e 3569
39f44b0b 3570(define_insn "*ashlhi3_n"
73a4d10b 3571 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
98e819b9
JW
3572 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3573 (match_operand:HI 2 "const_int_operand" "n")))
4773afa4 3574 (clobber (reg:SI T_REG))]
fa5322fa 3575 "TARGET_SH1"
98e819b9
JW
3576 "#"
3577 [(set (attr "length")
3578 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3579 (const_string "2")
3580 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3581 (const_string "4")]
3582 (const_string "6")))
3583 (set_attr "type" "arith")])
3584
39f44b0b
KK
3585(define_expand "ashlhi3"
3586 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3587 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3588 (match_operand:SI 2 "nonmemory_operand" "")))
3589 (clobber (reg:SI T_REG))])]
3590 "TARGET_SH1"
3591 "
3592{
3593 if (GET_CODE (operands[2]) != CONST_INT)
3594 FAIL;
3595 /* It may be possible to call gen_ashlhi3 directly with more generic
3596 operands. Make sure operands[1] is a HImode register here. */
3597 if (!arith_reg_operand (operands[1], HImode))
3598 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3599}")
3600
98e819b9 3601(define_split
73a4d10b 3602 [(set (match_operand:HI 0 "arith_reg_dest" "")
98e819b9 3603 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
e69d1422 3604 (match_operand:HI 2 "const_int_operand" "")))
4773afa4 3605 (clobber (reg:SI T_REG))]
fa5322fa 3606 "TARGET_SH1 && reload_completed"
4773afa4 3607 [(use (reg:SI R0_REG))]
98e819b9
JW
3608 "
3609{
3610 gen_shifty_hi_op (ASHIFT, operands);
3611 DONE;
3612}")
3613
0d7e008e
SC
3614;
3615; arithmetic shift right
3616;
bc45ade3 3617
157371cf 3618(define_insn "ashrsi3_sh2a"
73a4d10b 3619 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
157371cf
AO
3620 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3621 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3622 "TARGET_SH2A"
3623 "shad %2,%0"
3624 [(set_attr "type" "dyn_shift")
3625 (set_attr "length" "4")])
3626
bc45ade3 3627(define_insn "ashrsi3_k"
73a4d10b 3628 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
aa684c94 3629 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 3630 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 3631 (clobber (reg:SI T_REG))]
fa5322fa 3632 "TARGET_SH1 && INTVAL (operands[2]) == 1"
bc45ade3 3633 "shar %0"
c49439f1 3634 [(set_attr "type" "arith")])
bc45ade3 3635
d0c42859
R
3636;; We can't do HImode right shifts correctly unless we start out with an
3637;; explicit zero / sign extension; doing that would result in worse overall
3638;; code, so just let the machine independent code widen the mode.
3639;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3640
98e819b9 3641
ffae286a
JW
3642;; ??? This should be a define expand.
3643
00f8ff66 3644(define_insn "ashrsi2_16"
73a4d10b 3645 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
07a45e5c 3646 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3e8bd1ce 3647 (const_int 16)))]
fa5322fa 3648 "TARGET_SH1"
1245df60 3649 "#"
00f8ff66
SC
3650 [(set_attr "length" "4")])
3651
1245df60 3652(define_split
73a4d10b 3653 [(set (match_operand:SI 0 "arith_reg_dest" "")
e69d1422 3654 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 3655 (const_int 16)))]
fa5322fa 3656 "TARGET_SH1"
1245df60
R
3657 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3658 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3659 "operands[2] = gen_lowpart (HImode, operands[0]);")
3660
ffae286a
JW
3661;; ??? This should be a define expand.
3662
00f8ff66 3663(define_insn "ashrsi2_31"
73a4d10b 3664 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1245df60
R
3665 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3666 (const_int 31)))
4773afa4 3667 (clobber (reg:SI T_REG))]
fa5322fa 3668 "TARGET_SH1"
1245df60 3669 "#"
6b005b88 3670 [(set_attr "length" "4")])
3e8bd1ce 3671
1245df60 3672(define_split
73a4d10b 3673 [(set (match_operand:SI 0 "arith_reg_dest" "")
e69d1422 3674 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 3675 (const_int 31)))
4773afa4 3676 (clobber (reg:SI T_REG))]
fa5322fa 3677 "TARGET_SH1"
1245df60
R
3678 [(const_int 0)]
3679 "
3680{
5bac82c5 3681 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
73a4d10b
R
3682 emit_insn (gen_mov_neg_si_t (operands[0]));
3683 DONE;
3684}")
3685
3686(define_peephole2
3687 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3688 (set (reg:SI T_REG)
3689 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3690 "TARGET_SH1
3691 && peep2_reg_dead_p (2, operands[0])
3692 && peep2_reg_dead_p (2, operands[1])"
3693 [(const_int 0)]
3694 "
3695{
3696 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
1245df60
R
3697 DONE;
3698}")
3699
3700(define_insn "ashlsi_c"
73a4d10b 3701 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1245df60 3702 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4773afa4
AO
3703 (set (reg:SI T_REG)
3704 (lt:SI (match_dup 1) (const_int 0)))]
fa5322fa 3705 "TARGET_SH1"
1245df60 3706 "shll %0"
c49439f1 3707 [(set_attr "type" "arith")])
1245df60 3708
73a4d10b
R
3709(define_insn "*ashlsi_c_void"
3710 [(set (reg:SI T_REG)
3711 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3712 (clobber (match_scratch:SI 1 "=0"))]
3713 "TARGET_SH1 && cse_not_expected"
3714 "shll %0"
3715 [(set_attr "type" "arith")])
3716
6b005b88 3717(define_insn "ashrsi3_d"
73a4d10b 3718 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6b005b88
JW
3719 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3720 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3721 "TARGET_SH3"
1245df60 3722 "shad %2,%0"
c49439f1 3723 [(set_attr "type" "dyn_shift")])
51aea58d 3724
0d7e008e 3725(define_insn "ashrsi3_n"
4773afa4
AO
3726 [(set (reg:SI R4_REG)
3727 (ashiftrt:SI (reg:SI R4_REG)
ffae286a 3728 (match_operand:SI 0 "const_int_operand" "i")))
4773afa4
AO
3729 (clobber (reg:SI T_REG))
3730 (clobber (reg:SI PR_REG))
0d7e008e 3731 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 3732 "TARGET_SH1"
0d7e008e
SC
3733 "jsr @%1%#"
3734 [(set_attr "type" "sfunc")
0d7e008e
SC
3735 (set_attr "needs_delay_slot" "yes")])
3736
fa5322fa 3737(define_insn "ashrsi3_media"
73a4d10b 3738 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
b6d33983 3739 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
73a4d10b 3740 (match_operand:SI 2 "shift_count_operand" "r,n")))]
fa5322fa
AO
3741 "TARGET_SHMEDIA"
3742 "@
3743 shard.l %1, %2, %0
b6d33983 3744 shari.l %1, %2, %0"
73a4d10b
R
3745 [(set_attr "type" "arith_media")
3746 (set_attr "highpart" "ignore")])
fa5322fa 3747
bc45ade3 3748(define_expand "ashrsi3"
ffae286a
JW
3749 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3750 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3751 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 3752 (clobber (reg:SI T_REG))])]
bc45ade3 3753 ""
fa5322fa
AO
3754 "
3755{
3756 if (TARGET_SHMEDIA)
3757 {
3758 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3759 DONE;
3760 }
3761 if (expand_ashiftrt (operands))
3762 DONE;
3763 else
3764 FAIL;
3765}")
0d7e008e 3766
07a45e5c 3767;; logical shift right
bc45ade3 3768
157371cf 3769(define_insn "lshrsi3_sh2a"
73a4d10b 3770 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
157371cf
AO
3771 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3772 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3773 "TARGET_SH2A"
3774 "shld %2,%0"
3775 [(set_attr "type" "dyn_shift")
3776 (set_attr "length" "4")])
3777
6b005b88 3778(define_insn "lshrsi3_d"
73a4d10b 3779 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6b005b88
JW
3780 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3781 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3782 "TARGET_SH3"
1245df60 3783 "shld %2,%0"
c49439f1 3784 [(set_attr "type" "dyn_shift")])
00f8ff66 3785
ffae286a 3786;; Only the single bit shift clobbers the T bit.
07a45e5c
JW
3787
3788(define_insn "lshrsi3_m"
73a4d10b 3789 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
07a45e5c 3790 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 3791 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 3792 (clobber (reg:SI T_REG))]
fa5322fa 3793 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 3794 "shlr %0"
c49439f1 3795 [(set_attr "type" "arith")])
0d7e008e 3796
07a45e5c 3797(define_insn "lshrsi3_k"
73a4d10b 3798 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
07a45e5c 3799 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
735cb76e
R
3800 (match_operand:SI 2 "const_int_operand" "P27")))]
3801 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
07a45e5c 3802 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 3803 "shlr%O2 %0"
c49439f1 3804 [(set_attr "type" "arith")])
0d7e008e
SC
3805
3806(define_insn "lshrsi3_n"
73a4d10b 3807 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
0d7e008e 3808 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 3809 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 3810 (clobber (reg:SI T_REG))]
fa5322fa 3811 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
3812 "#"
3813 [(set (attr "length")
3814 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3815 (const_string "2")
3816 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3817 (const_string "4")
3818 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3819 (const_string "6")]
3820 (const_string "8")))
bc45ade3
SC
3821 (set_attr "type" "arith")])
3822
07a45e5c 3823(define_split
73a4d10b 3824 [(set (match_operand:SI 0 "arith_reg_dest" "")
07a45e5c 3825 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 3826 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 3827 (clobber (reg:SI T_REG))]
fa5322fa 3828 "TARGET_SH1 && reload_completed"
4773afa4 3829 [(use (reg:SI R0_REG))]
07a45e5c
JW
3830 "
3831{
3832 gen_shifty_op (LSHIFTRT, operands);
3833 DONE;
3834}")
3835
fa5322fa 3836(define_insn "lshrsi3_media"
73a4d10b 3837 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
b6d33983 3838 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
73a4d10b 3839 (match_operand:SI 2 "shift_count_operand" "r,n")))]
fa5322fa
AO
3840 "TARGET_SHMEDIA"
3841 "@
3842 shlrd.l %1, %2, %0
b6d33983 3843 shlri.l %1, %2, %0"
73a4d10b
R
3844 [(set_attr "type" "arith_media")
3845 (set_attr "highpart" "ignore")])
fa5322fa 3846
bc45ade3 3847(define_expand "lshrsi3"
73a4d10b 3848 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
ffae286a
JW
3849 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3850 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 3851 (clobber (reg:SI T_REG))])]
bc45ade3 3852 ""
d2f09a2f
JW
3853 "
3854{
fa5322fa
AO
3855 if (TARGET_SHMEDIA)
3856 {
3857 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3858 DONE;
3859 }
1245df60
R
3860 if (GET_CODE (operands[2]) == CONST_INT
3861 && sh_dynamicalize_shift_p (operands[2]))
3862 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
3863 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3864 {
3865 rtx count = copy_to_mode_reg (SImode, operands[2]);
3866 emit_insn (gen_negsi2 (count, count));
7b7499bf 3867 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
6b005b88
JW
3868 DONE;
3869 }
d2f09a2f
JW
3870 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3871 FAIL;
3872}")
bc45ade3 3873
ffae286a
JW
3874;; ??? This should be a define expand.
3875
bc45ade3 3876(define_insn "ashldi3_k"
73a4d10b 3877 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
aa684c94 3878 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 3879 (const_int 1)))
4773afa4 3880 (clobber (reg:SI T_REG))]
fa5322fa 3881 "TARGET_SH1"
00f8ff66 3882 "shll %R0\;rotcl %S0"
1245df60 3883 [(set_attr "length" "4")
c49439f1 3884 (set_attr "type" "arith")])
bc45ade3 3885
fa5322fa 3886(define_insn "ashldi3_media"
73a4d10b 3887 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
fa5322fa 3888 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
73a4d10b 3889 (match_operand:DI 2 "shift_count_operand" "r,n")))]
fa5322fa
AO
3890 "TARGET_SHMEDIA"
3891 "@
3892 shlld %1, %2, %0
2ad65b0e
SC
3893 shlli %1, %2, %0"
3894 [(set_attr "type" "arith_media")])
fa5322fa 3895
73a4d10b
R
3896(define_insn "*ashldisi3_media"
3897 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3898 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3899 (match_operand:DI 2 "const_int_operand" "n")))]
3900 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3901 "shlli.l %1, %2, %0"
3902 [(set_attr "type" "arith_media")
3903 (set_attr "highpart" "ignore")])
3904
bc45ade3 3905(define_expand "ashldi3"
ffae286a
JW
3906 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3907 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3908 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 3909 (clobber (reg:SI T_REG))])]
bc45ade3 3910 ""
fa5322fa
AO
3911 "
3912{
3913 if (TARGET_SHMEDIA)
3914 {
3915 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3916 DONE;
3917 }
3918 if (GET_CODE (operands[2]) != CONST_INT
3919 || INTVAL (operands[2]) != 1)
3920 FAIL;
3921}")
ffae286a
JW
3922
3923;; ??? This should be a define expand.
bc45ade3
SC
3924
3925(define_insn "lshrdi3_k"
73a4d10b 3926 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
b9654711 3927 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 3928 (const_int 1)))
4773afa4 3929 (clobber (reg:SI T_REG))]
fa5322fa 3930 "TARGET_SH1"
00f8ff66 3931 "shlr %S0\;rotcr %R0"
1245df60 3932 [(set_attr "length" "4")
c49439f1 3933 (set_attr "type" "arith")])
bc45ade3 3934
fa5322fa 3935(define_insn "lshrdi3_media"
73a4d10b 3936 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
fa5322fa 3937 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
73a4d10b
R
3938 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3939 "TARGET_SHMEDIA
3940 && (arith_reg_dest (operands[0], DImode)
3941 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
fa5322fa
AO
3942 "@
3943 shlrd %1, %2, %0
2ad65b0e
SC
3944 shlri %1, %2, %0"
3945 [(set_attr "type" "arith_media")])
fa5322fa 3946
73a4d10b
R
3947(define_insn "*lshrdisi3_media"
3948 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3949 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3950 (match_operand:DI 2 "const_int_operand" "n")))]
3951 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3952 "shlri.l %1, %2, %0"
3953 [(set_attr "type" "arith_media")
3954 (set_attr "highpart" "ignore")])
3955
bc45ade3 3956(define_expand "lshrdi3"
ffae286a
JW
3957 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3958 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
bc45ade3 3959 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 3960 (clobber (reg:SI T_REG))])]
bc45ade3 3961 ""
fa5322fa
AO
3962 "
3963{
3964 if (TARGET_SHMEDIA)
3965 {
3966 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3967 DONE;
3968 }
3969 if (GET_CODE (operands[2]) != CONST_INT
3970 || INTVAL (operands[2]) != 1)
3971 FAIL;
3972}")
ffae286a
JW
3973
3974;; ??? This should be a define expand.
bc45ade3
SC
3975
3976(define_insn "ashrdi3_k"
73a4d10b 3977 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
aa684c94 3978 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 3979 (const_int 1)))
4773afa4 3980 (clobber (reg:SI T_REG))]
fa5322fa 3981 "TARGET_SH1"
00f8ff66 3982 "shar %S0\;rotcr %R0"
1245df60 3983 [(set_attr "length" "4")
c49439f1 3984 (set_attr "type" "arith")])
bc45ade3 3985
fa5322fa 3986(define_insn "ashrdi3_media"
73a4d10b 3987 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
fa5322fa 3988 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
73a4d10b
R
3989 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3990 "TARGET_SHMEDIA
3991 && (arith_reg_dest (operands[0], DImode)
3992 || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
fa5322fa
AO
3993 "@
3994 shard %1, %2, %0
2ad65b0e
SC
3995 shari %1, %2, %0"
3996 [(set_attr "type" "arith_media")])
fa5322fa 3997
73a4d10b
R
3998(define_insn "*ashrdisi3_media"
3999 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4000 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4001 (match_operand:DI 2 "const_int_operand" "n")))]
4002 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4003 "shari.l %1, %2, %0"
4004 [(set_attr "type" "arith_media")
4005 (set_attr "highpart" "ignore")])
4006
4007(define_insn "ashrdisi3_media_high"
4008 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4009 (truncate:SI
4010 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4011 (match_operand:DI 2 "const_int_operand" "n"))))]
4012 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4013 "shari %1, %2, %0"
4014 [(set_attr "type" "arith_media")])
4015
4016(define_insn "ashrdisi3_media_opaque"
4017 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4018 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4019 (match_operand:DI 2 "const_int_operand" "n")]
4020 UNSPEC_ASHIFTRT))]
4021 "TARGET_SHMEDIA"
4022 "shari %1, %2, %0"
4023 [(set_attr "type" "arith_media")])
4024
bc45ade3 4025(define_expand "ashrdi3"
ffae286a
JW
4026 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4027 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4028 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 4029 (clobber (reg:SI T_REG))])]
bc45ade3 4030 ""
fa5322fa
AO
4031 "
4032{
4033 if (TARGET_SHMEDIA)
4034 {
4035 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4036 DONE;
4037 }
4038 if (GET_CODE (operands[2]) != CONST_INT
4039 || INTVAL (operands[2]) != 1)
4040 FAIL;
4041}")
98e819b9
JW
4042
4043;; combined left/right shift
4044
4045(define_split
4046 [(set (match_operand:SI 0 "register_operand" "")
4047 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
4048 (match_operand:SI 2 "const_int_operand" ""))
4049 (match_operand:SI 3 "const_int_operand" "")))]
85af47b9 4050 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 4051 [(use (reg:SI R0_REG))]
98e819b9
JW
4052 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4053 DONE;")
4054
4055(define_split
4056 [(set (match_operand:SI 0 "register_operand" "")
4057 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
4058 (match_operand:SI 2 "const_int_operand" ""))
4059 (match_operand:SI 3 "const_int_operand" "")))
4773afa4 4060 (clobber (reg:SI T_REG))]
85af47b9 4061 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 4062 [(use (reg:SI R0_REG))]
98e819b9
JW
4063 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4064 DONE;")
4065
4066(define_insn ""
4067 [(set (match_operand:SI 0 "register_operand" "=r")
4068 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4069 (match_operand:SI 2 "const_int_operand" "n"))
4070 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 4071 (clobber (reg:SI T_REG))]
fa5322fa 4072 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
98e819b9
JW
4073 "#"
4074 [(set (attr "length")
4075 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4076 (const_string "4")
4077 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4078 (const_string "6")
4079 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4080 (const_string "8")
4081 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4082 (const_string "10")
4083 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4084 (const_string "12")
4085 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4086 (const_string "14")
4087 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4088 (const_string "16")]
4089 (const_string "18")))
4090 (set_attr "type" "arith")])
4091
4092(define_insn ""
4093 [(set (match_operand:SI 0 "register_operand" "=z")
4094 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4095 (match_operand:SI 2 "const_int_operand" "n"))
4096 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 4097 (clobber (reg:SI T_REG))]
fa5322fa 4098 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
98e819b9
JW
4099 "#"
4100 [(set (attr "length")
4101 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4102 (const_string "4")
4103 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4104 (const_string "6")
4105 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4106 (const_string "8")]
4107 (const_string "10")))
4108 (set_attr "type" "arith")])
4109
4110;; shift left / and combination with a scratch register: The combine pass
4111;; does not accept the individual instructions, even though they are
4112;; cheap. But it needs a precise description so that it is usable after
4113;; reload.
4114(define_insn "and_shl_scratch"
4115 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4773afa4
AO
4116 (lshiftrt:SI
4117 (ashift:SI
4118 (and:SI
4119 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4120 (match_operand:SI 2 "const_int_operand" "N,n"))
4121 (match_operand:SI 3 "" "0,r"))
4122 (match_operand:SI 4 "const_int_operand" "n,n"))
4123 (match_operand:SI 5 "const_int_operand" "n,n")))
4124 (clobber (reg:SI T_REG))]
fa5322fa 4125 "TARGET_SH1"
98e819b9
JW
4126 "#"
4127 [(set (attr "length")
4128 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4129 (const_string "4")
4130 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4131 (const_string "6")
4132 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
9788ff4d 4133 (const_string "8")
98e819b9
JW
4134 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4135 (const_string "10")]
4136 (const_string "12")))
4137 (set_attr "type" "arith")])
4138
4139(define_split
e69d1422 4140 [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
4141 (lshiftrt:SI
4142 (ashift:SI
4143 (and:SI
e69d1422
R
4144 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4145 (match_operand:SI 2 "const_int_operand" ""))
4146 (match_operand:SI 3 "register_operand" ""))
4147 (match_operand:SI 4 "const_int_operand" ""))
4148 (match_operand:SI 5 "const_int_operand" "")))
4773afa4 4149 (clobber (reg:SI T_REG))]
fa5322fa 4150 "TARGET_SH1"
4773afa4 4151 [(use (reg:SI R0_REG))]
98e819b9
JW
4152 "
4153{
fc2380b9 4154 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
98e819b9
JW
4155
4156 if (INTVAL (operands[2]))
4157 {
4158 gen_shifty_op (LSHIFTRT, operands);
98e819b9
JW
4159 }
4160 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4161 operands[2] = operands[4];
4162 gen_shifty_op (ASHIFT, operands);
4163 if (INTVAL (operands[5]))
4164 {
4165 operands[2] = operands[5];
4166 gen_shifty_op (LSHIFTRT, operands);
4167 }
4168 DONE;
4169}")
4170
4171;; signed left/right shift combination.
4172(define_split
e69d1422 4173 [(set (match_operand:SI 0 "register_operand" "")
4773afa4 4174 (sign_extract:SI
e69d1422
R
4175 (ashift:SI (match_operand:SI 1 "register_operand" "")
4176 (match_operand:SI 2 "const_int_operand" ""))
4177 (match_operand:SI 3 "const_int_operand" "")
4773afa4
AO
4178 (const_int 0)))
4179 (clobber (reg:SI T_REG))]
fa5322fa 4180 "TARGET_SH1"
4773afa4 4181 [(use (reg:SI R0_REG))]
98e819b9
JW
4182 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4183 DONE;")
4184
4185(define_insn "shl_sext_ext"
4186 [(set (match_operand:SI 0 "register_operand" "=r")
4773afa4
AO
4187 (sign_extract:SI
4188 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4189 (match_operand:SI 2 "const_int_operand" "n"))
4190 (match_operand:SI 3 "const_int_operand" "n")
4191 (const_int 0)))
4192 (clobber (reg:SI T_REG))]
fa5322fa 4193 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
98e819b9
JW
4194 "#"
4195 [(set (attr "length")
4196 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4197 (const_string "2")
4198 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4199 (const_string "4")
4200 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4201 (const_string "6")
4202 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4203 (const_string "8")
4204 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4205 (const_string "10")
4206 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4207 (const_string "12")
4208 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4209 (const_string "14")
4210 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4211 (const_string "16")]
4212 (const_string "18")))
4213 (set_attr "type" "arith")])
4214
4215(define_insn "shl_sext_sub"
4216 [(set (match_operand:SI 0 "register_operand" "=z")
e11cddec
AO
4217 (sign_extract:SI
4218 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4219 (match_operand:SI 2 "const_int_operand" "n"))
4220 (match_operand:SI 3 "const_int_operand" "n")
4221 (const_int 0)))
4773afa4 4222 (clobber (reg:SI T_REG))]
fa5322fa 4223 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
98e819b9
JW
4224 "#"
4225 [(set (attr "length")
4226 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4227 (const_string "6")
4228 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4229 (const_string "8")
4230 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4231 (const_string "10")
4232 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4233 (const_string "12")]
4234 (const_string "14")))
4235 (set_attr "type" "arith")])
4236
977eef43
JW
4237;; These patterns are found in expansions of DImode shifts by 16, and
4238;; allow the xtrct instruction to be generated from C source.
4239
4240(define_insn "xtrct_left"
73a4d10b 4241 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
977eef43
JW
4242 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4243 (const_int 16))
4244 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4245 (const_int 16))))]
fa5322fa 4246 "TARGET_SH1"
1245df60 4247 "xtrct %1,%0"
c49439f1 4248 [(set_attr "type" "arith")])
977eef43
JW
4249
4250(define_insn "xtrct_right"
73a4d10b 4251 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
977eef43
JW
4252 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4253 (const_int 16))
4254 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4255 (const_int 16))))]
fa5322fa 4256 "TARGET_SH1"
1245df60 4257 "xtrct %2,%0"
c49439f1 4258 [(set_attr "type" "arith")])
fae15c93 4259
bc45ade3
SC
4260;; -------------------------------------------------------------------------
4261;; Unary arithmetic
4262;; -------------------------------------------------------------------------
4263
8e87e161 4264(define_insn "negc"
73a4d10b 4265 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4773afa4 4266 (neg:SI (plus:SI (reg:SI T_REG)
51bd623f 4267 (match_operand:SI 1 "arith_reg_operand" "r"))))
4773afa4
AO
4268 (set (reg:SI T_REG)
4269 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
51bd623f 4270 (const_int 0)))]
fa5322fa 4271 "TARGET_SH1"
8e87e161 4272 "negc %1,%0"
c49439f1 4273 [(set_attr "type" "arith")])
bc45ade3 4274
fa5322fa 4275(define_insn "*negdi_media"
73a4d10b 4276 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
fa5322fa
AO
4277 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4278 "TARGET_SHMEDIA"
2ad65b0e
SC
4279 "sub r63, %1, %0"
4280 [(set_attr "type" "arith_media")])
fa5322fa 4281
8e87e161 4282(define_expand "negdi2"
51aea58d 4283 [(set (match_operand:DI 0 "arith_reg_operand" "")
b6d33983 4284 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
8e87e161 4285 ""
ffae286a
JW
4286 "
4287{
fa5322fa
AO
4288 if (TARGET_SH1)
4289 {
4290 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4291 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
8e87e161 4292
fa5322fa
AO
4293 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4294 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
0a0b733a 4295
fa5322fa
AO
4296 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4297 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
8e87e161 4298
fa5322fa
AO
4299 emit_insn (gen_clrt ());
4300 emit_insn (gen_negc (low_dst, low_src));
4301 emit_insn (gen_negc (high_dst, high_src));
4302 DONE;
4303 }
ffae286a 4304}")
8e87e161 4305
bc45ade3 4306(define_insn "negsi2"
73a4d10b 4307 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
aa684c94 4308 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 4309 "TARGET_SH1"
bc45ade3 4310 "neg %1,%0"
c49439f1 4311 [(set_attr "type" "arith")])
bc45ade3
SC
4312
4313(define_insn "one_cmplsi2"
73a4d10b 4314 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
aa684c94 4315 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 4316 "TARGET_SH1"
bc45ade3 4317 "not %1,%0"
c49439f1 4318 [(set_attr "type" "arith")])
fa5322fa 4319
73a4d10b
R
4320(define_expand "one_cmpldi2"
4321 [(set (match_operand:DI 0 "arith_reg_dest" "")
4322 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4323 (const_int -1)))]
4324 "TARGET_SHMEDIA" "")
4325
4326/* The SH4 202 can do zero-offset branches without pipeline stalls.
4327 This can be used as some kind of conditional execution, which is useful
4328 for abs. */
4329(define_split
4330 [(set (match_operand:SI 0 "arith_reg_dest" "")
4331 (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4332 (match_operand:SI 1 "arith_reg_operand" ""))
4333 (reg:SI T_REG)))]
4334 "TARGET_HARD_SH4"
4335 [(const_int 0)]
4336 "emit_insn (gen_movsi_i (operands[0], operands[1]));
4337 emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4338 DONE;")
4339
4340(define_insn "cneg"
4341 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4342 (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4343 (match_operand:SI 1 "arith_reg_operand" "0")
4344 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4345 "TARGET_HARD_SH4"
4346 "bf 0f\;neg %2,%0\\n0:"
4347 [(set_attr "type" "arith") ;; poor approximation
4348 (set_attr "length" "4")])
4349
bc45ade3
SC
4350\f
4351;; -------------------------------------------------------------------------
4352;; Zero extension instructions
4353;; -------------------------------------------------------------------------
4354
fa5322fa 4355(define_insn "zero_extendsidi2"
73a4d10b 4356 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
b6d33983 4357 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
fa5322fa 4358 "TARGET_SHMEDIA"
b6d33983 4359 "addz.l %1, r63, %0"
73a4d10b
R
4360 [(set_attr "type" "arith_media")
4361 (set_attr "highpart" "extend")])
fa5322fa
AO
4362
4363(define_insn "zero_extendhidi2"
4364 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 4365 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
4366 "TARGET_SHMEDIA"
4367 "@
4368 #
b6d33983 4369 ld%M1.uw %m1, %0"
73a4d10b
R
4370 [(set_attr "type" "*,load_media")
4371 (set (attr "highpart")
4372 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4373 (const_string "user")]
4374 (const_string "ignore")))])
fa5322fa
AO
4375
4376(define_split
e69d1422
R
4377 [(set (match_operand:DI 0 "register_operand" "")
4378 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
4379 "TARGET_SHMEDIA && reload_completed"
4380 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
4381 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4382 "
4383{
4384 if (GET_CODE (operands[1]) == TRUNCATE)
4385 operands[1] = XEXP (operands[1], 0);
4386}")
4387
fae778eb
KH
4388;; ??? when a truncated input to a zero_extend is reloaded, reload will
4389;; reload the entire truncate expression.
b6d33983 4390(define_insn_and_split "*loaddi_trunc"
73a4d10b 4391 [(set (match_operand 0 "any_register_operand" "=r")
b6d33983
R
4392 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4393 "TARGET_SHMEDIA && reload_completed"
4394 "#"
4395 "TARGET_SHMEDIA && reload_completed"
4396 [(set (match_dup 0) (match_dup 1))]
4397 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
fa5322fa
AO
4398
4399(define_insn "zero_extendqidi2"
4400 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 4401 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
4402 "TARGET_SHMEDIA"
4403 "@
4404 andi %1, 255, %0
b6d33983 4405 ld%M1.ub %m1, %0"
73a4d10b
R
4406 [(set_attr "type" "arith_media,load_media")
4407 (set (attr "highpart")
4408 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4409 (const_string "user")]
4410 (const_string "ignore")))])
b6d33983
R
4411
4412(define_expand "zero_extendhisi2"
4413 [(set (match_operand:SI 0 "arith_reg_operand" "")
4414 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4415 ""
4416 "
4417{
4418 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4419 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4420}")
fa5322fa 4421
b6d33983 4422(define_insn "*zero_extendhisi2_compact"
73a4d10b 4423 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
aa684c94 4424 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
fa5322fa 4425 "TARGET_SH1"
bc45ade3 4426 "extu.w %1,%0"
c49439f1 4427 [(set_attr "type" "arith")])
bc45ade3 4428
b6d33983
R
4429(define_insn "*zero_extendhisi2_media"
4430 [(set (match_operand:SI 0 "register_operand" "=r,r")
4431 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4432 "TARGET_SHMEDIA"
4433 "@
4434 #
4435 ld%M1.uw %m1, %0"
73a4d10b
R
4436 [(set_attr "type" "arith_media,load_media")
4437 (set (attr "highpart")
4438 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4439 (const_string "user")]
4440 (const_string "ignore")))])
b6d33983
R
4441
4442(define_split
e69d1422
R
4443 [(set (match_operand:SI 0 "register_operand" "")
4444 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983 4445 "TARGET_SHMEDIA && reload_completed"
73a4d10b 4446 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
b6d33983
R
4447 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4448 "
4449{
73a4d10b
R
4450 rtx op1 = operands[1];
4451
4452 if (GET_CODE (op1) == TRUNCATE)
4453 op1 = XEXP (op1, 0);
4454 operands[2]
4455 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4456 subreg_lowpart_offset (SImode, GET_MODE (op1)));
b6d33983
R
4457}")
4458
4459(define_expand "zero_extendqisi2"
4460 [(set (match_operand:SI 0 "arith_reg_operand" "")
4461 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4462 ""
4463 "
4464{
4465 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4466 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4467}")
4468
4469(define_insn "*zero_extendqisi2_compact"
73a4d10b 4470 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
aa684c94 4471 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 4472 "TARGET_SH1"
bc45ade3 4473 "extu.b %1,%0"
c49439f1 4474 [(set_attr "type" "arith")])
bc45ade3 4475
b6d33983
R
4476(define_insn "*zero_extendqisi2_media"
4477 [(set (match_operand:SI 0 "register_operand" "=r,r")
4478 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4479 "TARGET_SHMEDIA"
4480 "@
4481 andi %1, 255, %0
4482 ld%M1.ub %m1, %0"
73a4d10b
R
4483 [(set_attr "type" "arith_media,load_media")
4484 (set (attr "highpart")
4485 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4486 (const_string "user")]
4487 (const_string "ignore")))])
b6d33983 4488
bc45ade3 4489(define_insn "zero_extendqihi2"
73a4d10b 4490 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
aa684c94 4491 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 4492 "TARGET_SH1"
bc45ade3 4493 "extu.b %1,%0"
c49439f1 4494 [(set_attr "type" "arith")])
fae15c93 4495
bc45ade3
SC
4496;; -------------------------------------------------------------------------
4497;; Sign extension instructions
4498;; -------------------------------------------------------------------------
4499
ffae286a
JW
4500;; ??? This should be a define expand.
4501;; ??? Or perhaps it should be dropped?
4502
fa5322fa
AO
4503;; convert_move generates good code for SH[1-4].
4504(define_insn "extendsidi2"
73a4d10b
R
4505 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4506 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
fa5322fa
AO
4507 "TARGET_SHMEDIA"
4508 "@
4509 add.l %1, r63, %0
73a4d10b
R
4510 ld%M1.l %m1, %0
4511 fmov.sl %1, %0"
4512 [(set_attr "type" "arith_media,load_media,fpconv_media")
4513 (set (attr "highpart")
4514 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4515 (const_string "user")]
4516 (const_string "extend")))])
fa5322fa
AO
4517
4518(define_insn "extendhidi2"
4519 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 4520 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
4521 "TARGET_SHMEDIA"
4522 "@
4523 #
b6d33983 4524 ld%M1.w %m1, %0"
73a4d10b
R
4525 [(set_attr "type" "*,load_media")
4526 (set (attr "highpart")
4527 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4528 (const_string "user")]
4529 (const_string "ignore")))])
fa5322fa
AO
4530
4531(define_split
e69d1422
R
4532 [(set (match_operand:DI 0 "register_operand" "")
4533 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
4534 "TARGET_SHMEDIA && reload_completed"
4535 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
4536 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4537 "
4538{
4539 if (GET_CODE (operands[1]) == TRUNCATE)
4540 operands[1] = XEXP (operands[1], 0);
4541}")
fa5322fa
AO
4542
4543(define_insn "extendqidi2"
4544 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 4545 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
4546 "TARGET_SHMEDIA"
4547 "@
4548 #
b6d33983 4549 ld%M1.b %m1, %0"
73a4d10b
R
4550 [(set_attr "type" "*,load_media")
4551 (set (attr "highpart")
4552 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4553 (const_string "user")]
4554 (const_string "ignore")))])
fa5322fa
AO
4555
4556(define_split
e69d1422
R
4557 [(set (match_operand:DI 0 "register_operand" "")
4558 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
fa5322fa
AO
4559 "TARGET_SHMEDIA && reload_completed"
4560 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
b6d33983
R
4561 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4562 "
4563{
4564 if (GET_CODE (operands[1]) == TRUNCATE)
4565 operands[1] = XEXP (operands[1], 0);
4566}")
4567
4568(define_expand "extendhisi2"
73a4d10b 4569 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
40779a72 4570 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
b6d33983
R
4571 ""
4572 "")
bc45ade3 4573
b6d33983 4574(define_insn "*extendhisi2_compact"
73a4d10b 4575 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
51bd623f 4576 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 4577 "TARGET_SH1"
0d7e008e
SC
4578 "@
4579 exts.w %1,%0
40779a72 4580 mov.w %1,%0"
c49439f1 4581 [(set_attr "type" "arith,load")])
bc45ade3 4582
b6d33983
R
4583(define_insn "*extendhisi2_media"
4584 [(set (match_operand:SI 0 "register_operand" "=r,r")
4585 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4586 "TARGET_SHMEDIA"
4587 "@
4588 #
4589 ld%M1.w %m1, %0"
73a4d10b
R
4590 [(set_attr "type" "arith_media,load_media")
4591 (set (attr "highpart")
4592 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4593 (const_string "user")]
4594 (const_string "ignore")))])
b6d33983
R
4595
4596(define_split
e69d1422
R
4597 [(set (match_operand:SI 0 "register_operand" "")
4598 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983 4599 "TARGET_SHMEDIA && reload_completed"
73a4d10b 4600 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
b6d33983
R
4601 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4602 "
4603{
73a4d10b
R
4604 rtx op1 = operands[1];
4605 if (GET_CODE (op1) == TRUNCATE)
4606 op1 = XEXP (op1, 0);
4607 operands[2]
4608 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4609 subreg_lowpart_offset (SImode, GET_MODE (op1)));
b6d33983
R
4610}")
4611
4612(define_expand "extendqisi2"
73a4d10b 4613 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
b6d33983
R
4614 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4615 ""
4616 "")
4617
4618(define_insn "*extendqisi2_compact"
73a4d10b 4619 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
51bd623f 4620 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 4621 "TARGET_SH1"
0d7e008e
SC
4622 "@
4623 exts.b %1,%0
51bd623f 4624 mov.b %1,%0"
c49439f1 4625 [(set_attr "type" "arith,load")])
bc45ade3 4626
b6d33983
R
4627(define_insn "*extendqisi2_media"
4628 [(set (match_operand:SI 0 "register_operand" "=r,r")
4629 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4630 "TARGET_SHMEDIA"
4631 "@
4632 #
4633 ld%M1.b %m1, %0"
73a4d10b
R
4634 [(set_attr "type" "arith_media,load_media")
4635 (set (attr "highpart")
4636 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4637 (const_string "user")]
4638 (const_string "ignore")))])
b6d33983
R
4639
4640(define_split
e69d1422
R
4641 [(set (match_operand:SI 0 "register_operand" "")
4642 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
b6d33983 4643 "TARGET_SHMEDIA && reload_completed"
73a4d10b 4644 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
b6d33983
R
4645 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4646 "
4647{
73a4d10b
R
4648 rtx op1 = operands[1];
4649 if (GET_CODE (op1) == TRUNCATE)
4650 op1 = XEXP (op1, 0);
4651 operands[2]
4652 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4653 subreg_lowpart_offset (SImode, GET_MODE (op1)));
b6d33983
R
4654}")
4655
bc45ade3 4656(define_insn "extendqihi2"
73a4d10b 4657 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
51bd623f 4658 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 4659 "TARGET_SH1"
0d7e008e
SC
4660 "@
4661 exts.b %1,%0
51bd623f 4662 mov.b %1,%0"
c49439f1 4663 [(set_attr "type" "arith,load")])
fae15c93 4664
b6d33983
R
4665/* It would seem useful to combine the truncXi patterns into the movXi
4666 patterns, but unary operators are ignored when matching constraints,
4667 so we need separate patterns. */
4668(define_insn "truncdisi2"
0ac78517 4669 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
b6d33983
R
4670 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4671 "TARGET_SHMEDIA"
4672 "@
4673 add.l %1, r63, %0
4674 st%M0.l %m0, %1
4675 fst%M0.s %m0, %T1
4676 fmov.ls %1, %0
4677 fmov.sl %T1, %0
4678 fmov.s %T1, %0"
73a4d10b
R
4679 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4680 (set (attr "highpart")
4681 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4682 (const_string "user")]
4683 (const_string "extend")))])
b6d33983
R
4684
4685(define_insn "truncdihi2"
0ac78517 4686 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
b6d33983
R
4687 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4688 "TARGET_SHMEDIA"
4689 "@
4690 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4691 st%M0.w %m0, %1"
4692 [(set_attr "type" "arith_media,store_media")
73a4d10b
R
4693 (set_attr "length" "8,4")
4694 (set (attr "highpart")
4695 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4696 (const_string "user")]
4697 (const_string "extend")))])
b6d33983 4698
59324685
R
4699; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4700; Because we use zero extension, we can't provide signed QImode compares
4701; using a simple compare or conditional banch insn.
b6d33983
R
4702(define_insn "truncdiqi2"
4703 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4704 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4705 "TARGET_SHMEDIA"
4706 "@
40779a72 4707 andi %1, 255, %0
b6d33983 4708 st%M0.b %m0, %1"
73a4d10b
R
4709 [(set_attr "type" "arith_media,store")
4710 (set (attr "highpart")
4711 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712 (const_string "user")]
4713 (const_string "extend")))])
bc45ade3
SC
4714;; -------------------------------------------------------------------------
4715;; Move instructions
4716;; -------------------------------------------------------------------------
4717
0d7e008e 4718;; define push and pop so it is easy for sh.c
fa5322fa
AO
4719;; We can't use push and pop on SHcompact because the stack must always
4720;; be 8-byte aligned.
b9654711 4721
225e4f43 4722(define_expand "push"
4773afa4 4723 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
ffae286a 4724 (match_operand:SI 0 "register_operand" "r,l,x"))]
fa5322fa 4725 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 4726 "")
b9654711 4727
225e4f43 4728(define_expand "pop"
51bd623f 4729 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4773afa4 4730 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
fa5322fa 4731 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
4732 "")
4733
4734(define_expand "push_e"
4773afa4 4735 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
225e4f43 4736 (match_operand:SF 0 "" ""))
4773afa4 4737 (use (reg:PSI FPSCR_REG))
225e4f43 4738 (clobber (scratch:SI))])]
fa5322fa 4739 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 4740 "")
b9654711 4741
225e4f43 4742(define_insn "push_fpul"
4773afa4 4743 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3a8699c7 4744 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 4745 "sts.l fpul,@-r15"
45348d9e 4746 [(set_attr "type" "store")
c49439f1 4747 (set_attr "late_fp_use" "yes")
45348d9e
JW
4748 (set_attr "hit_stack" "yes")])
4749
225e4f43
R
4750;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4751;; so use that.
4752(define_expand "push_4"
4773afa4
AO
4753 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4754 (match_operand:DF 0 "" ""))
4755 (use (reg:PSI FPSCR_REG))
225e4f43 4756 (clobber (scratch:SI))])]
fa5322fa 4757 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
4758 "")
4759
4760(define_expand "pop_e"
4761 [(parallel [(set (match_operand:SF 0 "" "")
4773afa4
AO
4762 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4763 (use (reg:PSI FPSCR_REG))
225e4f43 4764 (clobber (scratch:SI))])]
fa5322fa 4765 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
4766 "")
4767
4768(define_insn "pop_fpul"
4773afa4 4769 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3a8699c7 4770 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 4771 "lds.l @r15+,fpul"
45348d9e
JW
4772 [(set_attr "type" "load")
4773 (set_attr "hit_stack" "yes")])
4774
225e4f43
R
4775(define_expand "pop_4"
4776 [(parallel [(set (match_operand:DF 0 "" "")
4773afa4
AO
4777 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4778 (use (reg:PSI FPSCR_REG))
225e4f43 4779 (clobber (scratch:SI))])]
fa5322fa 4780 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
4781 "")
4782
7144b2d8
DD
4783(define_expand "push_fpscr"
4784 [(const_int 0)]
603ff6b5 4785 "TARGET_SH2E"
7144b2d8
DD
4786 "
4787{
57d38024 4788 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
c0d4e710 4789 gen_rtx_PRE_DEC (Pmode,
7144b2d8
DD
4790 stack_pointer_rtx)),
4791 get_fpscr_rtx ()));
c0d4e710 4792 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
7144b2d8
DD
4793 DONE;
4794}")
4795
4796(define_expand "pop_fpscr"
4797 [(const_int 0)]
603ff6b5 4798 "TARGET_SH2E"
7144b2d8
DD
4799 "
4800{
4801 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
57d38024 4802 gen_frame_mem (PSImode,
c0d4e710 4803 gen_rtx_POST_INC (Pmode,
7144b2d8 4804 stack_pointer_rtx))));
c0d4e710 4805 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
7144b2d8
DD
4806 DONE;
4807}")
4808
e3391510
JW
4809;; These two patterns can happen as the result of optimization, when
4810;; comparisons get simplified to a move of zero or 1 into the T reg.
4811;; They don't disappear completely, because the T reg is a fixed hard reg.
ffae286a 4812
0d7e008e 4813(define_insn "clrt"
4773afa4 4814 [(set (reg:SI T_REG) (const_int 0))]
fa5322fa 4815 "TARGET_SH1"
0d7e008e 4816 "clrt")
bc45ade3 4817
e3391510 4818(define_insn "sett"
4773afa4 4819 [(set (reg:SI T_REG) (const_int 1))]
fa5322fa 4820 "TARGET_SH1"
e3391510
JW
4821 "sett")
4822
3ca0a524 4823;; t/r must come after r/r, lest reload will try to reload stuff like
4773afa4 4824;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
e11cddec 4825;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
0d7e008e 4826(define_insn "movsi_i"
735cb76e
R
4827 [(set (match_operand:SI 0 "general_movdst_operand"
4828 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4829 (match_operand:SI 1 "general_movsrc_operand"
4830 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
fa5322fa 4831 "TARGET_SH1
3a8699c7 4832 && ! TARGET_SH2E
157371cf 4833 && ! TARGET_SH2A
1245df60
R
4834 && (register_operand (operands[0], SImode)
4835 || register_operand (operands[1], SImode))"
8e87e161
SC
4836 "@
4837 mov.l %1,%0
4838 mov %1,%0
3ca0a524 4839 cmp/pl %1
8e87e161
SC
4840 mov.l %1,%0
4841 sts %1,%0
99e87c10 4842 sts %1,%0
8e87e161
SC
4843 movt %0
4844 mov.l %1,%0
4845 sts.l %1,%0
1245df60 4846 sts.l %1,%0
8e87e161 4847 lds %1,%0
99e87c10 4848 lds %1,%0
8e87e161 4849 lds.l %1,%0
1245df60 4850 lds.l %1,%0
51bd623f 4851 fake %1,%0"
c49439f1 4852 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
99e87c10 4853 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
07a45e5c 4854
1245df60 4855;; t/r must come after r/r, lest reload will try to reload stuff like
e11cddec 4856;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
45348d9e
JW
4857;; ??? This allows moves from macl to fpul to be recognized, but these moves
4858;; will require a reload.
ec555f32
R
4859;; ??? We can't include f/f because we need the proper FPSCR setting when
4860;; TARGET_FMOVD is in effect, and mode switching is done before reload.
45348d9e 4861(define_insn "movsi_ie"
735cb76e 4862 [(set (match_operand:SI 0 "general_movdst_operand"
157371cf 4863 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
735cb76e 4864 (match_operand:SI 1 "general_movsrc_operand"
157371cf
AO
4865 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4866 "(TARGET_SH2E || TARGET_SH2A)
45348d9e
JW
4867 && (register_operand (operands[0], SImode)
4868 || register_operand (operands[1], SImode))"
4869 "@
45348d9e
JW
4870 mov.l %1,%0
4871 mov %1,%0
157371cf 4872 movi20 %1,%0
1245df60 4873 cmp/pl %1
45348d9e
JW
4874 mov.l %1,%0
4875 sts %1,%0
99e87c10 4876 sts %1,%0
45348d9e
JW
4877 movt %0
4878 mov.l %1,%0
4879 sts.l %1,%0
1245df60 4880 sts.l %1,%0
45348d9e 4881 lds %1,%0
99e87c10 4882 lds %1,%0
45348d9e 4883 lds.l %1,%0
1245df60 4884 lds.l %1,%0
225e4f43 4885 lds.l %1,%0
a92facbb 4886 sts.l %1,%0
45348d9e
JW
4887 fake %1,%0
4888 lds %1,%0
1245df60 4889 sts %1,%0
ec555f32
R
4890 fsts fpul,%0
4891 flds %1,fpul
4892 fmov %1,%0
1245df60 4893 ! move optimized away"
157371cf
AO
4894 [(set_attr "type" "pcload_si,move,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")
4895 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4896 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
1245df60
R
4897
4898(define_insn "movsi_i_lowpart"
99e87c10 4899 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
735cb76e 4900 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
fa5322fa
AO
4901 "TARGET_SH1
4902 && (register_operand (operands[0], SImode)
4903 || register_operand (operands[1], SImode))"
1245df60
R
4904 "@
4905 mov.l %1,%0
4906 mov %1,%0
4907 mov.l %1,%0
4908 sts %1,%0
99e87c10 4909 sts %1,%0
1245df60
R
4910 movt %0
4911 mov.l %1,%0
4912 fake %1,%0"
99e87c10 4913 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
a6f463a0 4914
7d73a2ba 4915(define_insn_and_split "load_ra"
b869f904 4916 [(set (match_operand:SI 0 "general_movdst_operand" "")
73a4d10b 4917 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
dce20bbc 4918 "TARGET_SH1"
7d73a2ba 4919 "#"
4586b4ca 4920 "&& ! currently_expanding_to_rtl"
b869f904 4921 [(set (match_dup 0) (match_dup 1))]
7d73a2ba
R
4922 "
4923{
dce20bbc 4924 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
57d38024 4925 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
7d73a2ba 4926}")
b869f904 4927
73a4d10b
R
4928;; The '?'s in the following constraints may not reflect the time taken
4929;; to perform the move. They are there to discourage the use of floating-
4930;; point registers for storing integer values.
fa5322fa 4931(define_insn "*movsi_media"
735cb76e 4932 [(set (match_operand:SI 0 "general_movdst_operand"
73a4d10b 4933 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
735cb76e 4934 (match_operand:SI 1 "general_movsrc_operand"
42201282 4935 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
fa5322fa
AO
4936 "TARGET_SHMEDIA_FPU
4937 && (register_operand (operands[0], SImode)
73a4d10b
R
4938 || sh_register_operand (operands[1], SImode)
4939 || GET_CODE (operands[1]) == TRUNCATE)"
fa5322fa
AO
4940 "@
4941 add.l %1, r63, %0
4942 movi %1, %0
4943 #
4944 ld%M1.l %m1, %0
d9da94a1 4945 st%M0.l %m0, %N1
fa5322fa
AO
4946 fld%M1.s %m1, %0
4947 fst%M0.s %m0, %1
0ac78517 4948 fmov.ls %N1, %0
fa5322fa
AO
4949 fmov.sl %1, %0
4950 fmov.s %1, %0
4951 ptabs %1, %0
4952 gettr %1, %0
4953 pt %1, %0"
2ad65b0e 4954 [(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")
73a4d10b
R
4955 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4956 (set (attr "highpart")
4957 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4958 (const_string "user")]
4959 (const_string "ignore")))])
fa5322fa
AO
4960
4961(define_insn "*movsi_media_nofpu"
735cb76e 4962 [(set (match_operand:SI 0 "general_movdst_operand"
73a4d10b 4963 "=r,r,r,r,m,*b,r,*b")
735cb76e 4964 (match_operand:SI 1 "general_movsrc_operand"
42201282 4965 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
fa5322fa
AO
4966 "TARGET_SHMEDIA
4967 && (register_operand (operands[0], SImode)
73a4d10b
R
4968 || sh_register_operand (operands[1], SImode)
4969 || GET_CODE (operands[1]) == TRUNCATE)"
fa5322fa
AO
4970 "@
4971 add.l %1, r63, %0
4972 movi %1, %0
4973 #
4974 ld%M1.l %m1, %0
d9da94a1 4975 st%M0.l %m0, %N1
fa5322fa
AO
4976 ptabs %1, %0
4977 gettr %1, %0
4978 pt %1, %0"
2ad65b0e 4979 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
73a4d10b
R
4980 (set_attr "length" "4,4,8,4,4,4,4,12")
4981 (set (attr "highpart")
4982 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4983 (const_string "user")]
4984 (const_string "ignore")))])
4985
4986(define_expand "movsi_const"
4987 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4988 (const:SI (sign_extend:SI
4989 (truncate:HI
4990 (ashiftrt:SI
4991 (match_operand:DI 1 "immediate_operand" "s")
4992 (const_int 16))))))
4993 (set (match_dup 0)
4994 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
42201282
R
4995 (const:SI
4996 (zero_extend:SI
4997 (truncate:HI (match_dup 1))))))]
73a4d10b
R
4998 "TARGET_SHMEDIA && reload_completed
4999 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5000 "
5001{
5002 if (GET_CODE (operands[1]) == LABEL_REF
5003 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5004 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5005 else if (GOTOFF_P (operands[1]))
5006 {
5007 rtx unspec = XEXP (operands[1], 0);
5008
5009 if (! UNSPEC_GOTOFF_P (unspec))
5010 {
5011 unspec = XEXP (unspec, 0);
5012 if (! UNSPEC_GOTOFF_P (unspec))
5013 abort ();
5014 }
5015 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5016 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5017 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5018 }
5019}")
5020
5021(define_expand "movsi_const_16bit"
5022 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5023 (const:SI (sign_extend:SI
5024 (truncate:HI
5025 (match_operand:DI 1 "immediate_operand" "s")))))]
5026 "TARGET_SHMEDIA && flag_pic && reload_completed
5027 && GET_CODE (operands[1]) == SYMBOL_REF"
5028 "")
fa5322fa
AO
5029
5030(define_split
73a4d10b 5031 [(set (match_operand:SI 0 "arith_reg_dest" "")
e69d1422 5032 (match_operand:SI 1 "immediate_operand" ""))]
fa5322fa
AO
5033 "TARGET_SHMEDIA && reload_completed
5034 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
73a4d10b 5035 [(const_int 0)]
fa5322fa
AO
5036 "
5037{
73a4d10b
R
5038 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5039
5040 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5041 REG_NOTES (insn));
5042
5043 DONE;
fa5322fa
AO
5044}")
5045
5046(define_split
e69d1422
R
5047 [(set (match_operand:SI 0 "register_operand" "")
5048 (match_operand:SI 1 "immediate_operand" ""))]
b6d33983 5049 "TARGET_SHMEDIA && reload_completed
fa5322fa 5050 && ((GET_CODE (operands[1]) == CONST_INT
735cb76e 5051 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
fa5322fa
AO
5052 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5053 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5054
bc45ade3 5055(define_expand "movsi"
0d7e008e
SC
5056 [(set (match_operand:SI 0 "general_movdst_operand" "")
5057 (match_operand:SI 1 "general_movsrc_operand" ""))]
bc45ade3 5058 ""
ffae286a 5059 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
961c4780 5060
225e4f43
R
5061(define_expand "ic_invalidate_line"
5062 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4773afa4 5063 (match_dup 1)] UNSPEC_ICACHE)
225e4f43 5064 (clobber (scratch:SI))])]
fa5322fa 5065 "TARGET_HARD_SH4 || TARGET_SH5"
225e4f43
R
5066 "
5067{
fa5322fa
AO
5068 if (TARGET_SHMEDIA)
5069 {
5070 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5071 DONE;
5072 }
5073 else if (TARGET_SHCOMPACT)
5074 {
73a4d10b 5075 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
fa5322fa
AO
5076 operands[1] = force_reg (Pmode, operands[1]);
5077 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5078 DONE;
5079 }
312209c6
AO
5080 else if (TARGET_SH4A_ARCH)
5081 {
5082 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5083 DONE;
5084 }
225e4f43 5085 operands[0] = force_reg (Pmode, operands[0]);
90e65b70
AO
5086 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5087 Pmode)));
225e4f43
R
5088}")
5089
5090;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
0aa54da2
R
5091;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5092;; the requirement *1*00 for associative address writes. The alignment of
225e4f43
R
5093;; %0 implies that its least significant bit is cleared,
5094;; thus we clear the V bit of a matching entry if there is one.
5095(define_insn "ic_invalidate_line_i"
0aa54da2 5096 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
4773afa4
AO
5097 (match_operand:SI 1 "register_operand" "r")]
5098 UNSPEC_ICACHE)
0aa54da2 5099 (clobber (match_scratch:SI 2 "=&r"))]
225e4f43 5100 "TARGET_HARD_SH4"
0aa54da2 5101 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
fae15c93 5102 [(set_attr "length" "8")
c49439f1 5103 (set_attr "type" "cwb")])
225e4f43 5104
312209c6
AO
5105(define_insn "ic_invalidate_line_sh4a"
5106 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5107 UNSPEC_ICACHE)]
5108 "TARGET_SH4A_ARCH"
5109 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5110 [(set_attr "length" "16")
5111 (set_attr "type" "cwb")])
5112
ca903bba
R
5113;; ??? could make arg 0 an offsettable memory operand to allow to save
5114;; an add in the code that calculates the address.
fa5322fa 5115(define_insn "ic_invalidate_line_media"
73a4d10b 5116 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
fa5322fa
AO
5117 UNSPEC_ICACHE)]
5118 "TARGET_SHMEDIA"
b6d33983
R
5119 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5120 [(set_attr "length" "16")
5121 (set_attr "type" "invalidate_line_media")])
fa5322fa
AO
5122
5123(define_insn "ic_invalidate_line_compact"
5124 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5125 (match_operand:SI 1 "register_operand" "r")]
5126 UNSPEC_ICACHE)
5127 (clobber (reg:SI PR_REG))]
5128 "TARGET_SHCOMPACT"
5129 "jsr @%1%#"
5130 [(set_attr "type" "sfunc")
5131 (set_attr "needs_delay_slot" "yes")])
5132
ca903bba
R
5133(define_expand "initialize_trampoline"
5134 [(match_operand:SI 0 "" "")
5135 (match_operand:SI 1 "" "")
5136 (match_operand:SI 2 "" "")]
5137 "TARGET_SHCOMPACT"
5138 "
5139{
5140 rtx sfun, tramp;
5141
e300c78c 5142 tramp = force_reg (Pmode, operands[0]);
73a4d10b
R
5143 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5144 SFUNC_STATIC));
ca903bba
R
5145 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5146 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5147
5148 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5149 DONE;
5150}")
5151
5152(define_insn "initialize_trampoline_compact"
5153 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5154 (match_operand:SI 1 "register_operand" "r")
5155 (reg:SI R2_REG) (reg:SI R3_REG)]
5156 UNSPEC_INIT_TRAMP)
5157
5158 (clobber (reg:SI PR_REG))]
5159 "TARGET_SHCOMPACT"
5160 "jsr @%1%#"
5161 [(set_attr "type" "sfunc")
5162 (set_attr "needs_delay_slot" "yes")])
5163
bc45ade3 5164(define_insn "movqi_i"
07a45e5c
JW
5165 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5166 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
fa5322fa
AO
5167 "TARGET_SH1
5168 && (arith_reg_operand (operands[0], QImode)
5169 || arith_reg_operand (operands[1], QImode))"
bc45ade3
SC
5170 "@
5171 mov %1,%0
0d7e008e
SC
5172 mov.b %1,%0
5173 mov.b %1,%0
5174 movt %0
bc45ade3 5175 sts %1,%0
0d7e008e 5176 lds %1,%0"
22e1ebf1 5177 [(set_attr "type" "move,load,store,move,move,move")])
bc45ade3 5178
fa5322fa
AO
5179(define_insn "*movqi_media"
5180 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
42201282 5181 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
fa5322fa
AO
5182 "TARGET_SHMEDIA
5183 && (arith_reg_operand (operands[0], QImode)
73a4d10b 5184 || extend_reg_or_0_operand (operands[1], QImode))"
fa5322fa
AO
5185 "@
5186 add.l %1, r63, %0
5187 movi %1, %0
59324685 5188 ld%M1.ub %m1, %0
d9da94a1 5189 st%M0.b %m0, %N1"
73a4d10b
R
5190 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5191 (set (attr "highpart")
5192 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5193 (const_string "user")]
5194 (const_string "ignore")))])
fa5322fa 5195
bc45ade3
SC
5196(define_expand "movqi"
5197 [(set (match_operand:QI 0 "general_operand" "")
5198 (match_operand:QI 1 "general_operand" ""))]
5199 ""
ffae286a 5200 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
bc45ade3 5201
b6d33983
R
5202(define_expand "reload_inqi"
5203 [(set (match_operand:SI 2 "" "=&r")
5204 (match_operand:QI 1 "inqhi_operand" ""))
5205 (set (match_operand:QI 0 "arith_reg_operand" "=r")
ea45c4b0 5206 (truncate:QI (match_dup 3)))]
b6d33983
R
5207 "TARGET_SHMEDIA"
5208 "
5209{
5210 rtx inner = XEXP (operands[1], 0);
5211 int regno = REGNO (inner);
5212
5213 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5214 operands[1] = gen_rtx_REG (SImode, regno);
5215 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5216}")
5217
266a2732 5218/* When storing r0, we have to avoid reg+reg addressing. */
bc45ade3 5219(define_insn "movhi_i"
735cb76e
R
5220 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5221 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
fa5322fa
AO
5222 "TARGET_SH1
5223 && (arith_reg_operand (operands[0], HImode)
266a2732
R
5224 || arith_reg_operand (operands[1], HImode))
5225 && (GET_CODE (operands[0]) != MEM
5226 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5227 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5228 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
8e87e161
SC
5229 "@
5230 mov.w %1,%0
5231 mov %1,%0
5232 mov.w %1,%0
5233 movt %0
5234 mov.w %1,%0
8e87e161 5235 sts %1,%0
51bd623f
JW
5236 lds %1,%0
5237 fake %1,%0"
27232d28 5238 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
bc45ade3 5239
fa5322fa 5240(define_insn "*movhi_media"
735cb76e 5241 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
42201282 5242 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
fa5322fa
AO
5243 "TARGET_SHMEDIA
5244 && (arith_reg_operand (operands[0], HImode)
d9da94a1 5245 || arith_reg_or_0_operand (operands[1], HImode))"
fa5322fa
AO
5246 "@
5247 add.l %1, r63, %0
5248 movi %1, %0
5249 #
5250 ld%M1.w %m1, %0
d9da94a1 5251 st%M0.w %m0, %N1"
73a4d10b
R
5252 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5253 (set (attr "highpart")
5254 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5255 (const_string "user")]
5256 (const_string "ignore")))])
fa5322fa
AO
5257
5258(define_split
e69d1422
R
5259 [(set (match_operand:HI 0 "register_operand" "")
5260 (match_operand:HI 1 "immediate_operand" ""))]
b6d33983 5261 "TARGET_SHMEDIA && reload_completed
735cb76e 5262 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa
AO
5263 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5264
bc45ade3 5265(define_expand "movhi"
0d7e008e
SC
5266 [(set (match_operand:HI 0 "general_movdst_operand" "")
5267 (match_operand:HI 1 "general_movsrc_operand" ""))]
bc45ade3 5268 ""
ffae286a
JW
5269 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5270
b6d33983
R
5271(define_expand "reload_inhi"
5272 [(set (match_operand:SI 2 "" "=&r")
5273 (match_operand:HI 1 "inqhi_operand" ""))
5274 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5275 (truncate:HI (match_dup 3)))]
5276 "TARGET_SHMEDIA"
5277 "
5278{
5279 rtx inner = XEXP (operands[1], 0);
5280 int regno = REGNO (inner);
5281
5282 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5283 operands[1] = gen_rtx_REG (SImode, regno);
5284 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5285}")
5286
1245df60
R
5287;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5288;; compiled with -m2 -ml -O3 -funroll-loops
0113c3c0 5289(define_insn "*movdi_i"
1245df60 5290 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
735cb76e 5291 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
fa5322fa
AO
5292 "TARGET_SH1
5293 && (arith_reg_operand (operands[0], DImode)
5294 || arith_reg_operand (operands[1], DImode))"
0d7e008e 5295 "* return output_movedouble (insn, operands, DImode);"
22e1ebf1 5296 [(set_attr "length" "4")
1245df60 5297 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
bc45ade3 5298
d0aae509 5299;; If the output is a register and the input is memory or a register, we have
52702ae1 5300;; to be careful and see which word needs to be loaded first.
b9b7c1c9 5301
8e87e161
SC
5302(define_split
5303 [(set (match_operand:DI 0 "general_movdst_operand" "")
5304 (match_operand:DI 1 "general_movsrc_operand" ""))]
fa5322fa 5305 "TARGET_SH1 && reload_completed"
8e87e161
SC
5306 [(set (match_dup 2) (match_dup 3))
5307 (set (match_dup 4) (match_dup 5))]
5308 "
d0aae509
RK
5309{
5310 int regno;
5311
5312 if ((GET_CODE (operands[0]) == MEM
5313 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5314 || (GET_CODE (operands[1]) == MEM
5315 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5316 FAIL;
5317
f5b9e7c9
NS
5318 switch (GET_CODE (operands[0]))
5319 {
5320 case REG:
5321 regno = REGNO (operands[0]);
5322 break;
5323 case SUBREG:
5324 regno = subreg_regno (operands[0]);
5325 break;
5326 case MEM:
5327 regno = -1;
5328 break;
5329 default:
5330 gcc_unreachable ();
5331 }
d0aae509
RK
5332
5333 if (regno == -1
5334 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
5335 {
5336 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5337 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5338 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5339 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5340 }
5341 else
5342 {
5343 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5344 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5345 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5346 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5347 }
5348
5349 if (operands[2] == 0 || operands[3] == 0
5350 || operands[4] == 0 || operands[5] == 0)
5351 FAIL;
5352}")
961c4780 5353
73a4d10b
R
5354;; The '?'s in the following constraints may not reflect the time taken
5355;; to perform the move. They are there to discourage the use of floating-
5356;; point registers for storing integer values.
fa5322fa 5357(define_insn "*movdi_media"
735cb76e 5358 [(set (match_operand:DI 0 "general_movdst_operand"
73a4d10b 5359 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
735cb76e 5360 (match_operand:DI 1 "general_movsrc_operand"
42201282 5361 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
fa5322fa
AO
5362 "TARGET_SHMEDIA_FPU
5363 && (register_operand (operands[0], DImode)
d9da94a1 5364 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
5365 "@
5366 add %1, r63, %0
5367 movi %1, %0
5368 #
5369 ld%M1.q %m1, %0
d9da94a1 5370 st%M0.q %m0, %N1
fa5322fa
AO
5371 fld%M1.d %m1, %0
5372 fst%M0.d %m0, %1
0ac78517 5373 fmov.qd %N1, %0
fa5322fa
AO
5374 fmov.dq %1, %0
5375 fmov.d %1, %0
5376 ptabs %1, %0
5377 gettr %1, %0
5378 pt %1, %0"
2ad65b0e 5379 [(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
5380 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5381
5382(define_insn "*movdi_media_nofpu"
73a4d10b 5383 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
42201282 5384 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
fa5322fa
AO
5385 "TARGET_SHMEDIA
5386 && (register_operand (operands[0], DImode)
d9da94a1 5387 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
5388 "@
5389 add %1, r63, %0
5390 movi %1, %0
5391 #
5392 ld%M1.q %m1, %0
d9da94a1 5393 st%M0.q %m0, %N1
fa5322fa
AO
5394 ptabs %1, %0
5395 gettr %1, %0
5396 pt %1, %0"
2ad65b0e 5397 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
5398 (set_attr "length" "4,4,16,4,4,4,4,*")])
5399
73a4d10b
R
5400(define_insn "*movdi_media_I16"
5401 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5402 (match_operand:DI 1 "const_int_operand" "I16"))]
5403 "TARGET_SHMEDIA && reload_completed"
5404 "movi %1, %0"
5405 [(set_attr "type" "arith_media")
5406 (set_attr "length" "4")])
5407
fa5322fa 5408(define_split
73a4d10b 5409 [(set (match_operand:DI 0 "arith_reg_dest" "")
e69d1422 5410 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
5411 "TARGET_SHMEDIA && reload_completed
5412 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5413 [(set (match_dup 0) (match_dup 1))]
5414 "
5415{
5416 rtx insn;
5417
5418 if (TARGET_SHMEDIA64)
5419 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5420 else
5421 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5422
5423 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5424 REG_NOTES (insn));
5425
5426 DONE;
5427}")
5428
5429(define_expand "movdi_const"
5430 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5431 (const:DI (sign_extend:DI
5432 (truncate:HI
5433 (ashiftrt:DI
5434 (match_operand:DI 1 "immediate_operand" "s")
5435 (const_int 48))))))
5436 (set (match_dup 0)
5437 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
42201282
R
5438 (const:DI
5439 (zero_extend:DI
5440 (truncate:HI
5441 (ashiftrt:SI
5442 (match_dup 1)
5443 (const_int 32)))))))
fa5322fa
AO
5444 (set (match_dup 0)
5445 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
42201282
R
5446 (const:DI
5447 (zero_extend:DI
5448 (truncate:HI
5449 (ashiftrt:SI
5450 (match_dup 1)
5451 (const_int 16)))))))
fa5322fa
AO
5452 (set (match_dup 0)
5453 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
42201282
R
5454 (const:DI
5455 (zero_extend:DI
5456 (truncate:HI
5457 (match_dup 1))))))]
fa5322fa
AO
5458 "TARGET_SHMEDIA64 && reload_completed
5459 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5460 "
5461{
ea4210ef 5462 sh_mark_label (operands[1], 4);
fa5322fa
AO
5463}")
5464
5465(define_expand "movdi_const_32bit"
5466 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5467 (const:DI (sign_extend:DI
5468 (truncate:HI
5469 (ashiftrt:DI
5470 (match_operand:DI 1 "immediate_operand" "s")
5471 (const_int 16))))))
5472 (set (match_dup 0)
5473 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
42201282
R
5474 (const:DI
5475 (zero_extend:DI
5476 (truncate:HI
5477 (match_dup 1))))))]
fa5322fa
AO
5478 "TARGET_SHMEDIA32 && reload_completed
5479 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5480 "
5481{
ea4210ef 5482 sh_mark_label (operands[1], 2);
fa5322fa
AO
5483}")
5484
5485(define_expand "movdi_const_16bit"
5486 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5487 (const:DI (sign_extend:DI
5488 (truncate:HI
5489 (match_operand:DI 1 "immediate_operand" "s")))))]
5490 "TARGET_SHMEDIA && flag_pic && reload_completed
5491 && GET_CODE (operands[1]) == SYMBOL_REF"
5492 "")
5493
5494(define_split
73a4d10b 5495 [(set (match_operand:DI 0 "ext_dest_operand" "")
e69d1422 5496 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
5497 "TARGET_SHMEDIA && reload_completed
5498 && GET_CODE (operands[1]) == CONST_INT
735cb76e 5499 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa 5500 [(set (match_dup 0) (match_dup 2))
c1b92d09 5501 (match_dup 1)]
fa5322fa
AO
5502 "
5503{
c1b92d09
R
5504 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5505 unsigned HOST_WIDE_INT low = val;
5506 unsigned HOST_WIDE_INT high = val;
fa5322fa 5507 unsigned HOST_WIDE_INT sign;
c1b92d09 5508 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
fa5322fa 5509
42201282 5510 /* Zero-extend the 16 least-significant bits. */
c1b92d09 5511 low &= 0xffff;
fa5322fa
AO
5512
5513 /* Arithmetic shift right the word by 16 bits. */
c1b92d09 5514 high >>= 16;
73a4d10b
R
5515 if (GET_CODE (operands[0]) == SUBREG
5516 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5517 {
5518 high &= 0xffff;
5519 high ^= 0x8000;
5520 high -= 0x8000;
5521 }
5522 else
5523 {
5524 sign = 1;
5525 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5526 high ^= sign;
5527 high -= sign;
5528 }
c1b92d09
R
5529 do
5530 {
5531 /* If we can't generate the constant with a two-insn movi / shori
5532 sequence, try some other strategies. */
735cb76e 5533 if (! CONST_OK_FOR_I16 (high))
c1b92d09
R
5534 {
5535 /* Try constant load / left shift. We know VAL != 0. */
5536 val2 = val ^ (val-1);
5537 if (val2 > 0x1ffff)
5538 {
5539 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5540
735cb76e
R
5541 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5542 || (! CONST_OK_FOR_I16 (high >> 16)
5543 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
c1b92d09
R
5544 {
5545 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5546 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5547 GEN_INT (trailing_zeroes));
5548 break;
5549 }
5550 }
5551 /* Try constant load / right shift. */
5552 val2 = (val >> 15) + 1;
5553 if (val2 == (val2 & -val2))
5554 {
5555 int shift = 49 - exact_log2 (val2);
5556
5557 val2 = trunc_int_for_mode (val << shift, DImode);
735cb76e 5558 if (CONST_OK_FOR_I16 (val2))
c1b92d09
R
5559 {
5560 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5561 GEN_INT (shift));
5562 break;
5563 }
5564 }
5565 /* Try mperm.w . */
5566 val2 = val & 0xffff;
5567 if ((val >> 16 & 0xffff) == val2
5568 && (val >> 32 & 0xffff) == val2
5569 && (val >> 48 & 0xffff) == val2)
5570 {
5571 val2 = (HOST_WIDE_INT) val >> 48;
5572 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5573 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5574 break;
5575 }
5576 /* Try movi / mshflo.l */
5577 val2 = (HOST_WIDE_INT) val >> 32;
45dc67b7
KK
5578 if (val2 == ((unsigned HOST_WIDE_INT)
5579 trunc_int_for_mode (val, SImode)))
c1b92d09
R
5580 {
5581 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5582 operands[0]);
5583 break;
5584 }
5585 /* Try movi / mshflo.l w/ r63. */
5586 val2 = val + ((HOST_WIDE_INT) -1 << 32);
735cb76e 5587 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
c1b92d09
R
5588 {
5589 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
a556fd39 5590 const0_rtx);
c1b92d09
R
5591 break;
5592 }
5593 }
5594 val2 = high;
5595 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5596 }
5597 while (0);
5598 operands[2] = GEN_INT (val2);
fa5322fa
AO
5599}")
5600
5601(define_split
73a4d10b 5602 [(set (match_operand:DI 0 "ext_dest_operand" "")
e69d1422 5603 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
5604 "TARGET_SHMEDIA && reload_completed
5605 && GET_CODE (operands[1]) == CONST_DOUBLE"
5606 [(set (match_dup 0) (match_dup 2))
5607 (set (match_dup 0)
42201282 5608 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
fa5322fa
AO
5609 "
5610{
5611 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5612 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5613 unsigned HOST_WIDE_INT val = low;
5614 unsigned HOST_WIDE_INT sign;
5615
42201282 5616 /* Zero-extend the 16 least-significant bits. */
fa5322fa 5617 val &= 0xffff;
fa5322fa
AO
5618 operands[1] = GEN_INT (val);
5619
5620 /* Arithmetic shift right the double-word by 16 bits. */
5621 low >>= 16;
5622 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5623 high >>= 16;
5624 sign = 1;
5625 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5626 high ^= sign;
5627 high -= sign;
5628
5629 /* This will only be true if high is a sign-extension of low, i.e.,
5630 it must be either 0 or (unsigned)-1, and be zero iff the
5631 most-significant bit of low is set. */
5632 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5633 operands[2] = GEN_INT (low);
5634 else
5635 operands[2] = immed_double_const (low, high, DImode);
5636}")
5637
c1b92d09 5638(define_insn "shori_media"
73a4d10b 5639 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
fa5322fa
AO
5640 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5641 (const_int 16))
42201282 5642 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
73a4d10b 5643 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
fa5322fa
AO
5644 "@
5645 shori %u2, %0
2ad65b0e
SC
5646 #"
5647 [(set_attr "type" "arith_media,*")])
fa5322fa 5648
73a4d10b
R
5649(define_insn "*shori_media_si"
5650 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5651 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5652 (const_int 16))
42201282 5653 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
73a4d10b
R
5654 "TARGET_SHMEDIA"
5655 "shori %u2, %0")
5656
bc45ade3 5657(define_expand "movdi"
961c4780
SC
5658 [(set (match_operand:DI 0 "general_movdst_operand" "")
5659 (match_operand:DI 1 "general_movsrc_operand" ""))]
bc45ade3 5660 ""
a6f463a0 5661 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
ffae286a 5662
fa5322fa
AO
5663(define_insn "movdf_media"
5664 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 5665 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
5666 "TARGET_SHMEDIA_FPU
5667 && (register_operand (operands[0], DFmode)
d9da94a1 5668 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
5669 "@
5670 fmov.d %1, %0
0ac78517 5671 fmov.qd %N1, %0
fa5322fa
AO
5672 fmov.dq %1, %0
5673 add %1, r63, %0
5674 #
5675 fld%M1.d %m1, %0
5676 fst%M0.d %m0, %1
5677 ld%M1.q %m1, %0
d9da94a1 5678 st%M0.q %m0, %N1"
2ad65b0e 5679 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
5680
5681(define_insn "movdf_media_nofpu"
5682 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 5683 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
5684 "TARGET_SHMEDIA
5685 && (register_operand (operands[0], DFmode)
d9da94a1 5686 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
5687 "@
5688 add %1, r63, %0
5689 #
5690 ld%M1.q %m1, %0
d9da94a1 5691 st%M0.q %m0, %N1"
2ad65b0e 5692 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
5693
5694(define_split
73a4d10b 5695 [(set (match_operand:DF 0 "arith_reg_dest" "")
fa5322fa
AO
5696 (match_operand:DF 1 "immediate_operand" ""))]
5697 "TARGET_SHMEDIA && reload_completed"
5698 [(set (match_dup 3) (match_dup 2))]
5699 "
5700{
5701 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5702 long values[2];
5703 REAL_VALUE_TYPE value;
5704
5705 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5706 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5707
5708 if (HOST_BITS_PER_WIDE_INT >= 64)
5709 operands[2] = immed_double_const ((unsigned long) values[endian]
5710 | ((HOST_WIDE_INT) values[1 - endian]
5711 << 32), 0, DImode);
fa5322fa 5712 else
f5b9e7c9
NS
5713 {
5714 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5715 operands[2] = immed_double_const (values[endian], values[1 - endian],
5716 DImode);
5717 }
fa5322fa
AO
5718
5719 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5720}")
5721
ffae286a 5722;; ??? This should be a define expand.
bc45ade3 5723
bc45ade3 5724(define_insn "movdf_k"
3e943b59
JR
5725 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5726 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
fa5322fa 5727 "TARGET_SH1
157371cf 5728 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
fa5322fa
AO
5729 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5730 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5731 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
225e4f43
R
5732 && (arith_reg_operand (operands[0], DFmode)
5733 || arith_reg_operand (operands[1], DFmode))"
0d7e008e 5734 "* return output_movedouble (insn, operands, DFmode);"
b9654711 5735 [(set_attr "length" "4")
3e943b59 5736 (set_attr "type" "move,pcload,load,store")])
bc45ade3 5737
225e4f43
R
5738;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5739;; However, the d/F/c/z alternative cannot be split directly; it is converted
5740;; with special code in machine_dependent_reorg into a load of the R0_REG and
5741;; the d/m/c/X alternative, which is split later into single-precision
5742;; instructions. And when not optimizing, no splits are done before fixing
5743;; up pcloads, so we need usable length information for that.
5744(define_insn "movdf_i4"
5745 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5746 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5747 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5748 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
157371cf 5749 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
225e4f43
R
5750 && (arith_reg_operand (operands[0], DFmode)
5751 || arith_reg_operand (operands[1], DFmode))"
5752 "@
5753 fmov %1,%0
5754 #
5755 #
5756 fmov.d %1,%0
5757 fmov.d %1,%0
5758 #
5759 #
5760 #
5761 #
5762 #"
5763 [(set_attr_alternative "length"
5764 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5765 (const_int 4)
5766 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
157371cf
AO
5767 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5768 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
225e4f43
R
5769 (const_int 4)
5770 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
fa5322fa
AO
5771 ;; We can't use 4-byte push/pop on SHcompact, so we have to
5772 ;; increment or decrement r15 explicitly.
5773 (if_then_else
5774 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5775 (const_int 10) (const_int 8))
5776 (if_then_else
5777 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5778 (const_int 10) (const_int 8))])
c49439f1
R
5779 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5780 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
d64264ff
R
5781 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5782 (const_string "double")
5783 (const_string "none")))])
225e4f43
R
5784
5785;; Moving DFmode between fp/general registers through memory
5786;; (the top of the stack) is faster than moving through fpul even for
5787;; little endian. Because the type of an instruction is important for its
5788;; scheduling, it is beneficial to split these operations, rather than
5789;; emitting them in one single chunk, even if this will expose a stack
5790;; use that will prevent scheduling of other stack accesses beyond this
5791;; instruction.
5792(define_split
5793 [(set (match_operand:DF 0 "register_operand" "")
5794 (match_operand:DF 1 "register_operand" ""))
e69d1422 5795 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43 5796 (clobber (match_scratch:SI 3 "=X"))]
157371cf 5797 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
225e4f43
R
5798 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5799 [(const_int 0)]
5800 "
5801{
5802 rtx insn, tos;
5803
fa5322fa
AO
5804 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5805 {
5806 emit_move_insn (stack_pointer_rtx,
5807 plus_constant (stack_pointer_rtx, -8));
57d38024 5808 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
fa5322fa
AO
5809 }
5810 else
57d38024
R
5811 tos = gen_tmp_stack_mem (DFmode,
5812 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
225e4f43 5813 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
fa5322fa 5814 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
c0d4e710 5815 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
fa5322fa 5816 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
57d38024 5817 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
fa5322fa 5818 else
57d38024
R
5819 tos = gen_tmp_stack_mem (DFmode,
5820 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
225e4f43 5821 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
fa5322fa
AO
5822 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5823 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5824 else
c0d4e710 5825 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
225e4f43
R
5826 DONE;
5827}")
5828
5829;; local-alloc sometimes allocates scratch registers even when not required,
5830;; so we must be prepared to handle these.
5831
5832;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5833(define_split
5834 [(set (match_operand:DF 0 "general_movdst_operand" "")
5835 (match_operand:DF 1 "general_movsrc_operand" ""))
e69d1422
R
5836 (use (match_operand:PSI 2 "fpscr_operand" ""))
5837 (clobber (match_scratch:SI 3 ""))]
157371cf 5838 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
225e4f43
R
5839 && reload_completed
5840 && true_regnum (operands[0]) < 16
5841 && true_regnum (operands[1]) < 16"
5842 [(set (match_dup 0) (match_dup 1))]
5843 "
5844{
5845 /* If this was a reg <-> mem operation with base + index reg addressing,
5846 we have to handle this in a special way. */
5847 rtx mem = operands[0];
5848 int store_p = 1;
5849 if (! memory_operand (mem, DFmode))
5850 {
5851 mem = operands[1];
5852 store_p = 0;
5853 }
ddef6bc7 5854 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
225e4f43
R
5855 mem = SUBREG_REG (mem);
5856 if (GET_CODE (mem) == MEM)
5857 {
5858 rtx addr = XEXP (mem, 0);
5859 if (GET_CODE (addr) == PLUS
5860 && GET_CODE (XEXP (addr, 0)) == REG
5861 && GET_CODE (XEXP (addr, 1)) == REG)
5862 {
5863 int offset;
c0d4e710 5864 rtx reg0 = gen_rtx_REG (Pmode, 0);
225e4f43
R
5865 rtx regop = operands[store_p], word0 ,word1;
5866
5867 if (GET_CODE (regop) == SUBREG)
4dd8c093 5868 alter_subreg (&regop);
225e4f43
R
5869 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5870 offset = 2;
5871 else
5872 offset = 4;
5873 mem = copy_rtx (mem);
5874 PUT_MODE (mem, SImode);
c0d4e710 5875 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4dd8c093 5876 alter_subreg (&word0);
c0d4e710 5877 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4dd8c093 5878 alter_subreg (&word1);
18a7c2a7
AO
5879 if (store_p || ! refers_to_regno_p (REGNO (word0),
5880 REGNO (word0) + 1, addr, 0))
5881 {
5882 emit_insn (store_p
5883 ? gen_movsi_ie (mem, word0)
5884 : gen_movsi_ie (word0, mem));
5885 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5886 mem = copy_rtx (mem);
5887 emit_insn (store_p
5888 ? gen_movsi_ie (mem, word1)
5889 : gen_movsi_ie (word1, mem));
5890 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5891 }
5892 else
5893 {
5894 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5895 emit_insn (gen_movsi_ie (word1, mem));
5896 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5897 mem = copy_rtx (mem);
5898 emit_insn (gen_movsi_ie (word0, mem));
5899 }
225e4f43
R
5900 DONE;
5901 }
5902 }
5903}")
5904
5905;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5906(define_split
5907 [(set (match_operand:DF 0 "register_operand" "")
5908 (match_operand:DF 1 "memory_operand" ""))
e69d1422 5909 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 5910 (clobber (reg:SI R0_REG))]
157371cf 5911 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
225e4f43
R
5912 [(parallel [(set (match_dup 0) (match_dup 1))
5913 (use (match_dup 2))
5914 (clobber (scratch:SI))])]
5915 "")
5916
8a99f6f9
R
5917(define_expand "reload_indf__frn"
5918 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
225e4f43 5919 (match_operand:DF 1 "immediate_operand" "FQ"))
4773afa4 5920 (use (reg:PSI FPSCR_REG))
225e4f43 5921 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 5922 "TARGET_SH1"
225e4f43
R
5923 "")
5924
8a99f6f9 5925(define_expand "reload_outdf__RnFRm"
225e4f43
R
5926 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5927 (match_operand:DF 1 "register_operand" "af,r"))
5928 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
fa5322fa 5929 "TARGET_SH1"
225e4f43
R
5930 "")
5931
5932;; Simplify no-op moves.
5933(define_split
5934 [(set (match_operand:SF 0 "register_operand" "")
5935 (match_operand:SF 1 "register_operand" ""))
5936 (use (match_operand:PSI 2 "fpscr_operand" ""))
40779a72 5937 (clobber (match_scratch:SI 3 ""))]
3a8699c7 5938 "TARGET_SH2E && reload_completed
225e4f43
R
5939 && true_regnum (operands[0]) == true_regnum (operands[1])"
5940 [(set (match_dup 0) (match_dup 0))]
5941 "")
5942
5943;; fmovd substitute post-reload splits
5944(define_split
5945 [(set (match_operand:DF 0 "register_operand" "")
5946 (match_operand:DF 1 "register_operand" ""))
e69d1422 5947 (use (match_operand:PSI 2 "fpscr_operand" ""))
40779a72 5948 (clobber (match_scratch:SI 3 ""))]
225e4f43 5949 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b
AO
5950 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5951 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
5952 [(const_int 0)]
5953 "
5954{
5955 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
c0d4e710
KH
5956 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5957 gen_rtx_REG (SFmode, src), operands[2]));
5958 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5959 gen_rtx_REG (SFmode, src + 1), operands[2]));
225e4f43
R
5960 DONE;
5961}")
5962
5963(define_split
5964 [(set (match_operand:DF 0 "register_operand" "")
5965 (mem:DF (match_operand:SI 1 "register_operand" "")))
e69d1422
R
5966 (use (match_operand:PSI 2 "fpscr_operand" ""))
5967 (clobber (match_scratch:SI 3 ""))]
157371cf 5968 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
b6c02328 5969 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
225e4f43
R
5970 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5971 [(const_int 0)]
5972 "
5973{
5974 int regno = true_regnum (operands[0]);
5975 rtx insn;
57d38024
R
5976 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5977 rtx mem2
5978 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
c0d4e710 5979 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
225e4f43
R
5980 regno + !! TARGET_LITTLE_ENDIAN),
5981 mem2, operands[2]));
c0d4e710
KH
5982 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5983 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
57d38024
R
5984 regno + ! TARGET_LITTLE_ENDIAN),
5985 change_address (mem, SFmode, NULL_RTX),
225e4f43
R
5986 operands[2]));
5987 DONE;
5988}")
5989
5990(define_split
5991 [(set (match_operand:DF 0 "register_operand" "")
5992 (match_operand:DF 1 "memory_operand" ""))
e69d1422
R
5993 (use (match_operand:PSI 2 "fpscr_operand" ""))
5994 (clobber (match_scratch:SI 3 ""))]
157371cf 5995 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
104ee20b 5996 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
225e4f43
R
5997 [(const_int 0)]
5998 "
5999{
6000 int regno = true_regnum (operands[0]);
6001 rtx addr, insn, adjust = NULL_RTX;
57d38024 6002 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
225e4f43
R
6003 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6004 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6005
225e4f43
R
6006 operands[1] = copy_rtx (mem2);
6007 addr = XEXP (mem2, 0);
6008 if (GET_CODE (addr) != POST_INC)
6009 {
6010 /* If we have to modify the stack pointer, the value that we have
6011 read with post-increment might be modified by an interrupt,
6012 so write it back. */
6013 if (REGNO (addr) == STACK_POINTER_REGNUM)
6014 adjust = gen_push_e (reg0);
6015 else
6016 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6017 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6018 }
6019 addr = XEXP (addr, 0);
6020 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6021 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6022 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6023 if (adjust)
6024 emit_insn (adjust);
6025 else
6026 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6027 DONE;
6028}")
6029
6030(define_split
6031 [(set (match_operand:DF 0 "memory_operand" "")
6032 (match_operand:DF 1 "register_operand" ""))
e69d1422
R
6033 (use (match_operand:PSI 2 "fpscr_operand" ""))
6034 (clobber (match_scratch:SI 3 ""))]
157371cf 6035 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
104ee20b 6036 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
6037 [(const_int 0)]
6038 "
6039{
6040 int regno = true_regnum (operands[1]);
6041 rtx insn, addr, adjust = NULL_RTX;
6042
6043 operands[0] = copy_rtx (operands[0]);
6044 PUT_MODE (operands[0], SFmode);
6045 insn = emit_insn (gen_movsf_ie (operands[0],
c0d4e710 6046 gen_rtx_REG (SFmode,
225e4f43
R
6047 regno + ! TARGET_LITTLE_ENDIAN),
6048 operands[2]));
6049 operands[0] = copy_rtx (operands[0]);
6050 addr = XEXP (operands[0], 0);
6051 if (GET_CODE (addr) != PRE_DEC)
6052 {
6053 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6054 emit_insn_before (adjust, insn);
c0d4e710 6055 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
225e4f43
R
6056 }
6057 addr = XEXP (addr, 0);
6058 if (! adjust)
c0d4e710 6059 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
225e4f43 6060 insn = emit_insn (gen_movsf_ie (operands[0],
c0d4e710 6061 gen_rtx_REG (SFmode,
225e4f43
R
6062 regno + !! TARGET_LITTLE_ENDIAN),
6063 operands[2]));
c0d4e710 6064 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
225e4f43
R
6065 DONE;
6066}")
6067
d0aae509 6068;; If the output is a register and the input is memory or a register, we have
52702ae1 6069;; to be careful and see which word needs to be loaded first.
07a45e5c 6070
8e87e161
SC
6071(define_split
6072 [(set (match_operand:DF 0 "general_movdst_operand" "")
6073 (match_operand:DF 1 "general_movsrc_operand" ""))]
fa5322fa 6074 "TARGET_SH1 && reload_completed"
8e87e161
SC
6075 [(set (match_dup 2) (match_dup 3))
6076 (set (match_dup 4) (match_dup 5))]
6077 "
d0aae509
RK
6078{
6079 int regno;
6080
6081 if ((GET_CODE (operands[0]) == MEM
6082 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6083 || (GET_CODE (operands[1]) == MEM
6084 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6085 FAIL;
6086
f5b9e7c9
NS
6087 switch (GET_CODE (operands[0]))
6088 {
6089 case REG:
6090 regno = REGNO (operands[0]);
6091 break;
6092 case SUBREG:
6093 regno = subreg_regno (operands[0]);
6094 break;
6095 case MEM:
6096 regno = -1;
6097 break;
6098 default:
6099 gcc_unreachable ();
6100 }
d0aae509
RK
6101
6102 if (regno == -1
6103 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
6104 {
6105 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6106 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6107 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6108 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6109 }
6110 else
6111 {
6112 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6113 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6114 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6115 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6116 }
6117
6118 if (operands[2] == 0 || operands[3] == 0
6119 || operands[4] == 0 || operands[5] == 0)
6120 FAIL;
6121}")
6122
653bd7a6
JW
6123;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6124;; used only once, let combine add in the index again.
6125
6126(define_split
6127 [(set (match_operand:SI 0 "register_operand" "")
6128 (match_operand:SI 1 "" ""))
6129 (clobber (match_operand 2 "register_operand" ""))]
73a4d10b
R
6130 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6131 && ALLOW_INDEXED_ADDRESS"
4773afa4 6132 [(use (reg:SI R0_REG))]
653bd7a6
JW
6133 "
6134{
6135 rtx addr, reg, const_int;
6136
6137 if (GET_CODE (operands[1]) != MEM)
6138 FAIL;
6139 addr = XEXP (operands[1], 0);
6140 if (GET_CODE (addr) != PLUS)
6141 FAIL;
6142 reg = XEXP (addr, 0);
6143 const_int = XEXP (addr, 1);
f295bdb5
AH
6144 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6145 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
6146 FAIL;
6147 emit_move_insn (operands[2], const_int);
6148 emit_move_insn (operands[0],
6149 change_address (operands[1], VOIDmode,
c5c76735 6150 gen_rtx_PLUS (SImode, reg, operands[2])));
653bd7a6
JW
6151 DONE;
6152}")
6153
6154(define_split
6155 [(set (match_operand:SI 1 "" "")
6156 (match_operand:SI 0 "register_operand" ""))
6157 (clobber (match_operand 2 "register_operand" ""))]
73a4d10b
R
6158 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6159 && ALLOW_INDEXED_ADDRESS"
4773afa4 6160 [(use (reg:SI R0_REG))]
653bd7a6
JW
6161 "
6162{
6163 rtx addr, reg, const_int;
6164
6165 if (GET_CODE (operands[1]) != MEM)
6166 FAIL;
6167 addr = XEXP (operands[1], 0);
6168 if (GET_CODE (addr) != PLUS)
6169 FAIL;
6170 reg = XEXP (addr, 0);
6171 const_int = XEXP (addr, 1);
f295bdb5
AH
6172 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6173 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
6174 FAIL;
6175 emit_move_insn (operands[2], const_int);
6176 emit_move_insn (change_address (operands[1], VOIDmode,
c5c76735 6177 gen_rtx_PLUS (SImode, reg, operands[2])),
653bd7a6
JW
6178 operands[0]);
6179 DONE;
6180}")
6181
bc45ade3 6182(define_expand "movdf"
0d7e008e
SC
6183 [(set (match_operand:DF 0 "general_movdst_operand" "")
6184 (match_operand:DF 1 "general_movsrc_operand" ""))]
bc45ade3 6185 ""
1245df60
R
6186 "
6187{
6188 if (prepare_move_operands (operands, DFmode)) DONE;
fa5322fa
AO
6189 if (TARGET_SHMEDIA)
6190 {
6191 if (TARGET_SHMEDIA_FPU)
6192 emit_insn (gen_movdf_media (operands[0], operands[1]));
6193 else
6194 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6195 DONE;
6196 }
157371cf 6197 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
225e4f43
R
6198 {
6199 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
6200 DONE;
6201 }
1245df60
R
6202}")
6203
0ac78517
R
6204;;This is incompatible with the way gcc uses subregs.
6205;;(define_insn "movv2sf_i"
6206;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6207;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6208;; "TARGET_SHMEDIA_FPU
6209;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6210;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6211;; "@
6212;; #
6213;; fld%M1.p %m1, %0
6214;; fst%M0.p %m0, %1"
6215;; [(set_attr "type" "*,fload_media,fstore_media")])
6216
6217(define_insn_and_split "movv2sf_i"
6218 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
735cb76e 6219 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
0ac78517
R
6220 "TARGET_SHMEDIA_FPU"
6221 "#"
6222 "TARGET_SHMEDIA_FPU && reload_completed"
6223 [(set (match_dup 0) (match_dup 1))]
6224 "
6225{
6226 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6227 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6228}")
fa5322fa
AO
6229
6230(define_expand "movv2sf"
0ac78517
R
6231 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6232 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
fa5322fa
AO
6233 "TARGET_SHMEDIA_FPU"
6234 "
6235{
6236 if (prepare_move_operands (operands, V2SFmode))
6237 DONE;
6238}")
6239
0ac78517
R
6240(define_expand "addv2sf3"
6241 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6242 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6243 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6244 "TARGET_SHMEDIA_FPU"
6245 "
6246{
6247 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6248 DONE;
6249}")
6250
6251(define_expand "subv2sf3"
6252 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6253 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6254 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6255 "TARGET_SHMEDIA_FPU"
6256 "
6257{
6258 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6259 DONE;
6260}")
6261
6262(define_expand "mulv2sf3"
6263 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6264 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6265 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6266 "TARGET_SHMEDIA_FPU"
6267 "
6268{
6269 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6270 DONE;
6271}")
6272
6273(define_expand "divv2sf3"
6274 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6275 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6276 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6277 "TARGET_SHMEDIA_FPU"
6278 "
6279{
6280 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6281 DONE;
6282}")
6283
fa5322fa 6284(define_insn_and_split "*movv4sf_i"
18943792
KK
6285 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6286 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
fa5322fa
AO
6287 "TARGET_SHMEDIA_FPU"
6288 "#"
6289 "&& reload_completed"
6290 [(const_int 0)]
6291 "
6292{
6293 int i;
6294
6295 for (i = 0; i < 4/2; i++)
6296 {
6297 rtx x, y;
6298
6299 if (GET_CODE (operands[0]) == MEM)
57d38024
R
6300 x = adjust_address (operands[0], V2SFmode,
6301 i * GET_MODE_SIZE (V2SFmode));
fa5322fa 6302 else
0ac78517 6303 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
fa5322fa
AO
6304
6305 if (GET_CODE (operands[1]) == MEM)
57d38024
R
6306 y = adjust_address (operands[1], V2SFmode,
6307 i * GET_MODE_SIZE (V2SFmode));
fa5322fa 6308 else
0ac78517 6309 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
fa5322fa
AO
6310
6311 emit_insn (gen_movv2sf_i (x, y));
6312 }
6313
6314 DONE;
6315}"
6316 [(set_attr "length" "8")])
52702ae1 6317
fa5322fa 6318(define_expand "movv4sf"
0ac78517
R
6319 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6320 (match_operand:V4SF 1 "general_operand" ""))]
fa5322fa
AO
6321 "TARGET_SHMEDIA_FPU"
6322 "
6323{
6324 if (prepare_move_operands (operands, V4SFmode))
6325 DONE;
6326}")
6327
6328(define_insn_and_split "*movv16sf_i"
6329 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6330 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6331 "TARGET_SHMEDIA_FPU"
6332 "#"
6333 "&& reload_completed"
6334 [(const_int 0)]
6335 "
6336{
6337 int i;
6338
6339 for (i = 0; i < 16/2; i++)
6340 {
6341 rtx x,y;
6342
6343 if (GET_CODE (operands[0]) == MEM)
57d38024
R
6344 x = adjust_address (operands[0], V2SFmode,
6345 i * GET_MODE_SIZE (V2SFmode));
fa5322fa
AO
6346 else
6347 {
40779a72 6348 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
fa5322fa
AO
6349 alter_subreg (&x);
6350 }
6351
6352 if (GET_CODE (operands[1]) == MEM)
57d38024
R
6353 y = adjust_address (operands[1], V2SFmode,
6354 i * GET_MODE_SIZE (V2SFmode));
fa5322fa
AO
6355 else
6356 {
40779a72 6357 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
fa5322fa
AO
6358 alter_subreg (&y);
6359 }
6360
6361 emit_insn (gen_movv2sf_i (x, y));
6362 }
6363
6364 DONE;
6365}"
6366 [(set_attr "length" "32")])
52702ae1 6367
fa5322fa
AO
6368(define_expand "movv16sf"
6369 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6370 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6371 "TARGET_SHMEDIA_FPU"
6372 "
6373{
6374 if (prepare_move_operands (operands, V16SFmode))
6375 DONE;
6376}")
6377
6378(define_insn "movsf_media"
6379 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 6380 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
6381 "TARGET_SHMEDIA_FPU
6382 && (register_operand (operands[0], SFmode)
d9da94a1 6383 || sh_register_operand (operands[1], SFmode))"
fa5322fa
AO
6384 "@
6385 fmov.s %1, %0
0ac78517 6386 fmov.ls %N1, %0
fa5322fa 6387 fmov.sl %1, %0
b6d33983 6388 add.l %1, r63, %0
fa5322fa
AO
6389 #
6390 fld%M1.s %m1, %0
6391 fst%M0.s %m0, %1
6392 ld%M1.l %m1, %0
d9da94a1 6393 st%M0.l %m0, %N1"
73a4d10b
R
6394 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6395 (set (attr "highpart")
6396 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6397 (const_string "user")]
6398 (const_string "ignore")))])
fa5322fa
AO
6399
6400(define_insn "movsf_media_nofpu"
6401 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 6402 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
6403 "TARGET_SHMEDIA
6404 && (register_operand (operands[0], SFmode)
d9da94a1 6405 || sh_register_operand (operands[1], SFmode))"
fa5322fa 6406 "@
b6d33983 6407 add.l %1, r63, %0
fa5322fa
AO
6408 #
6409 ld%M1.l %m1, %0
d9da94a1 6410 st%M0.l %m0, %N1"
73a4d10b
R
6411 [(set_attr "type" "arith_media,*,load_media,store_media")
6412 (set (attr "highpart")
6413 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6414 (const_string "user")]
6415 (const_string "ignore")))])
fa5322fa
AO
6416
6417(define_split
73a4d10b 6418 [(set (match_operand:SF 0 "arith_reg_dest" "")
fa5322fa 6419 (match_operand:SF 1 "immediate_operand" ""))]
0ac78517
R
6420 "TARGET_SHMEDIA && reload_completed
6421 && ! FP_REGISTER_P (true_regnum (operands[0]))"
fa5322fa
AO
6422 [(set (match_dup 3) (match_dup 2))]
6423 "
6424{
6425 long values;
6426 REAL_VALUE_TYPE value;
6427
6428 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6429 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6430 operands[2] = GEN_INT (values);
52702ae1 6431
fa5322fa
AO
6432 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6433}")
bc45ade3 6434
bc45ade3 6435(define_insn "movsf_i"
3e943b59 6436 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
735cb76e 6437 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
fa5322fa 6438 "TARGET_SH1
3a8699c7 6439 && (! TARGET_SH2E
fa5322fa
AO
6440 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6441 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6442 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
1245df60
R
6443 && (arith_reg_operand (operands[0], SFmode)
6444 || arith_reg_operand (operands[1], SFmode))"
bc45ade3
SC
6445 "@
6446 mov %1,%0
735cb76e 6447 mov #0,%0
bc45ade3
SC
6448 mov.l %1,%0
6449 mov.l %1,%0
3e943b59 6450 mov.l %1,%0
b9654711 6451 lds %1,%0
0d7e008e 6452 sts %1,%0"
3e943b59 6453 [(set_attr "type" "move,move,pcload,load,store,move,move")])
bc45ade3 6454
4dff12bf
R
6455;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6456;; update_flow_info would not know where to put REG_EQUAL notes
6457;; when the destination changes mode.
45348d9e 6458(define_insn "movsf_ie"
7f74cc8d 6459 [(set (match_operand:SF 0 "general_movdst_operand"
a92facbb 6460 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
7f74cc8d 6461 (match_operand:SF 1 "general_movsrc_operand"
a92facbb
AO
6462 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6463 (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 6464 (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 6465
3a8699c7 6466 "TARGET_SH2E
45348d9e 6467 && (arith_reg_operand (operands[0], SFmode)
c2d10707
AO
6468 || arith_reg_operand (operands[1], SFmode)
6469 || arith_reg_operand (operands[3], SImode)
6470 || (fpul_operand (operands[0], SFmode)
6471 && memory_operand (operands[1], SFmode)
6472 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6473 || (fpul_operand (operands[1], SFmode)
6474 && memory_operand (operands[0], SFmode)
6475 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
45348d9e
JW
6476 "@
6477 fmov %1,%0
6478 mov %1,%0
6479 fldi0 %0
6480 fldi1 %0
7f74cc8d 6481 #
45348d9e
JW
6482 fmov.s %1,%0
6483 fmov.s %1,%0
6484 mov.l %1,%0
6485 mov.l %1,%0
3e943b59 6486 mov.l %1,%0
1245df60
R
6487 fsts fpul,%0
6488 flds %1,fpul
6489 lds.l %1,%0
6490 #
4dff12bf
R
6491 sts %1,%0
6492 lds %1,%0
a92facbb
AO
6493 sts.l %1,%0
6494 lds.l %1,%0
4dff12bf 6495 ! move optimized away"
c49439f1
R
6496 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6497 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
157371cf 6498 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
d64264ff
R
6499 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6500 (const_string "single")
6501 (const_string "none")))])
79664856 6502
1245df60
R
6503(define_split
6504 [(set (match_operand:SF 0 "register_operand" "")
6505 (match_operand:SF 1 "register_operand" ""))
e69d1422 6506 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 6507 (clobber (reg:SI FPUL_REG))]
fa5322fa 6508 "TARGET_SH1"
4773afa4 6509 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
225e4f43 6510 (use (match_dup 2))
1245df60 6511 (clobber (scratch:SI))])
4773afa4 6512 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
225e4f43 6513 (use (match_dup 2))
1245df60
R
6514 (clobber (scratch:SI))])]
6515 "")
6516
bc45ade3 6517(define_expand "movsf"
0d7e008e 6518 [(set (match_operand:SF 0 "general_movdst_operand" "")
3e943b59 6519 (match_operand:SF 1 "general_movsrc_operand" ""))]
bc45ade3 6520 ""
3e943b59
JR
6521 "
6522{
6523 if (prepare_move_operands (operands, SFmode))
6524 DONE;
fa5322fa
AO
6525 if (TARGET_SHMEDIA)
6526 {
6527 if (TARGET_SHMEDIA_FPU)
6528 emit_insn (gen_movsf_media (operands[0], operands[1]));
6529 else
6530 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6531 DONE;
6532 }
3a8699c7 6533 if (TARGET_SH2E)
3e943b59 6534 {
225e4f43 6535 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
3e943b59
JR
6536 DONE;
6537 }
6538}")
7f74cc8d 6539
225e4f43 6540(define_insn "mov_nop"
e69d1422 6541 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
3a8699c7 6542 "TARGET_SH2E"
225e4f43
R
6543 ""
6544 [(set_attr "length" "0")
6545 (set_attr "type" "nil")])
6546
8a99f6f9 6547(define_expand "reload_insf__frn"
c2d10707 6548 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
7f74cc8d 6549 (match_operand:SF 1 "immediate_operand" "FQ"))
4773afa4 6550 (use (reg:PSI FPSCR_REG))
7f74cc8d 6551 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 6552 "TARGET_SH1"
7f74cc8d 6553 "")
225e4f43 6554
8a99f6f9 6555(define_expand "reload_insi__i_fpul"
73a4d10b
R
6556 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6557 (match_operand:SI 1 "immediate_operand" "i"))
225e4f43 6558 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 6559 "TARGET_SH1"
225e4f43
R
6560 "")
6561
73a4d10b
R
6562(define_expand "ptabs"
6563 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6564 "TARGET_SHMEDIA"
6565 "
6566{
6567 if (!TARGET_PT_FIXED)
6568 {
6569 rtx eq = operands[1];
6570
6571 /* ??? For canonical RTL we really should remove any CONST from EQ
6572 before wrapping it in the AND, and finally wrap the EQ into a
6573 const if is constant. However, for reload we must expose the
6574 input register or symbolic constant, and we can't have
6575 different insn structures outside of the operands for different
6576 alternatives of the same pattern. */
6577 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6578 GEN_INT (3));
6579 operands[1]
6580 = (gen_rtx_IF_THEN_ELSE
6581 (PDImode,
6582 eq,
6583 gen_rtx_MEM (PDImode, operands[1]),
6584 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6585 PDImode, operands[1])));
6586 }
6587}")
6588
6589;; expanded by ptabs expander.
6590(define_insn "*extendsipdi_media"
6591 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6592 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6593 "r,Csy")
6594 (const_int 3))
6595 (const_int 3))
6596 (mem:PDI (match_dup 1))
6597 (sign_extend:PDI (match_dup 1))))]
6598 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6599 "@
6600 ptabs %1, %0
6601 pt %1, %0"
6602 [(set_attr "type" "ptabs_media,pt_media")
6603 (set_attr "length" "4,*")])
6604
6605(define_insn "*truncdipdi_media"
6606 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6607 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6608 "r,Csy")
6609 (const_int 3))
6610 (const_int 3))
6611 (mem:PDI (match_dup 1))
6612 (truncate:PDI (match_dup 1))))]
6613 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6614 "@
6615 ptabs %1, %0
6616 pt %1, %0"
6617 [(set_attr "type" "ptabs_media,pt_media")
6618 (set_attr "length" "4,*")])
6619
225e4f43
R
6620(define_insn "*movsi_y"
6621 [(set (match_operand:SI 0 "register_operand" "=y,y")
735cb76e 6622 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
c77e04ae 6623 (clobber (match_scratch:SI 2 "=&z,r"))]
3a8699c7 6624 "TARGET_SH2E
225e4f43
R
6625 && (reload_in_progress || reload_completed)"
6626 "#"
6627 [(set_attr "length" "4")
6628 (set_attr "type" "pcload,move")])
6629
6630(define_split
997718c7
RH
6631 [(set (match_operand:SI 0 "register_operand" "")
6632 (match_operand:SI 1 "immediate_operand" ""))
6633 (clobber (match_operand:SI 2 "register_operand" ""))]
fa5322fa 6634 "TARGET_SH1"
225e4f43
R
6635 [(set (match_dup 2) (match_dup 1))
6636 (set (match_dup 0) (match_dup 2))]
6637 "")
6638
6639(define_split
997718c7
RH
6640 [(set (match_operand:SI 0 "register_operand" "")
6641 (match_operand:SI 1 "memory_operand" ""))
4773afa4 6642 (clobber (reg:SI R0_REG))]
fa5322fa 6643 "TARGET_SH1"
225e4f43
R
6644 [(set (match_dup 0) (match_dup 1))]
6645 "")
bc45ade3
SC
6646\f
6647;; ------------------------------------------------------------------------
6648;; Define the real conditional branch instructions.
6649;; ------------------------------------------------------------------------
6650
6651(define_insn "branch_true"
4773afa4 6652 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
6653 (label_ref (match_operand 0 "" ""))
6654 (pc)))]
fa5322fa 6655 "TARGET_SH1"
51aea58d 6656 "* return output_branch (1, insn, operands);"
bc45ade3
SC
6657 [(set_attr "type" "cbranch")])
6658
6659(define_insn "branch_false"
4773afa4 6660 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
bc45ade3
SC
6661 (label_ref (match_operand 0 "" ""))
6662 (pc)))]
fa5322fa 6663 "TARGET_SH1"
51aea58d 6664 "* return output_branch (0, insn, operands);"
bc45ade3
SC
6665 [(set_attr "type" "cbranch")])
6666
1245df60
R
6667;; Patterns to prevent reorg from re-combining a condbranch with a branch
6668;; which destination is too far away.
6669;; The const_int_operand is distinct for each branch target; it avoids
6670;; unwanted matches with redundant_insn.
6671(define_insn "block_branch_redirect"
e11cddec 6672 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
fa5322fa 6673 "TARGET_SH1"
1245df60
R
6674 ""
6675 [(set_attr "length" "0")])
bc45ade3 6676
1245df60
R
6677;; This one has the additional purpose to record a possible scratch register
6678;; for the following branch.
10f4f635
R
6679;; ??? Unfortunately, just setting the scratch register is not good enough,
6680;; because the insn then might be deemed dead and deleted. And we can't
6681;; make the use in the jump insn explicit because that would disable
6682;; delay slot scheduling from the target.
1245df60 6683(define_insn "indirect_jump_scratch"
e69d1422 6684 [(set (match_operand:SI 0 "register_operand" "=r")
73774972 6685 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
10f4f635 6686 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
fa5322fa 6687 "TARGET_SH1"
1245df60
R
6688 ""
6689 [(set_attr "length" "0")])
c608a684
R
6690
6691;; This one is used to preemt an insn from beyond the bra / braf / jmp
6692;; being pulled into the delay slot of a condbranch that has been made to
6693;; jump around the unconditional jump because it was out of range.
6694(define_insn "stuff_delay_slot"
6695 [(set (pc)
73a4d10b
R
6696 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6697 (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
c608a684
R
6698 "TARGET_SH1"
6699 ""
6700 [(set_attr "length" "0")
6701 (set_attr "cond_delay_slot" "yes")])
bc45ade3
SC
6702\f
6703;; Conditional branch insns
6704
fa5322fa 6705(define_expand "beq_media"
1245df60 6706 [(set (pc)
fa5322fa 6707 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 6708 (match_operand:DI 2 "arith_operand" "r,I06"))
73a4d10b 6709 (match_operand 0 "" "")
bc45ade3 6710 (pc)))]
fa5322fa 6711 "TARGET_SHMEDIA"
73a4d10b 6712 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
bc45ade3 6713
c8cc4417 6714(define_insn "*beq_media_i"
1245df60 6715 [(set (pc)
c8cc4417
R
6716 (if_then_else (match_operator 3 "equality_comparison_operator"
6717 [(match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 6718 (match_operand:DI 2 "arith_operand" "r,I06")])
73a4d10b
R
6719 (match_operand 0 "target_operand" "b,b")
6720 (pc)))]
6721 "TARGET_SHMEDIA"
6722 "@
6723 b%o3%' %1, %2, %0%>
6724 b%o3i%' %1, %2, %0%>"
6725 [(set_attr "type" "cbranch_media")])
6726
6727(define_insn "*beq_media_i32"
6728 [(set (pc)
6729 (if_then_else (match_operator 3 "equality_comparison_operator"
6730 [(match_operand:SI 1 "arith_reg_operand" "r,r")
6731 (match_operand:SI 2 "arith_operand" "r,I06")])
6732 (match_operand 0 "target_operand" "b,b")
1245df60 6733 (pc)))]
fa5322fa
AO
6734 "TARGET_SHMEDIA"
6735 "@
73a4d10b
R
6736 b%o3%' %1, %2, %0%>
6737 b%o3i%' %1, %2, %0%>"
c8cc4417 6738 [(set_attr "type" "cbranch_media")])
bc45ade3 6739
fa5322fa 6740(define_expand "bne_media"
1245df60 6741 [(set (pc)
fa5322fa 6742 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 6743 (match_operand:DI 2 "arith_operand" "r,I06"))
73a4d10b 6744 (match_operand 0 "" "")
ffae286a 6745 (pc)))]
fa5322fa 6746 "TARGET_SHMEDIA"
73a4d10b 6747 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
bc45ade3 6748
fa5322fa 6749(define_expand "bgt_media"
1245df60 6750 [(set (pc)
73a4d10b
R
6751 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6752 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6753 (match_operand 0 "" "")
1245df60 6754 (pc)))]
fa5322fa 6755 "TARGET_SHMEDIA"
73a4d10b 6756 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
fa5322fa 6757
fa5322fa
AO
6758(define_expand "bge_media"
6759 [(set (pc)
73a4d10b
R
6760 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6761 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6762 (match_operand 0 "" "")
fa5322fa
AO
6763 (pc)))]
6764 "TARGET_SHMEDIA"
73a4d10b 6765 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
fa5322fa 6766
fa5322fa
AO
6767(define_expand "bgtu_media"
6768 [(set (pc)
73a4d10b
R
6769 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6770 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6771 (match_operand 0 "" "")
fa5322fa
AO
6772 (pc)))]
6773 "TARGET_SHMEDIA"
73a4d10b 6774 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
fa5322fa 6775
fa5322fa
AO
6776(define_expand "bgeu_media"
6777 [(set (pc)
73a4d10b
R
6778 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6779 (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6780 (match_operand 0 "" "")
fa5322fa
AO
6781 (pc)))]
6782 "TARGET_SHMEDIA"
73a4d10b 6783 "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
fa5322fa 6784
c8cc4417 6785(define_insn "*bgt_media_i"
fa5322fa 6786 [(set (pc)
c8cc4417
R
6787 (if_then_else (match_operator 3 "greater_comparison_operator"
6788 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6789 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
73a4d10b
R
6790 (match_operand 0 "target_operand" "b")
6791 (pc)))]
6792 "TARGET_SHMEDIA"
6793 "b%o3%' %N1, %N2, %0%>"
6794 [(set_attr "type" "cbranch_media")])
6795
6796(define_insn "*bgt_media_i32"
6797 [(set (pc)
6798 (if_then_else (match_operator 3 "greater_comparison_operator"
6799 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6800 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6801 (match_operand 0 "target_operand" "b")
fa5322fa
AO
6802 (pc)))]
6803 "TARGET_SHMEDIA"
73a4d10b 6804 "b%o3%' %N1, %N2, %0%>"
c8cc4417 6805 [(set_attr "type" "cbranch_media")])
fa5322fa 6806
73a4d10b
R
6807;; These are only needed to make invert_jump() happy - otherwise, jump
6808;; optimization will be silently disabled.
b6d33983 6809(define_insn "*blt_media_i"
fa5322fa 6810 [(set (pc)
c8cc4417 6811 (if_then_else (match_operator 3 "less_comparison_operator"
b6d33983
R
6812 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6813 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
73a4d10b 6814 (match_operand 0 "target_operand" "b")
fa5322fa
AO
6815 (pc)))]
6816 "TARGET_SHMEDIA"
73a4d10b
R
6817 "b%o3%' %N2, %N1, %0%>"
6818 [(set_attr "type" "cbranch_media")])
6819
6820(define_insn "*blt_media_i32"
6821 [(set (pc)
6822 (if_then_else (match_operator 3 "less_comparison_operator"
6823 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6824 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6825 (match_operand 0 "target_operand" "b")
6826 (pc)))]
6827 "TARGET_SHMEDIA"
6828 "b%o3%' %N2, %N1, %0%>"
c8cc4417 6829 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
6830
6831(define_expand "beq"
6832 [(set (pc)
6833 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6834 (label_ref (match_operand 0 "" ""))
6835 (pc)))]
6836 ""
6837 "
6838{
6839 if (TARGET_SHMEDIA)
6840 {
73a4d10b
R
6841 enum machine_mode mode = GET_MODE (sh_compare_op0);
6842
6843 if (mode != DImode && mode != SImode)
fa5322fa
AO
6844 {
6845 rtx tmp = gen_reg_rtx (DImode);
6846
6847 emit_insn (gen_seq (tmp));
6848 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6849 DONE;
6850 }
6851
73a4d10b
R
6852 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6853 if (CONSTANT_P (sh_compare_op1)
6854 && (GET_CODE (sh_compare_op1) != CONST_INT
6855 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6856 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
6857 emit_jump_insn (gen_beq_media (operands[0],
6858 sh_compare_op0, sh_compare_op1));
6859 DONE;
6860 }
6861
6862 from_compare (operands, EQ);
6863}")
6864
6865(define_expand "bne"
6866 [(set (pc)
6867 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6868 (label_ref (match_operand 0 "" ""))
6869 (pc)))]
6870 ""
6871 "
6872{
6873 if (TARGET_SHMEDIA)
6874 {
73a4d10b
R
6875 enum machine_mode mode = GET_MODE (sh_compare_op0);
6876
6877 if (mode != DImode && mode != SImode)
fa5322fa
AO
6878 {
6879 rtx tmp = gen_reg_rtx (DImode);
6880
6881 emit_insn (gen_seq (tmp));
6882 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6883 DONE;
6884 }
6885
73a4d10b
R
6886 sh_compare_op0 = force_reg (mode, sh_compare_op0);
6887 if (CONSTANT_P (sh_compare_op1)
6888 && (GET_CODE (sh_compare_op1) != CONST_INT
6889 || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6890 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
6891 emit_jump_insn (gen_bne_media (operands[0],
6892 sh_compare_op0, sh_compare_op1));
6893 DONE;
6894 }
6895
6896 from_compare (operands, EQ);
6897}")
6898
6899(define_expand "bgt"
6900 [(set (pc)
6901 (if_then_else (ne (reg:SI T_REG) (const_int 0))
6902 (label_ref (match_operand 0 "" ""))
6903 (pc)))]
6904 ""
6905 "
6906{
6907 if (TARGET_SHMEDIA)
6908 {
73a4d10b
R
6909 enum machine_mode mode = GET_MODE (sh_compare_op0);
6910
6911 if (mode != DImode && mode != SImode)
fa5322fa
AO
6912 {
6913 rtx tmp = gen_reg_rtx (DImode);
6914
6915 emit_insn (gen_sgt (tmp));
6916 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6917 DONE;
6918 }
6919
c8cc4417 6920 if (sh_compare_op0 != const0_rtx)
73a4d10b 6921 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 6922 if (sh_compare_op1 != const0_rtx)
73a4d10b 6923 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
6924 emit_jump_insn (gen_bgt_media (operands[0],
6925 sh_compare_op0, sh_compare_op1));
6926 DONE;
6927 }
6928
6929 from_compare (operands, GT);
6930}")
6931
6932(define_expand "blt"
6933 [(set (pc)
6934 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6935 (label_ref (match_operand 0 "" ""))
6936 (pc)))]
6937 ""
6938 "
6939{
6940 if (TARGET_SHMEDIA)
6941 {
73a4d10b
R
6942 enum machine_mode mode = GET_MODE (sh_compare_op0);
6943
6944 if (mode != DImode && mode != SImode)
fa5322fa
AO
6945 {
6946 rtx tmp = gen_reg_rtx (DImode);
6947
6948 emit_insn (gen_slt (tmp));
6949 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6950 DONE;
6951 }
6952
c8cc4417 6953 if (sh_compare_op0 != const0_rtx)
73a4d10b 6954 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 6955 if (sh_compare_op1 != const0_rtx)
73a4d10b 6956 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
6957 emit_jump_insn (gen_bgt_media (operands[0],
6958 sh_compare_op1, sh_compare_op0));
6959 DONE;
6960 }
6961
6962 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6963 {
6964 rtx tmp = sh_compare_op0;
6965 sh_compare_op0 = sh_compare_op1;
6966 sh_compare_op1 = tmp;
6967 emit_insn (gen_bgt (operands[0]));
6968 DONE;
6969 }
6970 from_compare (operands, GE);
6971}")
6972
6973(define_expand "ble"
6974 [(set (pc)
6975 (if_then_else (eq (reg:SI T_REG) (const_int 0))
6976 (label_ref (match_operand 0 "" ""))
6977 (pc)))]
6978 ""
6979 "
6980{
6981 if (TARGET_SHMEDIA)
6982 {
73a4d10b
R
6983 enum machine_mode mode = GET_MODE (sh_compare_op0);
6984
6985 if (mode != DImode && mode != SImode)
fa5322fa
AO
6986 {
6987 rtx tmp = gen_reg_rtx (DImode);
6988
6989 emit_insn (gen_sle (tmp));
6990 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6991 DONE;
6992 }
6993
c8cc4417 6994 if (sh_compare_op0 != const0_rtx)
73a4d10b 6995 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 6996 if (sh_compare_op1 != const0_rtx)
73a4d10b 6997 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
6998 emit_jump_insn (gen_bge_media (operands[0],
6999 sh_compare_op1, sh_compare_op0));
7000 DONE;
7001 }
7002
3a8699c7 7003 if (TARGET_SH2E
fa5322fa 7004 && TARGET_IEEE
1245df60
R
7005 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7006 {
7007 rtx tmp = sh_compare_op0;
7008 sh_compare_op0 = sh_compare_op1;
7009 sh_compare_op1 = tmp;
7010 emit_insn (gen_bge (operands[0]));
7011 DONE;
7012 }
7013 from_compare (operands, GT);
7014}")
bc45ade3
SC
7015
7016(define_expand "bge"
1245df60 7017 [(set (pc)
4773afa4 7018 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 7019 (label_ref (match_operand 0 "" ""))
ffae286a 7020 (pc)))]
bc45ade3 7021 ""
45348d9e
JW
7022 "
7023{
fa5322fa
AO
7024 if (TARGET_SHMEDIA)
7025 {
73a4d10b
R
7026 enum machine_mode mode = GET_MODE (sh_compare_op0);
7027
7028 if (mode != DImode && mode != SImode)
fa5322fa
AO
7029 {
7030 rtx tmp = gen_reg_rtx (DImode);
7031
7032 emit_insn (gen_sge (tmp));
7033 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7034 DONE;
7035 }
7036
c8cc4417 7037 if (sh_compare_op0 != const0_rtx)
73a4d10b 7038 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 7039 if (sh_compare_op1 != const0_rtx)
73a4d10b 7040 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
7041 emit_jump_insn (gen_bge_media (operands[0],
7042 sh_compare_op0, sh_compare_op1));
7043 DONE;
7044 }
7045
3a8699c7 7046 if (TARGET_SH2E
1245df60
R
7047 && ! TARGET_IEEE
7048 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e
JW
7049 {
7050 rtx tmp = sh_compare_op0;
7051 sh_compare_op0 = sh_compare_op1;
7052 sh_compare_op1 = tmp;
7053 emit_insn (gen_ble (operands[0]));
7054 DONE;
7055 }
7056 from_compare (operands, GE);
7057}")
bc45ade3
SC
7058
7059(define_expand "bgtu"
1245df60 7060 [(set (pc)
4773afa4 7061 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
7062 (label_ref (match_operand 0 "" ""))
7063 (pc)))]
7064 ""
fa5322fa
AO
7065 "
7066{
7067 if (TARGET_SHMEDIA)
7068 {
73a4d10b
R
7069 enum machine_mode mode = GET_MODE (sh_compare_op0);
7070
c8cc4417 7071 if (sh_compare_op0 != const0_rtx)
73a4d10b 7072 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 7073 if (sh_compare_op1 != const0_rtx)
73a4d10b 7074 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
7075 emit_jump_insn (gen_bgtu_media (operands[0],
7076 sh_compare_op0, sh_compare_op1));
7077 DONE;
7078 }
7079
7080 from_compare (operands, GTU);
7081}")
bc45ade3
SC
7082
7083(define_expand "bltu"
1245df60 7084 [(set (pc)
4773afa4
AO
7085 (if_then_else (eq (reg:SI T_REG) (const_int 0))
7086 (label_ref (match_operand 0 "" ""))
7087 (pc)))]
bc45ade3 7088 ""
fa5322fa
AO
7089 "
7090{
7091 if (TARGET_SHMEDIA)
7092 {
73a4d10b
R
7093 enum machine_mode mode = GET_MODE (sh_compare_op0);
7094
c8cc4417 7095 if (sh_compare_op0 != const0_rtx)
73a4d10b 7096 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 7097 if (sh_compare_op1 != const0_rtx)
73a4d10b 7098 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
7099 emit_jump_insn (gen_bgtu_media (operands[0],
7100 sh_compare_op1, sh_compare_op0));
7101 DONE;
7102 }
7103
7104 from_compare (operands, GEU);
7105}")
bc45ade3
SC
7106
7107(define_expand "bgeu"
1245df60 7108 [(set (pc)
4773afa4 7109 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 7110 (label_ref (match_operand 0 "" ""))
ffae286a 7111 (pc)))]
bc45ade3 7112 ""
fa5322fa
AO
7113 "
7114{
7115 if (TARGET_SHMEDIA)
7116 {
73a4d10b
R
7117 enum machine_mode mode = GET_MODE (sh_compare_op0);
7118
c8cc4417 7119 if (sh_compare_op0 != const0_rtx)
73a4d10b 7120 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 7121 if (sh_compare_op1 != const0_rtx)
73a4d10b 7122 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
7123 emit_jump_insn (gen_bgeu_media (operands[0],
7124 sh_compare_op0, sh_compare_op1));
7125 DONE;
7126 }
7127
7128 from_compare (operands, GEU);
7129}")
bc45ade3
SC
7130
7131(define_expand "bleu"
1245df60 7132 [(set (pc)
4773afa4 7133 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1245df60
R
7134 (label_ref (match_operand 0 "" ""))
7135 (pc)))]
bc45ade3 7136 ""
fa5322fa
AO
7137 "
7138{
7139 if (TARGET_SHMEDIA)
7140 {
73a4d10b
R
7141 enum machine_mode mode = GET_MODE (sh_compare_op0);
7142
c8cc4417 7143 if (sh_compare_op0 != const0_rtx)
73a4d10b 7144 sh_compare_op0 = force_reg (mode, sh_compare_op0);
c8cc4417 7145 if (sh_compare_op1 != const0_rtx)
73a4d10b 7146 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa
AO
7147 emit_jump_insn (gen_bgeu_media (operands[0],
7148 sh_compare_op1, sh_compare_op0));
7149 DONE;
7150 }
7151
7152 from_compare (operands, GTU);
7153}")
7154
7155(define_expand "bunordered"
7156 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7157 (set (pc)
7158 (if_then_else (ne (match_dup 1) (const_int 0))
73a4d10b 7159 (match_operand 0 "" "")
fa5322fa
AO
7160 (pc)))]
7161 "TARGET_SHMEDIA"
7162 "
7163{
73a4d10b 7164 operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
fa5322fa
AO
7165 operands[1] = gen_reg_rtx (DImode);
7166 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7167 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7168}")
73a4d10b
R
7169
7170;; combiner splitter for test-and-branch on single bit in register. This
7171;; is endian dependent because the non-paradoxical subreg looks different
7172;; on big endian.
7173(define_split
7174 [(set (pc)
7175 (if_then_else
7176 (match_operator 3 "equality_comparison_operator"
7177 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7178 "extend_reg_operand" "")
7179 0)
7180 (const_int 1)
7181 (match_operand 2
7182 "const_int_operand" "")) 0)
7183 (const_int 0)])
7184 (match_operand 0 "target_operand" "")
7185 (pc)))
7186 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7187 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7188 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7189 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7190
7191 "
7192{
7193 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7194 operands[6] = (GET_CODE (operands[3]) == EQ
7195 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7196 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7197}")
bc45ade3
SC
7198\f
7199;; ------------------------------------------------------------------------
7200;; Jump and linkage insns
7201;; ------------------------------------------------------------------------
7202
fa5322fa 7203(define_insn "jump_compact"
bc45ade3
SC
7204 [(set (pc)
7205 (label_ref (match_operand 0 "" "")))]
fa5322fa 7206 "TARGET_SH1"
bc45ade3
SC
7207 "*
7208{
22e1ebf1 7209 /* The length is 16 if the delay slot is unfilled. */
1245df60 7210 if (get_attr_length(insn) > 4)
51aea58d 7211 return output_far_jump(insn, operands[0]);
bc45ade3 7212 else
51aea58d 7213 return \"bra %l0%#\";
bc45ade3
SC
7214}"
7215 [(set_attr "type" "jump")
7216 (set_attr "needs_delay_slot" "yes")])
7217
10f4f635
R
7218;; ??? It would be much saner to explicitly use the scratch register
7219;; in the jump insn, and have indirect_jump_scratch only set it,
7220;; but fill_simple_delay_slots would refuse to do delay slot filling
7221;; from the target then, as it uses simplejump_p.
7222;;(define_insn "jump_compact_far"
7223;; [(set (pc)
7224;; (label_ref (match_operand 0 "" "")))
7225;; (use (match_operand 1 "register_operand" "r")]
7226;; "TARGET_SH1"
7227;; "* return output_far_jump(insn, operands[0], operands[1]);"
7228;; [(set_attr "type" "jump")
7229;; (set_attr "needs_delay_slot" "yes")])
7230
fa5322fa
AO
7231(define_insn "jump_media"
7232 [(set (pc)
73a4d10b 7233 (match_operand 0 "target_operand" "b"))]
fa5322fa 7234 "TARGET_SHMEDIA"
73a4d10b 7235 "blink %0, r63%>"
2ad65b0e 7236 [(set_attr "type" "jump_media")])
fa5322fa
AO
7237
7238(define_expand "jump"
7239 [(set (pc)
7240 (label_ref (match_operand 0 "" "")))]
7241 ""
7242 "
7243{
7244 if (TARGET_SH1)
8e831557 7245 emit_jump_insn (gen_jump_compact (operands[0]));
fa5322fa
AO
7246 else if (TARGET_SHMEDIA)
7247 {
7248 if (reload_in_progress || reload_completed)
7249 FAIL;
73a4d10b 7250 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
8e831557 7251 operands[0])));
fa5322fa
AO
7252 }
7253 DONE;
7254}")
7255
7256(define_insn "force_mode_for_call"
7257 [(use (reg:PSI FPSCR_REG))]
7258 "TARGET_SHCOMPACT"
7259 ""
7260 [(set_attr "length" "0")
7261 (set (attr "fp_mode")
7262 (if_then_else (eq_attr "fpu_single" "yes")
7263 (const_string "single") (const_string "double")))])
7264
bc45ade3 7265(define_insn "calli"
aa684c94 7266 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
bc45ade3 7267 (match_operand 1 "" ""))
5d00b10a 7268 (use (reg:PSI FPSCR_REG))
4773afa4 7269 (clobber (reg:SI PR_REG))]
fa5322fa 7270 "TARGET_SH1"
bc45ade3 7271 "jsr @%0%#"
ffae286a 7272 [(set_attr "type" "call")
d64264ff
R
7273 (set (attr "fp_mode")
7274 (if_then_else (eq_attr "fpu_single" "yes")
7275 (const_string "single") (const_string "double")))
73774972
EC
7276 (set_attr "needs_delay_slot" "yes")
7277 (set_attr "fp_set" "unknown")])
961c4780 7278
1a66cd67
AO
7279;; This is a pc-rel call, using bsrf, for use with PIC.
7280
7281(define_insn "calli_pcrel"
7282 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7283 (match_operand 1 "" ""))
5d00b10a 7284 (use (reg:PSI FPSCR_REG))
2d01e445 7285 (use (reg:SI PIC_REG))
1a66cd67 7286 (use (match_operand 2 "" ""))
4773afa4 7287 (clobber (reg:SI PR_REG))]
eb69f95c 7288 "TARGET_SH2"
1a66cd67
AO
7289 "bsrf %0\\n%O2:%#"
7290 [(set_attr "type" "call")
7291 (set (attr "fp_mode")
7292 (if_then_else (eq_attr "fpu_single" "yes")
7293 (const_string "single") (const_string "double")))
73774972
EC
7294 (set_attr "needs_delay_slot" "yes")
7295 (set_attr "fp_set" "unknown")])
1a66cd67 7296
2d01e445
AO
7297(define_insn_and_split "call_pcrel"
7298 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7299 (match_operand 1 "" ""))
7300 (use (reg:PSI FPSCR_REG))
7301 (use (reg:SI PIC_REG))
7302 (clobber (reg:SI PR_REG))
7303 (clobber (match_scratch:SI 2 "=r"))]
cb51ecd2 7304 "TARGET_SH2"
2d01e445
AO
7305 "#"
7306 "reload_completed"
7307 [(const_int 0)]
7308 "
7309{
8e831557 7310 rtx lab = PATTERN (gen_call_site ());
2d01e445 7311
675ff4c7 7312 if (SYMBOL_REF_LOCAL_P (operands[0]))
2d01e445
AO
7313 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7314 else
7315 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7316 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7317 DONE;
7318}"
7319 [(set_attr "type" "call")
7320 (set (attr "fp_mode")
7321 (if_then_else (eq_attr "fpu_single" "yes")
7322 (const_string "single") (const_string "double")))
73774972
EC
7323 (set_attr "needs_delay_slot" "yes")
7324 (set_attr "fp_set" "unknown")])
2d01e445 7325
fa5322fa
AO
7326(define_insn "call_compact"
7327 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7328 (match_operand 1 "" ""))
7329 (match_operand 2 "immediate_operand" "n")
7330 (use (reg:SI R0_REG))
7331 (use (reg:SI R1_REG))
7332 (use (reg:PSI FPSCR_REG))
7333 (clobber (reg:SI PR_REG))]
7334 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7335 "jsr @%0%#"
7336 [(set_attr "type" "call")
7337 (set (attr "fp_mode")
7338 (if_then_else (eq_attr "fpu_single" "yes")
7339 (const_string "single") (const_string "double")))
7340 (set_attr "needs_delay_slot" "yes")])
7341
7342(define_insn "call_compact_rettramp"
7343 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7344 (match_operand 1 "" ""))
7345 (match_operand 2 "immediate_operand" "n")
7346 (use (reg:SI R0_REG))
7347 (use (reg:SI R1_REG))
7348 (use (reg:PSI FPSCR_REG))
7349 (clobber (reg:SI R10_REG))
7350 (clobber (reg:SI PR_REG))]
7351 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7352 "jsr @%0%#"
7353 [(set_attr "type" "call")
7354 (set (attr "fp_mode")
7355 (if_then_else (eq_attr "fpu_single" "yes")
7356 (const_string "single") (const_string "double")))
7357 (set_attr "needs_delay_slot" "yes")])
7358
7359(define_insn "call_media"
73a4d10b 7360 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
fa5322fa
AO
7361 (match_operand 1 "" ""))
7362 (clobber (reg:DI PR_MEDIA_REG))]
7363 "TARGET_SHMEDIA"
2ad65b0e
SC
7364 "blink %0, r18"
7365 [(set_attr "type" "jump_media")])
fa5322fa 7366
bc45ade3
SC
7367(define_insn "call_valuei"
7368 [(set (match_operand 0 "" "=rf")
aa684c94 7369 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
bc45ade3 7370 (match_operand 2 "" "")))
5d00b10a 7371 (use (reg:PSI FPSCR_REG))
4773afa4 7372 (clobber (reg:SI PR_REG))]
fa5322fa 7373 "TARGET_SH1"
bc45ade3 7374 "jsr @%1%#"
ffae286a 7375 [(set_attr "type" "call")
d64264ff
R
7376 (set (attr "fp_mode")
7377 (if_then_else (eq_attr "fpu_single" "yes")
7378 (const_string "single") (const_string "double")))
73774972
EC
7379 (set_attr "needs_delay_slot" "yes")
7380 (set_attr "fp_set" "unknown")])
bc45ade3 7381
1a66cd67
AO
7382(define_insn "call_valuei_pcrel"
7383 [(set (match_operand 0 "" "=rf")
7384 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7385 (match_operand 2 "" "")))
5d00b10a 7386 (use (reg:PSI FPSCR_REG))
2d01e445 7387 (use (reg:SI PIC_REG))
1a66cd67 7388 (use (match_operand 3 "" ""))
4773afa4 7389 (clobber (reg:SI PR_REG))]
eb69f95c 7390 "TARGET_SH2"
1a66cd67
AO
7391 "bsrf %1\\n%O3:%#"
7392 [(set_attr "type" "call")
7393 (set (attr "fp_mode")
7394 (if_then_else (eq_attr "fpu_single" "yes")
7395 (const_string "single") (const_string "double")))
73774972
EC
7396 (set_attr "needs_delay_slot" "yes")
7397 (set_attr "fp_set" "unknown")])
1a66cd67 7398
2d01e445
AO
7399(define_insn_and_split "call_value_pcrel"
7400 [(set (match_operand 0 "" "=rf")
7401 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7402 (match_operand 2 "" "")))
7403 (use (reg:PSI FPSCR_REG))
7404 (use (reg:SI PIC_REG))
7405 (clobber (reg:SI PR_REG))
7406 (clobber (match_scratch:SI 3 "=r"))]
cb51ecd2 7407 "TARGET_SH2"
2d01e445
AO
7408 "#"
7409 "reload_completed"
7410 [(const_int 0)]
7411 "
7412{
8e831557 7413 rtx lab = PATTERN (gen_call_site ());
2d01e445 7414
675ff4c7 7415 if (SYMBOL_REF_LOCAL_P (operands[1]))
2d01e445
AO
7416 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7417 else
7418 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7419 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7420 operands[2], lab));
7421 DONE;
7422}"
7423 [(set_attr "type" "call")
7424 (set (attr "fp_mode")
7425 (if_then_else (eq_attr "fpu_single" "yes")
7426 (const_string "single") (const_string "double")))
73774972
EC
7427 (set_attr "needs_delay_slot" "yes")
7428 (set_attr "fp_set" "unknown")])
2d01e445 7429
fa5322fa
AO
7430(define_insn "call_value_compact"
7431 [(set (match_operand 0 "" "=rf")
7432 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7433 (match_operand 2 "" "")))
7434 (match_operand 3 "immediate_operand" "n")
7435 (use (reg:SI R0_REG))
7436 (use (reg:SI R1_REG))
7437 (use (reg:PSI FPSCR_REG))
7438 (clobber (reg:SI PR_REG))]
7439 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7440 "jsr @%1%#"
7441 [(set_attr "type" "call")
7442 (set (attr "fp_mode")
7443 (if_then_else (eq_attr "fpu_single" "yes")
7444 (const_string "single") (const_string "double")))
7445 (set_attr "needs_delay_slot" "yes")])
7446
7447(define_insn "call_value_compact_rettramp"
7448 [(set (match_operand 0 "" "=rf")
7449 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7450 (match_operand 2 "" "")))
7451 (match_operand 3 "immediate_operand" "n")
7452 (use (reg:SI R0_REG))
7453 (use (reg:SI R1_REG))
7454 (use (reg:PSI FPSCR_REG))
7455 (clobber (reg:SI R10_REG))
7456 (clobber (reg:SI PR_REG))]
7457 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7458 "jsr @%1%#"
7459 [(set_attr "type" "call")
7460 (set (attr "fp_mode")
7461 (if_then_else (eq_attr "fpu_single" "yes")
7462 (const_string "single") (const_string "double")))
7463 (set_attr "needs_delay_slot" "yes")])
7464
7465(define_insn "call_value_media"
7466 [(set (match_operand 0 "" "=rf")
73a4d10b 7467 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
fa5322fa
AO
7468 (match_operand 2 "" "")))
7469 (clobber (reg:DI PR_MEDIA_REG))]
7470 "TARGET_SHMEDIA"
2ad65b0e
SC
7471 "blink %1, r18"
7472 [(set_attr "type" "jump_media")])
fa5322fa 7473
bc45ade3 7474(define_expand "call"
51aea58d
JW
7475 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7476 (match_operand 1 "" ""))
fa5322fa 7477 (match_operand 2 "" "")
5d00b10a 7478 (use (reg:PSI FPSCR_REG))
4773afa4 7479 (clobber (reg:SI PR_REG))])]
bc45ade3 7480 ""
1a66cd67 7481 "
827bdee4 7482{
fa5322fa
AO
7483 if (TARGET_SHMEDIA)
7484 {
73a4d10b 7485 operands[0] = shmedia_prepare_call_address (operands[0], 0);
fa5322fa
AO
7486 emit_call_insn (gen_call_media (operands[0], operands[1]));
7487 DONE;
7488 }
7489 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7490 {
7491 rtx cookie_rtx = operands[2];
7492 long cookie = INTVAL (cookie_rtx);
7493 rtx func = XEXP (operands[0], 0);
7494 rtx r0, r1;
7495
7496 if (flag_pic)
7497 {
675ff4c7 7498 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
7499 {
7500 rtx reg = gen_reg_rtx (Pmode);
7501
7502 emit_insn (gen_symGOTPLT2reg (reg, func));
7503 func = reg;
7504 }
7505 else
7506 func = legitimize_pic_address (func, Pmode, 0);
7507 }
7508
7509 r0 = gen_rtx_REG (SImode, R0_REG);
7510 r1 = gen_rtx_REG (SImode, R1_REG);
7511
7512 /* Since such a call function may use all call-clobbered
7513 registers, we force a mode switch earlier, so that we don't
7514 run out of registers when adjusting fpscr for the call. */
7515 emit_insn (gen_force_mode_for_call ());
7516
73a4d10b
R
7517 operands[0]
7518 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7519 SFUNC_GOT);
fa5322fa
AO
7520 operands[0] = force_reg (SImode, operands[0]);
7521
7522 emit_move_insn (r0, func);
7523 emit_move_insn (r1, cookie_rtx);
7524
7525 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7526 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7527 operands[2]));
7528 else
7529 emit_call_insn (gen_call_compact (operands[0], operands[1],
7530 operands[2]));
7531
7532 DONE;
7533 }
7534 else if (TARGET_SHCOMPACT && flag_pic
7535 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 7536 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
7537 {
7538 rtx reg = gen_reg_rtx (Pmode);
7539
7540 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7541 XEXP (operands[0], 0) = reg;
7542 }
cb51ecd2 7543 if (flag_pic && TARGET_SH2
827bdee4
AO
7544 && GET_CODE (operands[0]) == MEM
7545 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7546 {
2d01e445 7547 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
827bdee4
AO
7548 DONE;
7549 }
7550 else
61f71b34 7551 {
827bdee4 7552 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
61f71b34
DD
7553 operands[1] = operands[2];
7554 }
fa5322fa
AO
7555
7556 emit_call_insn (gen_calli (operands[0], operands[1]));
7557 DONE;
7558}")
7559
7560(define_insn "call_pop_compact"
7561 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7562 (match_operand 1 "" ""))
7563 (match_operand 2 "immediate_operand" "n")
7564 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7565 (match_operand 3 "immediate_operand" "n")))
7566 (use (reg:SI R0_REG))
7567 (use (reg:SI R1_REG))
7568 (use (reg:PSI FPSCR_REG))
7569 (clobber (reg:SI PR_REG))]
7570 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7571 "jsr @%0%#"
7572 [(set_attr "type" "call")
7573 (set (attr "fp_mode")
7574 (if_then_else (eq_attr "fpu_single" "yes")
7575 (const_string "single") (const_string "double")))
7576 (set_attr "needs_delay_slot" "yes")])
7577
7578(define_insn "call_pop_compact_rettramp"
7579 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7580 (match_operand 1 "" ""))
7581 (match_operand 2 "immediate_operand" "n")
7582 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7583 (match_operand 3 "immediate_operand" "n")))
7584 (use (reg:SI R0_REG))
7585 (use (reg:SI R1_REG))
7586 (use (reg:PSI FPSCR_REG))
7587 (clobber (reg:SI R10_REG))
7588 (clobber (reg:SI PR_REG))]
7589 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7590 "jsr @%0%#"
7591 [(set_attr "type" "call")
7592 (set (attr "fp_mode")
7593 (if_then_else (eq_attr "fpu_single" "yes")
7594 (const_string "single") (const_string "double")))
7595 (set_attr "needs_delay_slot" "yes")])
7596
7597(define_expand "call_pop"
7598 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7599 (match_operand 1 "" ""))
7600 (match_operand 2 "" "")
7601 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7602 (match_operand 3 "" "")))])]
7603 "TARGET_SHCOMPACT"
7604 "
7605{
f5b9e7c9
NS
7606 rtx cookie_rtx;
7607 long cookie;
7608 rtx func;
7609 rtx r0, r1;
fa5322fa 7610
f5b9e7c9
NS
7611 gcc_assert (operands[2] && INTVAL (operands[2]));
7612 cookie_rtx = operands[2];
7613 cookie = INTVAL (cookie_rtx);
7614 func = XEXP (operands[0], 0);
fa5322fa 7615
f5b9e7c9
NS
7616 if (flag_pic)
7617 {
7618 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7619 {
7620 rtx reg = gen_reg_rtx (Pmode);
7621 emit_insn (gen_symGOTPLT2reg (reg, func));
7622 func = reg;
fa5322fa 7623 }
f5b9e7c9
NS
7624 else
7625 func = legitimize_pic_address (func, Pmode, 0);
7626 }
fa5322fa 7627
f5b9e7c9
NS
7628 r0 = gen_rtx_REG (SImode, R0_REG);
7629 r1 = gen_rtx_REG (SImode, R1_REG);
fa5322fa 7630
f5b9e7c9
NS
7631 /* Since such a call function may use all call-clobbered
7632 registers, we force a mode switch earlier, so that we don't
7633 run out of registers when adjusting fpscr for the call. */
7634 emit_insn (gen_force_mode_for_call ());
fa5322fa 7635
73a4d10b
R
7636 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7637 SFUNC_GOT);
f5b9e7c9 7638 operands[0] = force_reg (SImode, operands[0]);
fa5322fa 7639
f5b9e7c9
NS
7640 emit_move_insn (r0, func);
7641 emit_move_insn (r1, cookie_rtx);
fa5322fa 7642
f5b9e7c9
NS
7643 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7644 emit_call_insn (gen_call_pop_compact_rettramp
7645 (operands[0], operands[1], operands[2], operands[3]));
7646 else
7647 emit_call_insn (gen_call_pop_compact
7648 (operands[0], operands[1], operands[2], operands[3]));
fa5322fa 7649
f5b9e7c9 7650 DONE;
827bdee4 7651}")
bc45ade3
SC
7652
7653(define_expand "call_value"
51aea58d
JW
7654 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7655 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7656 (match_operand 2 "" "")))
fa5322fa 7657 (match_operand 3 "" "")
5d00b10a 7658 (use (reg:PSI FPSCR_REG))
4773afa4 7659 (clobber (reg:SI PR_REG))])]
bc45ade3 7660 ""
1a66cd67 7661 "
827bdee4 7662{
fa5322fa
AO
7663 if (TARGET_SHMEDIA)
7664 {
73a4d10b 7665 operands[1] = shmedia_prepare_call_address (operands[1], 0);
fa5322fa
AO
7666 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7667 operands[2]));
7668 DONE;
7669 }
7670 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7671 {
7672 rtx cookie_rtx = operands[3];
7673 long cookie = INTVAL (cookie_rtx);
7674 rtx func = XEXP (operands[1], 0);
7675 rtx r0, r1;
7676
7677 if (flag_pic)
7678 {
675ff4c7 7679 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
7680 {
7681 rtx reg = gen_reg_rtx (Pmode);
7682
7683 emit_insn (gen_symGOTPLT2reg (reg, func));
7684 func = reg;
7685 }
7686 else
7687 func = legitimize_pic_address (func, Pmode, 0);
7688 }
7689
7690 r0 = gen_rtx_REG (SImode, R0_REG);
7691 r1 = gen_rtx_REG (SImode, R1_REG);
7692
7693 /* Since such a call function may use all call-clobbered
7694 registers, we force a mode switch earlier, so that we don't
7695 run out of registers when adjusting fpscr for the call. */
7696 emit_insn (gen_force_mode_for_call ());
7697
73a4d10b
R
7698 operands[1]
7699 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7700 SFUNC_GOT);
fa5322fa
AO
7701 operands[1] = force_reg (SImode, operands[1]);
7702
7703 emit_move_insn (r0, func);
7704 emit_move_insn (r1, cookie_rtx);
7705
7706 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7707 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7708 operands[1],
7709 operands[2],
7710 operands[3]));
7711 else
7712 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7713 operands[2], operands[3]));
7714
7715 DONE;
7716 }
7717 else if (TARGET_SHCOMPACT && flag_pic
7718 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
675ff4c7 7719 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
fa5322fa
AO
7720 {
7721 rtx reg = gen_reg_rtx (Pmode);
7722
7723 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7724 XEXP (operands[1], 0) = reg;
7725 }
cb51ecd2 7726 if (flag_pic && TARGET_SH2
827bdee4
AO
7727 && GET_CODE (operands[1]) == MEM
7728 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7729 {
2d01e445
AO
7730 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7731 operands[2]));
827bdee4
AO
7732 DONE;
7733 }
7734 else
7735 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
fa5322fa
AO
7736
7737 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7738 DONE;
827bdee4 7739}")
bc45ade3 7740
5db5a888 7741(define_insn "sibcalli"
cb51ecd2 7742 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5db5a888
AO
7743 (match_operand 1 "" ""))
7744 (use (reg:PSI FPSCR_REG))
7745 (return)]
fa5322fa 7746 "TARGET_SH1"
5db5a888
AO
7747 "jmp @%0%#"
7748 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
7749 (set (attr "fp_mode")
7750 (if_then_else (eq_attr "fpu_single" "yes")
7751 (const_string "single") (const_string "double")))
5db5a888
AO
7752 (set_attr "type" "jump_ind")])
7753
7754(define_insn "sibcalli_pcrel"
cb51ecd2 7755 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5db5a888
AO
7756 (match_operand 1 "" ""))
7757 (use (match_operand 2 "" ""))
7758 (use (reg:PSI FPSCR_REG))
7759 (return)]
7760 "TARGET_SH2"
7761 "braf %0\\n%O2:%#"
7762 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
7763 (set (attr "fp_mode")
7764 (if_then_else (eq_attr "fpu_single" "yes")
7765 (const_string "single") (const_string "double")))
5db5a888
AO
7766 (set_attr "type" "jump_ind")])
7767
73a4d10b
R
7768;; This uses an unspec to describe that the symbol_ref is very close.
7769(define_insn "sibcalli_thunk"
7770 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7771 UNSPEC_THUNK))
7772 (match_operand 1 "" ""))
7773 (use (reg:PSI FPSCR_REG))
7774 (return)]
7775 "TARGET_SH1"
7776 "bra %O0"
7777 [(set_attr "needs_delay_slot" "yes")
7778 (set (attr "fp_mode")
7779 (if_then_else (eq_attr "fpu_single" "yes")
7780 (const_string "single") (const_string "double")))
7781 (set_attr "type" "jump")
7782 (set_attr "length" "2")])
7783
5db5a888
AO
7784(define_insn_and_split "sibcall_pcrel"
7785 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7786 (match_operand 1 "" ""))
7787 (use (reg:PSI FPSCR_REG))
cb51ecd2 7788 (clobber (match_scratch:SI 2 "=k"))
5db5a888 7789 (return)]
cb51ecd2 7790 "TARGET_SH2"
5db5a888
AO
7791 "#"
7792 "reload_completed"
7793 [(const_int 0)]
7794 "
7795{
8e831557 7796 rtx lab = PATTERN (gen_call_site ());
5db5a888
AO
7797 rtx call_insn;
7798
fa5322fa
AO
7799 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7800 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7801 lab));
7802 SIBLING_CALL_P (call_insn) = 1;
7803 DONE;
7804}"
7805 [(set_attr "needs_delay_slot" "yes")
7806 (set (attr "fp_mode")
7807 (if_then_else (eq_attr "fpu_single" "yes")
7808 (const_string "single") (const_string "double")))
7809 (set_attr "type" "jump_ind")])
7810
7811(define_insn "sibcall_compact"
7812 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7813 (match_operand 1 "" ""))
7814 (return)
e69d1422 7815 (use (match_operand:SI 2 "register_operand" "z,x"))
fa5322fa
AO
7816 (use (reg:SI R1_REG))
7817 (use (reg:PSI FPSCR_REG))
7818 ;; We want to make sure the `x' above will only match MACH_REG
7819 ;; because sibcall_epilogue may clobber MACL_REG.
7820 (clobber (reg:SI MACL_REG))]
7821 "TARGET_SHCOMPACT"
7822 "@
7823 jmp @%0%#
7824 jmp @%0\\n sts %2, r0"
7825 [(set_attr "needs_delay_slot" "yes,no")
7826 (set_attr "length" "2,4")
7827 (set (attr "fp_mode") (const_string "single"))
7828 (set_attr "type" "jump_ind")])
7829
7830(define_insn "sibcall_media"
73a4d10b 7831 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
fa5322fa 7832 (match_operand 1 "" ""))
7d73a2ba 7833 (use (reg:SI PR_MEDIA_REG))
fa5322fa
AO
7834 (return)]
7835 "TARGET_SHMEDIA"
2ad65b0e
SC
7836 "blink %0, r63"
7837 [(set_attr "type" "jump_media")])
fa5322fa
AO
7838
7839(define_expand "sibcall"
7840 [(parallel
7841 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7842 (match_operand 1 "" ""))
7843 (match_operand 2 "" "")
7844 (use (reg:PSI FPSCR_REG))
7845 (return)])]
7846 ""
7847 "
7848{
7849 if (TARGET_SHMEDIA)
7850 {
73a4d10b 7851 operands[0] = shmedia_prepare_call_address (operands[0], 1);
fa5322fa
AO
7852 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7853 DONE;
7854 }
7855 else if (TARGET_SHCOMPACT && operands[2]
7856 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7857 {
7858 rtx cookie_rtx = operands[2];
7859 long cookie = INTVAL (cookie_rtx);
7860 rtx func = XEXP (operands[0], 0);
7861 rtx mach, r1;
7862
7863 if (flag_pic)
7864 {
675ff4c7 7865 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
7866 {
7867 rtx reg = gen_reg_rtx (Pmode);
7868
7869 emit_insn (gen_symGOT2reg (reg, func));
7870 func = reg;
7871 }
7872 else
7873 func = legitimize_pic_address (func, Pmode, 0);
7874 }
5db5a888 7875
fa5322fa
AO
7876 /* FIXME: if we could tell whether all argument registers are
7877 already taken, we could decide whether to force the use of
7878 MACH_REG or to stick to R0_REG. Unfortunately, there's no
7879 simple way to tell. We could use the CALL_COOKIE, but we
7880 can't currently tell a register used for regular argument
7881 passing from one that is unused. If we leave it up to reload
7882 to decide which register to use, it seems to always choose
7883 R0_REG, which leaves no available registers in SIBCALL_REGS
7884 to hold the address of the trampoline. */
7885 mach = gen_rtx_REG (SImode, MACH_REG);
7886 r1 = gen_rtx_REG (SImode, R1_REG);
7887
7888 /* Since such a call function may use all call-clobbered
7889 registers, we force a mode switch earlier, so that we don't
7890 run out of registers when adjusting fpscr for the call. */
7891 emit_insn (gen_force_mode_for_call ());
7892
73a4d10b
R
7893 operands[0]
7894 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7895 SFUNC_GOT);
fa5322fa
AO
7896 operands[0] = force_reg (SImode, operands[0]);
7897
7898 /* We don't need a return trampoline, since the callee will
7899 return directly to the upper caller. */
7900 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7901 {
7902 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7903 cookie_rtx = GEN_INT (cookie);
7904 }
7905
7906 emit_move_insn (mach, func);
7907 emit_move_insn (r1, cookie_rtx);
7908
7909 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7910 DONE;
7911 }
7912 else if (TARGET_SHCOMPACT && flag_pic
7913 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 7914 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
7915 {
7916 rtx reg = gen_reg_rtx (Pmode);
7917
7918 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7919 XEXP (operands[0], 0) = reg;
7920 }
cb51ecd2 7921 if (flag_pic && TARGET_SH2
5db5a888
AO
7922 && GET_CODE (operands[0]) == MEM
7923 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7924 /* The PLT needs the PIC register, but the epilogue would have
7925 to restore it, so we can only use PC-relative PIC calls for
7926 static functions. */
675ff4c7 7927 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5db5a888
AO
7928 {
7929 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7930 DONE;
7931 }
7932 else
7933 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
fa5322fa
AO
7934
7935 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7936 DONE;
5db5a888
AO
7937}")
7938
7939(define_expand "sibcall_value"
7940 [(set (match_operand 0 "" "")
7941 (call (match_operand 1 "" "")
fa5322fa
AO
7942 (match_operand 2 "" "")))
7943 (match_operand 3 "" "")]
5db5a888
AO
7944 ""
7945 "
7946{
fa5322fa 7947 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5db5a888
AO
7948 DONE;
7949}")
7950
fa5322fa
AO
7951(define_insn "call_value_pop_compact"
7952 [(set (match_operand 0 "" "=rf")
7953 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7954 (match_operand 2 "" "")))
7955 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7956 (match_operand 4 "immediate_operand" "n")))
7957 (match_operand 3 "immediate_operand" "n")
7958 (use (reg:SI R0_REG))
7959 (use (reg:SI R1_REG))
7960 (use (reg:PSI FPSCR_REG))
7961 (clobber (reg:SI PR_REG))]
7962 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7963 "jsr @%1%#"
7964 [(set_attr "type" "call")
7965 (set (attr "fp_mode")
7966 (if_then_else (eq_attr "fpu_single" "yes")
7967 (const_string "single") (const_string "double")))
7968 (set_attr "needs_delay_slot" "yes")])
7969
7970(define_insn "call_value_pop_compact_rettramp"
7971 [(set (match_operand 0 "" "=rf")
7972 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7973 (match_operand 2 "" "")))
7974 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7975 (match_operand 4 "immediate_operand" "n")))
7976 (match_operand 3 "immediate_operand" "n")
7977 (use (reg:SI R0_REG))
7978 (use (reg:SI R1_REG))
7979 (use (reg:PSI FPSCR_REG))
7980 (clobber (reg:SI R10_REG))
7981 (clobber (reg:SI PR_REG))]
7982 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7983 "jsr @%1%#"
7984 [(set_attr "type" "call")
7985 (set (attr "fp_mode")
7986 (if_then_else (eq_attr "fpu_single" "yes")
7987 (const_string "single") (const_string "double")))
7988 (set_attr "needs_delay_slot" "yes")])
7989
7990(define_expand "call_value_pop"
7991 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7992 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7993 (match_operand 2 "" "")))
7994 (match_operand 3 "" "")
7995 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7996 (match_operand 4 "" "")))])]
7997 "TARGET_SHCOMPACT"
7998 "
7999{
f5b9e7c9
NS
8000 rtx cookie_rtx;
8001 long cookie;
8002 rtx func;
8003 rtx r0, r1;
fa5322fa 8004
f5b9e7c9
NS
8005 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8006 cookie_rtx = operands[3];
8007 cookie = INTVAL (cookie_rtx);
8008 func = XEXP (operands[1], 0);
fa5322fa 8009
f5b9e7c9
NS
8010 if (flag_pic)
8011 {
8012 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8013 {
8014 rtx reg = gen_reg_rtx (Pmode);
fa5322fa 8015
f5b9e7c9
NS
8016 emit_insn (gen_symGOTPLT2reg (reg, func));
8017 func = reg;
8018 }
8019 else
8020 func = legitimize_pic_address (func, Pmode, 0);
8021 }
fa5322fa 8022
f5b9e7c9
NS
8023 r0 = gen_rtx_REG (SImode, R0_REG);
8024 r1 = gen_rtx_REG (SImode, R1_REG);
fa5322fa 8025
f5b9e7c9
NS
8026 /* Since such a call function may use all call-clobbered
8027 registers, we force a mode switch earlier, so that we don't
8028 run out of registers when adjusting fpscr for the call. */
8029 emit_insn (gen_force_mode_for_call ());
fa5322fa 8030
73a4d10b
R
8031 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8032 SFUNC_GOT);
f5b9e7c9 8033 operands[1] = force_reg (SImode, operands[1]);
fa5322fa 8034
f5b9e7c9
NS
8035 emit_move_insn (r0, func);
8036 emit_move_insn (r1, cookie_rtx);
8037
8038 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8039 emit_call_insn (gen_call_value_pop_compact_rettramp
fa5322fa
AO
8040 (operands[0], operands[1], operands[2],
8041 operands[3], operands[4]));
f5b9e7c9
NS
8042 else
8043 emit_call_insn (gen_call_value_pop_compact
fa5322fa
AO
8044 (operands[0], operands[1], operands[2],
8045 operands[3], operands[4]));
8046
f5b9e7c9 8047 DONE;
fa5322fa
AO
8048}")
8049
5db5a888
AO
8050(define_expand "sibcall_epilogue"
8051 [(return)]
8052 ""
8053 "
8054{
726d4cb7 8055 sh_expand_epilogue (1);
fa5322fa
AO
8056 if (TARGET_SHCOMPACT)
8057 {
8058 rtx insn, set;
8059
8060 /* If epilogue clobbers r0, preserve it in macl. */
8061 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8062 if ((set = single_set (insn))
8063 && GET_CODE (SET_DEST (set)) == REG
8064 && REGNO (SET_DEST (set)) == R0_REG)
8065 {
8066 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8067 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8068 rtx i;
8069
8070 /* We can't tell at this point whether the sibcall is a
8071 sibcall_compact and, if it is, whether it uses r0 or
8072 mach as operand 2, so let the instructions that
8073 preserve r0 be optimized away if r0 turns out to be
8074 dead. */
8075 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8076 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8077 REG_NOTES (i));
8078 i = emit_move_insn (r0, tmp);
8079 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8080 REG_NOTES (i));
8081 break;
8082 }
8083 }
5db5a888
AO
8084 DONE;
8085}")
8086
fa5322fa 8087(define_insn "indirect_jump_compact"
bc45ade3 8088 [(set (pc)
aa684c94 8089 (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 8090 "TARGET_SH1"
b9654711 8091 "jmp @%0%#"
1245df60
R
8092 [(set_attr "needs_delay_slot" "yes")
8093 (set_attr "type" "jump_ind")])
a1a0806a 8094
fa5322fa
AO
8095(define_expand "indirect_jump"
8096 [(set (pc)
8097 (match_operand 0 "register_operand" ""))]
8098 ""
8099 "
8100{
73a4d10b
R
8101 if (GET_MODE (operands[0]) != Pmode)
8102 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
fa5322fa
AO
8103}")
8104
1245df60 8105;; The use of operand 1 / 2 helps us distinguish case table jumps
f1ffca1c
JW
8106;; which can be present in structured code from indirect jumps which can not
8107;; be present in structured code. This allows -fprofile-arcs to work.
8108
1245df60
R
8109;; For SH1 processors.
8110(define_insn "casesi_jump_1"
f1ffca1c 8111 [(set (pc)
1245df60 8112 (match_operand:SI 0 "register_operand" "r"))
f1ffca1c 8113 (use (label_ref (match_operand 1 "" "")))]
fa5322fa 8114 "TARGET_SH1"
1245df60
R
8115 "jmp @%0%#"
8116 [(set_attr "needs_delay_slot" "yes")
8117 (set_attr "type" "jump_ind")])
8118
8119;; For all later processors.
8120(define_insn "casesi_jump_2"
8121 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
eb3881bf 8122 (label_ref (match_operand 1 "" ""))))
1245df60 8123 (use (label_ref (match_operand 2 "" "")))]
e6dfd05f
AO
8124 "TARGET_SH2
8125 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
1245df60
R
8126 "braf %0%#"
8127 [(set_attr "needs_delay_slot" "yes")
8128 (set_attr "type" "jump_ind")])
8129
fa5322fa 8130(define_insn "casesi_jump_media"
73a4d10b 8131 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
fa5322fa
AO
8132 (use (label_ref (match_operand 1 "" "")))]
8133 "TARGET_SHMEDIA"
2ad65b0e
SC
8134 "blink %0, r63"
8135 [(set_attr "type" "jump_media")])
52702ae1 8136
a1a0806a
JW
8137;; Call subroutine returning any type.
8138;; ??? This probably doesn't work.
8139
8140(define_expand "untyped_call"
8141 [(parallel [(call (match_operand 0 "" "")
8142 (const_int 0))
8143 (match_operand 1 "" "")
8144 (match_operand 2 "" "")])]
157371cf 8145 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
a1a0806a
JW
8146 "
8147{
8148 int i;
8149
fa5322fa 8150 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
a1a0806a
JW
8151
8152 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8153 {
8154 rtx set = XVECEXP (operands[2], 0, i);
8155 emit_move_insn (SET_DEST (set), SET_SRC (set));
8156 }
8157
8158 /* The optimizer does not know that the call sets the function value
8159 registers we stored in the result block. We avoid problems by
8160 claiming that all hard registers are used and clobbered at this
8161 point. */
8162 emit_insn (gen_blockage ());
8163
8164 DONE;
8165}")
bc45ade3
SC
8166\f
8167;; ------------------------------------------------------------------------
8168;; Misc insns
8169;; ------------------------------------------------------------------------
8170
51bd623f 8171(define_insn "dect"
4773afa4 8172 [(set (reg:SI T_REG)
73a4d10b 8173 (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
aff48e32 8174 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
51bd623f 8175 "TARGET_SH2"
1245df60
R
8176 "dt %0"
8177 [(set_attr "type" "arith")])
bc45ade3
SC
8178
8179(define_insn "nop"
8180 [(const_int 0)]
8181 ""
51bd623f 8182 "nop")
0d7e008e 8183
1245df60
R
8184;; Load address of a label. This is only generated by the casesi expand,
8185;; and by machine_dependent_reorg (fixing up fp moves).
8186;; This must use unspec, because this only works for labels that are
8187;; within range,
0d7e008e
SC
8188
8189(define_insn "mova"
4773afa4 8190 [(set (reg:SI R0_REG)
e69d1422 8191 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
fa5322fa 8192 "TARGET_SH1"
0d7e008e 8193 "mova %O0,r0"
1245df60
R
8194 [(set_attr "in_delay_slot" "no")
8195 (set_attr "type" "arith")])
0d7e008e 8196
18dbd950 8197;; machine_dependent_reorg will make this a `mova'.
43c05634
AO
8198(define_insn "mova_const"
8199 [(set (reg:SI R0_REG)
e69d1422 8200 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
fa5322fa 8201 "TARGET_SH1"
43c05634
AO
8202 "#"
8203 [(set_attr "in_delay_slot" "no")
8204 (set_attr "type" "arith")])
8205
1a66cd67 8206(define_expand "GOTaddr2picreg"
4773afa4 8207 [(set (reg:SI R0_REG)
e69d1422
R
8208 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8209 UNSPEC_MOVA))
615cd49b 8210 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
4773afa4 8211 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
1a66cd67
AO
8212 "" "
8213{
fa5322fa 8214 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
1a66cd67 8215 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
fa5322fa 8216
fa5322fa
AO
8217 if (TARGET_SHMEDIA)
8218 {
73a4d10b
R
8219 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8220 rtx pic = operands[0];
8e831557 8221 rtx lab = PATTERN (gen_call_site ());
fa5322fa
AO
8222 rtx insn, equiv;
8223
8224 equiv = operands[1];
73a4d10b 8225 operands[1] = gen_rtx_MINUS (Pmode,
fa5322fa
AO
8226 operands[1],
8227 gen_rtx_CONST
73a4d10b
R
8228 (Pmode,
8229 gen_rtx_MINUS (Pmode,
8230 gen_rtx_CONST (Pmode,
fa5322fa
AO
8231 lab),
8232 pc_rtx)));
8233 operands[1] = gen_sym2PIC (operands[1]);
73a4d10b 8234 PUT_MODE (operands[1], Pmode);
fa5322fa 8235
73a4d10b
R
8236 if (Pmode == SImode)
8237 {
8238 emit_insn (gen_movsi_const (pic, operands[1]));
8239 emit_insn (gen_ptrel_si (tr, pic, lab));
8240 }
fa5322fa 8241 else
73a4d10b
R
8242 {
8243 emit_insn (gen_movdi_const (pic, operands[1]));
8244 emit_insn (gen_ptrel_di (tr, pic, lab));
8245 }
fa5322fa
AO
8246
8247 insn = emit_move_insn (operands[0], tr);
52702ae1 8248
fa5322fa
AO
8249 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8250 REG_NOTES (insn));
8251
8252 DONE;
8253 }
1a66cd67
AO
8254}
8255")
8256
fa5322fa 8257(define_insn "*ptb"
73a4d10b
R
8258 [(set (match_operand 0 "target_reg_operand" "=b")
8259 (const (unspec [(match_operand 1 "" "Csy")]
fa5322fa
AO
8260 UNSPEC_DATALABEL)))]
8261 "TARGET_SHMEDIA && flag_pic
735cb76e 8262 && EXTRA_CONSTRAINT_Csy (operands[1])"
fa5322fa 8263 "ptb/u datalabel %1, %0"
73a4d10b 8264 [(set_attr "type" "ptabs_media")
fa5322fa
AO
8265 (set_attr "length" "*")])
8266
73a4d10b
R
8267(define_insn "ptrel_si"
8268 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8269 (plus:SI (match_operand:SI 1 "register_operand" "r")
8270 (pc)))
8271 (match_operand:SI 2 "" "")]
8272 "TARGET_SHMEDIA"
8273 "%O2: ptrel/u %1, %0"
8274 [(set_attr "type" "ptabs_media")])
8275
8276(define_insn "ptrel_di"
e69d1422
R
8277 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8278 (plus:DI (match_operand:DI 1 "register_operand" "r")
fa5322fa
AO
8279 (pc)))
8280 (match_operand:DI 2 "" "")]
8281 "TARGET_SHMEDIA"
8282 "%O2: ptrel/u %1, %0"
2ad65b0e 8283 [(set_attr "type" "ptabs_media")])
fa5322fa 8284
001643af
KK
8285(define_expand "builtin_setjmp_receiver"
8286 [(match_operand 0 "" "")]
8287 "flag_pic"
8288 "
8289{
8290 emit_insn (gen_GOTaddr2picreg ());
8291 DONE;
8292}")
8293
2d01e445
AO
8294(define_expand "call_site"
8295 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
fa5322fa 8296 "TARGET_SH1"
2d01e445
AO
8297 "
8298{
8299 static HOST_WIDE_INT i = 0;
8300 operands[0] = GEN_INT (i);
8301 i++;
8302}")
8303
1a66cd67
AO
8304(define_expand "sym_label2reg"
8305 [(set (match_operand:SI 0 "" "")
a4f76ef9
AO
8306 (const:SI (minus:SI
8307 (const:SI
8308 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8309 (const:SI
8310 (plus:SI
8311 (match_operand:SI 2 "" "")
8312 (const_int 2))))))]
fa5322fa 8313 "TARGET_SH1" "")
1a66cd67 8314
e1d71275
AO
8315(define_expand "symGOT_load"
8316 [(set (match_dup 2) (match_operand 1 "" ""))
8317 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8318 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8319 ""
8320 "
8321{
57d38024 8322 rtx insn, mem;
e1d71275
AO
8323
8324 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8325 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8326
fa5322fa
AO
8327 if (TARGET_SHMEDIA)
8328 {
8329 rtx reg = operands[2];
52702ae1 8330
73a4d10b
R
8331 if (Pmode == DImode)
8332 {
8333 if (flag_pic > 1)
8334 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8335 else
8336 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8337 }
fa5322fa 8338 else
73a4d10b
R
8339 {
8340 if (flag_pic > 1)
8341 emit_insn (gen_movsi_const (reg, operands[1]));
8342 else
8343 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8344 }
fa5322fa
AO
8345 }
8346 else
8347 emit_move_insn (operands[2], operands[1]);
e1d71275
AO
8348
8349 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8350 operands[2],
8351 gen_rtx_REG (Pmode, PIC_REG)));
8352
57d38024
R
8353 /* N.B. This is not constant for a GOTPLT relocation. */
8354 mem = gen_rtx_MEM (Pmode, operands[3]);
8355 MEM_NOTRAP_P (mem) = 1;
8356 /* ??? Should we have a special alias set for the GOT? */
8357 insn = emit_move_insn (operands[0], mem);
e1d71275
AO
8358
8359 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8360 0), 0, 0),
8361 REG_NOTES (insn));
52702ae1 8362
e1d71275
AO
8363 DONE;
8364}")
8365
8366(define_expand "sym2GOT"
8367 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8368 ""
8369 "")
8370
1a66cd67 8371(define_expand "symGOT2reg"
e1d71275 8372 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
8373 ""
8374 "
8375{
e1d71275
AO
8376 rtx gotsym, insn;
8377
8378 gotsym = gen_sym2GOT (operands[1]);
8379 PUT_MODE (gotsym, Pmode);
8380 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8381
389fdba0 8382 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
e1d71275
AO
8383
8384 DONE;
1a66cd67
AO
8385}")
8386
fa5322fa
AO
8387(define_expand "symGOTPLT2reg"
8388 [(match_operand 0 "" "") (match_operand 1 "" "")]
8389 ""
8390 "
8391{
42201282
R
8392 rtx pltsym = gen_rtx_CONST (Pmode,
8393 gen_rtx_UNSPEC (Pmode,
8394 gen_rtvec (1, operands[1]),
8395 UNSPEC_GOTPLT));
8396 emit_insn (gen_symGOT_load (operands[0], pltsym));
fa5322fa
AO
8397 DONE;
8398}")
8399
e1d71275
AO
8400(define_expand "sym2GOTOFF"
8401 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8402 ""
8403 "")
8404
1a66cd67 8405(define_expand "symGOTOFF2reg"
e1d71275 8406 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
8407 ""
8408 "
8409{
e1d71275
AO
8410 rtx gotoffsym, insn;
8411 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8412
8413 gotoffsym = gen_sym2GOTOFF (operands[1]);
8414 PUT_MODE (gotoffsym, Pmode);
8415 emit_move_insn (t, gotoffsym);
8416 insn = emit_move_insn (operands[0],
8417 gen_rtx_PLUS (Pmode, t,
8418 gen_rtx_REG (Pmode, PIC_REG)));
8419
8420 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8421 REG_NOTES (insn));
8422
8423 DONE;
1a66cd67
AO
8424}")
8425
8426(define_expand "symPLT_label2reg"
8427 [(set (match_operand:SI 0 "" "")
e1d71275
AO
8428 (const:SI (minus:SI
8429 (const:SI
8430 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8431 (const:SI
8432 (minus:SI
8433 (const:SI (plus:SI
8434 (match_operand:SI 2 "" "")
8435 (const_int 2)))
8436 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6915629f
AO
8437 ;; Even though the PIC register is not really used by the call
8438 ;; sequence in which this is expanded, the PLT code assumes the PIC
8439 ;; register is set, so we must not skip its initialization. Since
8440 ;; we only use this expand as part of calling sequences, and never
8441 ;; to take the address of a function, this is the best point to
8442 ;; insert the (use). Using the PLT to take the address of a
8443 ;; function would be wrong, not only because the PLT entry could
8444 ;; then be called from a function that doesn't initialize the PIC
8445 ;; register to the proper GOT, but also because pointers to the
8446 ;; same function might not compare equal, should they be set by
8447 ;; different shared libraries.
8448 (use (reg:SI PIC_REG))]
fa5322fa
AO
8449 "TARGET_SH1"
8450 "")
8451
8452(define_expand "sym2PIC"
8453 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6915629f
AO
8454 ""
8455 "")
1a66cd67 8456
463f02cd
KK
8457;; TLS code generation.
8458;; ??? this should be a define_insn_and_split
8459;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8460;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8461;; for details.
8462
8463(define_insn "tls_global_dynamic"
8464 [(set (match_operand:SI 0 "register_operand" "=&z")
73a4d10b 8465 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
07ea92d3 8466 UNSPEC_TLSGD))
13ecc9e0 8467 (const_int 0)))
463f02cd
KK
8468 (use (reg:PSI FPSCR_REG))
8469 (use (reg:SI PIC_REG))
8470 (clobber (reg:SI PR_REG))
8471 (clobber (scratch:SI))]
8472 "TARGET_SH1"
8473 "*
8474{
8475 return \"\\
8476mov.l\\t1f,r4\\n\\
8477\\tmova\\t2f,r0\\n\\
8478\\tmov.l\\t2f,r1\\n\\
8479\\tadd\\tr0,r1\\n\\
8480\\tjsr\\t@r1\\n\\
8481\\tadd\\tr12,r4\\n\\
8482\\tbra\\t3f\\n\\
8483\\tnop\\n\\
8484\\t.align\\t2\\n\\
84851:\\t.long\\t%a1@TLSGD\\n\\
84862:\\t.long\\t__tls_get_addr@PLT\\n\\
84873:\";
8488}"
8489 [(set_attr "type" "tls_load")
8490 (set_attr "length" "26")])
8491
8492(define_insn "tls_local_dynamic"
8493 [(set (match_operand:SI 0 "register_operand" "=&z")
73a4d10b 8494 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
07ea92d3 8495 UNSPEC_TLSLDM))
13ecc9e0 8496 (const_int 0)))
463f02cd
KK
8497 (use (reg:PSI FPSCR_REG))
8498 (use (reg:SI PIC_REG))
8499 (clobber (reg:SI PR_REG))
8500 (clobber (scratch:SI))]
8501 "TARGET_SH1"
8502 "*
8503{
8504 return \"\\
8505mov.l\\t1f,r4\\n\\
8506\\tmova\\t2f,r0\\n\\
8507\\tmov.l\\t2f,r1\\n\\
8508\\tadd\\tr0,r1\\n\\
8509\\tjsr\\t@r1\\n\\
8510\\tadd\\tr12,r4\\n\\
8511\\tbra\\t3f\\n\\
8512\\tnop\\n\\
8513\\t.align\\t2\\n\\
85141:\\t.long\\t%a1@TLSLDM\\n\\
85152:\\t.long\\t__tls_get_addr@PLT\\n\\
85163:\";
8517}"
8518 [(set_attr "type" "tls_load")
8519 (set_attr "length" "26")])
8520
8521(define_expand "sym2DTPOFF"
8522 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8523 ""
8524 "")
8525
8526(define_expand "symDTPOFF2reg"
8527 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8528 ""
8529 "
8530{
8531 rtx dtpoffsym, insn;
8532 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8533
8534 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8535 PUT_MODE (dtpoffsym, Pmode);
8536 emit_move_insn (t, dtpoffsym);
8537 insn = emit_move_insn (operands[0],
8538 gen_rtx_PLUS (Pmode, t, operands[2]));
8539 DONE;
8540}")
8541
8542(define_expand "sym2GOTTPOFF"
8543 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8544 ""
8545 "")
8546
8547(define_insn "tls_initial_exec"
8548 [(set (match_operand:SI 0 "register_operand" "=&r")
8549 (unspec:SI [(match_operand:SI 1 "" "")]
8550 UNSPEC_TLSIE))
8551 (use (reg:SI GBR_REG))
8552 (use (reg:SI PIC_REG))
8553 (clobber (reg:SI R0_REG))]
8554 ""
8555 "*
8556{
8557 return \"\\
8558mov.l\\t1f,r0\\n\\
8559\\tstc\\tgbr,%0\\n\\
8560\\tmov.l\\t@(r0,r12),r0\\n\\
8561\\tbra\\t2f\\n\\
8562\\tadd\\tr0,%0\\n\\
8563\\t.align\\t2\\n\\
85641:\\t.long\\t%a1\\n\\
85652:\";
8566}"
8567 [(set_attr "type" "tls_load")
8568 (set_attr "length" "16")])
8569
8570(define_expand "sym2TPOFF"
8571 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8572 ""
8573 "")
8574
8575(define_expand "symTPOFF2reg"
8576 [(match_operand 0 "" "") (match_operand 1 "" "")]
8577 ""
8578 "
8579{
8580 rtx tpoffsym, insn;
8581
8582 tpoffsym = gen_sym2TPOFF (operands[1]);
8583 PUT_MODE (tpoffsym, Pmode);
8584 insn = emit_move_insn (operands[0], tpoffsym);
8585 DONE;
8586}")
8587
8588(define_insn "load_gbr"
8589 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8590 (use (reg:SI GBR_REG))]
8591 ""
8592 "stc gbr,%0"
8593 [(set_attr "type" "tls_load")])
8594
0d7e008e
SC
8595;; case instruction for switch statements.
8596
8597;; Operand 0 is index
8598;; operand 1 is the minimum bound
8599;; operand 2 is the maximum bound - minimum bound + 1
8600;; operand 3 is CODE_LABEL for the table;
8601;; operand 4 is the CODE_LABEL to go to if index out of range.
8602
8603(define_expand "casesi"
1245df60
R
8604 [(match_operand:SI 0 "arith_reg_operand" "")
8605 (match_operand:SI 1 "arith_reg_operand" "")
8606 (match_operand:SI 2 "arith_reg_operand" "")
8607 (match_operand 3 "" "") (match_operand 4 "" "")]
8608 ""
8609 "
8610{
8611 rtx reg = gen_reg_rtx (SImode);
8612 rtx reg2 = gen_reg_rtx (SImode);
fa5322fa
AO
8613 if (TARGET_SHMEDIA)
8614 {
8615 rtx reg = gen_reg_rtx (DImode);
8616 rtx reg2 = gen_reg_rtx (DImode);
73a4d10b
R
8617 rtx reg3 = gen_reg_rtx (Pmode);
8618 rtx reg4 = gen_reg_rtx (Pmode);
8619 rtx reg5 = gen_reg_rtx (Pmode);
8620 rtx load;
fa5322fa
AO
8621
8622 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8623 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8624 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8625
8626 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8627 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8628 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8629 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8630 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
73a4d10b
R
8631 (Pmode, operands[3])));
8632 /* Messy: can we subreg to clean this up? */
8633 if (Pmode == DImode)
8634 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8635 else
8636 load = gen_casesi_load_media (reg4,
8637 gen_rtx_SUBREG (DImode, reg3, 0),
8638 reg2, operands[3]);
8639 PUT_MODE (SET_SRC (load), Pmode);
8640 emit_insn (load);
8641 /* ??? The following add could be eliminated if we used ptrel. */
8642 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
fa5322fa
AO
8643 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8644 emit_barrier ();
8645 DONE;
8646 }
1245df60
R
8647 operands[1] = copy_to_mode_reg (SImode, operands[1]);
8648 operands[2] = copy_to_mode_reg (SImode, operands[2]);
8649 /* If optimizing, casesi_worker depends on the mode of the instruction
8650 before label it 'uses' - operands[3]. */
8651 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8652 reg));
8653 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8654 if (TARGET_SH2)
eb3881bf 8655 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
1245df60 8656 else
eb3881bf 8657 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
1245df60
R
8658 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8659 operands[3], but to lab. We will fix this up in
8660 machine_dependent_reorg. */
8661 emit_barrier ();
8662 DONE;
8663}")
8664
8665(define_expand "casesi_0"
8666 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8667 (set (match_dup 4) (minus:SI (match_dup 4)
0d7e008e 8668 (match_operand:SI 1 "arith_operand" "")))
4773afa4 8669 (set (reg:SI T_REG)
1245df60 8670 (gtu:SI (match_dup 4)
22e1ebf1 8671 (match_operand:SI 2 "arith_reg_operand" "")))
0d7e008e 8672 (set (pc)
4773afa4 8673 (if_then_else (ne (reg:SI T_REG)
7c225e88 8674 (const_int 0))
1245df60
R
8675 (label_ref (match_operand 3 "" ""))
8676 (pc)))]
fa5322fa 8677 "TARGET_SH1"
1245df60 8678 "")
0d7e008e 8679
1245df60
R
8680;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8681;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8682;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8683
8684(define_insn "casesi_worker_0"
8685 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422 8686 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
4773afa4 8687 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
8688 (clobber (match_scratch:SI 3 "=X,1"))
8689 (clobber (match_scratch:SI 4 "=&z,z"))]
fa5322fa 8690 "TARGET_SH1"
1245df60
R
8691 "#")
8692
8693(define_split
8694 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
8695 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8696 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
8697 (clobber (match_scratch:SI 3 ""))
8698 (clobber (match_scratch:SI 4 ""))]
fa5322fa 8699 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
e69d1422 8700 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 8701 (parallel [(set (match_dup 0)
e69d1422
R
8702 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8703 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 8704 (clobber (match_dup 3))])
4773afa4 8705 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
b6d33983 8706 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
8707
8708(define_split
8709 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
8710 (unspec:SI [(match_operand:SI 1 "register_operand" "")
8711 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
8712 (clobber (match_scratch:SI 3 ""))
8713 (clobber (match_scratch:SI 4 ""))]
8714 "TARGET_SH2 && reload_completed"
e69d1422 8715 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 8716 (parallel [(set (match_dup 0)
615cd49b 8717 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
e69d1422 8718 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 8719 (clobber (match_dup 3))])]
b6d33983 8720 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60 8721
078c8b08 8722(define_insn "casesi_worker_1"
1245df60 8723 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422
R
8724 (unspec:SI [(reg:SI R0_REG)
8725 (match_operand:SI 1 "register_operand" "0,r")
8726 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60 8727 (clobber (match_scratch:SI 3 "=X,1"))]
fa5322fa 8728 "TARGET_SH1"
4fdd1f85 8729 "*
ffae286a 8730{
33f7f353
JR
8731 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8732
f5b9e7c9 8733 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
33f7f353
JR
8734
8735 switch (GET_MODE (diff_vec))
1245df60
R
8736 {
8737 case SImode:
8738 return \"shll2 %1\;mov.l @(r0,%1),%0\";
8739 case HImode:
8740 return \"add %1,%1\;mov.w @(r0,%1),%0\";
8741 case QImode:
33f7f353 8742 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
1245df60 8743 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
33f7f353 8744 return \"mov.b @(r0,%1),%0\";
1245df60 8745 default:
f5b9e7c9 8746 gcc_unreachable ();
1245df60 8747 }
ffae286a 8748}"
51bd623f 8749 [(set_attr "length" "4")])
0d7e008e 8750
078c8b08
R
8751(define_insn "casesi_worker_2"
8752 [(set (match_operand:SI 0 "register_operand" "=r,r")
8753 (unspec:SI [(reg:SI R0_REG)
8754 (match_operand:SI 1 "register_operand" "0,r")
8755 (label_ref (match_operand 2 "" ""))
8756 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8757 (clobber (match_operand:SI 4 "" "=X,1"))]
8758 "TARGET_SH2 && reload_completed && flag_pic"
8759 "*
8760{
8761 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
45dc67b7 8762 const char *load;
078c8b08 8763
f5b9e7c9 8764 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
078c8b08
R
8765
8766 switch (GET_MODE (diff_vec))
8767 {
8768 case SImode:
8769 output_asm_insn (\"shll2 %1\", operands);
8770 load = \"mov.l @(r0,%1),%0\"; break;
8771 case HImode:
8772 output_asm_insn (\"add %1,%1\", operands);
8773 load = \"mov.w @(r0,%1),%0\"; break;
8774 case QImode:
8775 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8776 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
8777 else
8778 load = \"mov.b @(r0,%1),%0\";
8779 break;
8780 default:
f5b9e7c9 8781 gcc_unreachable ();
078c8b08
R
8782 }
8783 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8784 return load;
8785}"
8786 [(set_attr "length" "8")])
8787
fa5322fa 8788(define_insn "casesi_shift_media"
73a4d10b 8789 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
51214775
R
8790 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8791 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8792 UNSPEC_CASESI)))]
fa5322fa
AO
8793 "TARGET_SHMEDIA"
8794 "*
8795{
8796 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8797
f5b9e7c9 8798 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
fa5322fa
AO
8799
8800 switch (GET_MODE (diff_vec))
8801 {
8802 case SImode:
8803 return \"shlli %1, 2, %0\";
8804 case HImode:
8805 return \"shlli %1, 1, %0\";
8806 case QImode:
8807 if (rtx_equal_p (operands[0], operands[1]))
8808 return \"\";
8809 return \"add %1, r63, %0\";
8810 default:
f5b9e7c9 8811 gcc_unreachable ();
fa5322fa 8812 }
2ad65b0e
SC
8813}"
8814 [(set_attr "type" "arith_media")])
fa5322fa
AO
8815
8816(define_insn "casesi_load_media"
73a4d10b
R
8817 [(set (match_operand 0 "any_arith_reg_dest" "=r")
8818 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8819 (match_operand:DI 2 "arith_reg_operand" "r")
8820 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
fa5322fa
AO
8821 "TARGET_SHMEDIA"
8822 "*
8823{
8824 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8825
f5b9e7c9 8826 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
fa5322fa
AO
8827
8828 switch (GET_MODE (diff_vec))
8829 {
8830 case SImode:
8831 return \"ldx.l %1, %2, %0\";
8832 case HImode:
8833#if 0
8834 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8835 return \"ldx.uw %1, %2, %0\";
8836#endif
8837 return \"ldx.w %1, %2, %0\";
8838 case QImode:
8839 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8840 return \"ldx.ub %1, %2, %0\";
8841 return \"ldx.b %1, %2, %0\";
8842 default:
f5b9e7c9 8843 gcc_unreachable ();
fa5322fa 8844 }
2ad65b0e
SC
8845}"
8846 [(set_attr "type" "load_media")])
fa5322fa 8847
afbc2905
R
8848(define_expand "return"
8849 [(return)]
8850 "reload_completed && ! sh_need_epilogue ()"
fa5322fa
AO
8851 "
8852{
8853 if (TARGET_SHMEDIA)
8854 {
8855 emit_jump_insn (gen_return_media ());
8856 DONE;
8857 }
8858
8859 if (TARGET_SHCOMPACT
8860 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8861 {
8862 emit_jump_insn (gen_shcompact_return_tramp ());
8863 DONE;
8864 }
8865}")
afbc2905
R
8866
8867(define_insn "*return_i"
0d7e008e 8868 [(return)]
fa5322fa
AO
8869 "TARGET_SH1 && ! (TARGET_SHCOMPACT
8870 && (current_function_args_info.call_cookie
8871 & CALL_COOKIE_RET_TRAMP (1)))
a6ab9fc0
R
8872 && reload_completed
8873 && lookup_attribute (\"trap_exit\",
8874 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
961c4780 8875 "%@ %#"
51bd623f
JW
8876 [(set_attr "type" "return")
8877 (set_attr "needs_delay_slot" "yes")])
b9654711 8878
a6ab9fc0
R
8879;; trapa has no delay slot.
8880(define_insn "*return_trapa"
8881 [(return)]
8882 "TARGET_SH1 && !TARGET_SHCOMPACT
8883 && reload_completed"
8884 "%@"
8885 [(set_attr "type" "return")])
8886
fa5322fa
AO
8887(define_expand "shcompact_return_tramp"
8888 [(return)]
8889 "TARGET_SHCOMPACT
8890 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8891 "
8892{
8893 rtx reg = gen_rtx_REG (Pmode, R0_REG);
fa5322fa 8894
73a4d10b 8895 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
fa5322fa
AO
8896 emit_jump_insn (gen_shcompact_return_tramp_i ());
8897 DONE;
8898}")
8899
8900(define_insn "shcompact_return_tramp_i"
8901 [(parallel [(return) (use (reg:SI R0_REG))])]
8902 "TARGET_SHCOMPACT
8903 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8904 "jmp @r0%#"
8905 [(set_attr "type" "jump_ind")
8906 (set_attr "needs_delay_slot" "yes")])
8907
8908(define_insn "return_media_i"
73a4d10b 8909 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
fa5322fa 8910 "TARGET_SHMEDIA && reload_completed"
2ad65b0e
SC
8911 "blink %0, r63"
8912 [(set_attr "type" "jump_media")])
fa5322fa 8913
1bf93c14
R
8914(define_insn "return_media_rte"
8915 [(return)]
8916 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8917 "rte"
8918 [(set_attr "type" "jump_media")])
8919
fa5322fa
AO
8920(define_expand "return_media"
8921 [(return)]
8922 "TARGET_SHMEDIA && reload_completed"
8923 "
8924{
8925 int tr_regno = sh_media_register_for_return ();
8926 rtx tr;
8927
1bf93c14
R
8928 if (current_function_interrupt)
8929 {
8930 emit_jump_insn (gen_return_media_rte ());
8931 DONE;
8932 }
fa5322fa
AO
8933 if (tr_regno < 0)
8934 {
73a4d10b 8935 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
fa5322fa 8936
f5b9e7c9 8937 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
fa5322fa 8938 tr_regno = TR0_REG;
73a4d10b 8939 tr = gen_rtx_REG (Pmode, tr_regno);
fa5322fa
AO
8940 emit_move_insn (tr, r18);
8941 }
8942 else
73a4d10b 8943 tr = gen_rtx_REG (Pmode, tr_regno);
fa5322fa
AO
8944
8945 emit_jump_insn (gen_return_media_i (tr));
8946 DONE;
8947}")
8948
8949(define_insn "shcompact_preserve_incoming_args"
e69d1422
R
8950 [(set (match_operand:SI 0 "register_operand" "+r")
8951 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
fa5322fa
AO
8952 "TARGET_SHCOMPACT"
8953 ""
8954 [(set_attr "length" "0")])
8955
8956(define_insn "shcompact_incoming_args"
e69d1422
R
8957 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8958 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8959 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8960 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8961 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8962 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8963 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8964 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa 8965 (set (mem:BLK (reg:SI MACL_REG))
e69d1422 8966 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa
AO
8967 (use (reg:SI R0_REG))
8968 (clobber (reg:SI R0_REG))
8969 (clobber (reg:SI MACL_REG))
8970 (clobber (reg:SI MACH_REG))
8971 (clobber (reg:SI PR_REG))]
8972 "TARGET_SHCOMPACT"
8973 "jsr @r0%#"
8974 [(set_attr "needs_delay_slot" "yes")])
8975
8976(define_insn "shmedia_save_restore_regs_compact"
8977 [(set (reg:SI SP_REG)
8978 (plus:SI (reg:SI SP_REG)
8979 (match_operand:SI 0 "immediate_operand" "i")))
8980 (use (reg:SI R0_REG))
8981 (clobber (reg:SI PR_REG))]
8982 "TARGET_SHCOMPACT
8983 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8984 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8985 "jsr @r0%#"
8986 [(set_attr "needs_delay_slot" "yes")])
8987
b9654711
SC
8988(define_expand "prologue"
8989 [(const_int 0)]
8990 ""
8991 "sh_expand_prologue (); DONE;")
8992
8993(define_expand "epilogue"
8994 [(return)]
8995 ""
fa5322fa
AO
8996 "
8997{
726d4cb7 8998 sh_expand_epilogue (0);
fa5322fa
AO
8999 emit_jump_insn (gen_return ());
9000 DONE;
9001}")
b9654711 9002
4977bab6 9003(define_expand "eh_return"
34dc173c 9004 [(use (match_operand 0 "register_operand" ""))]
4977bab6
ZW
9005 ""
9006{
45dc67b7 9007 rtx ra = operands[0];
4977bab6
ZW
9008
9009 if (TARGET_SHMEDIA64)
9010 emit_insn (gen_eh_set_ra_di (ra));
9011 else
9012 emit_insn (gen_eh_set_ra_si (ra));
9013
4977bab6
ZW
9014 DONE;
9015})
9016
9017;; Clobber the return address on the stack. We can't expand this
9018;; until we know where it will be put in the stack frame.
9019
9020(define_insn "eh_set_ra_si"
9021 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9022 (clobber (match_scratch:SI 1 "=&r"))]
9023 "! TARGET_SHMEDIA64"
9024 "#")
9025
9026(define_insn "eh_set_ra_di"
9027 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9028 (clobber (match_scratch:DI 1 "=&r"))]
9029 "TARGET_SHMEDIA64"
9030 "#")
9031
9032(define_split
9033 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9034 (clobber (match_scratch 1 ""))]
9035 "reload_completed"
9036 [(const_int 0)]
9037 "
9038{
9039 sh_set_return_address (operands[0], operands[1]);
9040 DONE;
9041}")
9042
b9654711 9043(define_insn "blockage"
4773afa4 9044 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
b9654711
SC
9045 ""
9046 ""
9047 [(set_attr "length" "0")])
bc45ade3
SC
9048\f
9049;; ------------------------------------------------------------------------
9050;; Scc instructions
9051;; ------------------------------------------------------------------------
9052
0d7e008e 9053(define_insn "movt"
73a4d10b 9054 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4773afa4 9055 (eq:SI (reg:SI T_REG) (const_int 1)))]
fa5322fa 9056 "TARGET_SH1"
1245df60
R
9057 "movt %0"
9058 [(set_attr "type" "arith")])
bc45ade3
SC
9059
9060(define_expand "seq"
73a4d10b 9061 [(set (match_operand:SI 0 "arith_reg_dest" "")
bc45ade3
SC
9062 (match_dup 1))]
9063 ""
fa5322fa
AO
9064 "
9065{
9066 if (TARGET_SHMEDIA)
9067 {
fa5322fa
AO
9068 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9069 if (sh_compare_op1 != const0_rtx)
9070 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9071 ? GET_MODE (sh_compare_op0)
9072 : GET_MODE (sh_compare_op1),
9073 sh_compare_op1);
73a4d10b
R
9074 if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9075 {
9076 if (GET_MODE (operands[0]) != SImode)
9077 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9078
9079 switch (GET_MODE (sh_compare_op0))
9080 {
9081 case SImode:
9082 emit_insn (gen_cmpsieqsi_media (operands[0],
9083 sh_compare_op0, sh_compare_op1));
9084 break;
9085
9086 case DImode:
9087 emit_insn (gen_cmpsieqdi_media (operands[0],
9088 sh_compare_op0, sh_compare_op1));
9089 break;
9090
9091 case SFmode:
9092 if (! TARGET_SHMEDIA_FPU)
9093 FAIL;
9094 emit_insn (gen_cmpsieqsf_media (operands[0],
9095 sh_compare_op0, sh_compare_op1));
9096 break;
9097
9098 case DFmode:
9099 if (! TARGET_SHMEDIA_FPU)
9100 FAIL;
9101 emit_insn (gen_cmpsieqdf_media (operands[0],
9102 sh_compare_op0, sh_compare_op1));
9103 break;
9104
9105 default:
9106 FAIL;
9107 }
9108 DONE;
9109 }
9110
9111 if (GET_MODE (operands[0]) != DImode)
9112 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
fa5322fa
AO
9113
9114 switch (GET_MODE (sh_compare_op0))
9115 {
73a4d10b
R
9116 case SImode:
9117 emit_insn (gen_cmpeqsi_media (operands[0],
9118 sh_compare_op0, sh_compare_op1));
9119 break;
9120
fa5322fa
AO
9121 case DImode:
9122 emit_insn (gen_cmpeqdi_media (operands[0],
9123 sh_compare_op0, sh_compare_op1));
9124 break;
9125
9126 case SFmode:
9127 if (! TARGET_SHMEDIA_FPU)
9128 FAIL;
9129 emit_insn (gen_cmpeqsf_media (operands[0],
9130 sh_compare_op0, sh_compare_op1));
9131 break;
9132
9133 case DFmode:
9134 if (! TARGET_SHMEDIA_FPU)
9135 FAIL;
9136 emit_insn (gen_cmpeqdf_media (operands[0],
9137 sh_compare_op0, sh_compare_op1));
9138 break;
9139
9140 default:
9141 FAIL;
9142 }
9143 DONE;
9144 }
3db1b434
R
9145 if (sh_expand_t_scc (EQ, operands[0]))
9146 DONE;
4586b4ca 9147 if (! currently_expanding_to_rtl)
3db1b434 9148 FAIL;
fa5322fa
AO
9149 operands[1] = prepare_scc_operands (EQ);
9150}")
bc45ade3
SC
9151
9152(define_expand "slt"
aa684c94 9153 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9154 (match_dup 1))]
9155 ""
fa5322fa
AO
9156 "
9157{
9158 if (TARGET_SHMEDIA)
9159 {
9160 if (GET_MODE (operands[0]) != DImode)
9161 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9162 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9163 if (sh_compare_op1 != const0_rtx)
9164 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9165 ? GET_MODE (sh_compare_op0)
9166 : GET_MODE (sh_compare_op1),
9167 sh_compare_op1);
9168
9169 switch (GET_MODE (sh_compare_op0))
9170 {
73a4d10b
R
9171 case SImode:
9172 emit_insn (gen_cmpgtsi_media (operands[0],
9173 sh_compare_op1, sh_compare_op0));
9174 break;
9175
fa5322fa
AO
9176 case DImode:
9177 emit_insn (gen_cmpgtdi_media (operands[0],
9178 sh_compare_op1, sh_compare_op0));
9179 break;
9180
9181 case SFmode:
9182 if (! TARGET_SHMEDIA_FPU)
9183 FAIL;
9184 emit_insn (gen_cmpgtsf_media (operands[0],
9185 sh_compare_op1, sh_compare_op0));
9186 break;
9187
9188 case DFmode:
9189 if (! TARGET_SHMEDIA_FPU)
9190 FAIL;
9191 emit_insn (gen_cmpgtdf_media (operands[0],
9192 sh_compare_op1, sh_compare_op0));
9193 break;
9194
9195 default:
9196 FAIL;
9197 }
9198 DONE;
9199 }
4586b4ca 9200 if (! currently_expanding_to_rtl)
3db1b434 9201 FAIL;
fa5322fa
AO
9202 operands[1] = prepare_scc_operands (LT);
9203}")
bc45ade3
SC
9204
9205(define_expand "sle"
1245df60 9206 [(match_operand:SI 0 "arith_reg_operand" "")]
bc45ade3 9207 ""
45348d9e
JW
9208 "
9209{
1245df60 9210 rtx tmp = sh_compare_op0;
fa5322fa
AO
9211
9212 if (TARGET_SHMEDIA)
9213 {
9214 if (GET_MODE (operands[0]) != DImode)
9215 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9216 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9217 if (sh_compare_op1 != const0_rtx)
9218 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9219 ? GET_MODE (sh_compare_op0)
9220 : GET_MODE (sh_compare_op1),
9221 sh_compare_op1);
9222
9223 switch (GET_MODE (sh_compare_op0))
9224 {
73a4d10b
R
9225 case SImode:
9226 {
9227 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9228
9229 emit_insn (gen_cmpgtsi_media (tmp,
9230 sh_compare_op0, sh_compare_op1));
9231 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9232 break;
9233 }
9234
fa5322fa
AO
9235 case DImode:
9236 {
9237 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9238
9239 emit_insn (gen_cmpgtdi_media (tmp,
9240 sh_compare_op0, sh_compare_op1));
9241 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9242 break;
9243 }
9244
9245 case SFmode:
9246 if (! TARGET_SHMEDIA_FPU)
9247 FAIL;
9248 emit_insn (gen_cmpgesf_media (operands[0],
9249 sh_compare_op1, sh_compare_op0));
9250 break;
9251
9252 case DFmode:
9253 if (! TARGET_SHMEDIA_FPU)
9254 FAIL;
9255 emit_insn (gen_cmpgedf_media (operands[0],
9256 sh_compare_op1, sh_compare_op0));
9257 break;
9258
9259 default:
9260 FAIL;
9261 }
9262 DONE;
9263 }
9264
1245df60
R
9265 sh_compare_op0 = sh_compare_op1;
9266 sh_compare_op1 = tmp;
9267 emit_insn (gen_sge (operands[0]));
9268 DONE;
45348d9e 9269}")
bc45ade3
SC
9270
9271(define_expand "sgt"
aa684c94 9272 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9273 (match_dup 1))]
9274 ""
fa5322fa
AO
9275 "
9276{
9277 if (TARGET_SHMEDIA)
9278 {
9279 if (GET_MODE (operands[0]) != DImode)
9280 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9281 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9282 if (sh_compare_op1 != const0_rtx)
9283 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9284 ? GET_MODE (sh_compare_op0)
9285 : GET_MODE (sh_compare_op1),
9286 sh_compare_op1);
9287
9288 switch (GET_MODE (sh_compare_op0))
9289 {
73a4d10b
R
9290 case SImode:
9291 emit_insn (gen_cmpgtsi_media (operands[0],
9292 sh_compare_op0, sh_compare_op1));
9293 break;
9294
fa5322fa
AO
9295 case DImode:
9296 emit_insn (gen_cmpgtdi_media (operands[0],
9297 sh_compare_op0, sh_compare_op1));
9298 break;
9299
9300 case SFmode:
9301 if (! TARGET_SHMEDIA_FPU)
9302 FAIL;
9303 emit_insn (gen_cmpgtsf_media (operands[0],
9304 sh_compare_op0, sh_compare_op1));
9305 break;
9306
9307 case DFmode:
9308 if (! TARGET_SHMEDIA_FPU)
9309 FAIL;
9310 emit_insn (gen_cmpgtdf_media (operands[0],
9311 sh_compare_op0, sh_compare_op1));
9312 break;
9313
9314 default:
9315 FAIL;
9316 }
9317 DONE;
9318 }
4586b4ca 9319 if (! currently_expanding_to_rtl)
3db1b434 9320 FAIL;
fa5322fa
AO
9321 operands[1] = prepare_scc_operands (GT);
9322}")
bc45ade3
SC
9323
9324(define_expand "sge"
aa684c94 9325 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9326 (match_dup 1))]
9327 ""
45348d9e
JW
9328 "
9329{
fa5322fa
AO
9330 if (TARGET_SHMEDIA)
9331 {
73a4d10b
R
9332 enum machine_mode mode = GET_MODE (sh_compare_op0);
9333
9334 if ((mode) == VOIDmode)
9335 mode = GET_MODE (sh_compare_op1);
fa5322fa
AO
9336 if (GET_MODE (operands[0]) != DImode)
9337 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
73a4d10b 9338 sh_compare_op0 = force_reg (mode, sh_compare_op0);
fa5322fa 9339 if (sh_compare_op1 != const0_rtx)
73a4d10b 9340 sh_compare_op1 = force_reg (mode, sh_compare_op1);
fa5322fa 9341
73a4d10b 9342 switch (mode)
fa5322fa 9343 {
73a4d10b
R
9344 case SImode:
9345 {
9346 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9347
9348 emit_insn (gen_cmpgtsi_media (tmp,
9349 sh_compare_op1, sh_compare_op0));
9350 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9351 break;
9352 }
9353
fa5322fa
AO
9354 case DImode:
9355 {
9356 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9357
9358 emit_insn (gen_cmpgtdi_media (tmp,
9359 sh_compare_op1, sh_compare_op0));
9360 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9361 break;
9362 }
9363
9364 case SFmode:
9365 if (! TARGET_SHMEDIA_FPU)
9366 FAIL;
9367 emit_insn (gen_cmpgesf_media (operands[0],
9368 sh_compare_op0, sh_compare_op1));
9369 break;
9370
9371 case DFmode:
9372 if (! TARGET_SHMEDIA_FPU)
9373 FAIL;
9374 emit_insn (gen_cmpgedf_media (operands[0],
9375 sh_compare_op0, sh_compare_op1));
9376 break;
9377
9378 default:
9379 FAIL;
9380 }
9381 DONE;
9382 }
9383
4586b4ca 9384 if (! currently_expanding_to_rtl)
3db1b434 9385 FAIL;
225e4f43 9386 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e 9387 {
1245df60
R
9388 if (TARGET_IEEE)
9389 {
1245df60 9390 rtx lab = gen_label_rtx ();
225e4f43 9391 prepare_scc_operands (EQ);
1245df60 9392 emit_jump_insn (gen_branch_true (lab));
225e4f43 9393 prepare_scc_operands (GT);
1245df60
R
9394 emit_label (lab);
9395 emit_insn (gen_movt (operands[0]));
9396 }
9397 else
9398 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
45348d9e
JW
9399 DONE;
9400 }
9401 operands[1] = prepare_scc_operands (GE);
9402}")
bc45ade3
SC
9403
9404(define_expand "sgtu"
aa684c94 9405 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9406 (match_dup 1))]
9407 ""
fa5322fa
AO
9408 "
9409{
9410 if (TARGET_SHMEDIA)
9411 {
9412 if (GET_MODE (operands[0]) != DImode)
9413 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9414 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9415 if (sh_compare_op1 != const0_rtx)
9416 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9417 ? GET_MODE (sh_compare_op0)
9418 : GET_MODE (sh_compare_op1),
9419 sh_compare_op1);
9420
9421 emit_insn (gen_cmpgtudi_media (operands[0],
9422 sh_compare_op0, sh_compare_op1));
9423 DONE;
9424 }
4586b4ca 9425 if (! currently_expanding_to_rtl)
3db1b434 9426 FAIL;
fa5322fa
AO
9427 operands[1] = prepare_scc_operands (GTU);
9428}")
bc45ade3
SC
9429
9430(define_expand "sltu"
aa684c94 9431 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9432 (match_dup 1))]
9433 ""
fa5322fa
AO
9434 "
9435{
9436 if (TARGET_SHMEDIA)
9437 {
9438 if (GET_MODE (operands[0]) != DImode)
9439 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9440 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9441 if (sh_compare_op1 != const0_rtx)
9442 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9443 ? GET_MODE (sh_compare_op0)
9444 : GET_MODE (sh_compare_op1),
9445 sh_compare_op1);
9446
9447 emit_insn (gen_cmpgtudi_media (operands[0],
9448 sh_compare_op1, sh_compare_op0));
9449 DONE;
9450 }
4586b4ca 9451 if (! currently_expanding_to_rtl)
3db1b434 9452 FAIL;
fa5322fa
AO
9453 operands[1] = prepare_scc_operands (LTU);
9454}")
bc45ade3
SC
9455
9456(define_expand "sleu"
aa684c94 9457 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9458 (match_dup 1))]
9459 ""
fa5322fa
AO
9460 "
9461{
9462 if (TARGET_SHMEDIA)
9463 {
9464 rtx tmp;
9465
9466 if (GET_MODE (operands[0]) != DImode)
9467 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9468 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9469 if (sh_compare_op1 != const0_rtx)
9470 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9471 ? GET_MODE (sh_compare_op0)
9472 : GET_MODE (sh_compare_op1),
9473 sh_compare_op1);
9474
9475 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9476
9477 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9478 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9479
9480 DONE;
9481 }
4586b4ca 9482 if (! currently_expanding_to_rtl)
3db1b434 9483 FAIL;
fa5322fa
AO
9484 operands[1] = prepare_scc_operands (LEU);
9485}")
bc45ade3
SC
9486
9487(define_expand "sgeu"
aa684c94 9488 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
9489 (match_dup 1))]
9490 ""
fa5322fa
AO
9491 "
9492{
9493 if (TARGET_SHMEDIA)
9494 {
9495 rtx tmp;
9496
9497 if (GET_MODE (operands[0]) != DImode)
9498 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9499 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9500 if (sh_compare_op1 != const0_rtx)
9501 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9502 ? GET_MODE (sh_compare_op0)
9503 : GET_MODE (sh_compare_op1),
9504 sh_compare_op1);
9505
9506 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9507
9508 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9509 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9510
9511 DONE;
9512 }
9513
4586b4ca 9514 if (! currently_expanding_to_rtl)
3db1b434 9515 FAIL;
fa5322fa
AO
9516 operands[1] = prepare_scc_operands (GEU);
9517}")
bc45ade3 9518
8bca10f4
JW
9519;; sne moves the complement of the T reg to DEST like this:
9520;; cmp/eq ...
9521;; mov #-1,temp
9522;; negc temp,dest
9523;; This is better than xoring compare result with 1 because it does
9524;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9525;; loop.
9526
bc45ade3 9527(define_expand "sne"
8bca10f4
JW
9528 [(set (match_dup 2) (const_int -1))
9529 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9530 (neg:SI (plus:SI (match_dup 1)
9531 (match_dup 2))))
4773afa4 9532 (set (reg:SI T_REG)
8bca10f4 9533 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
52702ae1 9534 (const_int 0)))])]
8bca10f4
JW
9535 ""
9536 "
9537{
fa5322fa
AO
9538 if (TARGET_SHMEDIA)
9539 {
9540 rtx tmp;
9541
9542 if (GET_MODE (operands[0]) != DImode)
9543 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9544
73a4d10b
R
9545 if (! TARGET_SHMEDIA_FPU
9546 && GET_MODE (sh_compare_op0) != DImode
9547 && GET_MODE (sh_compare_op0) != SImode)
fa5322fa
AO
9548 FAIL;
9549
9550 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9551 if (sh_compare_op1 != const0_rtx)
9552 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9553 ? GET_MODE (sh_compare_op0)
9554 : GET_MODE (sh_compare_op1),
9555 sh_compare_op1);
9556
9557 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9558
9559 emit_insn (gen_seq (tmp));
9560 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9561
9562 DONE;
9563 }
9564
3db1b434
R
9565 if (sh_expand_t_scc (NE, operands[0]))
9566 DONE;
4586b4ca 9567 if (! currently_expanding_to_rtl)
3db1b434
R
9568 FAIL;
9569 operands[1] = prepare_scc_operands (EQ);
9570 operands[2] = gen_reg_rtx (SImode);
8bca10f4
JW
9571}")
9572
fa5322fa
AO
9573(define_expand "sunordered"
9574 [(set (match_operand:DI 0 "arith_reg_operand" "")
9575 (unordered:DI (match_dup 1) (match_dup 2)))]
9576 "TARGET_SHMEDIA_FPU"
9577 "
9578{
9579 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9580 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9581}")
9582
1245df60 9583;; Use the same trick for FP sle / sge
73a4d10b
R
9584
9585;; Apart from the constant use and the T setting, this is like movt,
9586;; except that it uses the logically negated value of T, i.e.
9587;; operand[0] := T ? 0 : 1.
1245df60
R
9588(define_expand "movnegt"
9589 [(set (match_dup 2) (const_int -1))
9590 (parallel [(set (match_operand 0 "" "")
9591 (neg:SI (plus:SI (match_dup 1)
9592 (match_dup 2))))
4773afa4 9593 (set (reg:SI T_REG)
1245df60 9594 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
52702ae1 9595 (const_int 0)))])]
fa5322fa 9596 "TARGET_SH1"
1245df60
R
9597 "operands[2] = gen_reg_rtx (SImode);")
9598
8bca10f4 9599;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
956d6950 9600;; This prevents a regression that occurred when we switched from xor to
8bca10f4
JW
9601;; mov/neg for sne.
9602
9603(define_split
73a4d10b 9604 [(set (match_operand:SI 0 "arith_reg_dest" "")
4773afa4 9605 (plus:SI (reg:SI T_REG)
8bca10f4 9606 (const_int -1)))]
fa5322fa 9607 "TARGET_SH1"
4773afa4 9608 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
8bca10f4
JW
9609 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9610 "")
bc45ade3 9611
0d7e008e
SC
9612;; -------------------------------------------------------------------------
9613;; Instructions to cope with inline literal tables
9614;; -------------------------------------------------------------------------
9615
9616; 2 byte integer in line
b9654711 9617
0d7e008e 9618(define_insn "consttable_2"
b91455de
KK
9619 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9620 (match_operand 1 "" "")]
4773afa4 9621 UNSPECV_CONST2)]
0d7e008e
SC
9622 ""
9623 "*
9624{
b91455de 9625 if (operands[1] != const0_rtx)
c8af3574 9626 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
0d7e008e
SC
9627 return \"\";
9628}"
9629 [(set_attr "length" "2")
9630 (set_attr "in_delay_slot" "no")])
9631
9632; 4 byte integer in line
9633
9634(define_insn "consttable_4"
b91455de
KK
9635 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9636 (match_operand 1 "" "")]
4773afa4 9637 UNSPECV_CONST4)]
0d7e008e
SC
9638 ""
9639 "*
9640{
b91455de 9641 if (operands[1] != const0_rtx)
c8af3574 9642 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
0d7e008e
SC
9643 return \"\";
9644}"
9645 [(set_attr "length" "4")
9646 (set_attr "in_delay_slot" "no")])
9647
9648; 8 byte integer in line
9649
9650(define_insn "consttable_8"
b91455de
KK
9651 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9652 (match_operand 1 "" "")]
4773afa4 9653 UNSPECV_CONST8)]
0d7e008e
SC
9654 ""
9655 "*
9656{
b91455de 9657 if (operands[1] != const0_rtx)
c8af3574 9658 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
0d7e008e
SC
9659 return \"\";
9660}"
9661 [(set_attr "length" "8")
9662 (set_attr "in_delay_slot" "no")])
9663
3e943b59
JR
9664; 4 byte floating point
9665
9666(define_insn "consttable_sf"
b91455de
KK
9667 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9668 (match_operand 1 "" "")]
4773afa4 9669 UNSPECV_CONST4)]
3e943b59
JR
9670 ""
9671 "*
9672{
b91455de
KK
9673 if (operands[1] != const0_rtx)
9674 {
85654444
ZW
9675 REAL_VALUE_TYPE d;
9676 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9677 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
b91455de 9678 }
3e943b59
JR
9679 return \"\";
9680}"
9681 [(set_attr "length" "4")
9682 (set_attr "in_delay_slot" "no")])
9683
9684; 8 byte floating point
9685
9686(define_insn "consttable_df"
b91455de
KK
9687 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9688 (match_operand 1 "" "")]
4773afa4 9689 UNSPECV_CONST8)]
3e943b59
JR
9690 ""
9691 "*
9692{
b91455de
KK
9693 if (operands[1] != const0_rtx)
9694 {
85654444
ZW
9695 REAL_VALUE_TYPE d;
9696 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9697 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
b91455de 9698 }
3e943b59
JR
9699 return \"\";
9700}"
9701 [(set_attr "length" "8")
9702 (set_attr "in_delay_slot" "no")])
9703
1245df60
R
9704;; Alignment is needed for some constant tables; it may also be added for
9705;; Instructions at the start of loops, or after unconditional branches.
9706;; ??? We would get more accurate lengths if we did instruction
9707;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9708;; here is too conservative.
9709
0d7e008e
SC
9710; align to a two byte boundary
9711
33f7f353 9712(define_expand "align_2"
4773afa4 9713 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
0d7e008e 9714 ""
33f7f353 9715 "")
0d7e008e
SC
9716
9717; align to a four byte boundary
1245df60
R
9718;; align_4 and align_log are instructions for the starts of loops, or
9719;; after unconditional branches, which may take up extra room.
9720
9721(define_expand "align_4"
4773afa4 9722 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
1245df60
R
9723 ""
9724 "")
9725
9726; align to a cache line boundary
0d7e008e 9727
1245df60 9728(define_insn "align_log"
4773afa4 9729 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
0d7e008e 9730 ""
33f7f353
JR
9731 ""
9732 [(set_attr "length" "0")
1245df60 9733 (set_attr "in_delay_slot" "no")])
0d7e008e
SC
9734
9735; emitted at the end of the literal table, used to emit the
9736; 32bit branch labels if needed.
9737
9738(define_insn "consttable_end"
4773afa4 9739 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
0d7e008e
SC
9740 ""
9741 "* return output_jump_label_table ();"
9742 [(set_attr "in_delay_slot" "no")])
9743
b91455de
KK
9744; emitted at the end of the window in the literal table.
9745
9746(define_insn "consttable_window_end"
9747 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9748 ""
9749 ""
9750 [(set_attr "length" "0")
9751 (set_attr "in_delay_slot" "no")])
9752
0d7e008e
SC
9753;; -------------------------------------------------------------------------
9754;; Misc
9755;; -------------------------------------------------------------------------
9756
07a45e5c 9757;; String/block move insn.
0d7e008e 9758
70128ad9 9759(define_expand "movmemsi"
0d7e008e
SC
9760 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9761 (mem:BLK (match_operand:BLK 1 "" "")))
9762 (use (match_operand:SI 2 "nonmemory_operand" ""))
9763 (use (match_operand:SI 3 "immediate_operand" ""))
4773afa4
AO
9764 (clobber (reg:SI PR_REG))
9765 (clobber (reg:SI R4_REG))
9766 (clobber (reg:SI R5_REG))
9767 (clobber (reg:SI R0_REG))])]
fa5322fa 9768 "TARGET_SH1 && ! TARGET_SH5"
0d7e008e
SC
9769 "
9770{
9771 if(expand_block_move (operands))
9772 DONE;
9773 else FAIL;
9774}")
9775
9776(define_insn "block_move_real"
4773afa4
AO
9777 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9778 (mem:BLK (reg:SI R5_REG)))
0d7e008e 9779 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
9780 (clobber (reg:SI PR_REG))
9781 (clobber (reg:SI R0_REG))])]
fa5322fa 9782 "TARGET_SH1 && ! TARGET_HARD_SH4"
0d7e008e 9783 "jsr @%0%#"
22e1ebf1 9784 [(set_attr "type" "sfunc")
0d7e008e
SC
9785 (set_attr "needs_delay_slot" "yes")])
9786
9787(define_insn "block_lump_real"
4773afa4
AO
9788 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9789 (mem:BLK (reg:SI R5_REG)))
0d7e008e 9790 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
9791 (use (reg:SI R6_REG))
9792 (clobber (reg:SI PR_REG))
9793 (clobber (reg:SI T_REG))
9794 (clobber (reg:SI R4_REG))
9795 (clobber (reg:SI R5_REG))
9796 (clobber (reg:SI R6_REG))
9797 (clobber (reg:SI R0_REG))])]
fa5322fa 9798 "TARGET_SH1 && ! TARGET_HARD_SH4"
225e4f43
R
9799 "jsr @%0%#"
9800 [(set_attr "type" "sfunc")
9801 (set_attr "needs_delay_slot" "yes")])
9802
9803(define_insn "block_move_real_i4"
4773afa4
AO
9804 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9805 (mem:BLK (reg:SI R5_REG)))
225e4f43 9806 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
9807 (clobber (reg:SI PR_REG))
9808 (clobber (reg:SI R0_REG))
9809 (clobber (reg:SI R1_REG))
9810 (clobber (reg:SI R2_REG))])]
225e4f43
R
9811 "TARGET_HARD_SH4"
9812 "jsr @%0%#"
9813 [(set_attr "type" "sfunc")
9814 (set_attr "needs_delay_slot" "yes")])
9815
9816(define_insn "block_lump_real_i4"
4773afa4
AO
9817 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9818 (mem:BLK (reg:SI R5_REG)))
225e4f43 9819 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
9820 (use (reg:SI R6_REG))
9821 (clobber (reg:SI PR_REG))
9822 (clobber (reg:SI T_REG))
9823 (clobber (reg:SI R4_REG))
9824 (clobber (reg:SI R5_REG))
9825 (clobber (reg:SI R6_REG))
9826 (clobber (reg:SI R0_REG))
9827 (clobber (reg:SI R1_REG))
9828 (clobber (reg:SI R2_REG))
9829 (clobber (reg:SI R3_REG))])]
225e4f43 9830 "TARGET_HARD_SH4"
0d7e008e 9831 "jsr @%0%#"
22e1ebf1 9832 [(set_attr "type" "sfunc")
0d7e008e 9833 (set_attr "needs_delay_slot" "yes")])
45348d9e
JW
9834\f
9835;; -------------------------------------------------------------------------
9836;; Floating point instructions.
9837;; -------------------------------------------------------------------------
9838
9839;; ??? All patterns should have a type attribute.
9840
225e4f43
R
9841(define_expand "movpsi"
9842 [(set (match_operand:PSI 0 "register_operand" "")
9843 (match_operand:PSI 1 "general_movsrc_operand" ""))]
157371cf 9844 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43
R
9845 "")
9846
9847;; The c / m alternative is a fake to guide reload to load directly into
9848;; fpscr, since reload doesn't know how to use post-increment.
9849;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9850;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9851;; predicate after reload.
c49439f1
R
9852;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9853;; like a mac -> gpr move.
225e4f43 9854(define_insn "fpu_switch"
7144b2d8
DD
9855 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9856 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
603ff6b5 9857 "TARGET_SH2E
ecfdeaeb
AO
9858 && (! reload_completed
9859 || true_regnum (operands[0]) != FPSCR_REG
9860 || GET_CODE (operands[1]) != MEM
9861 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
225e4f43
R
9862 "@
9863 ! precision stays the same
9864 lds.l %1,fpscr
9865 mov.l %1,%0
9866 #
9867 lds %1,fpscr
9868 mov %1,%0
9869 mov.l %1,%0
7144b2d8
DD
9870 sts fpscr,%0
9871 sts.l fpscr,%0"
9872 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9873 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
225e4f43 9874
24c2fde2 9875(define_peephole2
4773afa4 9876 [(set (reg:PSI FPSCR_REG)
c1b92d09 9877 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
24c2fde2
RH
9878 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9879 [(const_int 0)]
225e4f43 9880{
24c2fde2 9881 rtx fpscr, mem, new_insn;
57d38024 9882
24c2fde2 9883 fpscr = SET_DEST (PATTERN (curr_insn));
57d38024 9884 mem = SET_SRC (PATTERN (curr_insn));
24c2fde2
RH
9885 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9886
9887 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9888 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9889 DONE;
9890})
225e4f43
R
9891
9892(define_split
4773afa4 9893 [(set (reg:PSI FPSCR_REG)
c1b92d09 9894 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
24c2fde2
RH
9895 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9896 && (flag_peephole2 ? flow2_completed : reload_completed)"
9897 [(const_int 0)]
225e4f43 9898{
24c2fde2 9899 rtx fpscr, mem, new_insn;
57d38024 9900
24c2fde2 9901 fpscr = SET_DEST (PATTERN (curr_insn));
57d38024 9902 mem = SET_SRC (PATTERN (curr_insn));
24c2fde2
RH
9903 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9904
9905 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9906 REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9907
9908 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9909 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9910 DONE;
9911})
225e4f43
R
9912
9913;; ??? This uses the fp unit, but has no type indicating that.
9914;; If we did that, this would either give a bogus latency or introduce
9915;; a bogus FIFO constraint.
9916;; Since this insn is currently only used for prologues/epilogues,
9917;; it is probably best to claim no function unit, which matches the
9918;; current setting.
9919(define_insn "toggle_sz"
4773afa4
AO
9920 [(set (reg:PSI FPSCR_REG)
9921 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
157371cf 9922 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
73774972 9923 "fschg"
312209c6
AO
9924 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9925
9926;; There's no way we can use it today, since optimize mode switching
9927;; doesn't enable us to know from which mode we're switching to the
9928;; mode it requests, to tell whether we can use a relative mode switch
9929;; (like toggle_pr) or an absolute switch (like loading fpscr from
9930;; memory).
9931(define_insn "toggle_pr"
9932 [(set (reg:PSI FPSCR_REG)
9933 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9934 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9935 "fpchg"
9936 [(set_attr "type" "fp")])
225e4f43
R
9937
9938(define_expand "addsf3"
fa5322fa
AO
9939 [(set (match_operand:SF 0 "arith_reg_operand" "")
9940 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9941 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 9942 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
9943 "
9944{
3a8699c7 9945 if (TARGET_SH2E)
fa5322fa
AO
9946 {
9947 expand_sf_binop (&gen_addsf3_i, operands);
9948 DONE;
9949 }
9950}")
9951
9952(define_insn "*addsf3_media"
9953 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9954 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9955 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9956 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9957 "fadd.s %1, %2, %0"
9958 [(set_attr "type" "fparith_media")])
225e4f43 9959
0ac78517
R
9960(define_insn_and_split "unary_sf_op"
9961 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9962 (vec_select:V2SF
9963 (vec_concat:V2SF
9964 (vec_select:SF
9965 (match_dup 0)
9966 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9967 (match_operator:SF 2 "unary_float_operator"
9968 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9969 (parallel [(match_operand 4
9970 "const_int_operand" "n")]))]))
9971 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9972 "TARGET_SHMEDIA_FPU"
9973 "#"
9974 "TARGET_SHMEDIA_FPU && reload_completed"
9975 [(set (match_dup 5) (match_dup 6))]
9976 "
9977{
9978 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9979 rtx op1 = gen_rtx_REG (SFmode,
9980 (true_regnum (operands[1])
9981 + (INTVAL (operands[4]) ^ endian)));
9982
9983 operands[7] = gen_rtx_REG (SFmode,
9984 (true_regnum (operands[0])
9985 + (INTVAL (operands[3]) ^ endian)));
1c563bed 9986 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
0ac78517
R
9987}"
9988 [(set_attr "type" "fparith_media")])
9989
9990(define_insn_and_split "binary_sf_op"
9991 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9992 (vec_select:V2SF
9993 (vec_concat:V2SF
9994 (vec_select:SF
9995 (match_dup 0)
a93d1ba2 9996 (parallel [(match_operand 7 "const_int_operand" "n")]))
0ac78517
R
9997 (match_operator:SF 3 "binary_float_operator"
9998 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9999 (parallel [(match_operand 5
10000 "const_int_operand" "n")]))
10001 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10002 (parallel [(match_operand 6
10003 "const_int_operand" "n")]))]))
a93d1ba2
R
10004 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10005 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
0ac78517 10006 "#"
a93d1ba2
R
10007 "&& reload_completed"
10008 [(set (match_dup 8) (match_dup 9))]
0ac78517
R
10009 "
10010{
10011 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10012 rtx op1 = gen_rtx_REG (SFmode,
10013 (true_regnum (operands[1])
10014 + (INTVAL (operands[5]) ^ endian)));
10015 rtx op2 = gen_rtx_REG (SFmode,
10016 (true_regnum (operands[2])
10017 + (INTVAL (operands[6]) ^ endian)));
10018
a93d1ba2 10019 operands[8] = gen_rtx_REG (SFmode,
0ac78517
R
10020 (true_regnum (operands[0])
10021 + (INTVAL (operands[4]) ^ endian)));
1c563bed 10022 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
0ac78517
R
10023}"
10024 [(set_attr "type" "fparith_media")])
10025
225e4f43 10026(define_insn "addsf3_i"
73a4d10b
R
10027 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10028 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10029 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 10030 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 10031 "TARGET_SH2E"
c1aef54d 10032 "fadd %2,%0"
d64264ff
R
10033 [(set_attr "type" "fp")
10034 (set_attr "fp_mode" "single")])
45348d9e 10035
225e4f43 10036(define_expand "subsf3"
fa5322fa
AO
10037 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10038 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10039 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 10040 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10041 "
10042{
3a8699c7 10043 if (TARGET_SH2E)
fa5322fa
AO
10044 {
10045 expand_sf_binop (&gen_subsf3_i, operands);
10046 DONE;
10047 }
10048}")
10049
10050(define_insn "*subsf3_media"
10051 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10052 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10053 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10054 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10055 "fsub.s %1, %2, %0"
10056 [(set_attr "type" "fparith_media")])
225e4f43
R
10057
10058(define_insn "subsf3_i"
66c0b347
R
10059 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10060 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10061 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 10062 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 10063 "TARGET_SH2E"
c1aef54d 10064 "fsub %2,%0"
d64264ff
R
10065 [(set_attr "type" "fp")
10066 (set_attr "fp_mode" "single")])
45348d9e 10067
225e4f43
R
10068;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10069;; register in feeding fp instructions. Thus, we cannot generate fmac for
10070;; mixed-precision SH4 targets. To allow it to be still generated for the
10071;; SH3E, we use a separate insn for SH3E mulsf3.
10072
10073(define_expand "mulsf3"
fa5322fa
AO
10074 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10075 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10076 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 10077 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
10078 "
10079{
157371cf 10080 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
225e4f43 10081 expand_sf_binop (&gen_mulsf3_i4, operands);
3a8699c7 10082 else if (TARGET_SH2E)
225e4f43 10083 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
fa5322fa
AO
10084 if (! TARGET_SHMEDIA)
10085 DONE;
225e4f43
R
10086}")
10087
fa5322fa
AO
10088(define_insn "*mulsf3_media"
10089 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10090 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10091 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10092 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10093 "fmul.s %1, %2, %0"
10094 [(set_attr "type" "fparith_media")])
fa5322fa 10095
225e4f43 10096(define_insn "mulsf3_i4"
4b9580a5
R
10097 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10098 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10099 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 10100 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 10101 "TARGET_SH2E"
c1aef54d 10102 "fmul %2,%0"
d64264ff
R
10103 [(set_attr "type" "fp")
10104 (set_attr "fp_mode" "single")])
45348d9e 10105
225e4f43 10106(define_insn "mulsf3_ie"
4b9580a5
R
10107 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10108 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10109 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
157371cf 10110 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
225e4f43
R
10111 "fmul %2,%0"
10112 [(set_attr "type" "fp")])
10113
73a4d10b 10114(define_insn "mac_media"
fa5322fa
AO
10115 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10116 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10117 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10118 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10119 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10120 "fmac.s %1, %2, %0"
10121 [(set_attr "type" "fparith_media")])
fa5322fa 10122
45348d9e 10123(define_insn "*macsf3"
4b9580a5
R
10124 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10125 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10126 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
225e4f43
R
10127 (match_operand:SF 3 "arith_reg_operand" "0")))
10128 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
3a8699c7 10129 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 10130 "fmac fr0,%2,%0"
d64264ff
R
10131 [(set_attr "type" "fp")
10132 (set_attr "fp_mode" "single")])
45348d9e 10133
225e4f43 10134(define_expand "divsf3"
fa5322fa
AO
10135 [(set (match_operand:SF 0 "arith_reg_operand" "")
10136 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10137 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 10138 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10139 "
10140{
3a8699c7 10141 if (TARGET_SH2E)
fa5322fa
AO
10142 {
10143 expand_sf_binop (&gen_divsf3_i, operands);
10144 DONE;
10145 }
10146}")
10147
10148(define_insn "*divsf3_media"
10149 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10150 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10151 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10152 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10153 "fdiv.s %1, %2, %0"
10154 [(set_attr "type" "fdiv_media")])
225e4f43
R
10155
10156(define_insn "divsf3_i"
73a4d10b 10157 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
45348d9e 10158 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
225e4f43
R
10159 (match_operand:SF 2 "arith_reg_operand" "f")))
10160 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 10161 "TARGET_SH2E"
c1aef54d 10162 "fdiv %2,%0"
d64264ff
R
10163 [(set_attr "type" "fdiv")
10164 (set_attr "fp_mode" "single")])
45348d9e 10165
fa5322fa
AO
10166(define_insn "floatdisf2"
10167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10168 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10169 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10170 "float.qs %1, %0"
10171 [(set_attr "type" "fpconv_media")])
fa5322fa 10172
1245df60 10173(define_expand "floatsisf2"
4b9580a5
R
10174 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10175 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
3a8699c7 10176 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
10177 "
10178{
157371cf 10179 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
225e4f43 10180 {
0c4c9b16 10181 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
10182 DONE;
10183 }
225e4f43
R
10184}")
10185
fa5322fa
AO
10186(define_insn "*floatsisf2_media"
10187 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10188 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10189 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10190 "float.ls %1, %0"
10191 [(set_attr "type" "fpconv_media")])
fa5322fa 10192
225e4f43 10193(define_insn "floatsisf2_i4"
4b9580a5
R
10194 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10195 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 10196 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10197 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
0c4c9b16 10198 "float %1,%0"
d64264ff
R
10199 [(set_attr "type" "fp")
10200 (set_attr "fp_mode" "single")])
45348d9e 10201
0f805606 10202(define_insn "*floatsisf2_ie"
4b9580a5
R
10203 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10204 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
157371cf 10205 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
0f805606
BS
10206 "float %1,%0"
10207 [(set_attr "type" "fp")])
45348d9e 10208
fa5322fa 10209(define_insn "fix_truncsfdi2"
73a4d10b 10210 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
fa5322fa
AO
10211 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10212 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10213 "ftrc.sq %1, %0"
10214 [(set_attr "type" "fpconv_media")])
fa5322fa 10215
1245df60 10216(define_expand "fix_truncsfsi2"
4b9580a5
R
10217 [(set (match_operand:SI 0 "fpul_operand" "=y")
10218 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 10219 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
10220 "
10221{
157371cf 10222 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
225e4f43 10223 {
0c4c9b16 10224 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
10225 DONE;
10226 }
10227}")
10228
fa5322fa
AO
10229(define_insn "*fix_truncsfsi2_media"
10230 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10231 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10232 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10233 "ftrc.sl %1, %0"
10234 [(set_attr "type" "fpconv_media")])
fa5322fa 10235
225e4f43 10236(define_insn "fix_truncsfsi2_i4"
4b9580a5
R
10237 [(set (match_operand:SI 0 "fpul_operand" "=y")
10238 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 10239 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10240 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
0c4c9b16 10241 "ftrc %1,%0"
c49439f1 10242 [(set_attr "type" "ftrc_s")
d64264ff 10243 (set_attr "fp_mode" "single")])
225e4f43 10244
0c4c9b16
BS
10245;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10246;; fix_truncsfsi2_i4.
10247;; (define_insn "fix_truncsfsi2_i4_2"
10248;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10249;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
5d00b10a 10250;; (use (reg:PSI FPSCR_REG))
4773afa4 10251;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
10252;; "TARGET_SH4"
10253;; "#"
10254;; [(set_attr "length" "4")
10255;; (set_attr "fp_mode" "single")])
10256
10257;;(define_split
10258;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10259;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10260;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 10261;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 10262;; "TARGET_SH4"
4773afa4 10263;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 10264;; (use (match_dup 2))])
4773afa4 10265;; (set (match_dup 0) (reg:SI FPUL_REG))])
45348d9e 10266
1245df60 10267(define_insn "*fixsfsi"
4b9580a5
R
10268 [(set (match_operand:SI 0 "fpul_operand" "=y")
10269 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
157371cf 10270 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
0c4c9b16 10271 "ftrc %1,%0"
1245df60 10272 [(set_attr "type" "fp")])
45348d9e 10273
1245df60 10274(define_insn "cmpgtsf_t"
4773afa4
AO
10275 [(set (reg:SI T_REG)
10276 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10277 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
157371cf 10278 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
c1aef54d 10279 "fcmp/gt %1,%0"
d64264ff
R
10280 [(set_attr "type" "fp")
10281 (set_attr "fp_mode" "single")])
45348d9e 10282
1245df60 10283(define_insn "cmpeqsf_t"
4773afa4
AO
10284 [(set (reg:SI T_REG)
10285 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10286 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
157371cf 10287 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
c1aef54d 10288 "fcmp/eq %1,%0"
d64264ff
R
10289 [(set_attr "type" "fp")
10290 (set_attr "fp_mode" "single")])
45348d9e 10291
1245df60 10292(define_insn "ieee_ccmpeqsf_t"
4773afa4
AO
10293 [(set (reg:SI T_REG)
10294 (ior:SI (reg:SI T_REG)
4b9580a5
R
10295 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10296 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
157371cf 10297 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
1245df60
R
10298 "* return output_ieee_ccmpeq (insn, operands);"
10299 [(set_attr "length" "4")])
10300
10301
225e4f43 10302(define_insn "cmpgtsf_t_i4"
4773afa4
AO
10303 [(set (reg:SI T_REG)
10304 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10305 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43 10306 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10307 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
225e4f43 10308 "fcmp/gt %1,%0"
d64264ff
R
10309 [(set_attr "type" "fp")
10310 (set_attr "fp_mode" "single")])
225e4f43
R
10311
10312(define_insn "cmpeqsf_t_i4"
4773afa4
AO
10313 [(set (reg:SI T_REG)
10314 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10315 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43 10316 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10317 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
225e4f43 10318 "fcmp/eq %1,%0"
d64264ff
R
10319 [(set_attr "type" "fp")
10320 (set_attr "fp_mode" "single")])
225e4f43
R
10321
10322(define_insn "*ieee_ccmpeqsf_t_4"
4773afa4
AO
10323 [(set (reg:SI T_REG)
10324 (ior:SI (reg:SI T_REG)
4b9580a5
R
10325 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10326 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
225e4f43 10327 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10328 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
225e4f43 10329 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
10330 [(set_attr "length" "4")
10331 (set_attr "fp_mode" "single")])
225e4f43 10332
fa5322fa
AO
10333(define_insn "cmpeqsf_media"
10334 [(set (match_operand:DI 0 "register_operand" "=r")
10335 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10336 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10337 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10338 "fcmpeq.s %1, %2, %0"
10339 [(set_attr "type" "fcmp_media")])
fa5322fa 10340
73a4d10b
R
10341(define_insn "cmpsieqsf_media"
10342 [(set (match_operand:SI 0 "register_operand" "=r")
10343 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10344 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10345 "TARGET_SHMEDIA_FPU"
10346 "fcmpeq.s %1, %2, %0"
10347 [(set_attr "type" "fcmp_media")])
10348
fa5322fa
AO
10349(define_insn "cmpgtsf_media"
10350 [(set (match_operand:DI 0 "register_operand" "=r")
10351 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10352 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10353 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10354 "fcmpgt.s %1, %2, %0"
10355 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
10356
10357(define_insn "cmpgesf_media"
10358 [(set (match_operand:DI 0 "register_operand" "=r")
10359 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10360 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10361 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10362 "fcmpge.s %1, %2, %0"
10363 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
10364
10365(define_insn "cmpunsf_media"
10366 [(set (match_operand:DI 0 "register_operand" "=r")
10367 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10368 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10369 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10370 "fcmpun.s %1, %2, %0"
10371 [(set_attr "type" "fcmp_media")])
fa5322fa 10372
45348d9e 10373(define_expand "cmpsf"
4773afa4
AO
10374 [(set (reg:SI T_REG)
10375 (compare (match_operand:SF 0 "arith_operand" "")
10376 (match_operand:SF 1 "arith_operand" "")))]
3a8699c7 10377 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
45348d9e
JW
10378 "
10379{
10380 sh_compare_op0 = operands[0];
10381 sh_compare_op1 = operands[1];
10382 DONE;
10383}")
b9654711 10384
225e4f43 10385(define_expand "negsf2"
fa5322fa
AO
10386 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10387 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 10388 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10389 "
10390{
3a8699c7 10391 if (TARGET_SH2E)
fa5322fa
AO
10392 {
10393 expand_sf_unop (&gen_negsf2_i, operands);
10394 DONE;
10395 }
10396}")
10397
10398(define_insn "*negsf2_media"
10399 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10400 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10401 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10402 "fneg.s %1, %0"
10403 [(set_attr "type" "fmove_media")])
225e4f43
R
10404
10405(define_insn "negsf2_i"
4b9580a5
R
10406 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10407 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 10408 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 10409 "TARGET_SH2E"
c1aef54d 10410 "fneg %0"
d64264ff
R
10411 [(set_attr "type" "fmove")
10412 (set_attr "fp_mode" "single")])
45348d9e 10413
225e4f43 10414(define_expand "sqrtsf2"
fa5322fa
AO
10415 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10416 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10417 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10418 "
10419{
10420 if (TARGET_SH3E)
10421 {
10422 expand_sf_unop (&gen_sqrtsf2_i, operands);
10423 DONE;
10424 }
10425}")
10426
10427(define_insn "*sqrtsf2_media"
10428 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10429 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10430 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10431 "fsqrt.s %1, %0"
10432 [(set_attr "type" "fdiv_media")])
225e4f43
R
10433
10434(define_insn "sqrtsf2_i"
4b9580a5
R
10435 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10436 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 10437 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 10438 "TARGET_SH3E"
c1aef54d 10439 "fsqrt %0"
d64264ff
R
10440 [(set_attr "type" "fdiv")
10441 (set_attr "fp_mode" "single")])
45348d9e 10442
312209c6
AO
10443(define_insn "rsqrtsf2"
10444 [(set (match_operand:SF 0 "register_operand" "=f")
10445 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10446 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10447 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10448 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10449 && operands[1] == CONST1_RTX (SFmode)"
10450 "fsrra %0"
10451 [(set_attr "type" "fsrra")
10452 (set_attr "fp_mode" "single")])
10453
10454(define_insn "fsca"
10455 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10456 (vec_concat:V2SF
10457 (unspec:SF [(mult:SF
10458 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10459 (match_operand:SF 2 "immediate_operand" "i"))
10460 ] UNSPEC_FSINA)
10461 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10462 ] UNSPEC_FCOSA)))
10463 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10464 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10465 && operands[2] == sh_fsca_int2sf ()"
10466 "fsca fpul,%d0"
10467 [(set_attr "type" "fsca")
10468 (set_attr "fp_mode" "single")])
10469
10470(define_expand "sinsf2"
10471 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10472 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10473 UNSPEC_FSINA))]
10474 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10475 "
10476{
10477 rtx scaled = gen_reg_rtx (SFmode);
10478 rtx truncated = gen_reg_rtx (SImode);
10479 rtx fsca = gen_reg_rtx (V2SFmode);
10480 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10481
10482 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10483 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10484 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10485 get_fpscr_rtx ()));
10486 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10487 DONE;
10488}")
10489
10490(define_expand "cossf2"
10491 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10492 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10493 UNSPEC_FCOSA))]
10494 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10495 "
10496{
10497 rtx scaled = gen_reg_rtx (SFmode);
10498 rtx truncated = gen_reg_rtx (SImode);
10499 rtx fsca = gen_reg_rtx (V2SFmode);
10500 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10501
10502 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10503 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10504 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10505 get_fpscr_rtx ()));
10506 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10507 DONE;
10508}")
10509
10510(define_expand "sindf2"
10511 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10512 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10513 UNSPEC_FSINA))]
10514 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10515 "
10516{
10517 rtx scaled = gen_reg_rtx (DFmode);
10518 rtx truncated = gen_reg_rtx (SImode);
10519 rtx fsca = gen_reg_rtx (V2SFmode);
10520 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10521 rtx sfresult = gen_reg_rtx (SFmode);
10522
10523 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10524 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10525 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10526 get_fpscr_rtx ()));
10527 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10528 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10529 DONE;
10530}")
10531
10532(define_expand "cosdf2"
10533 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10534 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10535 UNSPEC_FCOSA))]
10536 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10537 "
10538{
10539 rtx scaled = gen_reg_rtx (DFmode);
10540 rtx truncated = gen_reg_rtx (SImode);
10541 rtx fsca = gen_reg_rtx (V2SFmode);
10542 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10543 rtx sfresult = gen_reg_rtx (SFmode);
10544
10545 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10546 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10547 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10548 get_fpscr_rtx ()));
10549 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10550 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10551 DONE;
10552}")
10553
225e4f43 10554(define_expand "abssf2"
fa5322fa
AO
10555 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10556 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 10557 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10558 "
10559{
3a8699c7 10560 if (TARGET_SH2E)
fa5322fa
AO
10561 {
10562 expand_sf_unop (&gen_abssf2_i, operands);
10563 DONE;
10564 }
10565}")
10566
10567(define_insn "*abssf2_media"
10568 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10569 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10570 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10571 "fabs.s %1, %0"
10572 [(set_attr "type" "fmove_media")])
225e4f43
R
10573
10574(define_insn "abssf2_i"
4b9580a5
R
10575 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10576 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 10577 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 10578 "TARGET_SH2E"
c1aef54d 10579 "fabs %0"
d64264ff
R
10580 [(set_attr "type" "fmove")
10581 (set_attr "fp_mode" "single")])
225e4f43
R
10582
10583(define_expand "adddf3"
fa5322fa
AO
10584 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10585 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10586 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
157371cf 10587 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10588 "
10589{
157371cf 10590 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10591 {
10592 expand_df_binop (&gen_adddf3_i, operands);
10593 DONE;
10594 }
10595}")
10596
10597(define_insn "*adddf3_media"
10598 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10599 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10600 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10601 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10602 "fadd.d %1, %2, %0"
10603 [(set_attr "type" "dfparith_media")])
225e4f43
R
10604
10605(define_insn "adddf3_i"
4b9580a5
R
10606 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10607 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10608 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43 10609 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
157371cf 10610 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10611 "fadd %2,%0"
d64264ff
R
10612 [(set_attr "type" "dfp_arith")
10613 (set_attr "fp_mode" "double")])
225e4f43
R
10614
10615(define_expand "subdf3"
fa5322fa
AO
10616 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10617 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10618 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
157371cf 10619 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10620 "
10621{
157371cf 10622 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10623 {
10624 expand_df_binop (&gen_subdf3_i, operands);
10625 DONE;
10626 }
10627}")
10628
10629(define_insn "*subdf3_media"
10630 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10631 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10632 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10633 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10634 "fsub.d %1, %2, %0"
10635 [(set_attr "type" "dfparith_media")])
225e4f43
R
10636
10637(define_insn "subdf3_i"
4b9580a5
R
10638 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10639 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10640 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43 10641 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
157371cf 10642 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10643 "fsub %2,%0"
d64264ff
R
10644 [(set_attr "type" "dfp_arith")
10645 (set_attr "fp_mode" "double")])
225e4f43
R
10646
10647(define_expand "muldf3"
fa5322fa
AO
10648 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10649 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10650 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
157371cf 10651 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10652 "
10653{
157371cf 10654 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10655 {
10656 expand_df_binop (&gen_muldf3_i, operands);
10657 DONE;
10658 }
10659}")
10660
10661(define_insn "*muldf3_media"
10662 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10663 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10664 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10665 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10666 "fmul.d %1, %2, %0"
10667 [(set_attr "type" "dfmul_media")])
225e4f43
R
10668
10669(define_insn "muldf3_i"
4b9580a5
R
10670 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10671 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10672 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43 10673 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
157371cf 10674 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10675 "fmul %2,%0"
d64264ff
R
10676 [(set_attr "type" "dfp_arith")
10677 (set_attr "fp_mode" "double")])
225e4f43
R
10678
10679(define_expand "divdf3"
fa5322fa
AO
10680 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10681 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10682 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
157371cf 10683 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10684 "
10685{
157371cf 10686 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10687 {
10688 expand_df_binop (&gen_divdf3_i, operands);
10689 DONE;
10690 }
10691}")
10692
10693(define_insn "*divdf3_media"
10694 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10695 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10696 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10697 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10698 "fdiv.d %1, %2, %0"
10699 [(set_attr "type" "dfdiv_media")])
225e4f43
R
10700
10701(define_insn "divdf3_i"
4b9580a5
R
10702 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10703 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10704 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43 10705 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
157371cf 10706 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10707 "fdiv %2,%0"
d64264ff
R
10708 [(set_attr "type" "dfdiv")
10709 (set_attr "fp_mode" "double")])
225e4f43 10710
fa5322fa
AO
10711(define_insn "floatdidf2"
10712 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10713 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10714 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10715 "float.qd %1, %0"
10716 [(set_attr "type" "dfpconv_media")])
fa5322fa 10717
225e4f43 10718(define_expand "floatsidf2"
fa5322fa
AO
10719 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10720 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
157371cf 10721 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
225e4f43
R
10722 "
10723{
157371cf 10724 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10725 {
10726 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10727 get_fpscr_rtx ()));
10728 DONE;
10729 }
225e4f43
R
10730}")
10731
fa5322fa
AO
10732(define_insn "*floatsidf2_media"
10733 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10734 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10735 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10736 "float.ld %1, %0"
10737 [(set_attr "type" "dfpconv_media")])
fa5322fa 10738
225e4f43 10739(define_insn "floatsidf2_i"
4b9580a5
R
10740 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10741 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 10742 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10743 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
0c4c9b16 10744 "float %1,%0"
d64264ff
R
10745 [(set_attr "type" "dfp_conv")
10746 (set_attr "fp_mode" "double")])
225e4f43 10747
fa5322fa 10748(define_insn "fix_truncdfdi2"
73a4d10b 10749 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
fa5322fa
AO
10750 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10751 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10752 "ftrc.dq %1, %0"
10753 [(set_attr "type" "dfpconv_media")])
fa5322fa 10754
225e4f43 10755(define_expand "fix_truncdfsi2"
fa5322fa
AO
10756 [(set (match_operand:SI 0 "fpul_operand" "")
10757 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
157371cf 10758 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
225e4f43
R
10759 "
10760{
157371cf 10761 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10762 {
10763 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10764 get_fpscr_rtx ()));
10765 DONE;
10766 }
225e4f43
R
10767}")
10768
fa5322fa
AO
10769(define_insn "*fix_truncdfsi2_media"
10770 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10771 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10772 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10773 "ftrc.dl %1, %0"
10774 [(set_attr "type" "dfpconv_media")])
fa5322fa 10775
225e4f43 10776(define_insn "fix_truncdfsi2_i"
4b9580a5
R
10777 [(set (match_operand:SI 0 "fpul_operand" "=y")
10778 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 10779 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10780 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
0c4c9b16
BS
10781 "ftrc %1,%0"
10782 [(set_attr "type" "dfp_conv")
c49439f1 10783 (set_attr "dfp_comp" "no")
d64264ff 10784 (set_attr "fp_mode" "double")])
225e4f43 10785
0c4c9b16
BS
10786;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10787;; fix_truncdfsi2_i.
10788;; (define_insn "fix_truncdfsi2_i4"
10789;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10790;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10791;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 10792;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
10793;; "TARGET_SH4"
10794;; "#"
10795;; [(set_attr "length" "4")
10796;; (set_attr "fp_mode" "double")])
52702ae1 10797;;
0c4c9b16
BS
10798;; (define_split
10799;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10800;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10801;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 10802;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 10803;; "TARGET_SH4"
4773afa4 10804;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 10805;; (use (match_dup 2))])
4773afa4 10806;; (set (match_dup 0) (reg:SI FPUL_REG))])
225e4f43
R
10807
10808(define_insn "cmpgtdf_t"
4773afa4
AO
10809 [(set (reg:SI T_REG)
10810 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10811 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43 10812 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10813 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10814 "fcmp/gt %1,%0"
d64264ff
R
10815 [(set_attr "type" "dfp_cmp")
10816 (set_attr "fp_mode" "double")])
225e4f43
R
10817
10818(define_insn "cmpeqdf_t"
4773afa4
AO
10819 [(set (reg:SI T_REG)
10820 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10821 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43 10822 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10823 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10824 "fcmp/eq %1,%0"
d64264ff
R
10825 [(set_attr "type" "dfp_cmp")
10826 (set_attr "fp_mode" "double")])
225e4f43
R
10827
10828(define_insn "*ieee_ccmpeqdf_t"
4773afa4
AO
10829 [(set (reg:SI T_REG)
10830 (ior:SI (reg:SI T_REG)
10831 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10832 (match_operand:DF 1 "arith_reg_operand" "f"))))
225e4f43 10833 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10834 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10835 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
10836 [(set_attr "length" "4")
10837 (set_attr "fp_mode" "double")])
52702ae1 10838
fa5322fa
AO
10839(define_insn "cmpeqdf_media"
10840 [(set (match_operand:DI 0 "register_operand" "=r")
10841 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10842 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10843 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10844 "fcmpeq.d %1,%2,%0"
10845 [(set_attr "type" "fcmp_media")])
fa5322fa 10846
73a4d10b
R
10847(define_insn "cmpsieqdf_media"
10848 [(set (match_operand:SI 0 "register_operand" "=r")
10849 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10850 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10851 "TARGET_SHMEDIA_FPU"
10852 "fcmpeq.d %1,%2,%0"
10853 [(set_attr "type" "fcmp_media")])
10854
fa5322fa
AO
10855(define_insn "cmpgtdf_media"
10856 [(set (match_operand:DI 0 "register_operand" "=r")
10857 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10858 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10859 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10860 "fcmpgt.d %1,%2,%0"
10861 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
10862
10863(define_insn "cmpgedf_media"
10864 [(set (match_operand:DI 0 "register_operand" "=r")
10865 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10866 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10867 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10868 "fcmpge.d %1,%2,%0"
10869 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
10870
10871(define_insn "cmpundf_media"
10872 [(set (match_operand:DI 0 "register_operand" "=r")
10873 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10874 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10875 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10876 "fcmpun.d %1,%2,%0"
10877 [(set_attr "type" "fcmp_media")])
fa5322fa 10878
225e4f43 10879(define_expand "cmpdf"
4773afa4
AO
10880 [(set (reg:SI T_REG)
10881 (compare (match_operand:DF 0 "arith_operand" "")
10882 (match_operand:DF 1 "arith_operand" "")))]
157371cf 10883 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
225e4f43
R
10884 "
10885{
10886 sh_compare_op0 = operands[0];
10887 sh_compare_op1 = operands[1];
10888 DONE;
10889}")
10890
10891(define_expand "negdf2"
fa5322fa
AO
10892 [(set (match_operand:DF 0 "arith_reg_operand" "")
10893 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
157371cf 10894 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10895 "
10896{
157371cf 10897 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10898 {
10899 expand_df_unop (&gen_negdf2_i, operands);
10900 DONE;
10901 }
10902}")
10903
10904(define_insn "*negdf2_media"
10905 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10906 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10907 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10908 "fneg.d %1, %0"
10909 [(set_attr "type" "fmove_media")])
225e4f43
R
10910
10911(define_insn "negdf2_i"
73a4d10b
R
10912 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10913 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
225e4f43 10914 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10915 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10916 "fneg %0"
d64264ff
R
10917 [(set_attr "type" "fmove")
10918 (set_attr "fp_mode" "double")])
225e4f43
R
10919
10920(define_expand "sqrtdf2"
fa5322fa
AO
10921 [(set (match_operand:DF 0 "arith_reg_operand" "")
10922 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
157371cf 10923 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10924 "
10925{
157371cf 10926 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10927 {
10928 expand_df_unop (&gen_sqrtdf2_i, operands);
10929 DONE;
10930 }
10931}")
10932
10933(define_insn "*sqrtdf2_media"
10934 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10935 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10936 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10937 "fsqrt.d %1, %0"
10938 [(set_attr "type" "dfdiv_media")])
225e4f43
R
10939
10940(define_insn "sqrtdf2_i"
73a4d10b
R
10941 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10942 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
225e4f43 10943 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10944 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10945 "fsqrt %0"
d64264ff
R
10946 [(set_attr "type" "dfdiv")
10947 (set_attr "fp_mode" "double")])
225e4f43
R
10948
10949(define_expand "absdf2"
fa5322fa
AO
10950 [(set (match_operand:DF 0 "arith_reg_operand" "")
10951 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
157371cf 10952 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
fa5322fa
AO
10953 "
10954{
157371cf 10955 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10956 {
10957 expand_df_unop (&gen_absdf2_i, operands);
10958 DONE;
10959 }
10960}")
10961
10962(define_insn "*absdf2_media"
10963 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10964 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10965 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10966 "fabs.d %1, %0"
10967 [(set_attr "type" "fmove_media")])
225e4f43
R
10968
10969(define_insn "absdf2_i"
73a4d10b
R
10970 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10971 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
225e4f43 10972 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 10973 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
225e4f43 10974 "fabs %0"
d64264ff
R
10975 [(set_attr "type" "fmove")
10976 (set_attr "fp_mode" "double")])
225e4f43
R
10977
10978(define_expand "extendsfdf2"
fa5322fa
AO
10979 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10980 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
157371cf 10981 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
225e4f43
R
10982 "
10983{
157371cf 10984 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
10985 {
10986 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10987 get_fpscr_rtx ()));
10988 DONE;
10989 }
225e4f43
R
10990}")
10991
fa5322fa
AO
10992(define_insn "*extendsfdf2_media"
10993 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10994 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10995 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
10996 "fcnv.sd %1, %0"
10997 [(set_attr "type" "dfpconv_media")])
fa5322fa 10998
225e4f43 10999(define_insn "extendsfdf2_i4"
4b9580a5
R
11000 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11001 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
0c4c9b16 11002 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 11003 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
0c4c9b16 11004 "fcnvsd %1,%0"
d64264ff
R
11005 [(set_attr "type" "fp")
11006 (set_attr "fp_mode" "double")])
225e4f43
R
11007
11008(define_expand "truncdfsf2"
fa5322fa
AO
11009 [(set (match_operand:SF 0 "fpul_operand" "")
11010 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
157371cf 11011 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
225e4f43
R
11012 "
11013{
157371cf 11014 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
fa5322fa
AO
11015 {
11016 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11017 get_fpscr_rtx ()));
11018 DONE;
11019 }
225e4f43
R
11020}")
11021
fa5322fa
AO
11022(define_insn "*truncdfsf2_media"
11023 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11024 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11025 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
11026 "fcnv.ds %1, %0"
11027 [(set_attr "type" "dfpconv_media")])
fa5322fa 11028
225e4f43 11029(define_insn "truncdfsf2_i4"
4b9580a5
R
11030 [(set (match_operand:SF 0 "fpul_operand" "=y")
11031 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 11032 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
157371cf 11033 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
0c4c9b16 11034 "fcnvds %1,%0"
d64264ff
R
11035 [(set_attr "type" "fp")
11036 (set_attr "fp_mode" "double")])
45348d9e 11037\f
725de644
JW
11038;; Bit field extract patterns. These give better code for packed bitfields,
11039;; because they allow auto-increment addresses to be generated.
11040
11041(define_expand "insv"
11042 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11043 (match_operand:SI 1 "immediate_operand" "")
11044 (match_operand:SI 2 "immediate_operand" ""))
11045 (match_operand:SI 3 "general_operand" ""))]
fa5322fa 11046 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
725de644
JW
11047 "
11048{
a7f52356 11049 rtx addr_target, orig_address, shift_reg, qi_val;
45dc67b7 11050 HOST_WIDE_INT bitsize, size, v = 0;
a7f52356 11051 rtx x = operands[3];
725de644
JW
11052
11053 /* ??? expmed doesn't care for non-register predicates. */
11054 if (! memory_operand (operands[0], VOIDmode)
11055 || ! immediate_operand (operands[1], VOIDmode)
11056 || ! immediate_operand (operands[2], VOIDmode)
a7f52356 11057 || ! general_operand (x, VOIDmode))
725de644
JW
11058 FAIL;
11059 /* If this isn't a 16 / 24 / 32 bit field, or if
11060 it doesn't start on a byte boundary, then fail. */
a7f52356
R
11061 bitsize = INTVAL (operands[1]);
11062 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
725de644
JW
11063 || (INTVAL (operands[2]) % 8) != 0)
11064 FAIL;
11065
a7f52356 11066 size = bitsize / 8;
725de644 11067 orig_address = XEXP (operands[0], 0);
725de644 11068 shift_reg = gen_reg_rtx (SImode);
a7f52356
R
11069 if (GET_CODE (x) == CONST_INT)
11070 {
11071 v = INTVAL (x);
11072 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11073 }
11074 else
11075 {
11076 emit_insn (gen_movsi (shift_reg, operands[3]));
11077 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11078 }
ea3cbda5 11079 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
725de644 11080
792760b9 11081 operands[0] = replace_equiv_address (operands[0], addr_target);
a7f52356 11082 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
11083
11084 while (size -= 1)
11085 {
a7f52356
R
11086 if (GET_CODE (x) == CONST_INT)
11087 qi_val
11088 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11089 else
11090 {
11091 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11092 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11093 }
a556fd39 11094 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
a7f52356 11095 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
11096 }
11097
11098 DONE;
11099}")
312209c6
AO
11100
11101(define_insn "movua"
11102 [(set (match_operand:SI 0 "register_operand" "=z")
11103 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11104 (const_int 32) (const_int 0)))]
11105 "TARGET_SH4A_ARCH"
11106 "movua.l %1,%0"
11107 [(set_attr "type" "movua")])
11108
11109;; We shouldn't need this, but cse replaces increments with references
11110;; to other regs before flow has a chance to create post_inc
11111;; addressing modes, and only postreload's cse_move2add brings the
11112;; increments back to a usable form.
11113(define_peephole2
11114 [(set (match_operand:SI 0 "register_operand" "")
11115 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11116 (const_int 32) (const_int 0)))
11117 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11118 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11119 [(set (match_operand:SI 0 "register_operand" "")
11120 (sign_extract:SI (mem:SI (post_inc:SI
11121 (match_operand:SI 1 "register_operand" "")))
11122 (const_int 32) (const_int 0)))]
11123 "")
11124
11125(define_expand "extv"
11126 [(set (match_operand:SI 0 "register_operand" "")
11127 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11128 (match_operand 2 "const_int_operand" "")
11129 (match_operand 3 "const_int_operand" "")))]
dea1c1c5 11130 "TARGET_SH4A_ARCH"
312209c6
AO
11131{
11132 if (TARGET_SH4A_ARCH
11133 && INTVAL (operands[2]) == 32
11134 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11135 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11136 {
11137 emit_insn (gen_movua (operands[0],
11138 adjust_address (operands[1], SImode, 0)));
11139 DONE;
11140 }
11141
11142 FAIL;
11143})
11144
11145(define_expand "extzv"
11146 [(set (match_operand:SI 0 "register_operand" "")
11147 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11148 (match_operand 2 "const_int_operand" "")
11149 (match_operand 3 "const_int_operand" "")))]
dea1c1c5 11150 "TARGET_SH4A_ARCH"
312209c6
AO
11151{
11152 if (TARGET_SH4A_ARCH
11153 && INTVAL (operands[2]) == 32
11154 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11155 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11156 {
11157 emit_insn (gen_movua (operands[0],
11158 adjust_address (operands[1], SImode, 0)));
11159 DONE;
11160 }
11161
11162 FAIL;
11163})
11164
725de644 11165\f
51bd623f
JW
11166;; -------------------------------------------------------------------------
11167;; Peepholes
11168;; -------------------------------------------------------------------------
961c4780 11169
51bd623f
JW
11170;; This matches cases where a stack pointer increment at the start of the
11171;; epilogue combines with a stack slot read loading the return value.
aa684c94 11172
07a45e5c 11173(define_peephole
51bd623f
JW
11174 [(set (match_operand:SI 0 "arith_reg_operand" "")
11175 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11176 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
fa5322fa 11177 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
51bd623f 11178 "mov.l @%1+,%0")
00f8ff66 11179
51bd623f 11180;; See the comment on the dt combiner pattern above.
00f8ff66 11181
07a45e5c
JW
11182(define_peephole
11183 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
00f8ff66
SC
11184 (plus:SI (match_dup 0)
11185 (const_int -1)))
4773afa4 11186 (set (reg:SI T_REG)
00f8ff66
SC
11187 (eq:SI (match_dup 0)
11188 (const_int 0)))]
11189 "TARGET_SH2"
11190 "dt %0")
e4931540
RK
11191
11192;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11193;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11194;; reload when the constant is too large for a reg+offset address.
11195
11196;; ??? We would get much better code if this was done in reload. This would
11197;; require modifying find_reloads_address to recognize that if the constant
11198;; is out-of-range for an immediate add, then we get better code by reloading
11199;; the constant into a register than by reloading the sum into a register,
11200;; since the former is one instruction shorter if the address does not need
11201;; to be offsettable. Unfortunately this does not work, because there is
11202;; only one register, r0, that can be used as an index register. This register
11203;; is also the function return value register. So, if we try to force reload
11204;; to use double-reg addresses, then we end up with some instructions that
11205;; need to use r0 twice. The only way to fix this is to change the calling
11206;; convention so that r0 is not used to return values.
11207
11208(define_peephole
11209 [(set (match_operand:SI 0 "register_operand" "=r")
11210 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11211 (set (mem:SI (match_dup 0))
11212 (match_operand:SI 2 "general_movsrc_operand" ""))]
fa5322fa 11213 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
11214 "mov.l %2,@(%0,%1)")
11215
11216(define_peephole
11217 [(set (match_operand:SI 0 "register_operand" "=r")
11218 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11219 (set (match_operand:SI 2 "general_movdst_operand" "")
11220 (mem:SI (match_dup 0)))]
fa5322fa 11221 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
11222 "mov.l @(%0,%1),%2")
11223
11224(define_peephole
11225 [(set (match_operand:SI 0 "register_operand" "=r")
11226 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11227 (set (mem:HI (match_dup 0))
11228 (match_operand:HI 2 "general_movsrc_operand" ""))]
fa5322fa 11229 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
11230 "mov.w %2,@(%0,%1)")
11231
11232(define_peephole
11233 [(set (match_operand:SI 0 "register_operand" "=r")
11234 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11235 (set (match_operand:HI 2 "general_movdst_operand" "")
11236 (mem:HI (match_dup 0)))]
fa5322fa 11237 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
11238 "mov.w @(%0,%1),%2")
11239
11240(define_peephole
11241 [(set (match_operand:SI 0 "register_operand" "=r")
11242 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11243 (set (mem:QI (match_dup 0))
11244 (match_operand:QI 2 "general_movsrc_operand" ""))]
fa5322fa 11245 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
11246 "mov.b %2,@(%0,%1)")
11247
11248(define_peephole
11249 [(set (match_operand:SI 0 "register_operand" "=r")
11250 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11251 (set (match_operand:QI 2 "general_movdst_operand" "")
11252 (mem:QI (match_dup 0)))]
fa5322fa 11253 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
11254 "mov.b @(%0,%1),%2")
11255
11256(define_peephole
11257 [(set (match_operand:SI 0 "register_operand" "=r")
11258 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11259 (set (mem:SF (match_dup 0))
11260 (match_operand:SF 2 "general_movsrc_operand" ""))]
fa5322fa 11261 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
11262 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11263 || (GET_CODE (operands[2]) == SUBREG
11264 && REGNO (SUBREG_REG (operands[2])) < 16))
11265 && reg_unused_after (operands[0], insn)"
e4931540
RK
11266 "mov.l %2,@(%0,%1)")
11267
11268(define_peephole
11269 [(set (match_operand:SI 0 "register_operand" "=r")
11270 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11271 (set (match_operand:SF 2 "general_movdst_operand" "")
11272
11273 (mem:SF (match_dup 0)))]
fa5322fa 11274 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
11275 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11276 || (GET_CODE (operands[2]) == SUBREG
11277 && REGNO (SUBREG_REG (operands[2])) < 16))
11278 && reg_unused_after (operands[0], insn)"
e4931540 11279 "mov.l @(%0,%1),%2")
45348d9e
JW
11280
11281(define_peephole
11282 [(set (match_operand:SI 0 "register_operand" "=r")
11283 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11284 (set (mem:SF (match_dup 0))
11285 (match_operand:SF 2 "general_movsrc_operand" ""))]
3a8699c7 11286 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
11287 && ((GET_CODE (operands[2]) == REG
11288 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 11289 || (GET_CODE (operands[2]) == SUBREG
104ee20b 11290 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 11291 && reg_unused_after (operands[0], insn)"
1245df60 11292 "fmov{.s|} %2,@(%0,%1)")
45348d9e
JW
11293
11294(define_peephole
11295 [(set (match_operand:SI 0 "register_operand" "=r")
11296 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11297 (set (match_operand:SF 2 "general_movdst_operand" "")
11298
11299 (mem:SF (match_dup 0)))]
3a8699c7 11300 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
11301 && ((GET_CODE (operands[2]) == REG
11302 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 11303 || (GET_CODE (operands[2]) == SUBREG
104ee20b 11304 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 11305 && reg_unused_after (operands[0], insn)"
1245df60 11306 "fmov{.s|} @(%0,%1),%2")
4408efce
JL
11307
11308;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11309(define_insn "sp_switch_1"
a6ab9fc0 11310 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
fa5322fa 11311 "TARGET_SH1"
4408efce
JL
11312 "*
11313{
a6ab9fc0
R
11314 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11315 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
4408efce
JL
11316 return \"mov r0,r15\";
11317}"
11318 [(set_attr "length" "10")])
4408efce 11319
956d6950 11320;; Switch back to the original stack for interrupt functions with the
4408efce
JL
11321;; sp_switch attribute. */
11322(define_insn "sp_switch_2"
11323 [(const_int 2)]
fa5322fa 11324 "TARGET_SH1"
4408efce
JL
11325 "mov.l @r15+,r15\;mov.l @r15+,r0"
11326 [(set_attr "length" "4")])
fae15c93 11327
c1b92d09
R
11328;; Integer vector moves
11329
11330(define_expand "movv8qi"
11331 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11332 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11333 "TARGET_SHMEDIA"
11334 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11335
11336(define_insn "movv8qi_i"
11337 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
42201282 11338 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
c1b92d09
R
11339 "TARGET_SHMEDIA
11340 && (register_operand (operands[0], V8QImode)
d9da94a1 11341 || sh_register_operand (operands[1], V8QImode))"
c1b92d09
R
11342 "@
11343 add %1, r63, %0
11344 movi %1, %0
11345 #
11346 ld%M1.q %m1, %0
d9da94a1 11347 st%M0.q %m0, %N1"
c1b92d09
R
11348 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11349 (set_attr "length" "4,4,16,4,4")])
11350
11351(define_split
11352 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11353 (subreg:V8QI (const_int 0) 0))]
11354 "TARGET_SHMEDIA"
11355 [(set (match_dup 0)
11356 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11357 (const_int 0) (const_int 0) (const_int 0)
11358 (const_int 0) (const_int 0)]))])
11359
11360(define_split
11361 [(set (match_operand 0 "arith_reg_dest" "")
11362 (match_operand 1 "sh_rep_vec" ""))]
11363 "TARGET_SHMEDIA && reload_completed
11364 && GET_MODE (operands[0]) == GET_MODE (operands[1])
f676971a 11365 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
c1b92d09
R
11366 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11367 && (XVECEXP (operands[1], 0, 0) != const0_rtx
c034672a
R
11368 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11369 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11370 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
c1b92d09
R
11371 [(set (match_dup 0) (match_dup 1))
11372 (match_dup 2)]
11373 "
11374{
11375 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11376 rtx elt1 = XVECEXP (operands[1], 0, 1);
11377
11378 if (unit_size > 2)
11379 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11380 else
750afc12
R
11381 {
11382 if (unit_size < 2)
11383 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11384 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11385 }
c1b92d09
R
11386 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11387 operands[1] = XVECEXP (operands[1], 0, 0);
11388 if (unit_size < 2)
11389 {
11390 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
40779a72
R
11391 operands[1]
11392 = GEN_INT (TARGET_LITTLE_ENDIAN
11393 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11394 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
c1b92d09
R
11395 else
11396 {
11397 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11398 operands[1]
11399 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11400 }
11401 }
11402}")
11403
11404(define_split
11405 [(set (match_operand 0 "arith_reg_dest" "")
11406 (match_operand 1 "sh_const_vec" ""))]
11407 "TARGET_SHMEDIA && reload_completed
11408 && GET_MODE (operands[0]) == GET_MODE (operands[1])
73a4d10b 11409 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
c1b92d09
R
11410 [(set (match_dup 0) (match_dup 1))]
11411 "
11412{
11413 rtx v = operands[1];
11414 enum machine_mode new_mode
11415 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11416
11417 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11418 operands[1]
52702ae1 11419 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
c1b92d09
R
11420}")
11421
11422(define_expand "movv2hi"
11423 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11424 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11425 "TARGET_SHMEDIA"
11426 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11427
11428(define_insn "movv2hi_i"
11429 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
42201282 11430 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
c1b92d09
R
11431 "TARGET_SHMEDIA
11432 && (register_operand (operands[0], V2HImode)
d9da94a1 11433 || sh_register_operand (operands[1], V2HImode))"
c1b92d09 11434 "@
73a4d10b 11435 add.l %1, r63, %0
c1b92d09
R
11436 movi %1, %0
11437 #
11438 ld%M1.l %m1, %0
d9da94a1 11439 st%M0.l %m0, %N1"
c1b92d09 11440 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
73a4d10b
R
11441 (set_attr "length" "4,4,16,4,4")
11442 (set (attr "highpart")
11443 (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11444 (const_string "user")]
11445 (const_string "ignore")))])
c1b92d09
R
11446
11447(define_expand "movv4hi"
11448 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11449 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11450 "TARGET_SHMEDIA"
11451 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11452
11453(define_insn "movv4hi_i"
11454 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
42201282 11455 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
c1b92d09
R
11456 "TARGET_SHMEDIA
11457 && (register_operand (operands[0], V4HImode)
d9da94a1 11458 || sh_register_operand (operands[1], V4HImode))"
c1b92d09
R
11459 "@
11460 add %1, r63, %0
11461 movi %1, %0
11462 #
11463 ld%M1.q %m1, %0
d9da94a1 11464 st%M0.q %m0, %N1"
c1b92d09 11465 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
73a4d10b
R
11466 (set_attr "length" "4,4,16,4,4")
11467 (set_attr "highpart" "depend")])
c1b92d09
R
11468
11469(define_expand "movv2si"
11470 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11471 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11472 "TARGET_SHMEDIA"
11473 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11474
11475(define_insn "movv2si_i"
11476 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
42201282 11477 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
c1b92d09
R
11478 "TARGET_SHMEDIA
11479 && (register_operand (operands[0], V2SImode)
d9da94a1 11480 || sh_register_operand (operands[1], V2SImode))"
c1b92d09
R
11481 "@
11482 add %1, r63, %0
52702ae1 11483 #
c1b92d09
R
11484 #
11485 ld%M1.q %m1, %0
d9da94a1 11486 st%M0.q %m0, %N1"
c1b92d09 11487 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
73a4d10b
R
11488 (set_attr "length" "4,4,16,4,4")
11489 (set_attr "highpart" "depend")])
c1b92d09
R
11490
11491;; Multimedia Intrinsics
11492
11493(define_insn "absv2si2"
11494 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11495 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11496 "TARGET_SHMEDIA"
11497 "mabs.l %1, %0"
73a4d10b
R
11498 [(set_attr "type" "mcmp_media")
11499 (set_attr "highpart" "depend")])
c1b92d09
R
11500
11501(define_insn "absv4hi2"
11502 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11503 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11504 "TARGET_SHMEDIA"
11505 "mabs.w %1, %0"
73a4d10b
R
11506 [(set_attr "type" "mcmp_media")
11507 (set_attr "highpart" "depend")])
c1b92d09
R
11508
11509(define_insn "addv2si3"
11510 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11511 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11512 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11513 "TARGET_SHMEDIA"
11514 "madd.l %1, %2, %0"
73a4d10b
R
11515 [(set_attr "type" "arith_media")
11516 (set_attr "highpart" "depend")])
c1b92d09
R
11517
11518(define_insn "addv4hi3"
11519 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11520 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11521 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11522 "TARGET_SHMEDIA"
11523 "madd.w %1, %2, %0"
73a4d10b
R
11524 [(set_attr "type" "arith_media")
11525 (set_attr "highpart" "depend")])
11526
11527(define_insn_and_split "addv2hi3"
11528 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11529 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11530 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11531 "TARGET_SHMEDIA"
11532 "#"
11533 "TARGET_SHMEDIA"
11534 [(const_int 0)]
11535 "
11536{
11537 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11538 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11539 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11540 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11541 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11542
11543 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11544 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11545 DONE;
11546}"
11547 [(set_attr "highpart" "must_split")])
c1b92d09
R
11548
11549(define_insn "ssaddv2si3"
11550 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11551 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11552 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11553 "TARGET_SHMEDIA"
11554 "madds.l %1, %2, %0"
73a4d10b
R
11555 [(set_attr "type" "mcmp_media")
11556 (set_attr "highpart" "depend")])
c1b92d09
R
11557
11558(define_insn "usaddv8qi3"
11559 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11560 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11561 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11562 "TARGET_SHMEDIA"
11563 "madds.ub %1, %2, %0"
73a4d10b
R
11564 [(set_attr "type" "mcmp_media")
11565 (set_attr "highpart" "depend")])
c1b92d09
R
11566
11567(define_insn "ssaddv4hi3"
11568 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11569 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11570 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11571 "TARGET_SHMEDIA"
11572 "madds.w %1, %2, %0"
73a4d10b
R
11573 [(set_attr "type" "mcmp_media")
11574 (set_attr "highpart" "depend")])
c1b92d09
R
11575
11576(define_insn "negcmpeqv8qi"
11577 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
11578 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11579 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11580 "TARGET_SHMEDIA"
11581 "mcmpeq.b %N1, %N2, %0"
73a4d10b
R
11582 [(set_attr "type" "mcmp_media")
11583 (set_attr "highpart" "depend")])
c1b92d09
R
11584
11585(define_insn "negcmpeqv2si"
11586 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
11587 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11588 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11589 "TARGET_SHMEDIA"
11590 "mcmpeq.l %N1, %N2, %0"
73a4d10b
R
11591 [(set_attr "type" "mcmp_media")
11592 (set_attr "highpart" "depend")])
c1b92d09
R
11593
11594(define_insn "negcmpeqv4hi"
11595 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
11596 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11597 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11598 "TARGET_SHMEDIA"
11599 "mcmpeq.w %N1, %N2, %0"
73a4d10b
R
11600 [(set_attr "type" "mcmp_media")
11601 (set_attr "highpart" "depend")])
c1b92d09
R
11602
11603(define_insn "negcmpgtuv8qi"
11604 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
11605 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11606 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11607 "TARGET_SHMEDIA"
11608 "mcmpgt.ub %N1, %N2, %0"
73a4d10b
R
11609 [(set_attr "type" "mcmp_media")
11610 (set_attr "highpart" "depend")])
c1b92d09
R
11611
11612(define_insn "negcmpgtv2si"
11613 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
11614 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11615 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11616 "TARGET_SHMEDIA"
11617 "mcmpgt.l %N1, %N2, %0"
73a4d10b
R
11618 [(set_attr "type" "mcmp_media")
11619 (set_attr "highpart" "depend")])
c1b92d09
R
11620
11621(define_insn "negcmpgtv4hi"
11622 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
11623 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11624 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11625 "TARGET_SHMEDIA"
11626 "mcmpgt.w %N1, %N2, %0"
73a4d10b
R
11627 [(set_attr "type" "mcmp_media")
11628 (set_attr "highpart" "depend")])
c1b92d09
R
11629
11630(define_insn "mcmv"
11631 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 11632 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
11633 (match_operand:DI 2 "arith_reg_operand" "r"))
11634 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11635 (not:DI (match_dup 2)))))]
11636 "TARGET_SHMEDIA"
11637 "mcmv %N1, %2, %0"
73a4d10b
R
11638 [(set_attr "type" "arith_media")
11639 (set_attr "highpart" "depend")])
c1b92d09
R
11640
11641(define_insn "mcnvs_lw"
11642 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11643 (vec_concat:V4HI
735cb76e
R
11644 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11645 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11646 "TARGET_SHMEDIA"
11647 "mcnvs.lw %N1, %N2, %0"
11648 [(set_attr "type" "mcmp_media")])
11649
11650(define_insn "mcnvs_wb"
11651 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11652 (vec_concat:V8QI
735cb76e
R
11653 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11654 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11655 "TARGET_SHMEDIA"
11656 "mcnvs.wb %N1, %N2, %0"
11657 [(set_attr "type" "mcmp_media")])
11658
11659(define_insn "mcnvs_wub"
11660 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11661 (vec_concat:V8QI
735cb76e
R
11662 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11663 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
11664 "TARGET_SHMEDIA"
11665 "mcnvs.wub %N1, %N2, %0"
11666 [(set_attr "type" "mcmp_media")])
11667
11668(define_insn "mextr_rl"
11669 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 11670 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 11671 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 11672 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
11673 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11674 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11675 "*
11676{
9a487a45 11677 static char templ[21];
c1b92d09
R
11678
11679 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11680 (int) INTVAL (operands[3]) >> 3);
11681 return templ;
11682}"
11683 [(set_attr "type" "arith_media")])
11684
11685(define_insn "*mextr_lr"
11686 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 11687 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 11688 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 11689 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
11690 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11691 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11692 "*
11693{
9a487a45 11694 static char templ[21];
c1b92d09
R
11695
11696 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11697 (int) INTVAL (operands[4]) >> 3);
11698 return templ;
11699}"
11700 [(set_attr "type" "arith_media")])
11701
11702; mextrN can be modelled with vec_select / vec_concat, but the selection
11703; vector then varies depending on endianness.
11704(define_expand "mextr1"
0ac78517 11705 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11706 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11707 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11708 "TARGET_SHMEDIA"
11709 "
11710{
0ac78517 11711 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11712 GEN_INT (1 * 8), GEN_INT (7 * 8)));
11713 DONE;
11714}")
11715
11716(define_expand "mextr2"
0ac78517 11717 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11718 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11719 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11720 "TARGET_SHMEDIA"
11721 "
11722{
0ac78517 11723 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11724 GEN_INT (2 * 8), GEN_INT (6 * 8)));
11725 DONE;
11726}")
11727
11728(define_expand "mextr3"
0ac78517 11729 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11730 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11731 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11732 "TARGET_SHMEDIA"
11733 "
11734{
0ac78517 11735 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11736 GEN_INT (3 * 8), GEN_INT (5 * 8)));
11737 DONE;
11738}")
11739
11740(define_expand "mextr4"
0ac78517 11741 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11742 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11743 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11744 "TARGET_SHMEDIA"
11745 "
11746{
0ac78517 11747 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11748 GEN_INT (4 * 8), GEN_INT (4 * 8)));
11749 DONE;
11750}")
11751
11752(define_expand "mextr5"
0ac78517 11753 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11754 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11755 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11756 "TARGET_SHMEDIA"
11757 "
11758{
0ac78517 11759 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11760 GEN_INT (5 * 8), GEN_INT (3 * 8)));
11761 DONE;
11762}")
11763
11764(define_expand "mextr6"
0ac78517 11765 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11766 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11767 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11768 "TARGET_SHMEDIA"
11769 "
11770{
0ac78517 11771 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11772 GEN_INT (6 * 8), GEN_INT (2 * 8)));
11773 DONE;
11774}")
11775
11776(define_expand "mextr7"
0ac78517 11777 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
11778 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11779 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
11780 "TARGET_SHMEDIA"
11781 "
11782{
0ac78517 11783 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
11784 GEN_INT (7 * 8), GEN_INT (1 * 8)));
11785 DONE;
11786}")
11787
11788(define_expand "mmacfx_wl"
11789 [(match_operand:V2SI 0 "arith_reg_dest" "")
11790 (match_operand:V2HI 1 "extend_reg_operand" "")
11791 (match_operand:V2HI 2 "extend_reg_operand" "")
11792 (match_operand:V2SI 3 "arith_reg_operand" "")]
11793 "TARGET_SHMEDIA"
11794 "
11795{
11796 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11797 operands[1], operands[2]));
11798 DONE;
11799}")
11800
73a4d10b
R
11801;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11802;; is depend
c1b92d09
R
11803(define_insn "mmacfx_wl_i"
11804 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11805 (ss_plus:V2SI
11806 (match_operand:V2SI 1 "arith_reg_operand" "0")
11807 (ss_truncate:V2SI
11808 (ashift:V2DI
11809 (sign_extend:V2DI
11810 (mult:V2SI
11811 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11812 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11813 (const_int 1)))))]
11814 "TARGET_SHMEDIA"
11815 "mmacfx.wl %2, %3, %0"
73a4d10b
R
11816 [(set_attr "type" "mac_media")
11817 (set_attr "highpart" "depend")])
c1b92d09
R
11818
11819(define_expand "mmacnfx_wl"
11820 [(match_operand:V2SI 0 "arith_reg_dest" "")
11821 (match_operand:V2HI 1 "extend_reg_operand" "")
11822 (match_operand:V2HI 2 "extend_reg_operand" "")
11823 (match_operand:V2SI 3 "arith_reg_operand" "")]
11824 "TARGET_SHMEDIA"
11825 "
11826{
11827 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11828 operands[1], operands[2]));
11829 DONE;
11830}")
11831
11832(define_insn "mmacnfx_wl_i"
11833 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11834 (ss_minus:V2SI
11835 (match_operand:V2SI 1 "arith_reg_operand" "0")
11836 (ss_truncate:V2SI
11837 (ashift:V2DI
11838 (sign_extend:V2DI
11839 (mult:V2SI
11840 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11841 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11842 (const_int 1)))))]
11843 "TARGET_SHMEDIA"
11844 "mmacnfx.wl %2, %3, %0"
73a4d10b
R
11845 [(set_attr "type" "mac_media")
11846 (set_attr "highpart" "depend")])
c1b92d09
R
11847
11848(define_insn "mulv2si3"
11849 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11850 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11851 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11852 "TARGET_SHMEDIA"
11853 "mmul.l %1, %2, %0"
73a4d10b
R
11854 [(set_attr "type" "d2mpy_media")
11855 (set_attr "highpart" "depend")])
c1b92d09
R
11856
11857(define_insn "mulv4hi3"
11858 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11859 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11860 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11861 "TARGET_SHMEDIA"
11862 "mmul.w %1, %2, %0"
73a4d10b
R
11863 [(set_attr "type" "dmpy_media")
11864 (set_attr "highpart" "depend")])
c1b92d09
R
11865
11866(define_insn "mmulfx_l"
11867 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11868 (ss_truncate:V2SI
11869 (ashiftrt:V2DI
11870 (mult:V2DI
11871 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11872 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11873 (const_int 31))))]
11874 "TARGET_SHMEDIA"
11875 "mmulfx.l %1, %2, %0"
73a4d10b
R
11876 [(set_attr "type" "d2mpy_media")
11877 (set_attr "highpart" "depend")])
c1b92d09
R
11878
11879(define_insn "mmulfx_w"
11880 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11881 (ss_truncate:V4HI
11882 (ashiftrt:V4SI
11883 (mult:V4SI
11884 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11885 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11886 (const_int 15))))]
11887 "TARGET_SHMEDIA"
11888 "mmulfx.w %1, %2, %0"
73a4d10b
R
11889 [(set_attr "type" "dmpy_media")
11890 (set_attr "highpart" "depend")])
c1b92d09
R
11891
11892(define_insn "mmulfxrp_w"
11893 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11894 (ss_truncate:V4HI
11895 (ashiftrt:V4SI
11896 (plus:V4SI
11897 (mult:V4SI
11898 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11899 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11900 (const_int 16384))
11901 (const_int 15))))]
11902 "TARGET_SHMEDIA"
11903 "mmulfxrp.w %1, %2, %0"
73a4d10b
R
11904 [(set_attr "type" "dmpy_media")
11905 (set_attr "highpart" "depend")])
11906
c1b92d09
R
11907
11908(define_expand "mmulhi_wl"
11909 [(match_operand:V2SI 0 "arith_reg_dest" "")
11910 (match_operand:V4HI 1 "arith_reg_operand" "")
11911 (match_operand:V4HI 2 "arith_reg_operand" "")]
11912 "TARGET_SHMEDIA"
11913 "
11914{
11915 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11916 (operands[0], operands[1], operands[2]));
11917 DONE;
11918}")
11919
11920(define_expand "mmullo_wl"
11921 [(match_operand:V2SI 0 "arith_reg_dest" "")
11922 (match_operand:V4HI 1 "arith_reg_operand" "")
11923 (match_operand:V4HI 2 "arith_reg_operand" "")]
11924 "TARGET_SHMEDIA"
11925 "
11926{
11927 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11928 (operands[0], operands[1], operands[2]));
11929 DONE;
11930}")
11931
11932(define_insn "mmul23_wl"
11933 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11934 (vec_select:V2SI
11935 (mult:V4SI
11936 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11937 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 11938 (parallel [(const_int 2) (const_int 3)])))]
c1b92d09
R
11939 "TARGET_SHMEDIA"
11940 "* return (TARGET_LITTLE_ENDIAN
11941 ? \"mmulhi.wl %1, %2, %0\"
11942 : \"mmullo.wl %1, %2, %0\");"
73a4d10b
R
11943 [(set_attr "type" "dmpy_media")
11944 (set (attr "highpart")
11945 (cond [(eq_attr "endian" "big") (const_string "ignore")]
11946 (const_string "user")))])
c1b92d09
R
11947
11948(define_insn "mmul01_wl"
11949 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11950 (vec_select:V2SI
11951 (mult:V4SI
11952 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11953 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 11954 (parallel [(const_int 0) (const_int 1)])))]
c1b92d09
R
11955 "TARGET_SHMEDIA"
11956 "* return (TARGET_LITTLE_ENDIAN
11957 ? \"mmullo.wl %1, %2, %0\"
11958 : \"mmulhi.wl %1, %2, %0\");"
73a4d10b
R
11959 [(set_attr "type" "dmpy_media")
11960 (set (attr "highpart")
11961 (cond [(eq_attr "endian" "little") (const_string "ignore")]
11962 (const_string "user")))])
11963
c1b92d09
R
11964
11965(define_expand "mmulsum_wq"
11966 [(match_operand:DI 0 "arith_reg_dest" "")
11967 (match_operand:V4HI 1 "arith_reg_operand" "")
11968 (match_operand:V4HI 2 "arith_reg_operand" "")
11969 (match_operand:DI 3 "arith_reg_operand" "")]
11970 "TARGET_SHMEDIA"
11971 "
11972{
11973 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11974 operands[1], operands[2]));
11975 DONE;
11976}")
11977
11978(define_insn "mmulsum_wq_i"
11979 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11980 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11981 (plus:DI
11982 (plus:DI
11983 (vec_select:DI
11984 (mult:V4DI
11985 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11986 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
0ac78517 11987 (parallel [(const_int 0)]))
c1b92d09
R
11988 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11989 (sign_extend:V4DI (match_dup 3)))
0ac78517 11990 (parallel [(const_int 1)])))
c1b92d09
R
11991 (plus:DI
11992 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11993 (sign_extend:V4DI (match_dup 3)))
0ac78517 11994 (parallel [(const_int 2)]))
c1b92d09
R
11995 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11996 (sign_extend:V4DI (match_dup 3)))
0ac78517 11997 (parallel [(const_int 3)]))))))]
c1b92d09
R
11998 "TARGET_SHMEDIA"
11999 "mmulsum.wq %2, %3, %0"
12000 [(set_attr "type" "mac_media")])
12001
12002(define_expand "mperm_w"
12003 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12004 (match_operand:V4HI 1 "arith_reg_operand" "r")
735cb76e 12005 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
c1b92d09
R
12006 "TARGET_SHMEDIA"
12007 "
12008{
12009 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12010 (operands[0], operands[1], operands[2]));
c49439f1 12011 DONE;
c1b92d09
R
12012}")
12013
12014; This use of vec_select isn't exactly correct according to rtl.texi
12015; (because not constant), but it seems a straightforward extension.
12016(define_insn "mperm_w_little"
12017 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12018 (vec_select:V4HI
12019 (match_operand:V4HI 1 "arith_reg_operand" "r")
12020 (parallel
735cb76e 12021 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
502e6d5a
R
12022 (const_int 2) (const_int 0))
12023 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12024 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12025 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
c1b92d09
R
12026 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12027 "mperm.w %1, %N2, %0"
12028 [(set_attr "type" "arith_media")])
12029
12030(define_insn "mperm_w_big"
12031 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12032 (vec_select:V4HI
12033 (match_operand:V4HI 1 "arith_reg_operand" "r")
12034 (parallel
502e6d5a 12035 [(zero_extract:QI (not:QI (match_operand:QI 2
735cb76e 12036 "extend_reg_or_0_operand" "rZ"))
502e6d5a
R
12037 (const_int 2) (const_int 0))
12038 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12039 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12040 (zero_extract:QI (not:QI (match_dup 2))
12041 (const_int 2) (const_int 6))])))]
c1b92d09
R
12042 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12043 "mperm.w %1, %N2, %0"
12044 [(set_attr "type" "arith_media")])
12045
12046(define_insn "mperm_w0"
12047 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12048 (vec_duplicate:V4HI (truncate:HI (match_operand 1
e69d1422 12049 "trunc_hi_operand" "r"))))]
c1b92d09
R
12050 "TARGET_SHMEDIA"
12051 "mperm.w %1, r63, %0"
73a4d10b
R
12052 [(set_attr "type" "arith_media")
12053 (set_attr "highpart" "ignore")])
c1b92d09
R
12054
12055(define_expand "msad_ubq"
12056 [(match_operand:DI 0 "arith_reg_dest" "")
12057 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12058 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12059 (match_operand:DI 3 "arith_reg_operand" "")]
12060 "TARGET_SHMEDIA"
12061 "
12062{
12063 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12064 operands[1], operands[2]));
12065 DONE;
12066}")
12067
12068(define_insn "msad_ubq_i"
12069 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12070 (plus:DI
12071 (plus:DI
12072 (plus:DI
12073 (plus:DI
12074 (match_operand:DI 1 "arith_reg_operand" "0")
12075 (abs:DI (vec_select:DI
12076 (minus:V8DI
12077 (zero_extend:V8DI
735cb76e 12078 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
c1b92d09 12079 (zero_extend:V8DI
735cb76e 12080 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
0ac78517 12081 (parallel [(const_int 0)]))))
c1b92d09
R
12082 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12083 (zero_extend:V8DI (match_dup 3)))
0ac78517 12084 (parallel [(const_int 1)]))))
c1b92d09
R
12085 (plus:DI
12086 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12087 (zero_extend:V8DI (match_dup 3)))
0ac78517 12088 (parallel [(const_int 2)])))
c1b92d09
R
12089 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12090 (zero_extend:V8DI (match_dup 3)))
0ac78517 12091 (parallel [(const_int 3)])))))
c1b92d09
R
12092 (plus:DI
12093 (plus:DI
12094 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12095 (zero_extend:V8DI (match_dup 3)))
0ac78517 12096 (parallel [(const_int 4)])))
c1b92d09
R
12097 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12098 (zero_extend:V8DI (match_dup 3)))
0ac78517 12099 (parallel [(const_int 5)]))))
c1b92d09
R
12100 (plus:DI
12101 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12102 (zero_extend:V8DI (match_dup 3)))
0ac78517 12103 (parallel [(const_int 6)])))
c1b92d09
R
12104 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12105 (zero_extend:V8DI (match_dup 3)))
0ac78517 12106 (parallel [(const_int 7)])))))))]
c1b92d09
R
12107 "TARGET_SHMEDIA"
12108 "msad.ubq %N2, %N3, %0"
12109 [(set_attr "type" "mac_media")])
12110
12111(define_insn "mshalds_l"
12112 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12113 (ss_truncate:V2SI
12114 (ashift:V2DI
12115 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12116 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12117 (const_int 31)))))]
12118 "TARGET_SHMEDIA"
12119 "mshalds.l %1, %2, %0"
73a4d10b
R
12120 [(set_attr "type" "mcmp_media")
12121 (set_attr "highpart" "depend")])
c1b92d09
R
12122
12123(define_insn "mshalds_w"
12124 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12125 (ss_truncate:V4HI
12126 (ashift:V4SI
12127 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12128 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12129 (const_int 15)))))]
12130 "TARGET_SHMEDIA"
12131 "mshalds.w %1, %2, %0"
73a4d10b
R
12132 [(set_attr "type" "mcmp_media")
12133 (set_attr "highpart" "depend")])
c1b92d09
R
12134
12135(define_insn "ashrv2si3"
12136 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12137 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12138 (match_operand:DI 2 "arith_reg_operand" "r")))]
12139 "TARGET_SHMEDIA"
12140 "mshard.l %1, %2, %0"
73a4d10b
R
12141 [(set_attr "type" "arith_media")
12142 (set_attr "highpart" "depend")])
c1b92d09
R
12143
12144(define_insn "ashrv4hi3"
12145 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12146 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12147 (match_operand:DI 2 "arith_reg_operand" "r")))]
12148 "TARGET_SHMEDIA"
12149 "mshard.w %1, %2, %0"
73a4d10b
R
12150 [(set_attr "type" "arith_media")
12151 (set_attr "highpart" "depend")])
c1b92d09
R
12152
12153(define_insn "mshards_q"
12154 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12155 (ss_truncate:HI
12156 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
735cb76e 12157 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
12158 "TARGET_SHMEDIA"
12159 "mshards.q %1, %N2, %0"
12160 [(set_attr "type" "mcmp_media")])
12161
12162(define_expand "mshfhi_b"
12163 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
12164 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12165 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
12166 "TARGET_SHMEDIA"
12167 "
12168{
12169 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12170 (operands[0], operands[1], operands[2]));
8721e3df 12171 DONE;
c1b92d09
R
12172}")
12173
12174(define_expand "mshflo_b"
12175 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
12176 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12177 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
12178 "TARGET_SHMEDIA"
12179 "
12180{
12181 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12182 (operands[0], operands[1], operands[2]));
8721e3df 12183 DONE;
c1b92d09
R
12184}")
12185
12186(define_insn "mshf4_b"
12187 [(set
12188 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12189 (vec_select:V8QI
735cb76e
R
12190 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12191 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
12192 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12193 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
c1b92d09
R
12194 "TARGET_SHMEDIA"
12195 "* return (TARGET_LITTLE_ENDIAN
12196 ? \"mshfhi.b %N1, %N2, %0\"
12197 : \"mshflo.b %N1, %N2, %0\");"
73a4d10b
R
12198 [(set_attr "type" "arith_media")
12199 (set (attr "highpart")
12200 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12201 (const_string "user")))])
c1b92d09
R
12202
12203(define_insn "mshf0_b"
12204 [(set
12205 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12206 (vec_select:V8QI
735cb76e
R
12207 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12208 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
12209 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12210 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
c1b92d09
R
12211 "TARGET_SHMEDIA"
12212 "* return (TARGET_LITTLE_ENDIAN
12213 ? \"mshflo.b %N1, %N2, %0\"
12214 : \"mshfhi.b %N1, %N2, %0\");"
73a4d10b
R
12215 [(set_attr "type" "arith_media")
12216 (set (attr "highpart")
12217 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12218 (const_string "user")))])
c1b92d09
R
12219
12220(define_expand "mshfhi_l"
12221 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
12222 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12223 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
12224 "TARGET_SHMEDIA"
12225 "
12226{
12227 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12228 (operands[0], operands[1], operands[2]));
8721e3df 12229 DONE;
c1b92d09
R
12230}")
12231
12232(define_expand "mshflo_l"
12233 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
12234 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12235 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
12236 "TARGET_SHMEDIA"
12237 "
12238{
12239 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12240 (operands[0], operands[1], operands[2]));
8721e3df 12241 DONE;
c1b92d09
R
12242}")
12243
12244(define_insn "mshf4_l"
12245 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12246 (vec_select:V2SI
735cb76e
R
12247 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12248 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 12249 (parallel [(const_int 1) (const_int 3)])))]
c1b92d09
R
12250 "TARGET_SHMEDIA"
12251 "* return (TARGET_LITTLE_ENDIAN
12252 ? \"mshfhi.l %N1, %N2, %0\"
12253 : \"mshflo.l %N1, %N2, %0\");"
73a4d10b
R
12254 [(set_attr "type" "arith_media")
12255 (set (attr "highpart")
12256 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12257 (const_string "user")))])
c1b92d09
R
12258
12259(define_insn "mshf0_l"
12260 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12261 (vec_select:V2SI
735cb76e
R
12262 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12263 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 12264 (parallel [(const_int 0) (const_int 2)])))]
c1b92d09
R
12265 "TARGET_SHMEDIA"
12266 "* return (TARGET_LITTLE_ENDIAN
12267 ? \"mshflo.l %N1, %N2, %0\"
12268 : \"mshfhi.l %N1, %N2, %0\");"
73a4d10b
R
12269 [(set_attr "type" "arith_media")
12270 (set (attr "highpart")
12271 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12272 (const_string "user")))])
c1b92d09
R
12273
12274(define_expand "mshfhi_w"
12275 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
12276 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12277 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
12278 "TARGET_SHMEDIA"
12279 "
12280{
12281 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12282 (operands[0], operands[1], operands[2]));
8721e3df 12283 DONE;
c1b92d09
R
12284}")
12285
12286(define_expand "mshflo_w"
12287 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
12288 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12289 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
12290 "TARGET_SHMEDIA"
12291 "
12292{
12293 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12294 (operands[0], operands[1], operands[2]));
8721e3df 12295 DONE;
c1b92d09
R
12296}")
12297
12298(define_insn "mshf4_w"
12299 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12300 (vec_select:V4HI
735cb76e
R
12301 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12302 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 12303 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
c1b92d09
R
12304 "TARGET_SHMEDIA"
12305 "* return (TARGET_LITTLE_ENDIAN
12306 ? \"mshfhi.w %N1, %N2, %0\"
12307 : \"mshflo.w %N1, %N2, %0\");"
73a4d10b
R
12308 [(set_attr "type" "arith_media")
12309 (set (attr "highpart")
12310 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12311 (const_string "user")))])
c1b92d09
R
12312
12313(define_insn "mshf0_w"
12314 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12315 (vec_select:V4HI
735cb76e
R
12316 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12317 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 12318 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
c1b92d09
R
12319 "TARGET_SHMEDIA"
12320 "* return (TARGET_LITTLE_ENDIAN
12321 ? \"mshflo.w %N1, %N2, %0\"
12322 : \"mshfhi.w %N1, %N2, %0\");"
73a4d10b
R
12323 [(set_attr "type" "arith_media")
12324 (set (attr "highpart")
12325 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12326 (const_string "user")))])
c1b92d09 12327
0ac78517
R
12328(define_insn "mshflo_w_x"
12329 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12330 (vec_select:V4HI
735cb76e
R
12331 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12332 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
08c43ea7 12333 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
0ac78517
R
12334 "TARGET_SHMEDIA"
12335 "mshflo.w %N1, %N2, %0"
73a4d10b
R
12336 [(set_attr "type" "arith_media")
12337 (set_attr "highpart" "ignore")])
0ac78517 12338
c1b92d09 12339/* These are useful to expand ANDs and as combiner patterns. */
0ac78517
R
12340(define_insn_and_split "mshfhi_l_di"
12341 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
735cb76e 12342 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
c1b92d09 12343 (const_int 32))
735cb76e 12344 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
c1b92d09
R
12345 (const_int -4294967296))))]
12346 "TARGET_SHMEDIA"
0ac78517
R
12347 "@
12348 mshfhi.l %N1, %N2, %0
12349 #"
12350 "TARGET_SHMEDIA && reload_completed
12351 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12352 [(set (match_dup 3) (match_dup 4))
12353 (set (match_dup 5) (match_dup 6))]
12354 "
12355{
12356 operands[3] = gen_lowpart (SImode, operands[0]);
12357 operands[4] = gen_highpart (SImode, operands[1]);
12358 operands[5] = gen_highpart (SImode, operands[0]);
12359 operands[6] = gen_highpart (SImode, operands[2]);
12360}"
c1b92d09
R
12361 [(set_attr "type" "arith_media")])
12362
12363(define_insn "*mshfhi_l_di_rev"
12364 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 12365 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 12366 (const_int -4294967296))
735cb76e 12367 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
12368 (const_int 32))))]
12369 "TARGET_SHMEDIA"
12370 "mshfhi.l %N2, %N1, %0"
12371 [(set_attr "type" "arith_media")])
12372
52702ae1
R
12373(define_split
12374 [(set (match_operand:DI 0 "arith_reg_dest" "")
12375 (ior:DI (zero_extend:DI (match_operand:SI 1
12376 "extend_reg_or_0_operand" ""))
12377 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12378 (const_int -4294967296))))
12379 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12380 "TARGET_SHMEDIA"
12381 [(const_int 0)]
12382 "
12383{
12384 emit_insn (gen_ashldi3_media (operands[3],
12385 simplify_gen_subreg (DImode, operands[1],
12386 SImode, 0),
12387 GEN_INT (32)));
12388 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12389 DONE;
12390}")
12391
c1b92d09
R
12392(define_insn "mshflo_l_di"
12393 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 12394 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 12395 (const_int 4294967295))
735cb76e 12396 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 12397 (const_int 32))))]
73774972 12398
c1b92d09
R
12399 "TARGET_SHMEDIA"
12400 "mshflo.l %N1, %N2, %0"
73a4d10b
R
12401 [(set_attr "type" "arith_media")
12402 (set_attr "highpart" "ignore")])
c1b92d09
R
12403
12404(define_insn "*mshflo_l_di_rev"
12405 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 12406 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 12407 (const_int 32))
735cb76e 12408 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 12409 (const_int 4294967295))))]
73774972 12410
c1b92d09
R
12411 "TARGET_SHMEDIA"
12412 "mshflo.l %N2, %N1, %0"
73a4d10b
R
12413 [(set_attr "type" "arith_media")
12414 (set_attr "highpart" "ignore")])
c1b92d09 12415
ca903bba
R
12416;; Combiner pattern for trampoline initialization.
12417(define_insn_and_split "*double_shori"
12418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12419 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12420 (const_int 32))
12421 (match_operand:DI 2 "const_int_operand" "n")))]
12422 "TARGET_SHMEDIA
42201282 12423 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
ca903bba
R
12424 "#"
12425 "rtx_equal_p (operands[0], operands[1])"
12426 [(const_int 0)]
12427 "
12428{
12429 HOST_WIDE_INT v = INTVAL (operands[2]);
12430
42201282
R
12431 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12432 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
ca903bba 12433 DONE;
73a4d10b
R
12434}"
12435 [(set_attr "highpart" "ignore")])
ca903bba
R
12436
12437
c1b92d09
R
12438(define_insn "*mshflo_l_di_x"
12439 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
0ac78517 12440 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
735cb76e
R
12441 "rZ"))
12442 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 12443 (const_int 32))))]
73774972 12444
c1b92d09
R
12445 "TARGET_SHMEDIA"
12446 "mshflo.l %N1, %N2, %0"
73a4d10b
R
12447 [(set_attr "type" "arith_media")
12448 (set_attr "highpart" "ignore")])
c1b92d09 12449
0ac78517
R
12450(define_insn_and_split "concat_v2sf"
12451 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
735cb76e
R
12452;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12453 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12454 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
73774972 12455
0ac78517
R
12456 "TARGET_SHMEDIA"
12457 "@
12458 mshflo.l %N1, %N2, %0
12459 #
12460 #"
12461 "TARGET_SHMEDIA && reload_completed
12462 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12463 [(set (match_dup 3) (match_dup 1))
12464 (set (match_dup 4) (match_dup 2))]
12465 "
12466{
12467 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12468 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12469}"
73a4d10b
R
12470 [(set_attr "type" "arith_media")
12471 (set_attr "highpart" "ignore")])
0ac78517 12472
c1b92d09
R
12473(define_insn "*mshflo_l_di_x_rev"
12474 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 12475 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 12476 (const_int 32))
735cb76e 12477 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
73774972 12478
c1b92d09
R
12479 "TARGET_SHMEDIA"
12480 "mshflo.l %N2, %N1, %0"
73a4d10b
R
12481 [(set_attr "type" "arith_media")
12482 (set_attr "highpart" "ignore")])
c1b92d09
R
12483
12484(define_insn "ashlv2si3"
12485 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12486 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
73a4d10b 12487 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
c1b92d09
R
12488 "TARGET_SHMEDIA"
12489 "mshlld.l %1, %2, %0"
73a4d10b
R
12490 [(set_attr "type" "arith_media")
12491 (set_attr "highpart" "depend")])
12492
12493(define_split
12494 [(set (match_operand 0 "any_register_operand" "")
12495 (match_operator 3 "shift_operator"
12496 [(match_operand 1 "any_register_operand" "")
12497 (match_operand 2 "shift_count_reg_operand" "")]))]
12498 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12499 [(set (match_dup 0) (match_dup 3))]
12500 "
12501{
12502 rtx count = operands[2];
12503 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12504
12505 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12506 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12507 || GET_CODE (count) == TRUNCATE)
12508 count = XEXP (count, 0);
12509 inner_mode = GET_MODE (count);
12510 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12511 subreg_lowpart_offset (outer_mode, inner_mode));
12512 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12513 operands[1], count);
12514}")
c1b92d09
R
12515
12516(define_insn "ashlv4hi3"
12517 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12518 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
73a4d10b 12519 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
c1b92d09
R
12520 "TARGET_SHMEDIA"
12521 "mshlld.w %1, %2, %0"
73a4d10b
R
12522 [(set_attr "type" "arith_media")
12523 (set_attr "highpart" "depend")])
c1b92d09
R
12524
12525(define_insn "lshrv2si3"
12526 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12527 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
73a4d10b 12528 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
c1b92d09
R
12529 "TARGET_SHMEDIA"
12530 "mshlrd.l %1, %2, %0"
73a4d10b
R
12531 [(set_attr "type" "arith_media")
12532 (set_attr "highpart" "depend")])
c1b92d09
R
12533
12534(define_insn "lshrv4hi3"
12535 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12536 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
73a4d10b 12537 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
c1b92d09
R
12538 "TARGET_SHMEDIA"
12539 "mshlrd.w %1, %2, %0"
73a4d10b
R
12540 [(set_attr "type" "arith_media")
12541 (set_attr "highpart" "depend")])
c1b92d09
R
12542
12543(define_insn "subv2si3"
12544 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 12545 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
12546 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12547 "TARGET_SHMEDIA"
12548 "msub.l %N1, %2, %0"
73a4d10b
R
12549 [(set_attr "type" "arith_media")
12550 (set_attr "highpart" "depend")])
c1b92d09
R
12551
12552(define_insn "subv4hi3"
12553 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 12554 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
12555 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12556 "TARGET_SHMEDIA"
12557 "msub.w %N1, %2, %0"
73a4d10b
R
12558 [(set_attr "type" "arith_media")
12559 (set_attr "highpart" "depend")])
12560
12561(define_insn_and_split "subv2hi3"
12562 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12563 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12564 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12565 "TARGET_SHMEDIA"
12566 "#"
12567 "TARGET_SHMEDIA"
12568 [(const_int 0)]
12569 "
12570{
12571 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12572 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12573 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12574 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12575 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12576
12577 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12578 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12579 DONE;
12580}"
12581 [(set_attr "highpart" "must_split")])
c1b92d09
R
12582
12583(define_insn "sssubv2si3"
12584 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 12585 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
12586 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12587 "TARGET_SHMEDIA"
12588 "msubs.l %N1, %2, %0"
73a4d10b
R
12589 [(set_attr "type" "mcmp_media")
12590 (set_attr "highpart" "depend")])
c1b92d09
R
12591
12592(define_insn "ussubv8qi3"
12593 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
73a4d10b 12594 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
12595 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12596 "TARGET_SHMEDIA"
73a4d10b
R
12597 "msubs.ub %N1, %2, %0"
12598 [(set_attr "type" "mcmp_media")
12599 (set_attr "highpart" "depend")])
c1b92d09
R
12600
12601(define_insn "sssubv4hi3"
12602 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 12603 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
12604 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12605 "TARGET_SHMEDIA"
12606 "msubs.w %N1, %2, %0"
73a4d10b
R
12607 [(set_attr "type" "mcmp_media")
12608 (set_attr "highpart" "depend")])
c1b92d09
R
12609
12610;; Floating Point Intrinsics
12611
12612(define_insn "fcosa_s"
12613 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12614 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12615 UNSPEC_FCOSA))]
12616 "TARGET_SHMEDIA"
12617 "fcosa.s %1, %0"
12618 [(set_attr "type" "atrans_media")])
12619
12620(define_insn "fsina_s"
12621 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12622 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12623 UNSPEC_FSINA))]
12624 "TARGET_SHMEDIA"
12625 "fsina.s %1, %0"
12626 [(set_attr "type" "atrans_media")])
12627
12628(define_insn "fipr"
12629 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12630 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12631 "fp_arith_reg_operand" "f")
12632 (match_operand:V4SF 2
12633 "fp_arith_reg_operand" "f"))
0ac78517 12634 (parallel [(const_int 0)]))
c1b92d09 12635 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 12636 (parallel [(const_int 1)])))
c1b92d09 12637 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 12638 (parallel [(const_int 2)]))
c1b92d09 12639 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 12640 (parallel [(const_int 3)])))))]
c1b92d09 12641 "TARGET_SHMEDIA"
40779a72 12642 "fipr.s %1, %2, %0"
c1b92d09
R
12643 [(set_attr "type" "fparith_media")])
12644
12645(define_insn "fsrra_s"
12646 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12647 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12648 UNSPEC_FSRRA))]
12649 "TARGET_SHMEDIA"
12650 "fsrra.s %1, %0"
12651 [(set_attr "type" "atrans_media")])
12652
12653(define_insn "ftrv"
12654 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12655 (plus:V4SF
12656 (plus:V4SF
12657 (mult:V4SF
12658 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
0ac78517
R
12659 (parallel [(const_int 0) (const_int 5)
12660 (const_int 10) (const_int 15)]))
c1b92d09
R
12661 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12662 (mult:V4SF
12663 (vec_select:V4SF (match_dup 1)
0ac78517
R
12664 (parallel [(const_int 4) (const_int 9)
12665 (const_int 14) (const_int 3)]))
c1b92d09 12666 (vec_select:V4SF (match_dup 2)
0ac78517 12667 (parallel [(const_int 1) (const_int 2)
40779a72 12668 (const_int 3) (const_int 0)]))))
c1b92d09
R
12669 (plus:V4SF
12670 (mult:V4SF
12671 (vec_select:V4SF (match_dup 1)
0ac78517
R
12672 (parallel [(const_int 8) (const_int 13)
12673 (const_int 2) (const_int 7)]))
c1b92d09 12674 (vec_select:V4SF (match_dup 2)
0ac78517
R
12675 (parallel [(const_int 2) (const_int 3)
12676 (const_int 0) (const_int 1)])))
c1b92d09
R
12677 (mult:V4SF
12678 (vec_select:V4SF (match_dup 1)
0ac78517
R
12679 (parallel [(const_int 12) (const_int 1)
12680 (const_int 6) (const_int 11)]))
c1b92d09 12681 (vec_select:V4SF (match_dup 2)
0ac78517
R
12682 (parallel [(const_int 3) (const_int 0)
12683 (const_int 1) (const_int 2)]))))))]
c1b92d09 12684 "TARGET_SHMEDIA"
40779a72 12685 "ftrv.s %1, %2, %0"
c1b92d09
R
12686 [(set_attr "type" "fparith_media")])
12687
73a4d10b
R
12688(define_insn "ldhi_l"
12689 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12690 (zero_extract:SI
12691 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12692 (const_int 3))
12693 (const_int -3)))
12694 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12695 (const_int 0)))]
12696 "TARGET_SHMEDIA32"
12697 "ldhi.l %U1, %0"
12698 [(set_attr "type" "load_media")])
12699
12700(define_insn "ldhi_q"
12701 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12702 (zero_extract:DI
12703 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12704 (const_int 7))
12705 (const_int -7)))
12706 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12707 (const_int 0)))]
12708 "TARGET_SHMEDIA32"
12709 "ldhi.q %U1, %0"
12710 [(set_attr "type" "load_media")])
12711
12712(define_insn_and_split "*ldhi_q_comb0"
12713 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12714 (zero_extract:DI
12715 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12716 "register_operand" "r")
12717 (match_operand:SI 2
12718 "ua_offset" "I06"))
12719 (const_int 7))
12720 (const_int -7)))
12721 (plus:SI (and:SI (match_dup 1) (const_int 7))
12722 (const_int 1))
12723 (const_int 0)))]
12724 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12725 "#"
12726 ""
12727 [(pc)]
12728 "emit_insn (gen_ldhi_q (operands[0],
12729 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12730 DONE;")
12731
12732
12733(define_insn_and_split "*ldhi_q_comb1"
12734 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12735 (zero_extract:DI
12736 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12737 "register_operand" "r")
12738 (match_operand:SI 2
12739 "ua_offset" "I06"))
12740 (const_int 7))
12741 (const_int -7)))
12742 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
12743 "ua_offset" "I06"))
12744 (const_int 7))
12745 (const_int 1))
12746 (const_int 0)))]
12747 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12748 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12749 "#"
12750 ""
12751 [(pc)]
12752 "emit_insn (gen_ldhi_q (operands[0],
12753 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12754 DONE;")
12755
12756
12757(define_insn "ldlo_l"
12758 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12759 (zero_extract:SI
12760 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12761 (const_int -4)))
12762 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12763 (and:SI (match_dup 1) (const_int 3))))]
12764 "TARGET_SHMEDIA32"
12765 "ldlo.l %U1, %0"
12766 [(set_attr "type" "load_media")])
12767
12768(define_insn "ldlo_q"
12769 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12770 (zero_extract:DI
12771 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12772 (const_int -8)))
12773 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12774 (and:SI (match_dup 1) (const_int 7))))]
12775 "TARGET_SHMEDIA32"
12776 "ldlo.q %U1, %0"
12777 [(set_attr "type" "load_media")])
12778
12779(define_insn_and_split "*ldlo_q_comb0"
12780 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12781 (zero_extract:DI
12782 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12783 (match_operand:SI 2 "ua_offset" "I06"))
12784 (const_int -8)))
12785 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12786 (and:SI (match_dup 1) (const_int 7))))]
12787 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12788 "#"
12789 ""
12790 [(pc)]
12791 "emit_insn (gen_ldlo_q (operands[0],
12792 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12793 DONE;")
12794
12795(define_insn_and_split "*ldlo_q_comb1"
12796 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12797 (zero_extract:DI
12798 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12799 (match_operand:SI 2 "ua_offset" "I06"))
12800 (const_int -8)))
12801 (minus:SI (const_int 8)
12802 (and:SI (plus:SI (match_dup 1)
12803 (match_operand:SI 3 "ua_offset" "I06"))
12804 (const_int 7)))
12805 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12806 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12807 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12808 "#"
12809 ""
12810 [(pc)]
12811 "emit_insn (gen_ldlo_q (operands[0],
12812 gen_rtx_PLUS (SImode, operands[1], operands[2])));
12813 DONE;")
12814
12815(define_insn "sthi_l"
12816 [(set (zero_extract:SI
12817 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12818 (const_int 3))
12819 (const_int -3)))
12820 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12821 (const_int 0))
12822 (match_operand:SI 1 "arith_reg_operand" "r"))]
12823 "TARGET_SHMEDIA32"
12824 "sthi.l %U0, %1"
12825 [(set_attr "type" "ustore_media")])
12826
12827;; All unaligned stores are considered to be 'narrow' because they typically
12828;; operate on less that a quadword, and when they operate on a full quadword,
12829;; the vanilla store high / store low sequence will cause a stall if not
12830;; scheduled apart.
12831(define_insn "sthi_q"
12832 [(set (zero_extract:DI
12833 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12834 (const_int 7))
12835 (const_int -7)))
12836 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12837 (const_int 0))
12838 (match_operand:DI 1 "arith_reg_operand" "r"))]
12839 "TARGET_SHMEDIA32"
12840 "sthi.q %U0, %1"
12841 [(set_attr "type" "ustore_media")])
12842
12843(define_insn_and_split "*sthi_q_comb0"
12844 [(set (zero_extract:DI
12845 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12846 "register_operand" "r")
12847 (match_operand:SI 1 "ua_offset"
12848 "I06"))
12849 (const_int 7))
12850 (const_int -7)))
12851 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12852 (const_int 0))
12853 (match_operand:DI 2 "arith_reg_operand" "r"))]
12854 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12855 "#"
12856 ""
12857 [(pc)]
12858 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12859 operands[2]));
12860 DONE;")
12861
12862(define_insn_and_split "*sthi_q_comb1"
12863 [(set (zero_extract:DI
12864 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12865 "register_operand" "r")
12866 (match_operand:SI 1 "ua_offset"
12867 "I06"))
12868 (const_int 7))
12869 (const_int -7)))
12870 (plus:SI (and:SI (plus:SI (match_dup 0)
12871 (match_operand:SI 2 "ua_offset" "I06"))
12872 (const_int 7))
12873 (const_int 1))
12874 (const_int 0))
12875 (match_operand:DI 3 "arith_reg_operand" "r"))]
12876 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12877 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12878 "#"
12879 ""
12880 [(pc)]
12881 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12882 operands[3]));
12883 DONE;")
12884
12885;; This is highpart user because the address is used as full 64 bit.
12886(define_insn "stlo_l"
12887 [(set (zero_extract:SI
12888 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12889 (const_int -4)))
12890 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12891 (and:SI (match_dup 0) (const_int 3)))
12892 (match_operand:SI 1 "arith_reg_operand" "r"))]
12893 "TARGET_SHMEDIA32"
12894 "stlo.l %U0, %1"
12895 [(set_attr "type" "ustore_media")])
12896
12897(define_insn "stlo_q"
12898 [(set (zero_extract:DI
12899 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12900 (const_int -8)))
12901 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12902 (and:SI (match_dup 0) (const_int 7)))
12903 (match_operand:DI 1 "arith_reg_operand" "r"))]
12904 "TARGET_SHMEDIA32"
12905 "stlo.q %U0, %1"
12906 [(set_attr "type" "ustore_media")])
12907
12908(define_insn_and_split "*stlo_q_comb0"
12909 [(set (zero_extract:DI
12910 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12911 (match_operand:SI 1 "ua_offset" "I06"))
12912 (const_int -8)))
12913 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12914 (and:SI (match_dup 0) (const_int 7)))
12915 (match_operand:DI 2 "arith_reg_operand" "r"))]
12916 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12917 "#"
12918 ""
12919 [(pc)]
12920 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12921 operands[2]));
12922 DONE;")
12923
12924(define_insn_and_split "*stlo_q_comb1"
12925 [(set (zero_extract:DI
12926 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12927 (match_operand:SI 1 "ua_offset" "I06"))
12928 (const_int -8)))
12929 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12930 (match_operand:SI 2
12931 "ua_offset" "I06"))
12932 (const_int 7)))
12933 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12934 (match_operand:DI 3 "arith_reg_operand" "r"))]
12935 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12936 "#"
12937 ""
12938 [(pc)]
12939 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12940 operands[3]));
12941 DONE;")
12942
12943(define_insn "ldhi_l64"
12944 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12945 (zero_extract:SI
12946 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12947 (const_int 3))
12948 (const_int -3)))
12949 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12950 (const_int 0)))]
12951 "TARGET_SHMEDIA64"
12952 "ldhi.l %U1, %0"
12953 [(set_attr "type" "load_media")])
12954
12955(define_insn "ldhi_q64"
12956 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12957 (zero_extract:DI
12958 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12959 (const_int 7))
12960 (const_int -7)))
12961 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12962 (const_int 0)))]
12963 "TARGET_SHMEDIA64"
12964 "ldhi.q %U1, %0"
12965 [(set_attr "type" "load_media")])
12966
12967(define_insn "ldlo_l64"
12968 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12969 (zero_extract:SI
12970 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12971 (const_int -4)))
12972 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12973 (and:DI (match_dup 1) (const_int 3))))]
12974 "TARGET_SHMEDIA64"
12975 "ldlo.l %U1, %0"
12976 [(set_attr "type" "load_media")])
12977
12978(define_insn "ldlo_q64"
12979 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12980 (zero_extract:DI
12981 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12982 (const_int -8)))
12983 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12984 (and:DI (match_dup 1) (const_int 7))))]
12985 "TARGET_SHMEDIA64"
12986 "ldlo.q %U1, %0"
12987 [(set_attr "type" "load_media")])
12988
12989(define_insn "sthi_l64"
12990 [(set (zero_extract:SI
12991 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12992 (const_int 3))
12993 (const_int -3)))
12994 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12995 (const_int 0))
12996 (match_operand:SI 1 "arith_reg_operand" "r"))]
12997 "TARGET_SHMEDIA64"
12998 "sthi.l %U0, %1"
12999 [(set_attr "type" "ustore_media")])
13000
13001(define_insn "sthi_q64"
13002 [(set (zero_extract:DI
13003 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13004 (const_int 7))
13005 (const_int -7)))
13006 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13007 (const_int 0))
13008 (match_operand:DI 1 "arith_reg_operand" "r"))]
13009 "TARGET_SHMEDIA64"
13010 "sthi.q %U0, %1"
13011 [(set_attr "type" "ustore_media")])
13012
13013(define_insn "stlo_l64"
13014 [(set (zero_extract:SI
13015 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13016 (const_int -4)))
13017 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13018 (and:DI (match_dup 0) (const_int 3)))
13019 (match_operand:SI 1 "arith_reg_operand" "r"))]
13020 "TARGET_SHMEDIA64"
13021 "stlo.l %U0, %1"
13022 [(set_attr "type" "ustore_media")])
13023
13024(define_insn "stlo_q64"
13025 [(set (zero_extract:DI
13026 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13027 (const_int -8)))
13028 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13029 (and:DI (match_dup 0) (const_int 7)))
13030 (match_operand:DI 1 "arith_reg_operand" "r"))]
13031 "TARGET_SHMEDIA64"
13032 "stlo.q %U0, %1"
13033 [(set_attr "type" "ustore_media")])
13034
b6d33983
R
13035(define_insn "nsb"
13036 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13037 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13038 UNSPEC_NSB))]
13039 "TARGET_SHMEDIA"
13040 "nsb %1, %0"
13041 [(set_attr "type" "arith_media")])
13042
13043(define_insn "nsbsi"
13044 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13045 (zero_extend:SI
13046 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13047 UNSPEC_NSB)))]
13048 "TARGET_SHMEDIA"
13049 "nsb %1, %0"
13050 [(set_attr "type" "arith_media")])
13051
13052(define_insn "nsbdi"
13053 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13054 (zero_extend:DI
13055 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13056 UNSPEC_NSB)))]
13057 "TARGET_SHMEDIA"
13058 "nsb %1, %0"
13059 [(set_attr "type" "arith_media")])
13060
13061(define_expand "ffsdi2"
13062 [(set (match_operand:DI 0 "arith_reg_dest" "")
13063 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13064 "TARGET_SHMEDIA"
13065 "
13066{
13067 rtx scratch = gen_reg_rtx (DImode);
13068 rtx last;
13069
a556fd39 13070 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
b6d33983
R
13071 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13072 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13073 emit_insn (gen_nsbdi (scratch, scratch));
13074 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13075 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13076 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13077 REG_NOTES (last)
13078 = gen_rtx_EXPR_LIST (REG_EQUAL,
13079 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13080 DONE;
13081}")
13082
13083(define_expand "ffssi2"
13084 [(set (match_operand:SI 0 "arith_reg_dest" "")
13085 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13086 "TARGET_SHMEDIA"
13087 "
13088{
13089 rtx scratch = gen_reg_rtx (SImode);
13090 rtx discratch = gen_reg_rtx (DImode);
13091 rtx last;
13092
e3c62520
R
13093 emit_insn (gen_adddi3 (discratch,
13094 simplify_gen_subreg (DImode, operands[1], SImode, 0),
a556fd39 13095 constm1_rtx));
e3c62520
R
13096 emit_insn (gen_andcdi3 (discratch,
13097 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13098 discratch));
b6d33983
R
13099 emit_insn (gen_nsbsi (scratch, discratch));
13100 last = emit_insn (gen_subsi3 (operands[0],
e3c62520 13101 force_reg (SImode, GEN_INT (63)), scratch));
b6d33983
R
13102 REG_NOTES (last)
13103 = gen_rtx_EXPR_LIST (REG_EQUAL,
13104 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13105 DONE;
13106}")
13107
13108(define_insn "byterev"
13109 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13110 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13111 (parallel [(const_int 7) (const_int 6) (const_int 5)
13112 (const_int 4) (const_int 3) (const_int 2)
13113 (const_int 1) (const_int 0)])))]
13114 "TARGET_SHMEDIA"
13115 "byterev %1, %0"
13116 [(set_attr "type" "arith_media")])
13117
73a4d10b 13118(define_insn "*prefetch_media"
88f08cca
R
13119 [(prefetch (match_operand:QI 0 "address_operand" "p")
13120 (match_operand:SI 1 "const_int_operand" "n")
13121 (match_operand:SI 2 "const_int_operand" "n"))]
07ea92d3 13122 "TARGET_SHMEDIA"
88f08cca
R
13123 "*
13124{
13125 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13126 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13127 return \"\";
13128}"
13129 [(set_attr "type" "other")])
07ea92d3 13130
73a4d10b 13131(define_insn "*prefetch_i4"
07ea92d3
KK
13132 [(prefetch (match_operand:SI 0 "register_operand" "r")
13133 (match_operand:SI 1 "const_int_operand" "n")
13134 (match_operand:SI 2 "const_int_operand" "n"))]
73a4d10b 13135 "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
07ea92d3
KK
13136 "*
13137{
13138 return \"pref @%0\";
13139}"
13140 [(set_attr "type" "other")])
13141
13142(define_expand "prefetch"
73a4d10b 13143 [(prefetch (match_operand 0 "address_operand" "p")
07ea92d3
KK
13144 (match_operand:SI 1 "const_int_operand" "n")
13145 (match_operand:SI 2 "const_int_operand" "n"))]
73a4d10b 13146 "TARGET_HARD_SH4 || TARGET_SH5"
07ea92d3
KK
13147 "
13148{
73a4d10b
R
13149 if (GET_MODE (operands[0]) != Pmode
13150 || GET_CODE (operands[1]) != CONST_INT
13151 || GET_CODE (operands[2]) != CONST_INT)
13152 FAIL;
13153 if (! TARGET_SHMEDIA)
13154 operands[0] = force_reg (Pmode, operands[0]);
13155}")
13156
13157(define_insn "alloco_i"
13158 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13159 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13160 "TARGET_SHMEDIA32"
13161 "*
13162{
13163 rtx xops[2];
13164
13165 if (GET_CODE (operands[0]) == PLUS)
13166 {
13167 xops[0] = XEXP (operands[0], 0);
13168 xops[1] = XEXP (operands[0], 1);
13169 }
13170 else
07ea92d3 13171 {
73a4d10b
R
13172 xops[0] = operands[0];
13173 xops[1] = const0_rtx;
07ea92d3 13174 }
73a4d10b
R
13175 output_asm_insn (\"alloco %0, %1\", xops);
13176 return \"\";
13177}"
13178 [(set_attr "type" "other")])
07ea92d3 13179
73a4d10b
R
13180(define_split
13181 [(set (match_operand 0 "any_register_operand" "")
13182 (match_operand 1 "" ""))]
13183 "TARGET_SHMEDIA && reload_completed"
13184 [(set (match_dup 0) (match_dup 1))]
13185 "
13186{
13187 int n_changes = 0;
13188
13189 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13190 if (!n_changes)
13191 FAIL;
07ea92d3 13192}")
50b69666
KK
13193
13194; Stack Protector Patterns
13195
13196(define_expand "stack_protect_set"
13197 [(set (match_operand 0 "memory_operand" "")
13198 (match_operand 1 "memory_operand" ""))]
13199 ""
13200{
13201 if (TARGET_SHMEDIA)
13202 {
13203 if (TARGET_SHMEDIA64)
13204 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13205 else
13206 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13207 }
13208 else
13209 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13210
13211 DONE;
13212})
13213
13214(define_insn "stack_protect_set_si"
13215 [(set (match_operand:SI 0 "memory_operand" "=m")
13216 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13217 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13218 "!TARGET_SHMEDIA"
13219 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13220 [(set_attr "type" "other")
13221 (set_attr "length" "6")])
13222
13223(define_insn "stack_protect_set_si_media"
13224 [(set (match_operand:SI 0 "memory_operand" "=m")
13225 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13226 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13227 "TARGET_SHMEDIA"
13228 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13229 [(set_attr "type" "other")
13230 (set_attr "length" "12")])
13231
13232(define_insn "stack_protect_set_di_media"
13233 [(set (match_operand:DI 0 "memory_operand" "=m")
13234 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13235 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13236 "TARGET_SHMEDIA64"
13237 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13238 [(set_attr "type" "other")
13239 (set_attr "length" "12")])
13240
13241(define_expand "stack_protect_test"
13242 [(match_operand 0 "memory_operand" "")
13243 (match_operand 1 "memory_operand" "")
13244 (match_operand 2 "" "")]
13245 ""
13246{
13247 if (TARGET_SHMEDIA)
13248 {
13249 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13250
13251 if (TARGET_SHMEDIA64)
13252 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13253 operands[1]));
13254 else
13255 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13256 operands[1]));
13257
13258 emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13259 }
13260 else
13261 {
13262 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13263 emit_jump_insn (gen_branch_true (operands[2]));
13264 }
13265
13266 DONE;
13267})
13268
13269(define_insn "stack_protect_test_si"
13270 [(set (reg:SI T_REG)
13271 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13272 (match_operand:SI 1 "memory_operand" "m")]
13273 UNSPEC_SP_TEST))
13274 (set (match_scratch:SI 2 "=&r") (const_int 0))
13275 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13276 "!TARGET_SHMEDIA"
13277 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13278 [(set_attr "type" "other")
13279 (set_attr "length" "10")])
13280
13281(define_insn "stack_protect_test_si_media"
13282 [(set (match_operand:SI 0 "register_operand" "=&r")
13283 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13284 (match_operand:SI 2 "memory_operand" "m")]
13285 UNSPEC_SP_TEST))
13286 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13287 "TARGET_SHMEDIA"
13288 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13289 [(set_attr "type" "other")
13290 (set_attr "length" "16")])
13291
13292(define_insn "stack_protect_test_di_media"
13293 [(set (match_operand:DI 0 "register_operand" "=&r")
13294 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13295 (match_operand:DI 2 "memory_operand" "m")]
13296 UNSPEC_SP_TEST))
13297 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13298 "TARGET_SHMEDIA64"
13299 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13300 [(set_attr "type" "other")
13301 (set_attr "length" "16")])