]> gcc.gnu.org Git - gcc.git/blame - gcc/config/sh/sh.md
sh.md (truncdiqi2): Use andi opcode for immediate.
[gcc.git] / gcc / config / sh / sh.md
CommitLineData
c8f0269d 1;;- Machine description for Renesas / SuperH SH.
3a8699c7 2;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4592bdcb 3;; Free Software Foundation, Inc.
51aea58d
JW
4;; Contributed by Steve Chamberlain (sac@cygnus.com).
5;; Improved by Jim Wilson (wilson@cygnus.com).
bc45ade3 6
7ec022b2 7;; This file is part of GCC.
bc45ade3 8
7ec022b2 9;; GCC is free software; you can redistribute it and/or modify
bc45ade3
SC
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
7ec022b2 14;; GCC is distributed in the hope that it will be useful,
bc45ade3
SC
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
7ec022b2 20;; along with GCC; see the file COPYING. If not, write to
3f63df56
RK
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
bc45ade3 23
bc45ade3 24
d0aae509
RK
25;; ??? Should prepend a * to all pattern names which are not used.
26;; This will make the compiler smaller, and rebuilds after changes faster.
27
ffae286a
JW
28;; ??? Should be enhanced to include support for many more GNU superoptimizer
29;; sequences. Especially the sequences for arithmetic right shifts.
30
31;; ??? Should check all DImode patterns for consistency and usefulness.
32
51bd623f
JW
33;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34;; way to generate them.
35
ffae286a
JW
36;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37;; for a str* inline function.
38
4ed4cb9a
JR
39;; BSR is not generated by the compiler proper, but when relaxing, it
40;; generates .uses pseudo-ops that allow linker relaxation to create
41;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42
0d7e008e
SC
43;; Special constraints for SH machine description:
44;;
07a45e5c
JW
45;; t -- T
46;; x -- mac
47;; l -- pr
0d7e008e
SC
48;; z -- r0
49;;
50;; Special formats used for outputting SH instructions:
51;;
52;; %. -- print a .s if insn needs delay slot
51aea58d 53;; %@ -- print rte/rts if is/isn't an interrupt function
0d7e008e 54;; %# -- output a nop if there is nothing to put in the delay slot
0d7e008e 55;; %O -- print a constant without the #
51aea58d
JW
56;; %R -- print the lsw reg of a double
57;; %S -- print the msw reg of a double
58;; %T -- print next word of a double REG or MEM
0d7e008e
SC
59;;
60;; Special predicates:
61;;
62;; arith_operand -- operand is valid source for arithmetic op
63;; arith_reg_operand -- operand is valid register for arithmetic op
0d7e008e
SC
64;; general_movdst_operand -- operand is valid move destination
65;; general_movsrc_operand -- operand is valid move source
66;; logical_operand -- operand is valid source for logical op
4773afa4
AO
67
68;; -------------------------------------------------------------------------
69;; Constants
70;; -------------------------------------------------------------------------
71
72(define_constants [
fa5322fa
AO
73 (AP_REG 145)
74 (PR_REG 146)
75 (T_REG 147)
76 (GBR_REG 144)
77 (MACH_REG 148)
78 (MACL_REG 149)
79 (FPUL_REG 150)
80 (RAP_REG 152)
4773afa4 81
fa5322fa 82 (FPSCR_REG 151)
4773afa4
AO
83
84 (PIC_REG 12)
85 (FP_REG 14)
86 (SP_REG 15)
87
fa5322fa
AO
88 (PR_MEDIA_REG 18)
89 (T_MEDIA_REG 19)
90
4773afa4
AO
91 (R0_REG 0)
92 (R1_REG 1)
93 (R2_REG 2)
94 (R3_REG 3)
95 (R4_REG 4)
96 (R5_REG 5)
97 (R6_REG 6)
fa5322fa
AO
98 (R7_REG 7)
99 (R8_REG 8)
100 (R9_REG 9)
101 (R10_REG 10)
9e96203d
R
102 (R20_REG 20)
103 (R21_REG 21)
104 (R22_REG 22)
105 (R23_REG 23)
fa5322fa
AO
106
107 (DR0_REG 64)
108 (DR2_REG 66)
109 (DR4_REG 68)
9e96203d 110 (FR23_REG 87)
4773afa4 111
fa5322fa
AO
112 (TR0_REG 128)
113 (TR1_REG 129)
114 (TR2_REG 130)
4773afa4 115
fa5322fa 116 (XD0_REG 136)
4773afa4
AO
117
118 ;; These are used with unspec.
fa5322fa 119 (UNSPEC_COMPACT_ARGS 0)
4773afa4
AO
120 (UNSPEC_MOVA 1)
121 (UNSPEC_CASESI 2)
fa5322fa 122 (UNSPEC_DATALABEL 3)
4773afa4
AO
123 (UNSPEC_BBR 4)
124 (UNSPEC_SFUNC 5)
125 (UNSPEC_PIC 6)
126 (UNSPEC_GOT 7)
127 (UNSPEC_GOTOFF 8)
128 (UNSPEC_PLT 9)
2d01e445 129 (UNSPEC_CALLER 10)
fa5322fa 130 (UNSPEC_GOTPLT 11)
4773afa4 131 (UNSPEC_ICACHE 12)
c1b92d09
R
132 (UNSPEC_INIT_TRAMP 13)
133 (UNSPEC_FCOSA 14)
134 (UNSPEC_FSRRA 15)
135 (UNSPEC_FSINA 16)
136 (UNSPEC_NSB 17)
137 (UNSPEC_ALLOCO 18)
4977bab6 138 (UNSPEC_EH_RETURN 19)
463f02cd
KK
139 (UNSPEC_TLSGD 20)
140 (UNSPEC_TLSLDM 21)
141 (UNSPEC_TLSIE 22)
142 (UNSPEC_DTPOFF 23)
143 (UNSPEC_GOTTPOFF 24)
144 (UNSPEC_TPOFF 25)
7d73a2ba 145 (UNSPEC_RA 26)
4773afa4
AO
146
147 ;; These are used with unspec_volatile.
148 (UNSPECV_BLOCKAGE 0)
b927e8c7 149 (UNSPECV_ALIGN 1)
4773afa4
AO
150 (UNSPECV_CONST2 2)
151 (UNSPECV_CONST4 4)
152 (UNSPECV_CONST8 6)
b91455de 153 (UNSPECV_WINDOW_END 10)
4773afa4 154 (UNSPECV_CONST_END 11)
73774972 155])
4773afa4 156
bc45ade3
SC
157;; -------------------------------------------------------------------------
158;; Attributes
159;; -------------------------------------------------------------------------
160
eeb531d5 161;; Target CPU.
b9654711 162
1245df60 163(define_attr "cpu"
3a8699c7 164 "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
07a45e5c 165 (const (symbol_ref "sh_cpu_attr")))
961c4780 166
1245df60
R
167(define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
170
d64264ff
R
171;; Indicate if the default fpu mode is single precision.
172(define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
175
225e4f43
R
176(define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
2ad65b0e
SC
179;; pipeline model
180(define_attr "pipe_model" "sh1,sh4,sh5media"
181 (const
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
225e4f43 185
0d7e008e
SC
186;; cbranch conditional branch instructions
187;; jump unconditional jumps
188;; arith ordinary arithmetic
956d6950 189;; arith3 a compound insn that behaves similarly to a sequence of
1245df60
R
190;; three insns of type arith
191;; arith3b like above, but might end with a redirected branch
0d7e008e 192;; load from memory
1245df60 193;; load_si Likewise, SImode variant for general register.
c49439f1 194;; fload Likewise, but load to fp register.
0d7e008e 195;; store to memory
c49439f1
R
196;; move general purpose register to register
197;; mt_group other sh4 mt instructions
1245df60 198;; fmove register to register, floating point
51bd623f
JW
199;; smpy word precision integer multiply
200;; dmpy longword or doublelongword precision integer multiply
0d7e008e 201;; return rts
ffae286a 202;; pload load of pr reg, which can't be put into delay slot of rts
99e87c10 203;; prset copy register to pr reg, ditto
ffae286a 204;; pstore store of pr reg, which can't be put into delay slot of jsr
99e87c10 205;; prget copy pr to register, ditto
22e1ebf1 206;; pcload pc relative load of constant value
c49439f1 207;; pcfload Likewise, but load to fp register.
1245df60 208;; pcload_si Likewise, SImode variant for general register.
0d7e008e
SC
209;; rte return from exception
210;; sfunc special function call with known used registers
ffae286a 211;; call function call
c1aef54d
ILT
212;; fp floating point
213;; fdiv floating point divide (or square root)
c49439f1
R
214;; gp_fpul move from general purpose register to fpul
215;; fpul_gp move from fpul to general purpose register
216;; mac_gp move from mac[lh] to general purpose register
225e4f43 217;; dfp_arith, dfp_cmp,dfp_conv
c49439f1 218;; ftrc_s fix_truncsfsi2_i4
225e4f43 219;; dfdiv double precision floating point divide (or square root)
c49439f1 220;; cwb ic_invalidate_line_i
73774972 221;; tls_load load TLS related address
2ad65b0e
SC
222;; arith_media SHmedia arithmetic, logical, and shift instructions
223;; cbranch_media SHmedia conditional branch instructions
224;; cmp_media SHmedia compare instructions
225;; dfdiv_media SHmedia double precision divide and square root
226;; dfmul_media SHmedia double precision multiply instruction
227;; dfparith_media SHmedia double precision floating point arithmetic
228;; dfpconv_media SHmedia double precision floating point conversions
229;; dmpy_media SHmedia longword multiply
230;; fcmp_media SHmedia floating point compare instructions
231;; fdiv_media SHmedia single precision divide and square root
232;; fload_media SHmedia floating point register load instructions
233;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
234;; fparith_media SHmedia single precision floating point arithmetic
235;; fpconv_media SHmedia single precision floating point conversions
236;; fstore_media SHmedia floating point register store instructions
237;; gettr_media SHmedia gettr instruction
825db093 238;; invalidate_line_media SHmedia invalidate_line sequence
2ad65b0e
SC
239;; jump_media SHmedia unconditional branch instructions
240;; load_media SHmedia general register load instructions
241;; pt_media SHmedia pt instruction (expanded by assembler)
242;; ptabs_media SHmedia ptabs instruction
243;; store_media SHmedia general register store instructions
244;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
245;; mac_media SHmedia mac-style fixed point operations
246;; d2mpy_media SHmedia: two 32 bit integer multiplies
825db093 247;; atrans SHmedia approximate transcendental functions
2ad65b0e 248;; ustore_media SHmedia unaligned stores
4dff12bf 249;; nil no-op move, will be deleted.
0d7e008e 250
07a45e5c 251(define_attr "type"
463f02cd 252 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
bc45ade3
SC
253 (const_string "other"))
254
fae15c93 255;; We define a new attribute namely "insn_class".We use
c49439f1 256;; this for the DFA based pipeline description.
fae15c93
VM
257;;
258;; mt_group SH4 "mt" group instructions.
259;;
c49439f1
R
260;; ex_group SH4 "ex" group instructions.
261;;
262;; ls_group SH4 "ls" group instructions.
fae15c93 263;;
fae15c93
VM
264
265(define_attr "insn_class"
c49439f1
R
266 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270 (eq_attr "type" "cbranch,jump") (const_string "br_group")
271 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272 (const_string "fe_group")
273 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
274 (const_string "none")))
275;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276;; so these do not belong in an insn group, although they are modeled
277;; with their own define_insn_reservations.
fae15c93 278
d64264ff
R
279;; Indicate what precision must be selected in fpscr for this insn, if any.
280
281(define_attr "fp_mode" "single,double,none" (const_string "none"))
282
73774972
EC
283;; Indicate if the fpu mode is set by this instruction
284;; "unknown" must have the value as "none" in fp_mode, and means
285;; that the instruction/abi has left the processor in an unknown
286;; state.
287;; "none" means that nothing has changed and no mode is set.
288;; This attribute is only used for the Renesas ABI.
289(define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
290
07a45e5c 291; If a conditional branch destination is within -252..258 bytes away
bc45ade3 292; from the instruction it can be 2 bytes long. Something in the
22e1ebf1 293; range -4090..4100 bytes can be 6 bytes long. All other conditional
1245df60
R
294; branches are initially assumed to be 16 bytes long.
295; In machine_dependent_reorg, we split all branches that are longer than
296; 2 bytes.
bc45ade3 297
536fe39c 298;; The maximum range used for SImode constant pool entries is 1018. A final
33f7f353
JR
299;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
301;; instruction around the pool table, 2 bytes of alignment before the table,
302;; and 30 bytes of alignment after the table. That gives a maximum total
303;; pool size of 1058 bytes.
304;; Worst case code/pool content size ratio is 1:2 (using asms).
305;; Thus, in the worst case, there is one instruction in front of a maximum
306;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
308;; If we have a forward branch, the initial table will be put after the
309;; unconditional branch.
310;;
311;; ??? We could do much better by keeping track of the actual pcloads within
312;; the branch range and in the pcload range in front of the branch range.
313
314;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
315;; inside an le.
316(define_attr "short_cbranch_p" "no,yes"
317 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
318 (const_string "no")
319 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
320 (const_string "yes")
321 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
322 (const_string "no")
323 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
324 (const_string "yes")
325 ] (const_string "no")))
326
327(define_attr "med_branch_p" "no,yes"
328 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
329 (const_int 1988))
330 (const_string "yes")
331 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
332 (const_string "no")
333 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
334 (const_int 8186))
335 (const_string "yes")
336 ] (const_string "no")))
337
338(define_attr "med_cbranch_p" "no,yes"
339 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
340 (const_int 1986))
341 (const_string "yes")
342 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343 (const_string "no")
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
345 (const_int 8184))
346 (const_string "yes")
347 ] (const_string "no")))
348
349(define_attr "braf_branch_p" "no,yes"
350 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
351 (const_string "no")
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
353 (const_int 20660))
354 (const_string "yes")
355 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356 (const_string "no")
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
358 (const_int 65530))
359 (const_string "yes")
360 ] (const_string "no")))
361
362(define_attr "braf_cbranch_p" "no,yes"
363 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364 (const_string "no")
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
366 (const_int 20658))
367 (const_string "yes")
368 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369 (const_string "no")
370 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
371 (const_int 65528))
372 (const_string "yes")
373 ] (const_string "no")))
374
22e1ebf1 375; An unconditional jump in the range -4092..4098 can be 2 bytes long.
1245df60
R
376; For wider ranges, we need a combination of a code and a data part.
377; If we can get a scratch register for a long range jump, the code
378; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379; If the jump is in the range -32764..32770, the data part can be 2 bytes
380; long; otherwise, it must be 6 bytes long.
bc45ade3
SC
381
382; All other instructions are two bytes long by default.
383
33f7f353
JR
384;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385;; but getattrtab doesn't understand this.
07a45e5c 386(define_attr "length" ""
bc45ade3 387 (cond [(eq_attr "type" "cbranch")
33f7f353 388 (cond [(eq_attr "short_cbranch_p" "yes")
1245df60 389 (const_int 2)
33f7f353 390 (eq_attr "med_cbranch_p" "yes")
1245df60 391 (const_int 6)
33f7f353 392 (eq_attr "braf_cbranch_p" "yes")
1245df60 393 (const_int 12)
33f7f353
JR
394;; ??? using pc is not computed transitively.
395 (ne (match_dup 0) (match_dup 0))
396 (const_int 14)
e6dfd05f
AO
397 (ne (symbol_ref ("flag_pic")) (const_int 0))
398 (const_int 24)
1245df60 399 ] (const_int 16))
bc45ade3 400 (eq_attr "type" "jump")
33f7f353 401 (cond [(eq_attr "med_branch_p" "yes")
1245df60 402 (const_int 2)
10f4f635 403 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
1245df60 404 (symbol_ref "INSN"))
10f4f635 405 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
1245df60 406 (symbol_ref "code_for_indirect_jump_scratch")))
33f7f353 407 (if_then_else (eq_attr "braf_branch_p" "yes")
1245df60
R
408 (const_int 6)
409 (const_int 10))
33f7f353 410 (eq_attr "braf_branch_p" "yes")
1245df60 411 (const_int 10)
33f7f353
JR
412;; ??? using pc is not computed transitively.
413 (ne (match_dup 0) (match_dup 0))
1245df60 414 (const_int 12)
e6dfd05f
AO
415 (ne (symbol_ref ("flag_pic")) (const_int 0))
416 (const_int 22)
1245df60 417 ] (const_int 14))
2ad65b0e 418 (eq_attr "type" "pt_media")
fa5322fa
AO
419 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420 (const_int 20) (const_int 12))
421 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
422 (const_int 4)
423 (const_int 2))))
b9654711
SC
424
425;; (define_function_unit {name} {num-units} {n-users} {test}
426;; {ready-delay} {issue-delay} [{conflict-list}])
07a45e5c 427
c1aef54d
ILT
428;; Load and store instructions save a cycle if they are aligned on a
429;; four byte boundary. Using a function unit for stores encourages
430;; gcc to separate load and store instructions by one instruction,
431;; which makes it more likely that the linker will be able to word
432;; align them when relaxing.
1245df60
R
433
434;; Loads have a latency of two.
deeef0ac 435;; However, call insns can have a delay slot, so that we want one more
1245df60
R
436;; insn to be scheduled between the load of the function address and the call.
437;; This is equivalent to a latency of three.
438;; We cannot use a conflict list for this, because we need to distinguish
439;; between the actual call address and the function arguments.
440;; ADJUST_COST can only properly handle reductions of the cost, so we
441;; use a latency of three here.
956d6950 442;; We only do this for SImode loads of general registers, to make the work
1245df60
R
443;; for ADJUST_COST easier.
444(define_function_unit "memory" 1 0
2ad65b0e 445 (and (eq_attr "pipe_model" "sh1")
225e4f43 446 (eq_attr "type" "load_si,pcload_si"))
1245df60 447 3 2)
c1aef54d 448(define_function_unit "memory" 1 0
2ad65b0e 449 (and (eq_attr "pipe_model" "sh1")
225e4f43 450 (eq_attr "type" "load,pcload,pload,store,pstore"))
1245df60
R
451 2 2)
452
453(define_function_unit "int" 1 0
2ad65b0e 454 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
1245df60
R
455
456(define_function_unit "int" 1 0
2ad65b0e 457 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
1245df60
R
458
459(define_function_unit "int" 1 0
2ad65b0e 460 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
c1aef54d
ILT
461
462;; ??? These are approximations.
225e4f43 463(define_function_unit "mpy" 1 0
2ad65b0e 464 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
225e4f43 465(define_function_unit "mpy" 1 0
2ad65b0e 466 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
225e4f43
R
467
468(define_function_unit "fp" 1 0
2ad65b0e 469 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
225e4f43 470(define_function_unit "fp" 1 0
2ad65b0e 471 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
225e4f43
R
472
473
2ad65b0e
SC
474;; SH-5 SHmedia scheduling
475;; When executing SHmedia code, the SH-5 is a fairly straightforward
476;; single-issue machine. It has four pipelines, the branch unit (br),
477;; the integer and multimedia unit (imu), the load/store unit (lsu), and
478;; the floating point unit (fpu).
479;; Here model the instructions with a latency greater than one cycle.
480
481;; Every instruction on SH-5 occupies the issue resource for at least one
482;; cycle.
483(define_function_unit "sh5issue" 1 0
484 (and (eq_attr "pipe_model" "sh5media")
485 (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
486
487;; Specify the various types of instruction which have latency > 1
488(define_function_unit "sh5issue" 1 0
489 (and (eq_attr "pipe_model" "sh5media")
490 (eq_attr "type" "mcmp_media")) 2 1)
491
492(define_function_unit "sh5issue" 1 0
493 (and (eq_attr "pipe_model" "sh5media")
494 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
495;; but see sh_adjust_cost for mac_media exception.
496
497(define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "fload_media,fmove_media")) 4 1)
500
501(define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "d2mpy_media")) 4 2)
504
505(define_function_unit "sh5issue" 1 0
506 (and (eq_attr "pipe_model" "sh5media")
507 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
508
509(define_function_unit "sh5issue" 1 0
510 (and (eq_attr "pipe_model" "sh5media")
511 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
512
513(define_function_unit "sh5issue" 1 0
514 (and (eq_attr "pipe_model" "sh5media")
515 (eq_attr "type" "invalidate_line_media")) 7 7)
516
517(define_function_unit "sh5issue" 1 0
518 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
519
520(define_function_unit "sh5issue" 1 0
521 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
522
523;; Floating-point divide and square-root occupy an additional resource,
524;; which is not internally pipelined. However, other instructions
525;; can continue to issue.
526(define_function_unit "sh5fds" 1 0
527 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
528
529(define_function_unit "sh5fds" 1 0
530 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
fa5322fa 531
51bd623f 532; Definitions for filling branch delay slots.
bc45ade3 533
51bd623f
JW
534(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
535
225e4f43
R
536;; ??? This should be (nil) instead of (const_int 0)
537(define_attr "hit_stack" "yes,no"
4773afa4
AO
538 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
539 (const_int 0))
225e4f43
R
540 (const_string "no")]
541 (const_string "yes")))
51bd623f
JW
542
543(define_attr "interrupt_function" "no,yes"
552ecbd9 544 (const (symbol_ref "current_function_interrupt")))
51bd623f 545
07a45e5c 546(define_attr "in_delay_slot" "yes,no"
51bd623f 547 (cond [(eq_attr "type" "cbranch") (const_string "no")
1245df60 548 (eq_attr "type" "pcload,pcload_si") (const_string "no")
51bd623f
JW
549 (eq_attr "needs_delay_slot" "yes") (const_string "no")
550 (eq_attr "length" "2") (const_string "yes")
551 ] (const_string "no")))
552
c608a684
R
553(define_attr "cond_delay_slot" "yes,no"
554 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
555 ] (const_string "no")))
556
0603a39d
R
557(define_attr "is_sfunc" ""
558 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
559
2ad65b0e
SC
560(define_attr "is_mac_media" ""
561 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
562
c49439f1
R
563(define_attr "branch_zero" "yes,no"
564 (cond [(eq_attr "type" "!cbranch") (const_string "no")
565 (ne (symbol_ref "(next_active_insn (insn)\
566 == (prev_active_insn\
567 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
568 && get_attr_length (next_active_insn (insn)) == 2")
569 (const_int 0))
570 (const_string "yes")]
571 (const_string "no")))
572
573;; SH4 Double-precision computation with double-precision result -
574;; the two halves are ready at different times.
575(define_attr "dfp_comp" "yes,no"
576 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
577 (const_string "no")))
578
579;; Insns for which the latency of a preceding fp insn is decreased by one.
580(define_attr "late_fp_use" "yes,no" (const_string "no"))
581;; And feeding insns for which this relevant.
582(define_attr "any_fp_comp" "yes,no"
583 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
584 (const_string "yes")]
585 (const_string "no")))
586
587(define_attr "any_int_load" "yes,no"
588 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
589 (const_string "yes")]
590 (const_string "no")))
591
51bd623f 592(define_delay
0d7e008e 593 (eq_attr "needs_delay_slot" "yes")
b9654711
SC
594 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
595
51aea58d
JW
596;; On the SH and SH2, the rte instruction reads the return pc from the stack,
597;; and thus we can't put a pop instruction in its delay slot.
6b005b88
JW
598;; ??? On the SH3, the rte instruction does not use the stack, so a pop
599;; instruction can go in the delay slot.
51aea58d 600
ffae286a
JW
601;; Since a normal return (rts) implicitly uses the PR register,
602;; we can't allow PR register loads in an rts delay slot.
603
07a45e5c 604(define_delay
961c4780 605 (eq_attr "type" "return")
07a45e5c 606 [(and (eq_attr "in_delay_slot" "yes")
ffae286a 607 (ior (and (eq_attr "interrupt_function" "no")
99e87c10 608 (eq_attr "type" "!pload,prset"))
ffae286a 609 (and (eq_attr "interrupt_function" "yes")
552ecbd9
AH
610 (ior
611 (ne (symbol_ref "TARGET_SH3") (const_int 0))
612 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
ffae286a
JW
613
614;; Since a call implicitly uses the PR register, we can't allow
615;; a PR register store in a jsr delay slot.
616
617(define_delay
618 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
619 [(and (eq_attr "in_delay_slot" "yes")
99e87c10 620 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
ffae286a
JW
621
622;; Say that we have annulled true branches, since this gives smaller and
623;; faster code when branches are predicted as not taken.
624
07a45e5c
JW
625(define_delay
626 (and (eq_attr "type" "cbranch")
1245df60 627 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
3a8699c7
AO
628 ;; SH2e has a hardware bug that pretty much prohibits the use of
629 ;; annuled delay slots.
630 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
631 (not (eq_attr "cpu" "sh2e"))) (nil)])
bc45ade3
SC
632\f
633;; -------------------------------------------------------------------------
634;; SImode signed integer comparisons
635;; -------------------------------------------------------------------------
636
51bd623f 637(define_insn ""
4773afa4 638 [(set (reg:SI T_REG)
51bd623f 639 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
735cb76e 640 (match_operand:SI 1 "arith_operand" "K08,r"))
51bd623f 641 (const_int 0)))]
fa5322fa 642 "TARGET_SH1"
fae15c93 643 "tst %1,%0"
c49439f1 644 [(set_attr "type" "mt_group")])
0d7e008e 645
07a45e5c
JW
646;; ??? Perhaps should only accept reg/constant if the register is reg 0.
647;; That would still allow reload to create cmpi instructions, but would
648;; perhaps allow forcing the constant into a register when that is better.
ffae286a
JW
649;; Probably should use r0 for mem/imm compares, but force constant into a
650;; register for pseudo/imm compares.
07a45e5c 651
0d7e008e 652(define_insn "cmpeqsi_t"
4773afa4
AO
653 [(set (reg:SI T_REG)
654 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
735cb76e 655 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
fa5322fa 656 "TARGET_SH1"
0d7e008e 657 "@
51bd623f 658 tst %0,%0
0d7e008e 659 cmp/eq %1,%0
fae15c93 660 cmp/eq %1,%0"
c49439f1 661 [(set_attr "type" "mt_group")])
bc45ade3
SC
662
663(define_insn "cmpgtsi_t"
4773afa4
AO
664 [(set (reg:SI T_REG)
665 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
666 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 667 "TARGET_SH1"
0d7e008e 668 "@
22e1ebf1 669 cmp/gt %1,%0
fae15c93 670 cmp/pl %0"
c49439f1 671 [(set_attr "type" "mt_group")])
bc45ade3
SC
672
673(define_insn "cmpgesi_t"
4773afa4
AO
674 [(set (reg:SI T_REG)
675 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
676 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
fa5322fa 677 "TARGET_SH1"
0d7e008e 678 "@
22e1ebf1 679 cmp/ge %1,%0
fae15c93 680 cmp/pz %0"
c49439f1 681 [(set_attr "type" "mt_group")])
fae15c93 682
bc45ade3
SC
683;; -------------------------------------------------------------------------
684;; SImode unsigned integer comparisons
685;; -------------------------------------------------------------------------
686
687(define_insn "cmpgeusi_t"
4773afa4
AO
688 [(set (reg:SI T_REG)
689 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 691 "TARGET_SH1"
fae15c93 692 "cmp/hs %1,%0"
c49439f1 693 [(set_attr "type" "mt_group")])
bc45ade3
SC
694
695(define_insn "cmpgtusi_t"
4773afa4
AO
696 [(set (reg:SI T_REG)
697 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
698 (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 699 "TARGET_SH1"
fae15c93 700 "cmp/hi %1,%0"
c49439f1 701 [(set_attr "type" "mt_group")])
bc45ade3
SC
702
703;; We save the compare operands in the cmpxx patterns and use them when
704;; we generate the branch.
705
706(define_expand "cmpsi"
4773afa4
AO
707 [(set (reg:SI T_REG)
708 (compare (match_operand:SI 0 "arith_operand" "")
709 (match_operand:SI 1 "arith_operand" "")))]
fa5322fa 710 "TARGET_SH1"
bc45ade3 711 "
0d7e008e
SC
712{
713 sh_compare_op0 = operands[0];
bc45ade3
SC
714 sh_compare_op1 = operands[1];
715 DONE;
716}")
bc45ade3
SC
717\f
718;; -------------------------------------------------------------------------
1245df60
R
719;; DImode signed integer comparisons
720;; -------------------------------------------------------------------------
721
722;; ??? Could get better scheduling by splitting the initial test from the
723;; rest of the insn after reload. However, the gain would hardly justify
724;; the sh.md size increase necessary to do that.
725
726(define_insn ""
4773afa4 727 [(set (reg:SI T_REG)
1245df60
R
728 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
729 (match_operand:DI 1 "arith_operand" "r"))
730 (const_int 0)))]
fa5322fa 731 "TARGET_SH1"
1245df60
R
732 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
733 insn, operands);"
734 [(set_attr "length" "6")
735 (set_attr "type" "arith3b")])
736
737(define_insn "cmpeqdi_t"
4773afa4
AO
738 [(set (reg:SI T_REG)
739 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
740 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
fa5322fa 741 "TARGET_SH1"
712646d0 742 "@
4c0d0505
JR
743 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
744 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
1245df60
R
745 [(set_attr "length" "6")
746 (set_attr "type" "arith3b")])
747
1987b7bc 748(define_split
4773afa4 749 [(set (reg:SI T_REG)
e69d1422
R
750 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
751 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
712646d0
R
752;; If we applied this split when not optimizing, it would only be
753;; applied during the machine-dependent reorg, when no new basic blocks
754;; may be created.
fa5322fa 755 "TARGET_SH1 && reload_completed && optimize"
4773afa4
AO
756 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
757 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
712646d0
R
758 (label_ref (match_dup 6))
759 (pc)))
4773afa4 760 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
712646d0 761 (match_dup 6)]
1987b7bc
R
762 "
763{
764 operands[2]
765 = gen_rtx_REG (SImode,
766 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
767 operands[3]
768 = (operands[1] == const0_rtx
769 ? const0_rtx
770 : gen_rtx_REG (SImode,
771 true_regnum (operands[1])
772 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
773 operands[4] = gen_lowpart (SImode, operands[0]);
774 operands[5] = gen_lowpart (SImode, operands[1]);
712646d0 775 operands[6] = gen_label_rtx ();
1987b7bc
R
776}")
777
1245df60 778(define_insn "cmpgtdi_t"
4773afa4
AO
779 [(set (reg:SI T_REG)
780 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
781 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
782 "TARGET_SH2"
783 "@
784 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
785 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
786 [(set_attr "length" "8")
787 (set_attr "type" "arith3")])
788
789(define_insn "cmpgedi_t"
4773afa4
AO
790 [(set (reg:SI T_REG)
791 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
792 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
1245df60
R
793 "TARGET_SH2"
794 "@
795 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
796 cmp/pz\\t%S0"
797 [(set_attr "length" "8,2")
c49439f1 798 (set_attr "type" "arith3,mt_group")])
1245df60
R
799\f
800;; -------------------------------------------------------------------------
801;; DImode unsigned integer comparisons
802;; -------------------------------------------------------------------------
803
804(define_insn "cmpgeudi_t"
4773afa4
AO
805 [(set (reg:SI T_REG)
806 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
807 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
808 "TARGET_SH2"
809 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
810 [(set_attr "length" "8")
811 (set_attr "type" "arith3")])
812
813(define_insn "cmpgtudi_t"
4773afa4
AO
814 [(set (reg:SI T_REG)
815 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
816 (match_operand:DI 1 "arith_reg_operand" "r")))]
1245df60
R
817 "TARGET_SH2"
818 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
819 [(set_attr "length" "8")
820 (set_attr "type" "arith3")])
821
fa5322fa 822(define_insn "cmpeqdi_media"
b6d33983
R
823 [(set (match_operand:DI 0 "register_operand" "=r")
824 (eq:DI (match_operand:DI 1 "register_operand" "%r")
825 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
fa5322fa 826 "TARGET_SHMEDIA"
b6d33983
R
827 "cmpeq %1, %N2, %0"
828 [(set_attr "type" "cmp_media")])
fa5322fa
AO
829
830(define_insn "cmpgtdi_media"
b6d33983
R
831 [(set (match_operand:DI 0 "register_operand" "=r")
832 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 834 "TARGET_SHMEDIA"
b6d33983
R
835 "cmpgt %N1, %N2, %0"
836 [(set_attr "type" "cmp_media")])
fa5322fa
AO
837
838(define_insn "cmpgtudi_media"
b6d33983
R
839 [(set (match_operand:DI 0 "register_operand" "=r")
840 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
841 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
fa5322fa 842 "TARGET_SHMEDIA"
68cef009 843 "cmpgtu %N1, %N2, %0"
b6d33983 844 [(set_attr "type" "cmp_media")])
fa5322fa 845
1245df60
R
846;; We save the compare operands in the cmpxx patterns and use them when
847;; we generate the branch.
848
849(define_expand "cmpdi"
4773afa4
AO
850 [(set (reg:SI T_REG)
851 (compare (match_operand:DI 0 "arith_operand" "")
852 (match_operand:DI 1 "arith_operand" "")))]
fa5322fa 853 "TARGET_SH2 || TARGET_SHMEDIA"
1245df60
R
854 "
855{
856 sh_compare_op0 = operands[0];
857 sh_compare_op1 = operands[1];
858 DONE;
859}")
fa5322fa
AO
860;; -------------------------------------------------------------------------
861;; Conditional move instructions
862;; -------------------------------------------------------------------------
863
864;; The insn names may seem reversed, but note that cmveq performs the move
865;; if op1 == 0, and cmvne does it if op1 != 0.
866
867(define_insn "movdicc_false"
b6d33983
R
868 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
869 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 870 (const_int 0))
b6d33983
R
871 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
872 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 873 "TARGET_SHMEDIA"
b6d33983
R
874 "cmveq %1, %N2, %0"
875 [(set_attr "type" "arith_media")])
fa5322fa
AO
876
877(define_insn "movdicc_true"
b6d33983
R
878 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
879 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
fa5322fa 880 (const_int 0))
b6d33983
R
881 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
882 (match_operand:DI 3 "arith_reg_operand" "0")))]
fa5322fa 883 "TARGET_SHMEDIA"
b6d33983
R
884 "cmvne %1, %N2, %0"
885 [(set_attr "type" "arith_media")])
fa5322fa
AO
886
887(define_expand "movdicc"
888 [(set (match_operand:DI 0 "register_operand" "")
889 (if_then_else:DI (match_operand 1 "comparison_operator" "")
890 (match_operand:DI 2 "register_operand" "")
891 (match_operand:DI 3 "register_operand" "")))]
892 "TARGET_SHMEDIA"
893 "
894{
895 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
896 && GET_MODE (sh_compare_op0) == DImode
897 && sh_compare_op1 == const0_rtx)
898 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
899 sh_compare_op0, sh_compare_op1);
900 else
901 {
902 rtx tmp;
903
904 if (no_new_pseudos)
905 FAIL;
906
907 tmp = gen_reg_rtx (DImode);
908
909 switch (GET_CODE (operands[1]))
910 {
911 case EQ:
912 emit_insn (gen_seq (tmp));
913 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
914 break;
915
916 case NE:
917 emit_insn (gen_seq (tmp));
918 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
919 break;
920
921 case GT:
922 emit_insn (gen_sgt (tmp));
923 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
924 break;
925
926 case LT:
927 emit_insn (gen_slt (tmp));
928 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
929 break;
930
931 case GE:
932 emit_insn (gen_slt (tmp));
933 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
934 break;
935
936 case LE:
937 emit_insn (gen_sgt (tmp));
938 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
939 break;
940
941 case GTU:
942 emit_insn (gen_sgtu (tmp));
943 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944 break;
945
946 case LTU:
947 emit_insn (gen_sltu (tmp));
948 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
949 break;
950
951 case GEU:
952 emit_insn (gen_sltu (tmp));
953 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
954 break;
955
956 case LEU:
957 emit_insn (gen_sgtu (tmp));
958 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
959 break;
960
961 case UNORDERED:
962 emit_insn (gen_sunordered (tmp));
963 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
964 break;
965
966 case ORDERED:
967 emit_insn (gen_sunordered (tmp));
968 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
969 break;
970
971 case UNEQ:
972 case UNGE:
973 case UNGT:
974 case UNLE:
975 case UNLT:
976 case LTGT:
977 FAIL;
978
979 default:
980 abort ();
981 }
982 }
983}")
1245df60
R
984\f
985;; -------------------------------------------------------------------------
bc45ade3
SC
986;; Addition instructions
987;; -------------------------------------------------------------------------
988
fa5322fa
AO
989(define_expand "adddi3"
990 [(set (match_operand:DI 0 "arith_reg_operand" "")
991 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
992 (match_operand:DI 2 "arith_operand" "")))]
993 ""
994 "
995{
996 if (TARGET_SH1)
997 {
998 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
999 FAIL;
1000 operands[2] = force_reg (DImode, operands[2]);
1001 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1002 DONE;
1003 }
1004}")
0d7e008e 1005
fa5322fa
AO
1006(define_insn "*adddi3_media"
1007 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1008 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 1009 (match_operand:DI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1010 "TARGET_SHMEDIA"
1011 "@
1012 add %1, %2, %0
2ad65b0e
SC
1013 addi %1, %2, %0"
1014 [(set_attr "type" "arith_media")])
fa5322fa 1015
b6d33983
R
1016(define_insn "adddi3z_media"
1017 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
fa5322fa 1018 (zero_extend:DI
b6d33983
R
1019 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1020 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
fa5322fa 1021 "TARGET_SHMEDIA"
b6d33983
R
1022 "addz.l %1, %N2, %0"
1023 [(set_attr "type" "arith_media")])
52702ae1 1024
fa5322fa 1025(define_insn "adddi3_compact"
38b3ef8b 1026 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
07a45e5c
JW
1027 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1028 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1029 (clobber (reg:SI T_REG))]
fa5322fa 1030 "TARGET_SH1"
1245df60 1031 "#"
4fdd1f85 1032 [(set_attr "length" "6")])
961c4780 1033
1245df60 1034(define_split
e69d1422
R
1035 [(set (match_operand:DI 0 "arith_reg_operand" "")
1036 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1037 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1038 (clobber (reg:SI T_REG))]
fa5322fa 1039 "TARGET_SH1 && reload_completed"
1245df60
R
1040 [(const_int 0)]
1041 "
1042{
1043 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1044 high0 = gen_rtx_REG (SImode,
1045 true_regnum (operands[0])
1046 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1047 high2 = gen_rtx_REG (SImode,
1048 true_regnum (operands[2])
1049 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1050 emit_insn (gen_clrt ());
1051 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1052 emit_insn (gen_addc1 (high0, high0, high2));
1053 DONE;
1054}")
1055
1056(define_insn "addc"
1057 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1058 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1059 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1060 (reg:SI T_REG)))
1061 (set (reg:SI T_REG)
1245df60 1062 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1063 "TARGET_SH1"
1245df60 1064 "addc %2,%0"
c49439f1 1065 [(set_attr "type" "arith")])
1245df60
R
1066
1067(define_insn "addc1"
1068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1069 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1070 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1071 (reg:SI T_REG)))
1072 (clobber (reg:SI T_REG))]
fa5322fa 1073 "TARGET_SH1"
1245df60 1074 "addc %2,%0"
c49439f1 1075 [(set_attr "type" "arith")])
1245df60 1076
fa5322fa
AO
1077(define_expand "addsi3"
1078 [(set (match_operand:SI 0 "arith_reg_operand" "")
1079 (plus:SI (match_operand:SI 1 "arith_operand" "")
1080 (match_operand:SI 2 "arith_operand" "")))]
1081 ""
1082 "
1083{
1084 if (TARGET_SHMEDIA)
1085 operands[1] = force_reg (SImode, operands[1]);
1086}")
1087
1088(define_insn "addsi3_media"
1089 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 1090 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
735cb76e 1091 (match_operand:SI 2 "arith_operand" "r,I10")))]
fa5322fa
AO
1092 "TARGET_SHMEDIA"
1093 "@
1094 add.l %1, %2, %0
b6d33983
R
1095 addi.l %1, %2, %0"
1096 [(set_attr "type" "arith_media")])
52702ae1 1097
fa5322fa 1098(define_insn "*addsi3_compact"
aa684c94 1099 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f 1100 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
735cb76e 1101 (match_operand:SI 2 "arith_operand" "rI08")))]
fa5322fa 1102 "TARGET_SH1"
bc45ade3 1103 "add %2,%0"
c49439f1 1104 [(set_attr "type" "arith")])
fae15c93 1105
bc45ade3
SC
1106;; -------------------------------------------------------------------------
1107;; Subtraction instructions
1108;; -------------------------------------------------------------------------
1109
fa5322fa
AO
1110(define_expand "subdi3"
1111 [(set (match_operand:DI 0 "arith_reg_operand" "")
52702ae1 1112 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
fa5322fa
AO
1113 (match_operand:DI 2 "arith_reg_operand" "")))]
1114 ""
1115 "
1116{
1117 if (TARGET_SH1)
1118 {
52702ae1 1119 operands[1] = force_reg (DImode, operands[1]);
fa5322fa
AO
1120 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1121 DONE;
1122 }
1123}")
52702ae1 1124
fa5322fa
AO
1125(define_insn "*subdi3_media"
1126 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
52702ae1 1127 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
fa5322fa
AO
1128 (match_operand:DI 2 "arith_reg_operand" "r")))]
1129 "TARGET_SHMEDIA"
2ad65b0e
SC
1130 "sub %N1, %2, %0"
1131 [(set_attr "type" "arith_media")])
52702ae1 1132
fa5322fa 1133(define_insn "subdi3_compact"
38b3ef8b 1134 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
07a45e5c
JW
1135 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1136 (match_operand:DI 2 "arith_reg_operand" "r")))
4773afa4 1137 (clobber (reg:SI T_REG))]
fa5322fa 1138 "TARGET_SH1"
1245df60 1139 "#"
4fdd1f85 1140 [(set_attr "length" "6")])
bc45ade3 1141
1245df60 1142(define_split
e69d1422
R
1143 [(set (match_operand:DI 0 "arith_reg_operand" "")
1144 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1145 (match_operand:DI 2 "arith_reg_operand" "")))
4773afa4 1146 (clobber (reg:SI T_REG))]
fa5322fa 1147 "TARGET_SH1 && reload_completed"
1245df60
R
1148 [(const_int 0)]
1149 "
1150{
1151 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
c5c76735
JL
1152 high0 = gen_rtx_REG (SImode,
1153 true_regnum (operands[0])
1154 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1155 high2 = gen_rtx_REG (SImode,
1156 true_regnum (operands[2])
1157 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1245df60
R
1158 emit_insn (gen_clrt ());
1159 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1160 emit_insn (gen_subc1 (high0, high0, high2));
1161 DONE;
1162}")
1163
1164(define_insn "subc"
1165 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1166 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1167 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1168 (reg:SI T_REG)))
1169 (set (reg:SI T_REG)
1245df60 1170 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
fa5322fa 1171 "TARGET_SH1"
1245df60 1172 "subc %2,%0"
c49439f1 1173 [(set_attr "type" "arith")])
1245df60
R
1174
1175(define_insn "subc1"
1176 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1177 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1178 (match_operand:SI 2 "arith_reg_operand" "r"))
4773afa4
AO
1179 (reg:SI T_REG)))
1180 (clobber (reg:SI T_REG))]
fa5322fa 1181 "TARGET_SH1"
1245df60 1182 "subc %2,%0"
c49439f1 1183 [(set_attr "type" "arith")])
1245df60 1184
caca3c8a 1185(define_insn "*subsi3_internal"
0d7e008e
SC
1186 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1187 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1188 (match_operand:SI 2 "arith_reg_operand" "r")))]
fa5322fa 1189 "TARGET_SH1"
0d7e008e 1190 "sub %2,%0"
c49439f1 1191 [(set_attr "type" "arith")])
caca3c8a 1192
fa5322fa
AO
1193(define_insn "*subsi3_media"
1194 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
b6d33983
R
1195 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1196 (match_operand:SI 2 "extend_reg_operand" "r")))]
fa5322fa 1197 "TARGET_SHMEDIA"
b6d33983
R
1198 "sub.l %N1, %2, %0"
1199 [(set_attr "type" "arith_media")])
fa5322fa 1200
caca3c8a
JW
1201;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1202;; will sometimes save one instruction. Otherwise we might get
1203;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1204;; are the same.
1205
1206(define_expand "subsi3"
1207 [(set (match_operand:SI 0 "arith_reg_operand" "")
1208 (minus:SI (match_operand:SI 1 "arith_operand" "")
1209 (match_operand:SI 2 "arith_reg_operand" "")))]
1210 ""
1211 "
1212{
fa5322fa 1213 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
caca3c8a
JW
1214 {
1215 emit_insn (gen_negsi2 (operands[0], operands[2]));
1216 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1217 DONE;
1218 }
fa5322fa
AO
1219 if (TARGET_SHMEDIA)
1220 {
b6d33983 1221 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
fa5322fa 1222 FAIL;
b6d33983
R
1223 if (operands[1] != const0_rtx)
1224 operands[1] = force_reg (SImode, operands[1]);
fa5322fa 1225 }
caca3c8a 1226}")
bc45ade3
SC
1227\f
1228;; -------------------------------------------------------------------------
0d7e008e 1229;; Division instructions
bc45ade3
SC
1230;; -------------------------------------------------------------------------
1231
ffae286a 1232;; We take advantage of the library routines which don't clobber as many
0d7e008e
SC
1233;; registers as a normal function call would.
1234
1245df60 1235;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
956d6950 1236;; also has an effect on the register that holds the address of the sfunc.
e69d1422 1237;; To make this work, we have an extra dummy insn that shows the use
1245df60
R
1238;; of this register for reorg.
1239
1240(define_insn "use_sfunc_addr"
4773afa4 1241 [(set (reg:SI PR_REG)
e69d1422 1242 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
fa5322fa 1243 "TARGET_SH1"
1245df60
R
1244 ""
1245 [(set_attr "length" "0")])
1246
ddd5a7c1 1247;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
e96a50cc
JW
1248;; hard register 0. If we used hard register 0, then the next instruction
1249;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1250;; gets allocated to a stack slot that needs its address reloaded, then
1251;; there is nothing to prevent reload from using r0 to reload the address.
1252;; This reload would clobber the value in r0 we are trying to store.
1253;; If we let reload allocate r0, then this problem can never happen.
0d7e008e 1254
a512fa97 1255(define_insn "udivsi3_i1"
1245df60 1256 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1257 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258 (clobber (reg:SI T_REG))
1259 (clobber (reg:SI PR_REG))
1260 (clobber (reg:SI R4_REG))
1245df60 1261 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1262 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1263 "jsr @%1%#"
1264 [(set_attr "type" "sfunc")
1265 (set_attr "needs_delay_slot" "yes")])
1266
9e96203d
R
1267; Since shmedia-nofpu code could be linked against shcompact code, and
1268; the udivsi3 libcall has the same name, we must consider all registers
1269; clobbered that are in the union of the registers clobbered by the
1270; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1271; implementation actually used shcompact code, we'd need to clobber
9e96203d 1272; also r23 and fr23.
fa5322fa
AO
1273(define_insn "udivsi3_i1_media"
1274 [(set (match_operand:SI 0 "register_operand" "=z")
1275 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1276 (clobber (reg:SI T_MEDIA_REG))
1277 (clobber (reg:SI PR_MEDIA_REG))
9e96203d
R
1278 (clobber (reg:SI R20_REG))
1279 (clobber (reg:SI R21_REG))
1280 (clobber (reg:SI R22_REG))
fa5322fa
AO
1281 (clobber (reg:DI TR0_REG))
1282 (clobber (reg:DI TR1_REG))
1283 (clobber (reg:DI TR2_REG))
1284 (use (match_operand:DI 1 "target_operand" "b"))]
1285 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1286 "blink %1, r18"
1287 [(set_attr "type" "sfunc")
1288 (set_attr "needs_delay_slot" "yes")])
1289
1290(define_expand "udivsi3_i4_media"
b6d33983
R
1291 [(set (match_dup 3)
1292 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1293 (set (match_dup 4)
1294 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
fa5322fa 1295 (set (match_dup 5) (float:DF (match_dup 3)))
b6d33983
R
1296 (set (match_dup 6) (float:DF (match_dup 4)))
1297 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1298 (set (match_dup 8) (fix:DI (match_dup 7)))
0ac78517
R
1299 (set (match_operand:SI 0 "register_operand" "")
1300 (truncate:SI (match_dup 8)))]
fa5322fa
AO
1301 "TARGET_SHMEDIA_FPU"
1302 "
1303{
fa5322fa 1304 operands[3] = gen_reg_rtx (DImode);
b6d33983 1305 operands[4] = gen_reg_rtx (DImode);
fa5322fa
AO
1306 operands[5] = gen_reg_rtx (DFmode);
1307 operands[6] = gen_reg_rtx (DFmode);
b6d33983
R
1308 operands[7] = gen_reg_rtx (DFmode);
1309 operands[8] = gen_reg_rtx (DImode);
fa5322fa
AO
1310}")
1311
225e4f43
R
1312(define_insn "udivsi3_i4"
1313 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1314 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1315 (clobber (reg:SI T_REG))
4773afa4
AO
1316 (clobber (reg:SI PR_REG))
1317 (clobber (reg:DF DR0_REG))
1318 (clobber (reg:DF DR2_REG))
1319 (clobber (reg:DF DR4_REG))
1320 (clobber (reg:SI R0_REG))
1321 (clobber (reg:SI R1_REG))
1322 (clobber (reg:SI R4_REG))
1323 (clobber (reg:SI R5_REG))
1324 (use (reg:PSI FPSCR_REG))
225e4f43
R
1325 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1326 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1327 "jsr @%1%#"
1328 [(set_attr "type" "sfunc")
d64264ff 1329 (set_attr "fp_mode" "double")
225e4f43
R
1330 (set_attr "needs_delay_slot" "yes")])
1331
1332(define_insn "udivsi3_i4_single"
1333 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4 1334 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
5f6fa212 1335 (clobber (reg:SI T_REG))
4773afa4
AO
1336 (clobber (reg:SI PR_REG))
1337 (clobber (reg:DF DR0_REG))
1338 (clobber (reg:DF DR2_REG))
1339 (clobber (reg:DF DR4_REG))
1340 (clobber (reg:SI R0_REG))
1341 (clobber (reg:SI R1_REG))
1342 (clobber (reg:SI R4_REG))
1343 (clobber (reg:SI R5_REG))
225e4f43 1344 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1345 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1346 "jsr @%1%#"
0d7e008e 1347 [(set_attr "type" "sfunc")
0d7e008e
SC
1348 (set_attr "needs_delay_slot" "yes")])
1349
1350(define_expand "udivsi3"
a512fa97 1351 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
4773afa4
AO
1352 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1353 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1354 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1355 (udiv:SI (reg:SI R4_REG)
1356 (reg:SI R5_REG)))
1357 (clobber (reg:SI T_REG))
1358 (clobber (reg:SI PR_REG))
1359 (clobber (reg:SI R4_REG))
ffae286a 1360 (use (match_dup 3))])]
0d7e008e 1361 ""
225e4f43
R
1362 "
1363{
4392ebd3 1364 rtx first, last;
a512fa97 1365
fa5322fa 1366 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1367 /* Emit the move of the address to a pseudo outside of the libcall. */
3a8699c7 1368 if (TARGET_HARD_SH4 && TARGET_SH2E)
225e4f43 1369 {
90534361 1370 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
225e4f43 1371 if (TARGET_FPU_SINGLE)
a512fa97 1372 last = gen_udivsi3_i4_single (operands[0], operands[3]);
225e4f43 1373 else
a512fa97 1374 last = gen_udivsi3_i4 (operands[0], operands[3]);
225e4f43 1375 }
fa5322fa 1376 else if (TARGET_SHMEDIA_FPU)
b6d33983
R
1377 {
1378 operands[1] = force_reg (SImode, operands[1]);
1379 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1380 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1381 DONE;
b6d33983 1382 }
fa5322fa
AO
1383 else if (TARGET_SH5)
1384 {
1385 emit_move_insn (operands[3],
90534361
R
1386 function_symbol (TARGET_FPU_ANY
1387 ? \"__udivsi3_i4\"
1388 : \"__udivsi3\"));
fa5322fa
AO
1389
1390 if (TARGET_SHMEDIA)
1391 last = gen_udivsi3_i1_media (operands[0],
1392 Pmode == DImode
1393 ? operands[3]
1394 : gen_rtx_SUBREG (DImode, operands[3],
1395 0));
1396 else if (TARGET_FPU_ANY)
1397 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1398 else
1399 last = gen_udivsi3_i1 (operands[0], operands[3]);
1400 }
a512fa97
R
1401 else
1402 {
90534361 1403 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
a512fa97
R
1404 last = gen_udivsi3_i1 (operands[0], operands[3]);
1405 }
4392ebd3
RS
1406 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1407 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1408 last = emit_insn (last);
1409 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1410 invariant code motion can move it. */
1411 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1412 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1413 DONE;
225e4f43 1414}")
0d7e008e 1415
a512fa97 1416(define_insn "divsi3_i1"
1245df60 1417 [(set (match_operand:SI 0 "register_operand" "=z")
4773afa4
AO
1418 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419 (clobber (reg:SI T_REG))
1420 (clobber (reg:SI PR_REG))
1421 (clobber (reg:SI R1_REG))
1422 (clobber (reg:SI R2_REG))
1423 (clobber (reg:SI R3_REG))
1245df60 1424 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1425 "TARGET_SH1 && ! TARGET_SH4"
225e4f43
R
1426 "jsr @%1%#"
1427 [(set_attr "type" "sfunc")
1428 (set_attr "needs_delay_slot" "yes")])
1429
9e96203d 1430; Since shmedia-nofpu code could be linked against shcompact code, and
b6d33983 1431; the sdivsi3 libcall has the same name, we must consider all registers
9e96203d
R
1432; clobbered that are in the union of the registers clobbered by the
1433; shmedia and the shcompact implementation. Note, if the shcompact
825db093 1434; implementation actually used shcompact code, we'd need to clobber
9e96203d 1435; also r22, r23 and fr23.
fa5322fa
AO
1436(define_insn "divsi3_i1_media"
1437 [(set (match_operand:SI 0 "register_operand" "=z")
1438 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1439 (clobber (reg:SI T_MEDIA_REG))
1440 (clobber (reg:SI PR_MEDIA_REG))
1441 (clobber (reg:SI R1_REG))
1442 (clobber (reg:SI R2_REG))
1443 (clobber (reg:SI R3_REG))
9e96203d
R
1444 (clobber (reg:SI R20_REG))
1445 (clobber (reg:SI R21_REG))
fa5322fa
AO
1446 (clobber (reg:DI TR0_REG))
1447 (clobber (reg:DI TR1_REG))
1448 (clobber (reg:DI TR2_REG))
1449 (use (match_operand:DI 1 "target_operand" "b"))]
1450 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
2ad65b0e
SC
1451 "blink %1, r18"
1452 [(set_attr "type" "sfunc")])
fa5322fa
AO
1453
1454(define_expand "divsi3_i4_media"
51214775
R
1455 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1456 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1457 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
fa5322fa 1458 (set (match_operand:SI 0 "register_operand" "=r")
51214775 1459 (fix:SI (match_dup 5)))]
fa5322fa
AO
1460 "TARGET_SHMEDIA_FPU"
1461 "
1462{
51214775 1463 operands[3] = gen_reg_rtx (DFmode);
fa5322fa
AO
1464 operands[4] = gen_reg_rtx (DFmode);
1465 operands[5] = gen_reg_rtx (DFmode);
fa5322fa
AO
1466}")
1467
225e4f43
R
1468(define_insn "divsi3_i4"
1469 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1470 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471 (clobber (reg:SI PR_REG))
1472 (clobber (reg:DF DR0_REG))
1473 (clobber (reg:DF DR2_REG))
1474 (use (reg:PSI FPSCR_REG))
225e4f43
R
1475 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1477 "jsr @%1%#"
1478 [(set_attr "type" "sfunc")
d64264ff 1479 (set_attr "fp_mode" "double")
225e4f43
R
1480 (set_attr "needs_delay_slot" "yes")])
1481
1482(define_insn "divsi3_i4_single"
1483 [(set (match_operand:SI 0 "register_operand" "=y")
4773afa4
AO
1484 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1485 (clobber (reg:SI PR_REG))
1486 (clobber (reg:DF DR0_REG))
1487 (clobber (reg:DF DR2_REG))
1488 (clobber (reg:SI R2_REG))
225e4f43 1489 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 1490 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1245df60 1491 "jsr @%1%#"
0d7e008e 1492 [(set_attr "type" "sfunc")
0d7e008e
SC
1493 (set_attr "needs_delay_slot" "yes")])
1494
1495(define_expand "divsi3"
a512fa97 1496 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
4773afa4
AO
1497 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1498 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
ffae286a 1499 (parallel [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1500 (div:SI (reg:SI R4_REG)
1501 (reg:SI R5_REG)))
1502 (clobber (reg:SI T_REG))
1503 (clobber (reg:SI PR_REG))
1504 (clobber (reg:SI R1_REG))
1505 (clobber (reg:SI R2_REG))
1506 (clobber (reg:SI R3_REG))
ffae286a 1507 (use (match_dup 3))])]
0d7e008e 1508 ""
225e4f43
R
1509 "
1510{
4392ebd3 1511 rtx first, last;
a512fa97 1512
fa5322fa 1513 operands[3] = gen_reg_rtx (Pmode);
a512fa97 1514 /* Emit the move of the address to a pseudo outside of the libcall. */
3a8699c7 1515 if (TARGET_HARD_SH4 && TARGET_SH2E)
225e4f43 1516 {
90534361 1517 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
225e4f43 1518 if (TARGET_FPU_SINGLE)
a512fa97 1519 last = gen_divsi3_i4_single (operands[0], operands[3]);
225e4f43 1520 else
a512fa97 1521 last = gen_divsi3_i4 (operands[0], operands[3]);
225e4f43 1522 }
fa5322fa 1523 else if (TARGET_SHMEDIA_FPU)
51214775
R
1524 {
1525 operands[1] = force_reg (SImode, operands[1]);
1526 operands[2] = force_reg (SImode, operands[2]);
4392ebd3
RS
1527 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1528 DONE;
51214775 1529 }
fa5322fa
AO
1530 else if (TARGET_SH5)
1531 {
1532 emit_move_insn (operands[3],
90534361
R
1533 function_symbol (TARGET_FPU_ANY
1534 ? \"__sdivsi3_i4\"
1535 : \"__sdivsi3\"));
fa5322fa
AO
1536
1537 if (TARGET_SHMEDIA)
52702ae1 1538 last = gen_divsi3_i1_media (operands[0],
fa5322fa
AO
1539 Pmode == DImode
1540 ? operands[3]
1541 : gen_rtx_SUBREG (DImode, operands[3],
1542 0));
1543 else if (TARGET_FPU_ANY)
1544 last = gen_divsi3_i4_single (operands[0], operands[3]);
1545 else
1546 last = gen_divsi3_i1 (operands[0], operands[3]);
1547 }
a512fa97
R
1548 else
1549 {
90534361 1550 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
a512fa97
R
1551 last = gen_divsi3_i1 (operands[0], operands[3]);
1552 }
4392ebd3
RS
1553 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1554 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
a512fa97
R
1555 last = emit_insn (last);
1556 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1557 invariant code motion can move it. */
1558 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1559 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1560 DONE;
225e4f43 1561}")
0d7e008e
SC
1562\f
1563;; -------------------------------------------------------------------------
1564;; Multiplication instructions
1565;; -------------------------------------------------------------------------
1566
a512fa97 1567(define_insn "umulhisi3_i"
4773afa4
AO
1568 [(set (reg:SI MACL_REG)
1569 (mult:SI (zero_extend:SI
1570 (match_operand:HI 0 "arith_reg_operand" "r"))
1571 (zero_extend:SI
1572 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1573 "TARGET_SH1"
e9a9e960 1574 "mulu.w %1,%0"
b9654711 1575 [(set_attr "type" "smpy")])
bc45ade3 1576
a512fa97 1577(define_insn "mulhisi3_i"
4773afa4 1578 [(set (reg:SI MACL_REG)
bc45ade3 1579 (mult:SI (sign_extend:SI
af55dae3 1580 (match_operand:HI 0 "arith_reg_operand" "r"))
bc45ade3 1581 (sign_extend:SI
af55dae3 1582 (match_operand:HI 1 "arith_reg_operand" "r"))))]
fa5322fa 1583 "TARGET_SH1"
e9a9e960 1584 "muls.w %1,%0"
b9654711 1585 [(set_attr "type" "smpy")])
bc45ade3
SC
1586
1587(define_expand "mulhisi3"
4773afa4 1588 [(set (reg:SI MACL_REG)
bc45ade3 1589 (mult:SI (sign_extend:SI
51aea58d 1590 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1591 (sign_extend:SI
51aea58d
JW
1592 (match_operand:HI 2 "arith_reg_operand" ""))))
1593 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1594 (reg:SI MACL_REG))]
fa5322fa 1595 "TARGET_SH1"
a512fa97
R
1596 "
1597{
1598 rtx first, last;
1599
1600 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
4773afa4 1601 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1602 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1603 invariant code motion can move it. */
1604 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1605 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1606 /* expand_binop can't find a suitable code in umul_widen_optab to
1607 make a REG_EQUAL note from, so make one here.
1608 See also smulsi3_highpart.
1609 ??? Alternatively, we could put this at the calling site of expand_binop,
1610 i.e. expand_expr. */
1611 REG_NOTES (last)
1612 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1613 REG_NOTES (last));
a512fa97
R
1614 DONE;
1615}")
bc45ade3
SC
1616
1617(define_expand "umulhisi3"
4773afa4 1618 [(set (reg:SI MACL_REG)
bc45ade3 1619 (mult:SI (zero_extend:SI
51aea58d 1620 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 1621 (zero_extend:SI
51aea58d
JW
1622 (match_operand:HI 2 "arith_reg_operand" ""))))
1623 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1624 (reg:SI MACL_REG))]
fa5322fa 1625 "TARGET_SH1"
a512fa97
R
1626 "
1627{
1628 rtx first, last;
1629
1630 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
4773afa4 1631 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
a512fa97
R
1632 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1633 invariant code motion can move it. */
1634 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1635 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
c49439f1
R
1636 /* expand_binop can't find a suitable code in umul_widen_optab to
1637 make a REG_EQUAL note from, so make one here.
1638 See also smulsi3_highpart.
1639 ??? Alternatively, we could put this at the calling site of expand_binop,
1640 i.e. expand_expr. */
1641 REG_NOTES (last)
1642 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1643 REG_NOTES (last));
a512fa97
R
1644 DONE;
1645}")
bc45ade3 1646
0d7e008e
SC
1647;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1648;; a call to a routine which clobbers known registers.
1649
1650(define_insn ""
e96a50cc 1651 [(set (match_operand:SI 1 "register_operand" "=z")
4773afa4
AO
1652 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1653 (clobber (reg:SI MACL_REG))
1654 (clobber (reg:SI T_REG))
1655 (clobber (reg:SI PR_REG))
1656 (clobber (reg:SI R3_REG))
1657 (clobber (reg:SI R2_REG))
1658 (clobber (reg:SI R1_REG))
07a45e5c 1659 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 1660 "TARGET_SH1"
0d7e008e
SC
1661 "jsr @%0%#"
1662 [(set_attr "type" "sfunc")
0d7e008e
SC
1663 (set_attr "needs_delay_slot" "yes")])
1664
1665(define_expand "mulsi3_call"
4773afa4
AO
1666 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1667 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
51aea58d 1668 (parallel[(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
1669 (mult:SI (reg:SI R4_REG)
1670 (reg:SI R5_REG)))
1671 (clobber (reg:SI MACL_REG))
1672 (clobber (reg:SI T_REG))
1673 (clobber (reg:SI PR_REG))
1674 (clobber (reg:SI R3_REG))
1675 (clobber (reg:SI R2_REG))
1676 (clobber (reg:SI R1_REG))
225e4f43 1677 (use (match_operand:SI 3 "register_operand" ""))])]
fa5322fa 1678 "TARGET_SH1"
225e4f43 1679 "")
07a45e5c 1680
0d7e008e 1681(define_insn "mul_l"
4773afa4 1682 [(set (reg:SI MACL_REG)
0d7e008e
SC
1683 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1684 (match_operand:SI 1 "arith_reg_operand" "r")))]
1685 "TARGET_SH2"
1686 "mul.l %1,%0"
51bd623f 1687 [(set_attr "type" "dmpy")])
0d7e008e
SC
1688
1689(define_expand "mulsi3"
4773afa4 1690 [(set (reg:SI MACL_REG)
51aea58d
JW
1691 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1692 (match_operand:SI 2 "arith_reg_operand" "")))
1693 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1694 (reg:SI MACL_REG))]
fa5322fa 1695 "TARGET_SH1"
51bd623f
JW
1696 "
1697{
225e4f43
R
1698 rtx first, last;
1699
51bd623f
JW
1700 if (!TARGET_SH2)
1701 {
225e4f43
R
1702 /* The address must be set outside the libcall,
1703 since it goes into a pseudo. */
90534361 1704 rtx sym = function_symbol (\"__mulsi3\");
a6f463a0
AO
1705 rtx addr = force_reg (SImode, sym);
1706 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1707 operands[2], addr);
fa60f36d
R
1708 first = insns;
1709 last = emit_insn (insns);
51bd623f 1710 }
225e4f43
R
1711 else
1712 {
1713 rtx macl = gen_rtx_REG (SImode, MACL_REG);
aa4778b6 1714
225e4f43 1715 first = emit_insn (gen_mul_l (operands[1], operands[2]));
aa4778b6
R
1716 /* consec_sets_giv can only recognize the first insn that sets a
1717 giv as the giv insn. So we must tag this also with a REG_EQUAL
1718 note. */
78d114ef 1719 last = emit_insn (gen_movsi_i ((operands[0]), macl));
225e4f43
R
1720 }
1721 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1722 invariant code motion can move it. */
1723 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1724 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1725 DONE;
51bd623f 1726}")
00f8ff66 1727
af55dae3 1728(define_insn "mulsidi3_i"
4773afa4 1729 [(set (reg:SI MACH_REG)
a512fa97 1730 (truncate:SI
4773afa4
AO
1731 (lshiftrt:DI
1732 (mult:DI
1733 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1734 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1735 (const_int 32))))
1736 (set (reg:SI MACL_REG)
a512fa97
R
1737 (mult:SI (match_dup 0)
1738 (match_dup 1)))]
06e1bace 1739 "TARGET_SH2"
af55dae3 1740 "dmuls.l %1,%0"
0d7e008e
SC
1741 [(set_attr "type" "dmpy")])
1742
fa5322fa
AO
1743(define_expand "mulsidi3"
1744 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1745 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1746 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1747 "TARGET_SH2 || TARGET_SHMEDIA"
1748 "
1749{
1750 if (TARGET_SH2)
1751 {
1752 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1753 operands[2]));
1754 DONE;
1755 }
1756}")
1757
1758(define_insn "mulsidi3_media"
1759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1760 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1761 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1762 "TARGET_SHMEDIA"
b6d33983
R
1763 "muls.l %1, %2, %0"
1764 [(set_attr "type" "dmpy_media")])
52702ae1 1765
fa5322fa 1766(define_insn "mulsidi3_compact"
a512fa97 1767 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1768 (mult:DI
1769 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1770 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1771 (clobber (reg:SI MACH_REG))
1772 (clobber (reg:SI MACL_REG))]
a512fa97
R
1773 "TARGET_SH2"
1774 "#")
1775
1776(define_split
1777 [(set (match_operand:DI 0 "arith_reg_operand" "")
4773afa4
AO
1778 (mult:DI
1779 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1780 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1781 (clobber (reg:SI MACH_REG))
1782 (clobber (reg:SI MACL_REG))]
06e1bace 1783 "TARGET_SH2"
a512fa97 1784 [(const_int 0)]
af55dae3
JW
1785 "
1786{
a512fa97
R
1787 rtx low_dst = gen_lowpart (SImode, operands[0]);
1788 rtx high_dst = gen_highpart (SImode, operands[0]);
0d7e008e 1789
a512fa97 1790 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
af55dae3 1791
4773afa4
AO
1792 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1793 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1794 /* We need something to tag the possible REG_EQUAL notes on to. */
1795 emit_move_insn (operands[0], operands[0]);
1796 DONE;
af55dae3
JW
1797}")
1798
1799(define_insn "umulsidi3_i"
4773afa4 1800 [(set (reg:SI MACH_REG)
a512fa97 1801 (truncate:SI
4773afa4
AO
1802 (lshiftrt:DI
1803 (mult:DI
1804 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1805 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1806 (const_int 32))))
1807 (set (reg:SI MACL_REG)
a512fa97
R
1808 (mult:SI (match_dup 0)
1809 (match_dup 1)))]
06e1bace 1810 "TARGET_SH2"
af55dae3 1811 "dmulu.l %1,%0"
0d7e008e
SC
1812 [(set_attr "type" "dmpy")])
1813
fa5322fa
AO
1814(define_expand "umulsidi3"
1815 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1816 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1817 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1818 "TARGET_SH2 || TARGET_SHMEDIA"
1819 "
1820{
1821 if (TARGET_SH2)
1822 {
1823 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1824 operands[2]));
1825 DONE;
1826 }
1827}")
1828
1829(define_insn "umulsidi3_media"
1830 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b6d33983
R
1831 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1832 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
fa5322fa 1833 "TARGET_SHMEDIA"
b6d33983
R
1834 "mulu.l %1, %2, %0"
1835 [(set_attr "type" "dmpy_media")])
52702ae1 1836
fa5322fa 1837(define_insn "umulsidi3_compact"
a512fa97 1838 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4773afa4
AO
1839 (mult:DI
1840 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1841 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
5d00b10a
AO
1842 (clobber (reg:SI MACH_REG))
1843 (clobber (reg:SI MACL_REG))]
a512fa97
R
1844 "TARGET_SH2"
1845 "#")
1846
1847(define_split
1848 [(set (match_operand:DI 0 "arith_reg_operand" "")
51aea58d
JW
1849 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1850 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
5d00b10a
AO
1851 (clobber (reg:SI MACH_REG))
1852 (clobber (reg:SI MACL_REG))]
06e1bace 1853 "TARGET_SH2"
a512fa97 1854 [(const_int 0)]
af55dae3
JW
1855 "
1856{
a512fa97
R
1857 rtx low_dst = gen_lowpart (SImode, operands[0]);
1858 rtx high_dst = gen_highpart (SImode, operands[0]);
af55dae3 1859
a512fa97 1860 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
af55dae3 1861
4773afa4
AO
1862 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1863 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1864 /* We need something to tag the possible REG_EQUAL notes on to. */
1865 emit_move_insn (operands[0], operands[0]);
1866 DONE;
af55dae3 1867}")
06e1bace 1868
a512fa97 1869(define_insn "smulsi3_highpart_i"
4773afa4 1870 [(set (reg:SI MACH_REG)
06e1bace 1871 (truncate:SI
4773afa4
AO
1872 (lshiftrt:DI
1873 (mult:DI
1874 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1875 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1876 (const_int 32))))
1877 (clobber (reg:SI MACL_REG))]
06e1bace 1878 "TARGET_SH2"
af55dae3 1879 "dmuls.l %1,%0"
06e1bace
RK
1880 [(set_attr "type" "dmpy")])
1881
1882(define_expand "smulsi3_highpart"
4773afa4
AO
1883 [(parallel
1884 [(set (reg:SI MACH_REG)
1885 (truncate:SI
1886 (lshiftrt:DI
1887 (mult:DI
1888 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1889 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1890 (const_int 32))))
1891 (clobber (reg:SI MACL_REG))])
06e1bace 1892 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1893 (reg:SI MACH_REG))]
06e1bace 1894 "TARGET_SH2"
a512fa97
R
1895 "
1896{
1897 rtx first, last;
06e1bace 1898
a512fa97 1899 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1900 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1901 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1902 invariant code motion can move it. */
1903 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1904 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
22d05f60
R
1905 /* expand_binop can't find a suitable code in mul_highpart_optab to
1906 make a REG_EQUAL note from, so make one here.
c49439f1 1907 See also {,u}mulhisi.
22d05f60
R
1908 ??? Alternatively, we could put this at the calling site of expand_binop,
1909 i.e. expand_mult_highpart. */
1910 REG_NOTES (last)
1911 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1912 REG_NOTES (last));
a512fa97
R
1913 DONE;
1914}")
1915
1916(define_insn "umulsi3_highpart_i"
4773afa4 1917 [(set (reg:SI MACH_REG)
06e1bace 1918 (truncate:SI
4773afa4
AO
1919 (lshiftrt:DI
1920 (mult:DI
1921 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1922 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1923 (const_int 32))))
1924 (clobber (reg:SI MACL_REG))]
06e1bace 1925 "TARGET_SH2"
af55dae3 1926 "dmulu.l %1,%0"
06e1bace
RK
1927 [(set_attr "type" "dmpy")])
1928
1929(define_expand "umulsi3_highpart"
4773afa4
AO
1930 [(parallel
1931 [(set (reg:SI MACH_REG)
1932 (truncate:SI
1933 (lshiftrt:DI
1934 (mult:DI
1935 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1936 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1937 (const_int 32))))
1938 (clobber (reg:SI MACL_REG))])
06e1bace 1939 (set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 1940 (reg:SI MACH_REG))]
06e1bace 1941 "TARGET_SH2"
a512fa97
R
1942 "
1943{
1944 rtx first, last;
1945
1946 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
4773afa4 1947 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
a512fa97
R
1948 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1949 invariant code motion can move it. */
1950 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1951 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1952 DONE;
1953}")
bc45ade3
SC
1954\f
1955;; -------------------------------------------------------------------------
1956;; Logical operations
1957;; -------------------------------------------------------------------------
1958
b6d33983 1959(define_insn "*andsi3_compact"
aa684c94
SC
1960 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1961 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 1962 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 1963 "TARGET_SH1"
bc45ade3 1964 "and %2,%0"
c49439f1 1965 [(set_attr "type" "arith")])
bc45ade3 1966
43aa4e05 1967;; If the constant is 255, then emit an extu.b instruction instead of an
51bd623f
JW
1968;; and, since that will give better code.
1969
0d7e008e
SC
1970(define_expand "andsi3"
1971 [(set (match_operand:SI 0 "arith_reg_operand" "")
1972 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1973 (match_operand:SI 2 "logical_operand" "")))]
fa5322fa 1974 "TARGET_SH1"
51bd623f
JW
1975 "
1976{
1977 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1978 {
1979 emit_insn (gen_zero_extendqisi2 (operands[0],
1980 gen_lowpart (QImode, operands[1])));
1981 DONE;
1982 }
1983}")
0d7e008e 1984
c1b92d09
R
1985(define_insn_and_split "anddi3"
1986 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1987 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
735cb76e 1988 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
fa5322fa
AO
1989 "TARGET_SHMEDIA"
1990 "@
1991 and %1, %2, %0
c1b92d09
R
1992 andi %1, %2, %0
1993 #"
1994 "reload_completed
1995 && ! logical_operand (operands[2], DImode)"
1996 [(const_int 0)]
1997 "
1998{
1999 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2000 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2001 else
2002 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2003 DONE;
2ad65b0e
SC
2004}"
2005 [(set_attr "type" "arith_media")])
fa5322fa 2006
b6d33983 2007(define_insn "andcdi3"
fa5322fa
AO
2008 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2009 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2010 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2011 "TARGET_SHMEDIA"
2ad65b0e
SC
2012 "andc %1,%2,%0"
2013 [(set_attr "type" "arith_media")])
fa5322fa 2014
bc45ade3 2015(define_insn "iorsi3"
aa684c94
SC
2016 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2017 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 2018 (match_operand:SI 2 "logical_operand" "r,K08")))]
fa5322fa 2019 "TARGET_SH1"
1245df60 2020 "or %2,%0"
c49439f1 2021 [(set_attr "type" "arith")])
bc45ade3 2022
fa5322fa
AO
2023(define_insn "iordi3"
2024 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2025 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 2026 (match_operand:DI 2 "logical_operand" "r,I10")))]
fa5322fa
AO
2027 "TARGET_SHMEDIA"
2028 "@
2029 or %1, %2, %0
2ad65b0e
SC
2030 ori %1, %2, %0"
2031 [(set_attr "type" "arith_media")])
fa5322fa 2032
bc45ade3 2033(define_insn "xorsi3"
0d7e008e 2034 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
aa684c94 2035 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
735cb76e 2036 (match_operand:SI 2 "logical_operand" "K08,r")))]
fa5322fa 2037 "TARGET_SH1"
bc45ade3 2038 "xor %2,%0"
c49439f1 2039 [(set_attr "type" "arith")])
fa5322fa
AO
2040
2041(define_insn "xordi3"
2042 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2043 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
735cb76e 2044 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
fa5322fa
AO
2045 "TARGET_SHMEDIA"
2046 "@
2047 xor %1, %2, %0
2ad65b0e
SC
2048 xori %1, %2, %0"
2049 [(set_attr "type" "arith_media")])
ff881d52
R
2050
2051;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2052;; converts 2 * sign extend -> logical op into logical op -> sign extend
2053(define_split
2054 [(set (match_operand:DI 0 "arith_reg_operand" "")
2055 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2056 [(match_operand 1 "any_register_operand" "")
2057 (match_operand 2 "any_register_operand" "")])))]
2058 "TARGET_SHMEDIA"
2059 [(set (match_dup 5) (match_dup 4))
2060 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2061"
2062{
2063 enum machine_mode inmode = GET_MODE (operands[1]);
fada1961 2064 int offset = 0;
ff881d52
R
2065
2066 if (GET_CODE (operands[0]) == SUBREG)
2067 {
2068 offset = SUBREG_BYTE (operands[0]);
2069 operands[0] = SUBREG_REG (operands[0]);
2070 }
2071 if (GET_CODE (operands[0]) != REG)
2072 abort ();
2073 if (! TARGET_LITTLE_ENDIAN)
2074 offset += 8 - GET_MODE_SIZE (inmode);
2075 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2076}")
bc45ade3
SC
2077\f
2078;; -------------------------------------------------------------------------
2079;; Shifts and rotates
2080;; -------------------------------------------------------------------------
2081
b6d33983
R
2082(define_expand "rotldi3"
2083 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2084 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2085 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2086 "TARGET_SHMEDIA"
2087 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2088
2089(define_insn "rotldi3_mextr"
2090 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2091 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2092 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2093 "TARGET_SHMEDIA"
2094 "*
2095{
2096 static char templ[16];
2097
2098 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2099 8 - (int) (INTVAL (operands[2]) >> 3));
2100 return templ;
2101}"
2102 [(set_attr "type" "arith_media")])
2103
2104(define_expand "rotrdi3"
2105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2106 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2107 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2108 "TARGET_SHMEDIA"
2109 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2110
2111(define_insn "rotrdi3_mextr"
2112 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2113 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2114 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2115 "TARGET_SHMEDIA"
2116 "*
2117{
2118 static char templ[16];
2119
2120 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2121 return templ;
2122}"
2123 [(set_attr "type" "arith_media")])
2124
51bd623f 2125(define_insn "rotlsi3_1"
b9654711
SC
2126 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2127 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2128 (const_int 1)))
4773afa4 2129 (set (reg:SI T_REG)
51aea58d 2130 (lshiftrt:SI (match_dup 1) (const_int 31)))]
fa5322fa 2131 "TARGET_SH1"
1245df60 2132 "rotl %0"
c49439f1 2133 [(set_attr "type" "arith")])
b9654711 2134
51bd623f 2135(define_insn "rotlsi3_31"
b9654711 2136 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f
JW
2137 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2138 (const_int 31)))
4773afa4 2139 (clobber (reg:SI T_REG))]
fa5322fa 2140 "TARGET_SH1"
1245df60 2141 "rotr %0"
c49439f1 2142 [(set_attr "type" "arith")])
b9654711 2143
1245df60 2144(define_insn "rotlsi3_16"
51bd623f
JW
2145 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2146 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2147 (const_int 16)))]
fa5322fa 2148 "TARGET_SH1"
1245df60 2149 "swap.w %1,%0"
c49439f1 2150 [(set_attr "type" "arith")])
b9654711 2151
51bd623f
JW
2152(define_expand "rotlsi3"
2153 [(set (match_operand:SI 0 "arith_reg_operand" "")
2154 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2155 (match_operand:SI 2 "immediate_operand" "")))]
fa5322fa 2156 "TARGET_SH1"
51bd623f
JW
2157 "
2158{
0139adca 2159 static const char rot_tab[] = {
1245df60
R
2160 000, 000, 000, 000, 000, 000, 010, 001,
2161 001, 001, 011, 013, 003, 003, 003, 003,
2162 003, 003, 003, 003, 003, 013, 012, 002,
2163 002, 002, 010, 000, 000, 000, 000, 000,
2164 };
2165
2166 int count, choice;
2167
51bd623f
JW
2168 if (GET_CODE (operands[2]) != CONST_INT)
2169 FAIL;
1245df60
R
2170 count = INTVAL (operands[2]);
2171 choice = rot_tab[count];
2172 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2173 FAIL;
2174 choice &= 7;
2175 switch (choice)
51bd623f 2176 {
1245df60
R
2177 case 0:
2178 emit_move_insn (operands[0], operands[1]);
2179 count -= (count & 16) * 2;
2180 break;
2181 case 3:
2182 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2183 count -= 16;
2184 break;
2185 case 1:
2186 case 2:
2187 {
2188 rtx parts[2];
2189 parts[0] = gen_reg_rtx (SImode);
2190 parts[1] = gen_reg_rtx (SImode);
2191 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2192 parts[choice-1] = operands[1];
2193 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2194 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2195 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2196 count = (count & ~16) - 8;
2197 }
51bd623f 2198 }
1245df60
R
2199
2200 for (; count > 0; count--)
2201 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2202 for (; count < 0; count++)
2203 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2204
2205 DONE;
51bd623f
JW
2206}")
2207
1245df60 2208(define_insn "*rotlhi3_8"
51bd623f
JW
2209 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2210 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2211 (const_int 8)))]
fa5322fa 2212 "TARGET_SH1"
1245df60 2213 "swap.b %1,%0"
c49439f1 2214 [(set_attr "type" "arith")])
51bd623f
JW
2215
2216(define_expand "rotlhi3"
2217 [(set (match_operand:HI 0 "arith_reg_operand" "")
2218 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2219 (match_operand:HI 2 "immediate_operand" "")))]
fa5322fa 2220 "TARGET_SH1"
51bd623f
JW
2221 "
2222{
2223 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2224 FAIL;
2225}")
0d7e008e
SC
2226
2227;;
2228;; shift left
2229
7e2fda6e
BS
2230;; This pattern is used by init_expmed for computing the costs of shift
2231;; insns.
2232
2233(define_insn_and_split "ashlsi3_std"
2234 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2235 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
735cb76e 2236 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
7e2fda6e
BS
2237 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2238 "TARGET_SH3
fa5322fa 2239 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
735cb76e 2240 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
0d7e008e 2241 "@
7e2fda6e
BS
2242 shld %2,%0
2243 add %0,%0
2244 shll%O2 %0
2245 #"
2246 "TARGET_SH3
615cd49b 2247 && reload_completed
7e2fda6e 2248 && GET_CODE (operands[2]) == CONST_INT
735cb76e 2249 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
7e2fda6e
BS
2250 [(set (match_dup 3) (match_dup 2))
2251 (parallel
2252 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2253 (clobber (match_dup 4))])]
2254 "operands[4] = gen_rtx_SCRATCH (SImode);"
2255 [(set_attr "length" "*,*,*,4")
c49439f1 2256 (set_attr "type" "dyn_shift,arith,arith,arith")])
0d7e008e 2257
98e819b9
JW
2258(define_insn "ashlhi3_k"
2259 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2260 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
735cb76e
R
2261 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2262 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
98e819b9
JW
2263 "@
2264 add %0,%0
1245df60 2265 shll%O2 %0"
c49439f1 2266 [(set_attr "type" "arith")])
98e819b9 2267
0d7e008e
SC
2268(define_insn "ashlsi3_n"
2269 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2270 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2271 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2272 (clobber (reg:SI T_REG))]
fa5322fa 2273 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2274 "#"
2275 [(set (attr "length")
2276 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2277 (const_string "2")
2278 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2279 (const_string "4")
2280 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2281 (const_string "6")]
2282 (const_string "8")))
c49439f1 2283 (set_attr "type" "arith")])
bc45ade3 2284
07a45e5c
JW
2285(define_split
2286 [(set (match_operand:SI 0 "arith_reg_operand" "")
2287 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2288 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2289 (clobber (reg:SI T_REG))]
fa5322fa 2290 "TARGET_SH1 && reload_completed"
4773afa4 2291 [(use (reg:SI R0_REG))]
07a45e5c
JW
2292 "
2293{
2294 gen_shifty_op (ASHIFT, operands);
2295 DONE;
2296}")
2297
fa5322fa
AO
2298(define_insn "ashlsi3_media"
2299 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2300 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2301 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2302 "TARGET_SHMEDIA"
2303 "@
2304 shlld.l %1, %2, %0
b6d33983
R
2305 shlli.l %1, %2, %0"
2306 [(set_attr "type" "arith_media")])
fa5322fa 2307
bc45ade3 2308(define_expand "ashlsi3"
ffae286a
JW
2309 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2310 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2311 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2312 (clobber (reg:SI T_REG))])]
bc45ade3 2313 ""
d2f09a2f
JW
2314 "
2315{
fa5322fa
AO
2316 if (TARGET_SHMEDIA)
2317 {
2318 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2319 DONE;
2320 }
1245df60
R
2321 if (GET_CODE (operands[2]) == CONST_INT
2322 && sh_dynamicalize_shift_p (operands[2]))
2323 operands[2] = force_reg (SImode, operands[2]);
7e2fda6e 2324 if (TARGET_SH3)
6b005b88 2325 {
7e2fda6e 2326 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
6b005b88
JW
2327 DONE;
2328 }
d2f09a2f
JW
2329 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2330 FAIL;
2331}")
0d7e008e 2332
98e819b9
JW
2333(define_insn "ashlhi3"
2334 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2335 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2336 (match_operand:HI 2 "const_int_operand" "n")))
4773afa4 2337 (clobber (reg:SI T_REG))]
fa5322fa 2338 "TARGET_SH1"
98e819b9
JW
2339 "#"
2340 [(set (attr "length")
2341 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2342 (const_string "2")
2343 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2344 (const_string "4")]
2345 (const_string "6")))
2346 (set_attr "type" "arith")])
2347
2348(define_split
2349 [(set (match_operand:HI 0 "arith_reg_operand" "")
2350 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
e69d1422 2351 (match_operand:HI 2 "const_int_operand" "")))
4773afa4 2352 (clobber (reg:SI T_REG))]
fa5322fa 2353 "TARGET_SH1 && reload_completed"
4773afa4 2354 [(use (reg:SI R0_REG))]
98e819b9
JW
2355 "
2356{
2357 gen_shifty_hi_op (ASHIFT, operands);
2358 DONE;
2359}")
2360
0d7e008e
SC
2361;
2362; arithmetic shift right
2363;
bc45ade3
SC
2364
2365(define_insn "ashrsi3_k"
aa684c94
SC
2366 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2367 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2368 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2369 (clobber (reg:SI T_REG))]
fa5322fa 2370 "TARGET_SH1 && INTVAL (operands[2]) == 1"
bc45ade3 2371 "shar %0"
c49439f1 2372 [(set_attr "type" "arith")])
bc45ade3 2373
d0c42859
R
2374;; We can't do HImode right shifts correctly unless we start out with an
2375;; explicit zero / sign extension; doing that would result in worse overall
2376;; code, so just let the machine independent code widen the mode.
2377;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2378
98e819b9 2379
ffae286a
JW
2380;; ??? This should be a define expand.
2381
00f8ff66 2382(define_insn "ashrsi2_16"
07a45e5c
JW
2383 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2384 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3e8bd1ce 2385 (const_int 16)))]
fa5322fa 2386 "TARGET_SH1"
1245df60 2387 "#"
00f8ff66
SC
2388 [(set_attr "length" "4")])
2389
1245df60 2390(define_split
e69d1422
R
2391 [(set (match_operand:SI 0 "arith_reg_operand" "")
2392 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2393 (const_int 16)))]
fa5322fa 2394 "TARGET_SH1"
1245df60
R
2395 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2396 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2397 "operands[2] = gen_lowpart (HImode, operands[0]);")
2398
ffae286a
JW
2399;; ??? This should be a define expand.
2400
00f8ff66 2401(define_insn "ashrsi2_31"
6b005b88 2402 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1245df60
R
2403 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2404 (const_int 31)))
4773afa4 2405 (clobber (reg:SI T_REG))]
fa5322fa 2406 "TARGET_SH1"
1245df60 2407 "#"
6b005b88 2408 [(set_attr "length" "4")])
3e8bd1ce 2409
1245df60 2410(define_split
e69d1422
R
2411 [(set (match_operand:SI 0 "arith_reg_operand" "")
2412 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1245df60 2413 (const_int 31)))
4773afa4 2414 (clobber (reg:SI T_REG))]
fa5322fa 2415 "TARGET_SH1"
1245df60
R
2416 [(const_int 0)]
2417 "
2418{
5bac82c5 2419 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
1245df60
R
2420 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2421 DONE;
2422}")
2423
2424(define_insn "ashlsi_c"
2425 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
4773afa4
AO
2427 (set (reg:SI T_REG)
2428 (lt:SI (match_dup 1) (const_int 0)))]
fa5322fa 2429 "TARGET_SH1"
1245df60 2430 "shll %0"
c49439f1 2431 [(set_attr "type" "arith")])
1245df60 2432
6b005b88
JW
2433(define_insn "ashrsi3_d"
2434 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2435 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2436 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2437 "TARGET_SH3"
1245df60 2438 "shad %2,%0"
c49439f1 2439 [(set_attr "type" "dyn_shift")])
51aea58d 2440
0d7e008e 2441(define_insn "ashrsi3_n"
4773afa4
AO
2442 [(set (reg:SI R4_REG)
2443 (ashiftrt:SI (reg:SI R4_REG)
ffae286a 2444 (match_operand:SI 0 "const_int_operand" "i")))
4773afa4
AO
2445 (clobber (reg:SI T_REG))
2446 (clobber (reg:SI PR_REG))
0d7e008e 2447 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
fa5322fa 2448 "TARGET_SH1"
0d7e008e
SC
2449 "jsr @%1%#"
2450 [(set_attr "type" "sfunc")
0d7e008e
SC
2451 (set_attr "needs_delay_slot" "yes")])
2452
fa5322fa
AO
2453(define_insn "ashrsi3_media"
2454 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2455 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2456 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2457 "TARGET_SHMEDIA"
2458 "@
2459 shard.l %1, %2, %0
b6d33983
R
2460 shari.l %1, %2, %0"
2461 [(set_attr "type" "arith_media")])
fa5322fa 2462
bc45ade3 2463(define_expand "ashrsi3"
ffae286a
JW
2464 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2465 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2466 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2467 (clobber (reg:SI T_REG))])]
bc45ade3 2468 ""
fa5322fa
AO
2469 "
2470{
2471 if (TARGET_SHMEDIA)
2472 {
2473 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2474 DONE;
2475 }
2476 if (expand_ashiftrt (operands))
2477 DONE;
2478 else
2479 FAIL;
2480}")
0d7e008e 2481
07a45e5c 2482;; logical shift right
bc45ade3 2483
6b005b88
JW
2484(define_insn "lshrsi3_d"
2485 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2488 "TARGET_SH3"
1245df60 2489 "shld %2,%0"
c49439f1 2490 [(set_attr "type" "dyn_shift")])
00f8ff66 2491
ffae286a 2492;; Only the single bit shift clobbers the T bit.
07a45e5c
JW
2493
2494(define_insn "lshrsi3_m"
2495 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2497 (match_operand:SI 2 "const_int_operand" "M")))
4773afa4 2498 (clobber (reg:SI T_REG))]
fa5322fa 2499 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2500 "shlr %0"
c49439f1 2501 [(set_attr "type" "arith")])
0d7e008e 2502
07a45e5c
JW
2503(define_insn "lshrsi3_k"
2504 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
735cb76e
R
2506 (match_operand:SI 2 "const_int_operand" "P27")))]
2507 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
07a45e5c 2508 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60 2509 "shlr%O2 %0"
c49439f1 2510 [(set_attr "type" "arith")])
0d7e008e
SC
2511
2512(define_insn "lshrsi3_n"
2513 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2514 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 2515 (match_operand:SI 2 "const_int_operand" "n")))
4773afa4 2516 (clobber (reg:SI T_REG))]
fa5322fa 2517 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
2518 "#"
2519 [(set (attr "length")
2520 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2521 (const_string "2")
2522 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2523 (const_string "4")
2524 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2525 (const_string "6")]
2526 (const_string "8")))
bc45ade3
SC
2527 (set_attr "type" "arith")])
2528
07a45e5c
JW
2529(define_split
2530 [(set (match_operand:SI 0 "arith_reg_operand" "")
2531 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
e69d1422 2532 (match_operand:SI 2 "const_int_operand" "")))
4773afa4 2533 (clobber (reg:SI T_REG))]
fa5322fa 2534 "TARGET_SH1 && reload_completed"
4773afa4 2535 [(use (reg:SI R0_REG))]
07a45e5c
JW
2536 "
2537{
2538 gen_shifty_op (LSHIFTRT, operands);
2539 DONE;
2540}")
2541
fa5322fa
AO
2542(define_insn "lshrsi3_media"
2543 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
b6d33983 2544 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
fa5322fa
AO
2545 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2546 "TARGET_SHMEDIA"
2547 "@
2548 shlrd.l %1, %2, %0
b6d33983
R
2549 shlri.l %1, %2, %0"
2550 [(set_attr "type" "arith_media")])
fa5322fa 2551
bc45ade3 2552(define_expand "lshrsi3"
ffae286a
JW
2553 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2554 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2555 (match_operand:SI 2 "nonmemory_operand" "")))
4773afa4 2556 (clobber (reg:SI T_REG))])]
bc45ade3 2557 ""
d2f09a2f
JW
2558 "
2559{
fa5322fa
AO
2560 if (TARGET_SHMEDIA)
2561 {
2562 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2563 DONE;
2564 }
1245df60
R
2565 if (GET_CODE (operands[2]) == CONST_INT
2566 && sh_dynamicalize_shift_p (operands[2]))
2567 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
2568 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2569 {
2570 rtx count = copy_to_mode_reg (SImode, operands[2]);
2571 emit_insn (gen_negsi2 (count, count));
7b7499bf 2572 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
6b005b88
JW
2573 DONE;
2574 }
d2f09a2f
JW
2575 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2576 FAIL;
2577}")
bc45ade3 2578
ffae286a
JW
2579;; ??? This should be a define expand.
2580
bc45ade3 2581(define_insn "ashldi3_k"
aa684c94
SC
2582 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2583 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2584 (const_int 1)))
4773afa4 2585 (clobber (reg:SI T_REG))]
fa5322fa 2586 "TARGET_SH1"
00f8ff66 2587 "shll %R0\;rotcl %S0"
1245df60 2588 [(set_attr "length" "4")
c49439f1 2589 (set_attr "type" "arith")])
bc45ade3 2590
fa5322fa
AO
2591(define_insn "ashldi3_media"
2592 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2593 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2594 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2595 "TARGET_SHMEDIA"
2596 "@
2597 shlld %1, %2, %0
2ad65b0e
SC
2598 shlli %1, %2, %0"
2599 [(set_attr "type" "arith_media")])
fa5322fa 2600
bc45ade3 2601(define_expand "ashldi3"
ffae286a
JW
2602 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2603 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2604 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2605 (clobber (reg:SI T_REG))])]
bc45ade3 2606 ""
fa5322fa
AO
2607 "
2608{
2609 if (TARGET_SHMEDIA)
2610 {
2611 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2612 DONE;
2613 }
2614 if (GET_CODE (operands[2]) != CONST_INT
2615 || INTVAL (operands[2]) != 1)
2616 FAIL;
2617}")
ffae286a
JW
2618
2619;; ??? This should be a define expand.
bc45ade3
SC
2620
2621(define_insn "lshrdi3_k"
aa684c94 2622 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b9654711 2623 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2624 (const_int 1)))
4773afa4 2625 (clobber (reg:SI T_REG))]
fa5322fa 2626 "TARGET_SH1"
00f8ff66 2627 "shlr %S0\;rotcr %R0"
1245df60 2628 [(set_attr "length" "4")
c49439f1 2629 (set_attr "type" "arith")])
bc45ade3 2630
fa5322fa
AO
2631(define_insn "lshrdi3_media"
2632 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2633 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2634 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2635 "TARGET_SHMEDIA"
2636 "@
2637 shlrd %1, %2, %0
2ad65b0e
SC
2638 shlri %1, %2, %0"
2639 [(set_attr "type" "arith_media")])
fa5322fa 2640
bc45ade3 2641(define_expand "lshrdi3"
ffae286a
JW
2642 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2643 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
bc45ade3 2644 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2645 (clobber (reg:SI T_REG))])]
bc45ade3 2646 ""
fa5322fa
AO
2647 "
2648{
2649 if (TARGET_SHMEDIA)
2650 {
2651 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2652 DONE;
2653 }
2654 if (GET_CODE (operands[2]) != CONST_INT
2655 || INTVAL (operands[2]) != 1)
2656 FAIL;
2657}")
ffae286a
JW
2658
2659;; ??? This should be a define expand.
bc45ade3
SC
2660
2661(define_insn "ashrdi3_k"
aa684c94
SC
2662 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2663 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 2664 (const_int 1)))
4773afa4 2665 (clobber (reg:SI T_REG))]
fa5322fa 2666 "TARGET_SH1"
00f8ff66 2667 "shar %S0\;rotcr %R0"
1245df60 2668 [(set_attr "length" "4")
c49439f1 2669 (set_attr "type" "arith")])
bc45ade3 2670
fa5322fa
AO
2671(define_insn "ashrdi3_media"
2672 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2673 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2674 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2675 "TARGET_SHMEDIA"
2676 "@
2677 shard %1, %2, %0
2ad65b0e
SC
2678 shari %1, %2, %0"
2679 [(set_attr "type" "arith_media")])
fa5322fa 2680
bc45ade3 2681(define_expand "ashrdi3"
ffae286a
JW
2682 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2683 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2684 (match_operand:DI 2 "immediate_operand" "")))
4773afa4 2685 (clobber (reg:SI T_REG))])]
bc45ade3 2686 ""
fa5322fa
AO
2687 "
2688{
2689 if (TARGET_SHMEDIA)
2690 {
2691 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2692 DONE;
2693 }
2694 if (GET_CODE (operands[2]) != CONST_INT
2695 || INTVAL (operands[2]) != 1)
2696 FAIL;
2697}")
98e819b9
JW
2698
2699;; combined left/right shift
2700
2701(define_split
2702 [(set (match_operand:SI 0 "register_operand" "")
2703 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2704 (match_operand:SI 2 "const_int_operand" ""))
2705 (match_operand:SI 3 "const_int_operand" "")))]
85af47b9 2706 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2707 [(use (reg:SI R0_REG))]
98e819b9
JW
2708 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2709 DONE;")
2710
2711(define_split
2712 [(set (match_operand:SI 0 "register_operand" "")
2713 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
e69d1422
R
2714 (match_operand:SI 2 "const_int_operand" ""))
2715 (match_operand:SI 3 "const_int_operand" "")))
4773afa4 2716 (clobber (reg:SI T_REG))]
85af47b9 2717 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4773afa4 2718 [(use (reg:SI R0_REG))]
98e819b9
JW
2719 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2720 DONE;")
2721
2722(define_insn ""
2723 [(set (match_operand:SI 0 "register_operand" "=r")
2724 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2725 (match_operand:SI 2 "const_int_operand" "n"))
2726 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2727 (clobber (reg:SI T_REG))]
fa5322fa 2728 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
98e819b9
JW
2729 "#"
2730 [(set (attr "length")
2731 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2732 (const_string "4")
2733 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2734 (const_string "6")
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2736 (const_string "8")
2737 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2738 (const_string "10")
2739 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2740 (const_string "12")
2741 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2742 (const_string "14")
2743 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2744 (const_string "16")]
2745 (const_string "18")))
2746 (set_attr "type" "arith")])
2747
2748(define_insn ""
2749 [(set (match_operand:SI 0 "register_operand" "=z")
2750 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2751 (match_operand:SI 2 "const_int_operand" "n"))
2752 (match_operand:SI 3 "const_int_operand" "n")))
4773afa4 2753 (clobber (reg:SI T_REG))]
fa5322fa 2754 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
98e819b9
JW
2755 "#"
2756 [(set (attr "length")
2757 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2758 (const_string "4")
2759 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2760 (const_string "6")
2761 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2762 (const_string "8")]
2763 (const_string "10")))
2764 (set_attr "type" "arith")])
2765
2766;; shift left / and combination with a scratch register: The combine pass
2767;; does not accept the individual instructions, even though they are
2768;; cheap. But it needs a precise description so that it is usable after
2769;; reload.
2770(define_insn "and_shl_scratch"
2771 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4773afa4
AO
2772 (lshiftrt:SI
2773 (ashift:SI
2774 (and:SI
2775 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2776 (match_operand:SI 2 "const_int_operand" "N,n"))
2777 (match_operand:SI 3 "" "0,r"))
2778 (match_operand:SI 4 "const_int_operand" "n,n"))
2779 (match_operand:SI 5 "const_int_operand" "n,n")))
2780 (clobber (reg:SI T_REG))]
fa5322fa 2781 "TARGET_SH1"
98e819b9
JW
2782 "#"
2783 [(set (attr "length")
2784 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2785 (const_string "4")
2786 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2787 (const_string "6")
2788 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
9788ff4d 2789 (const_string "8")
98e819b9
JW
2790 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2791 (const_string "10")]
2792 (const_string "12")))
2793 (set_attr "type" "arith")])
2794
2795(define_split
e69d1422 2796 [(set (match_operand:SI 0 "register_operand" "")
4773afa4
AO
2797 (lshiftrt:SI
2798 (ashift:SI
2799 (and:SI
e69d1422
R
2800 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2801 (match_operand:SI 2 "const_int_operand" ""))
2802 (match_operand:SI 3 "register_operand" ""))
2803 (match_operand:SI 4 "const_int_operand" ""))
2804 (match_operand:SI 5 "const_int_operand" "")))
4773afa4 2805 (clobber (reg:SI T_REG))]
fa5322fa 2806 "TARGET_SH1"
4773afa4 2807 [(use (reg:SI R0_REG))]
98e819b9
JW
2808 "
2809{
fc2380b9 2810 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
98e819b9
JW
2811
2812 if (INTVAL (operands[2]))
2813 {
2814 gen_shifty_op (LSHIFTRT, operands);
98e819b9
JW
2815 }
2816 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2817 operands[2] = operands[4];
2818 gen_shifty_op (ASHIFT, operands);
2819 if (INTVAL (operands[5]))
2820 {
2821 operands[2] = operands[5];
2822 gen_shifty_op (LSHIFTRT, operands);
2823 }
2824 DONE;
2825}")
2826
2827;; signed left/right shift combination.
2828(define_split
e69d1422 2829 [(set (match_operand:SI 0 "register_operand" "")
4773afa4 2830 (sign_extract:SI
e69d1422
R
2831 (ashift:SI (match_operand:SI 1 "register_operand" "")
2832 (match_operand:SI 2 "const_int_operand" ""))
2833 (match_operand:SI 3 "const_int_operand" "")
4773afa4
AO
2834 (const_int 0)))
2835 (clobber (reg:SI T_REG))]
fa5322fa 2836 "TARGET_SH1"
4773afa4 2837 [(use (reg:SI R0_REG))]
98e819b9
JW
2838 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2839 DONE;")
2840
2841(define_insn "shl_sext_ext"
2842 [(set (match_operand:SI 0 "register_operand" "=r")
4773afa4
AO
2843 (sign_extract:SI
2844 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2845 (match_operand:SI 2 "const_int_operand" "n"))
2846 (match_operand:SI 3 "const_int_operand" "n")
2847 (const_int 0)))
2848 (clobber (reg:SI T_REG))]
fa5322fa 2849 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
98e819b9
JW
2850 "#"
2851 [(set (attr "length")
2852 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2853 (const_string "2")
2854 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2855 (const_string "4")
2856 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2857 (const_string "6")
2858 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2859 (const_string "8")
2860 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2861 (const_string "10")
2862 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2863 (const_string "12")
2864 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2865 (const_string "14")
2866 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2867 (const_string "16")]
2868 (const_string "18")))
2869 (set_attr "type" "arith")])
2870
2871(define_insn "shl_sext_sub"
2872 [(set (match_operand:SI 0 "register_operand" "=z")
e11cddec
AO
2873 (sign_extract:SI
2874 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2875 (match_operand:SI 2 "const_int_operand" "n"))
2876 (match_operand:SI 3 "const_int_operand" "n")
2877 (const_int 0)))
4773afa4 2878 (clobber (reg:SI T_REG))]
fa5322fa 2879 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
98e819b9
JW
2880 "#"
2881 [(set (attr "length")
2882 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2883 (const_string "6")
2884 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2885 (const_string "8")
2886 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2887 (const_string "10")
2888 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2889 (const_string "12")]
2890 (const_string "14")))
2891 (set_attr "type" "arith")])
2892
977eef43
JW
2893;; These patterns are found in expansions of DImode shifts by 16, and
2894;; allow the xtrct instruction to be generated from C source.
2895
2896(define_insn "xtrct_left"
2897 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2899 (const_int 16))
2900 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2901 (const_int 16))))]
fa5322fa 2902 "TARGET_SH1"
1245df60 2903 "xtrct %1,%0"
c49439f1 2904 [(set_attr "type" "arith")])
977eef43
JW
2905
2906(define_insn "xtrct_right"
2907 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2908 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2909 (const_int 16))
2910 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2911 (const_int 16))))]
fa5322fa 2912 "TARGET_SH1"
1245df60 2913 "xtrct %2,%0"
c49439f1 2914 [(set_attr "type" "arith")])
fae15c93 2915
bc45ade3
SC
2916;; -------------------------------------------------------------------------
2917;; Unary arithmetic
2918;; -------------------------------------------------------------------------
2919
8e87e161
SC
2920(define_insn "negc"
2921 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 2922 (neg:SI (plus:SI (reg:SI T_REG)
51bd623f 2923 (match_operand:SI 1 "arith_reg_operand" "r"))))
4773afa4
AO
2924 (set (reg:SI T_REG)
2925 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
51bd623f 2926 (const_int 0)))]
fa5322fa 2927 "TARGET_SH1"
8e87e161 2928 "negc %1,%0"
c49439f1 2929 [(set_attr "type" "arith")])
bc45ade3 2930
fa5322fa
AO
2931(define_insn "*negdi_media"
2932 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2933 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2934 "TARGET_SHMEDIA"
2ad65b0e
SC
2935 "sub r63, %1, %0"
2936 [(set_attr "type" "arith_media")])
fa5322fa 2937
8e87e161 2938(define_expand "negdi2"
51aea58d 2939 [(set (match_operand:DI 0 "arith_reg_operand" "")
b6d33983 2940 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
8e87e161 2941 ""
ffae286a
JW
2942 "
2943{
fa5322fa
AO
2944 if (TARGET_SH1)
2945 {
2946 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2947 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
8e87e161 2948
fa5322fa
AO
2949 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2950 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
0a0b733a 2951
fa5322fa
AO
2952 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2953 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
8e87e161 2954
fa5322fa
AO
2955 emit_insn (gen_clrt ());
2956 emit_insn (gen_negc (low_dst, low_src));
2957 emit_insn (gen_negc (high_dst, high_src));
2958 DONE;
2959 }
ffae286a 2960}")
8e87e161 2961
bc45ade3 2962(define_insn "negsi2"
aa684c94
SC
2963 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2964 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2965 "TARGET_SH1"
bc45ade3 2966 "neg %1,%0"
c49439f1 2967 [(set_attr "type" "arith")])
bc45ade3
SC
2968
2969(define_insn "one_cmplsi2"
aa684c94
SC
2970 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2971 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
fa5322fa 2972 "TARGET_SH1"
bc45ade3 2973 "not %1,%0"
c49439f1 2974 [(set_attr "type" "arith")])
fa5322fa
AO
2975
2976(define_expand "one_cmpldi2"
2977 [(set (match_operand:DI 0 "arith_reg_operand" "")
2978 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2979 (const_int -1)))]
2980 "TARGET_SHMEDIA" "")
bc45ade3
SC
2981\f
2982;; -------------------------------------------------------------------------
2983;; Zero extension instructions
2984;; -------------------------------------------------------------------------
2985
fa5322fa
AO
2986(define_insn "zero_extendsidi2"
2987 [(set (match_operand:DI 0 "register_operand" "=r")
b6d33983 2988 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
fa5322fa 2989 "TARGET_SHMEDIA"
b6d33983
R
2990 "addz.l %1, r63, %0"
2991 [(set_attr "type" "arith_media")])
fa5322fa
AO
2992
2993(define_insn "zero_extendhidi2"
2994 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 2995 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
2996 "TARGET_SHMEDIA"
2997 "@
2998 #
b6d33983
R
2999 ld%M1.uw %m1, %0"
3000 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3001
3002(define_split
e69d1422
R
3003 [(set (match_operand:DI 0 "register_operand" "")
3004 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3005 "TARGET_SHMEDIA && reload_completed"
3006 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
3007 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3008 "
3009{
3010 if (GET_CODE (operands[1]) == TRUNCATE)
3011 operands[1] = XEXP (operands[1], 0);
3012}")
3013
fae778eb
KH
3014;; ??? when a truncated input to a zero_extend is reloaded, reload will
3015;; reload the entire truncate expression.
b6d33983 3016(define_insn_and_split "*loaddi_trunc"
e69d1422 3017 [(set (match_operand 0 "int_gpr_dest" "=r")
b6d33983
R
3018 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3019 "TARGET_SHMEDIA && reload_completed"
3020 "#"
3021 "TARGET_SHMEDIA && reload_completed"
3022 [(set (match_dup 0) (match_dup 1))]
3023 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
fa5322fa
AO
3024
3025(define_insn "zero_extendqidi2"
3026 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3027 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3028 "TARGET_SHMEDIA"
3029 "@
3030 andi %1, 255, %0
b6d33983
R
3031 ld%M1.ub %m1, %0"
3032 [(set_attr "type" "arith_media,load_media")])
3033
3034(define_expand "zero_extendhisi2"
3035 [(set (match_operand:SI 0 "arith_reg_operand" "")
3036 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3037 ""
3038 "
3039{
3040 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3041 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3042}")
fa5322fa 3043
b6d33983 3044(define_insn "*zero_extendhisi2_compact"
aa684c94
SC
3045 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3046 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
fa5322fa 3047 "TARGET_SH1"
bc45ade3 3048 "extu.w %1,%0"
c49439f1 3049 [(set_attr "type" "arith")])
bc45ade3 3050
b6d33983
R
3051(define_insn "*zero_extendhisi2_media"
3052 [(set (match_operand:SI 0 "register_operand" "=r,r")
3053 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3054 "TARGET_SHMEDIA"
3055 "@
3056 #
3057 ld%M1.uw %m1, %0"
3058 [(set_attr "type" "arith_media,load_media")])
3059
3060(define_split
e69d1422
R
3061 [(set (match_operand:SI 0 "register_operand" "")
3062 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3063 "TARGET_SHMEDIA && reload_completed"
3064 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3065 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3066 "
3067{
3068 if (GET_CODE (operands[1]) == TRUNCATE)
3069 operands[1] = XEXP (operands[1], 0);
3070}")
3071
3072(define_expand "zero_extendqisi2"
3073 [(set (match_operand:SI 0 "arith_reg_operand" "")
3074 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3075 ""
3076 "
3077{
3078 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3079 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3080}")
3081
3082(define_insn "*zero_extendqisi2_compact"
aa684c94
SC
3083 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3084 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3085 "TARGET_SH1"
bc45ade3 3086 "extu.b %1,%0"
c49439f1 3087 [(set_attr "type" "arith")])
bc45ade3 3088
b6d33983
R
3089(define_insn "*zero_extendqisi2_media"
3090 [(set (match_operand:SI 0 "register_operand" "=r,r")
3091 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3092 "TARGET_SHMEDIA"
3093 "@
3094 andi %1, 255, %0
3095 ld%M1.ub %m1, %0"
3096 [(set_attr "type" "arith_media,load_media")])
3097
bc45ade3 3098(define_insn "zero_extendqihi2"
aa684c94
SC
3099 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3100 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
fa5322fa 3101 "TARGET_SH1"
bc45ade3 3102 "extu.b %1,%0"
c49439f1 3103 [(set_attr "type" "arith")])
fae15c93 3104
bc45ade3
SC
3105;; -------------------------------------------------------------------------
3106;; Sign extension instructions
3107;; -------------------------------------------------------------------------
3108
ffae286a
JW
3109;; ??? This should be a define expand.
3110;; ??? Or perhaps it should be dropped?
3111
fa5322fa
AO
3112;; convert_move generates good code for SH[1-4].
3113(define_insn "extendsidi2"
3114 [(set (match_operand:DI 0 "register_operand" "=r,r")
3115 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3116 "TARGET_SHMEDIA"
3117 "@
3118 add.l %1, r63, %0
2ad65b0e
SC
3119 ld%M1.l %m1, %0"
3120 [(set_attr "type" "arith_media,load_media")])
fa5322fa
AO
3121
3122(define_insn "extendhidi2"
3123 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3124 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3125 "TARGET_SHMEDIA"
3126 "@
3127 #
b6d33983
R
3128 ld%M1.w %m1, %0"
3129 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3130
3131(define_split
e69d1422
R
3132 [(set (match_operand:DI 0 "register_operand" "")
3133 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3134 "TARGET_SHMEDIA && reload_completed"
3135 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
b6d33983
R
3136 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3137 "
3138{
3139 if (GET_CODE (operands[1]) == TRUNCATE)
3140 operands[1] = XEXP (operands[1], 0);
3141}")
fa5322fa
AO
3142
3143(define_insn "extendqidi2"
3144 [(set (match_operand:DI 0 "register_operand" "=r,r")
b6d33983 3145 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
fa5322fa
AO
3146 "TARGET_SHMEDIA"
3147 "@
3148 #
b6d33983
R
3149 ld%M1.b %m1, %0"
3150 [(set_attr "type" "*,load_media")])
fa5322fa
AO
3151
3152(define_split
e69d1422
R
3153 [(set (match_operand:DI 0 "register_operand" "")
3154 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
fa5322fa
AO
3155 "TARGET_SHMEDIA && reload_completed"
3156 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
b6d33983
R
3157 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3158 "
3159{
3160 if (GET_CODE (operands[1]) == TRUNCATE)
3161 operands[1] = XEXP (operands[1], 0);
3162}")
3163
3164(define_expand "extendhisi2"
3165 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
40779a72 3166 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
b6d33983
R
3167 ""
3168 "")
bc45ade3 3169
b6d33983 3170(define_insn "*extendhisi2_compact"
51bd623f
JW
3171 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3172 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3173 "TARGET_SH1"
0d7e008e
SC
3174 "@
3175 exts.w %1,%0
40779a72 3176 mov.w %1,%0"
c49439f1 3177 [(set_attr "type" "arith,load")])
bc45ade3 3178
b6d33983
R
3179(define_insn "*extendhisi2_media"
3180 [(set (match_operand:SI 0 "register_operand" "=r,r")
3181 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3182 "TARGET_SHMEDIA"
3183 "@
3184 #
3185 ld%M1.w %m1, %0"
3186 [(set_attr "type" "arith_media,load_media")])
3187
3188(define_split
e69d1422
R
3189 [(set (match_operand:SI 0 "register_operand" "")
3190 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
b6d33983
R
3191 "TARGET_SHMEDIA && reload_completed"
3192 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3193 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3194 "
3195{
3196 if (GET_CODE (operands[1]) == TRUNCATE)
3197 operands[1] = XEXP (operands[1], 0);
3198}")
3199
3200(define_expand "extendqisi2"
3201 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3202 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3203 ""
3204 "")
3205
3206(define_insn "*extendqisi2_compact"
51bd623f
JW
3207 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3208 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3209 "TARGET_SH1"
0d7e008e
SC
3210 "@
3211 exts.b %1,%0
51bd623f 3212 mov.b %1,%0"
c49439f1 3213 [(set_attr "type" "arith,load")])
bc45ade3 3214
b6d33983
R
3215(define_insn "*extendqisi2_media"
3216 [(set (match_operand:SI 0 "register_operand" "=r,r")
3217 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3218 "TARGET_SHMEDIA"
3219 "@
3220 #
3221 ld%M1.b %m1, %0"
3222 [(set_attr "type" "arith_media,load_media")])
3223
3224(define_split
e69d1422
R
3225 [(set (match_operand:SI 0 "register_operand" "")
3226 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
b6d33983
R
3227 "TARGET_SHMEDIA && reload_completed"
3228 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3229 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3230 "
3231{
3232 if (GET_CODE (operands[1]) == TRUNCATE)
3233 operands[1] = XEXP (operands[1], 0);
3234}")
3235
bc45ade3 3236(define_insn "extendqihi2"
51bd623f
JW
3237 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3238 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
fa5322fa 3239 "TARGET_SH1"
0d7e008e
SC
3240 "@
3241 exts.b %1,%0
51bd623f 3242 mov.b %1,%0"
c49439f1 3243 [(set_attr "type" "arith,load")])
fae15c93 3244
b6d33983
R
3245/* It would seem useful to combine the truncXi patterns into the movXi
3246 patterns, but unary operators are ignored when matching constraints,
3247 so we need separate patterns. */
3248(define_insn "truncdisi2"
0ac78517 3249 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
b6d33983
R
3250 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3251 "TARGET_SHMEDIA"
3252 "@
3253 add.l %1, r63, %0
3254 st%M0.l %m0, %1
3255 fst%M0.s %m0, %T1
3256 fmov.ls %1, %0
3257 fmov.sl %T1, %0
3258 fmov.s %T1, %0"
3259 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3260
3261
3262(define_insn "truncdihi2"
0ac78517 3263 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
b6d33983
R
3264 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3265 "TARGET_SHMEDIA"
3266 "@
3267 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3268 st%M0.w %m0, %1"
3269 [(set_attr "type" "arith_media,store_media")
3270 (set_attr "length" "8,4")])
3271
59324685
R
3272; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3273; Because we use zero extension, we can't provide signed QImode compares
3274; using a simple compare or conditional banch insn.
b6d33983
R
3275(define_insn "truncdiqi2"
3276 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3277 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3278 "TARGET_SHMEDIA"
3279 "@
40779a72 3280 andi %1, 255, %0
b6d33983
R
3281 st%M0.b %m0, %1"
3282 [(set_attr "type" "arith_media,store")])
3283
bc45ade3
SC
3284;; -------------------------------------------------------------------------
3285;; Move instructions
3286;; -------------------------------------------------------------------------
3287
0d7e008e 3288;; define push and pop so it is easy for sh.c
fa5322fa
AO
3289;; We can't use push and pop on SHcompact because the stack must always
3290;; be 8-byte aligned.
b9654711 3291
225e4f43 3292(define_expand "push"
4773afa4 3293 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
ffae286a 3294 (match_operand:SI 0 "register_operand" "r,l,x"))]
fa5322fa 3295 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3296 "")
b9654711 3297
225e4f43 3298(define_expand "pop"
51bd623f 3299 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4773afa4 3300 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
fa5322fa 3301 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3302 "")
3303
3304(define_expand "push_e"
4773afa4 3305 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
225e4f43 3306 (match_operand:SF 0 "" ""))
4773afa4 3307 (use (reg:PSI FPSCR_REG))
225e4f43 3308 (clobber (scratch:SI))])]
fa5322fa 3309 "TARGET_SH1 && ! TARGET_SH5"
225e4f43 3310 "")
b9654711 3311
225e4f43 3312(define_insn "push_fpul"
4773afa4 3313 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3a8699c7 3314 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 3315 "sts.l fpul,@-r15"
45348d9e 3316 [(set_attr "type" "store")
c49439f1 3317 (set_attr "late_fp_use" "yes")
45348d9e
JW
3318 (set_attr "hit_stack" "yes")])
3319
225e4f43
R
3320;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3321;; so use that.
3322(define_expand "push_4"
4773afa4
AO
3323 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3324 (match_operand:DF 0 "" ""))
3325 (use (reg:PSI FPSCR_REG))
225e4f43 3326 (clobber (scratch:SI))])]
fa5322fa 3327 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3328 "")
3329
3330(define_expand "pop_e"
3331 [(parallel [(set (match_operand:SF 0 "" "")
4773afa4
AO
3332 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3333 (use (reg:PSI FPSCR_REG))
225e4f43 3334 (clobber (scratch:SI))])]
fa5322fa 3335 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3336 "")
3337
3338(define_insn "pop_fpul"
4773afa4 3339 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3a8699c7 3340 "TARGET_SH2E && ! TARGET_SH5"
225e4f43 3341 "lds.l @r15+,fpul"
45348d9e
JW
3342 [(set_attr "type" "load")
3343 (set_attr "hit_stack" "yes")])
3344
225e4f43
R
3345(define_expand "pop_4"
3346 [(parallel [(set (match_operand:DF 0 "" "")
4773afa4
AO
3347 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3348 (use (reg:PSI FPSCR_REG))
225e4f43 3349 (clobber (scratch:SI))])]
fa5322fa 3350 "TARGET_SH1 && ! TARGET_SH5"
225e4f43
R
3351 "")
3352
7144b2d8
DD
3353(define_expand "push_fpscr"
3354 [(const_int 0)]
603ff6b5 3355 "TARGET_SH2E"
7144b2d8
DD
3356 "
3357{
3358 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3359 gen_rtx (PRE_DEC, Pmode,
3360 stack_pointer_rtx)),
3361 get_fpscr_rtx ()));
3362 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3363 DONE;
3364}")
3365
3366(define_expand "pop_fpscr"
3367 [(const_int 0)]
603ff6b5 3368 "TARGET_SH2E"
7144b2d8
DD
3369 "
3370{
3371 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3372 gen_rtx (MEM, PSImode,
3373 gen_rtx (POST_INC, Pmode,
3374 stack_pointer_rtx))));
3375 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3376 DONE;
3377}")
3378
e3391510
JW
3379;; These two patterns can happen as the result of optimization, when
3380;; comparisons get simplified to a move of zero or 1 into the T reg.
3381;; They don't disappear completely, because the T reg is a fixed hard reg.
ffae286a 3382
0d7e008e 3383(define_insn "clrt"
4773afa4 3384 [(set (reg:SI T_REG) (const_int 0))]
fa5322fa 3385 "TARGET_SH1"
0d7e008e 3386 "clrt")
bc45ade3 3387
e3391510 3388(define_insn "sett"
4773afa4 3389 [(set (reg:SI T_REG) (const_int 1))]
fa5322fa 3390 "TARGET_SH1"
e3391510
JW
3391 "sett")
3392
3ca0a524 3393;; t/r must come after r/r, lest reload will try to reload stuff like
4773afa4 3394;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
e11cddec 3395;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
0d7e008e 3396(define_insn "movsi_i"
735cb76e
R
3397 [(set (match_operand:SI 0 "general_movdst_operand"
3398 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3399 (match_operand:SI 1 "general_movsrc_operand"
3400 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
fa5322fa 3401 "TARGET_SH1
3a8699c7 3402 && ! TARGET_SH2E
1245df60
R
3403 && (register_operand (operands[0], SImode)
3404 || register_operand (operands[1], SImode))"
8e87e161
SC
3405 "@
3406 mov.l %1,%0
3407 mov %1,%0
3ca0a524 3408 cmp/pl %1
8e87e161
SC
3409 mov.l %1,%0
3410 sts %1,%0
99e87c10 3411 sts %1,%0
8e87e161
SC
3412 movt %0
3413 mov.l %1,%0
3414 sts.l %1,%0
1245df60 3415 sts.l %1,%0
8e87e161 3416 lds %1,%0
99e87c10 3417 lds %1,%0
8e87e161 3418 lds.l %1,%0
1245df60 3419 lds.l %1,%0
51bd623f 3420 fake %1,%0"
c49439f1 3421 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
99e87c10 3422 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
07a45e5c 3423
1245df60 3424;; t/r must come after r/r, lest reload will try to reload stuff like
e11cddec 3425;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
45348d9e
JW
3426;; ??? This allows moves from macl to fpul to be recognized, but these moves
3427;; will require a reload.
ec555f32
R
3428;; ??? We can't include f/f because we need the proper FPSCR setting when
3429;; TARGET_FMOVD is in effect, and mode switching is done before reload.
45348d9e 3430(define_insn "movsi_ie"
735cb76e
R
3431 [(set (match_operand:SI 0 "general_movdst_operand"
3432 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3433 (match_operand:SI 1 "general_movsrc_operand"
3434 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3a8699c7 3435 "TARGET_SH2E
45348d9e
JW
3436 && (register_operand (operands[0], SImode)
3437 || register_operand (operands[1], SImode))"
3438 "@
45348d9e
JW
3439 mov.l %1,%0
3440 mov %1,%0
1245df60 3441 cmp/pl %1
45348d9e
JW
3442 mov.l %1,%0
3443 sts %1,%0
99e87c10 3444 sts %1,%0
45348d9e
JW
3445 movt %0
3446 mov.l %1,%0
3447 sts.l %1,%0
1245df60 3448 sts.l %1,%0
45348d9e 3449 lds %1,%0
99e87c10 3450 lds %1,%0
45348d9e 3451 lds.l %1,%0
1245df60 3452 lds.l %1,%0
225e4f43 3453 lds.l %1,%0
a92facbb 3454 sts.l %1,%0
45348d9e
JW
3455 fake %1,%0
3456 lds %1,%0
1245df60 3457 sts %1,%0
ec555f32
R
3458 fsts fpul,%0
3459 flds %1,fpul
3460 fmov %1,%0
1245df60 3461 ! move optimized away"
ec555f32
R
3462 [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3463 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3464 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
1245df60
R
3465
3466(define_insn "movsi_i_lowpart"
99e87c10 3467 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
735cb76e 3468 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
fa5322fa
AO
3469 "TARGET_SH1
3470 && (register_operand (operands[0], SImode)
3471 || register_operand (operands[1], SImode))"
1245df60
R
3472 "@
3473 mov.l %1,%0
3474 mov %1,%0
3475 mov.l %1,%0
3476 sts %1,%0
99e87c10 3477 sts %1,%0
1245df60
R
3478 movt %0
3479 mov.l %1,%0
3480 fake %1,%0"
99e87c10 3481 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
a6f463a0 3482
7d73a2ba 3483(define_insn_and_split "load_ra"
b869f904 3484 [(set (match_operand:SI 0 "general_movdst_operand" "")
7d73a2ba 3485 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
dce20bbc 3486 "TARGET_SH1"
7d73a2ba
R
3487 "#"
3488 "&& ! rtx_equal_function_value_matters"
b869f904 3489 [(set (match_dup 0) (match_dup 1))]
7d73a2ba
R
3490 "
3491{
dce20bbc 3492 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
7d73a2ba
R
3493 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3494}")
b869f904 3495
fa5322fa 3496(define_insn "*movsi_media"
735cb76e
R
3497 [(set (match_operand:SI 0 "general_movdst_operand"
3498 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3499 (match_operand:SI 1 "general_movsrc_operand"
3500 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
fa5322fa
AO
3501 "TARGET_SHMEDIA_FPU
3502 && (register_operand (operands[0], SImode)
d9da94a1 3503 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3504 "@
3505 add.l %1, r63, %0
3506 movi %1, %0
3507 #
3508 ld%M1.l %m1, %0
d9da94a1 3509 st%M0.l %m0, %N1
fa5322fa
AO
3510 fld%M1.s %m1, %0
3511 fst%M0.s %m0, %1
0ac78517 3512 fmov.ls %N1, %0
fa5322fa
AO
3513 fmov.sl %1, %0
3514 fmov.s %1, %0
3515 ptabs %1, %0
3516 gettr %1, %0
3517 pt %1, %0"
2ad65b0e 3518 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3519 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3520
3521(define_insn "*movsi_media_nofpu"
735cb76e
R
3522 [(set (match_operand:SI 0 "general_movdst_operand"
3523 "=r,r,r,r,m,*b,r,b")
3524 (match_operand:SI 1 "general_movsrc_operand"
3525 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
fa5322fa
AO
3526 "TARGET_SHMEDIA
3527 && (register_operand (operands[0], SImode)
d9da94a1 3528 || sh_register_operand (operands[1], SImode))"
fa5322fa
AO
3529 "@
3530 add.l %1, r63, %0
3531 movi %1, %0
3532 #
3533 ld%M1.l %m1, %0
d9da94a1 3534 st%M0.l %m0, %N1
fa5322fa
AO
3535 ptabs %1, %0
3536 gettr %1, %0
3537 pt %1, %0"
2ad65b0e 3538 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3539 (set_attr "length" "4,4,8,4,4,4,4,12")])
3540
3541(define_split
e69d1422
R
3542 [(set (match_operand:SI 0 "arith_reg_operand" "")
3543 (match_operand:SI 1 "immediate_operand" ""))]
fa5322fa
AO
3544 "TARGET_SHMEDIA && reload_completed
3545 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3546 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3547 "
3548{
3549 operands[2] = shallow_copy_rtx (operands[1]);
3550 PUT_MODE (operands[2], DImode);
3551}")
3552
3553(define_split
e69d1422
R
3554 [(set (match_operand:SI 0 "register_operand" "")
3555 (match_operand:SI 1 "immediate_operand" ""))]
b6d33983 3556 "TARGET_SHMEDIA && reload_completed
fa5322fa 3557 && ((GET_CODE (operands[1]) == CONST_INT
735cb76e 3558 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
fa5322fa
AO
3559 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3560 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3561
bc45ade3 3562(define_expand "movsi"
0d7e008e
SC
3563 [(set (match_operand:SI 0 "general_movdst_operand" "")
3564 (match_operand:SI 1 "general_movsrc_operand" ""))]
bc45ade3 3565 ""
ffae286a 3566 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
961c4780 3567
225e4f43
R
3568(define_expand "ic_invalidate_line"
3569 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4773afa4 3570 (match_dup 1)] UNSPEC_ICACHE)
225e4f43 3571 (clobber (scratch:SI))])]
fa5322fa 3572 "TARGET_HARD_SH4 || TARGET_SH5"
225e4f43
R
3573 "
3574{
fa5322fa
AO
3575 if (TARGET_SHMEDIA)
3576 {
3577 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3578 DONE;
3579 }
3580 else if (TARGET_SHCOMPACT)
3581 {
90534361 3582 operands[1] = function_symbol (\"__ic_invalidate\");
fa5322fa
AO
3583 operands[1] = force_reg (Pmode, operands[1]);
3584 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3585 DONE;
3586 }
225e4f43 3587 operands[0] = force_reg (Pmode, operands[0]);
90e65b70
AO
3588 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3589 Pmode)));
225e4f43
R
3590}")
3591
3592;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
0aa54da2
R
3593;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3594;; the requirement *1*00 for associative address writes. The alignment of
225e4f43
R
3595;; %0 implies that its least significant bit is cleared,
3596;; thus we clear the V bit of a matching entry if there is one.
3597(define_insn "ic_invalidate_line_i"
0aa54da2 3598 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
4773afa4
AO
3599 (match_operand:SI 1 "register_operand" "r")]
3600 UNSPEC_ICACHE)
0aa54da2 3601 (clobber (match_scratch:SI 2 "=&r"))]
225e4f43 3602 "TARGET_HARD_SH4"
0aa54da2 3603 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
fae15c93 3604 [(set_attr "length" "8")
c49439f1 3605 (set_attr "type" "cwb")])
225e4f43 3606
ca903bba
R
3607;; ??? could make arg 0 an offsettable memory operand to allow to save
3608;; an add in the code that calculates the address.
fa5322fa
AO
3609(define_insn "ic_invalidate_line_media"
3610 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3611 UNSPEC_ICACHE)]
3612 "TARGET_SHMEDIA"
b6d33983
R
3613 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3614 [(set_attr "length" "16")
3615 (set_attr "type" "invalidate_line_media")])
fa5322fa
AO
3616
3617(define_insn "ic_invalidate_line_compact"
3618 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3619 (match_operand:SI 1 "register_operand" "r")]
3620 UNSPEC_ICACHE)
3621 (clobber (reg:SI PR_REG))]
3622 "TARGET_SHCOMPACT"
3623 "jsr @%1%#"
3624 [(set_attr "type" "sfunc")
3625 (set_attr "needs_delay_slot" "yes")])
3626
ca903bba
R
3627(define_expand "initialize_trampoline"
3628 [(match_operand:SI 0 "" "")
3629 (match_operand:SI 1 "" "")
3630 (match_operand:SI 2 "" "")]
3631 "TARGET_SHCOMPACT"
3632 "
3633{
3634 rtx sfun, tramp;
3635
e300c78c 3636 tramp = force_reg (Pmode, operands[0]);
90534361 3637 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
ca903bba
R
3638 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3639 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3640
3641 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3642 DONE;
3643}")
3644
3645(define_insn "initialize_trampoline_compact"
3646 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3647 (match_operand:SI 1 "register_operand" "r")
3648 (reg:SI R2_REG) (reg:SI R3_REG)]
3649 UNSPEC_INIT_TRAMP)
3650
3651 (clobber (reg:SI PR_REG))]
3652 "TARGET_SHCOMPACT"
3653 "jsr @%1%#"
3654 [(set_attr "type" "sfunc")
3655 (set_attr "needs_delay_slot" "yes")])
3656
bc45ade3 3657(define_insn "movqi_i"
07a45e5c
JW
3658 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3659 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
fa5322fa
AO
3660 "TARGET_SH1
3661 && (arith_reg_operand (operands[0], QImode)
3662 || arith_reg_operand (operands[1], QImode))"
bc45ade3
SC
3663 "@
3664 mov %1,%0
0d7e008e
SC
3665 mov.b %1,%0
3666 mov.b %1,%0
3667 movt %0
bc45ade3 3668 sts %1,%0
0d7e008e 3669 lds %1,%0"
22e1ebf1 3670 [(set_attr "type" "move,load,store,move,move,move")])
bc45ade3 3671
fa5322fa
AO
3672(define_insn "*movqi_media"
3673 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 3674 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
fa5322fa
AO
3675 "TARGET_SHMEDIA
3676 && (arith_reg_operand (operands[0], QImode)
d9da94a1 3677 || arith_reg_or_0_operand (operands[1], QImode))"
fa5322fa
AO
3678 "@
3679 add.l %1, r63, %0
3680 movi %1, %0
59324685 3681 ld%M1.ub %m1, %0
d9da94a1 3682 st%M0.b %m0, %N1"
2ad65b0e 3683 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
fa5322fa 3684
bc45ade3
SC
3685(define_expand "movqi"
3686 [(set (match_operand:QI 0 "general_operand" "")
3687 (match_operand:QI 1 "general_operand" ""))]
3688 ""
ffae286a 3689 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
bc45ade3 3690
b6d33983
R
3691(define_expand "reload_inqi"
3692 [(set (match_operand:SI 2 "" "=&r")
3693 (match_operand:QI 1 "inqhi_operand" ""))
3694 (set (match_operand:QI 0 "arith_reg_operand" "=r")
ea45c4b0 3695 (truncate:QI (match_dup 3)))]
b6d33983
R
3696 "TARGET_SHMEDIA"
3697 "
3698{
3699 rtx inner = XEXP (operands[1], 0);
3700 int regno = REGNO (inner);
3701
3702 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3703 operands[1] = gen_rtx_REG (SImode, regno);
3704 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3705}")
3706
266a2732 3707/* When storing r0, we have to avoid reg+reg addressing. */
bc45ade3 3708(define_insn "movhi_i"
735cb76e
R
3709 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3710 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
fa5322fa
AO
3711 "TARGET_SH1
3712 && (arith_reg_operand (operands[0], HImode)
266a2732
R
3713 || arith_reg_operand (operands[1], HImode))
3714 && (GET_CODE (operands[0]) != MEM
3715 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3716 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3717 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
8e87e161
SC
3718 "@
3719 mov.w %1,%0
3720 mov %1,%0
3721 mov.w %1,%0
3722 movt %0
3723 mov.w %1,%0
8e87e161 3724 sts %1,%0
51bd623f
JW
3725 lds %1,%0
3726 fake %1,%0"
27232d28 3727 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
bc45ade3 3728
fa5322fa 3729(define_insn "*movhi_media"
735cb76e
R
3730 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3731 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
fa5322fa
AO
3732 "TARGET_SHMEDIA
3733 && (arith_reg_operand (operands[0], HImode)
d9da94a1 3734 || arith_reg_or_0_operand (operands[1], HImode))"
fa5322fa
AO
3735 "@
3736 add.l %1, r63, %0
3737 movi %1, %0
3738 #
3739 ld%M1.w %m1, %0
d9da94a1 3740 st%M0.w %m0, %N1"
2ad65b0e 3741 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
fa5322fa
AO
3742
3743(define_split
e69d1422
R
3744 [(set (match_operand:HI 0 "register_operand" "")
3745 (match_operand:HI 1 "immediate_operand" ""))]
b6d33983 3746 "TARGET_SHMEDIA && reload_completed
735cb76e 3747 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa
AO
3748 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3749
bc45ade3 3750(define_expand "movhi"
0d7e008e
SC
3751 [(set (match_operand:HI 0 "general_movdst_operand" "")
3752 (match_operand:HI 1 "general_movsrc_operand" ""))]
bc45ade3 3753 ""
ffae286a
JW
3754 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3755
b6d33983
R
3756(define_expand "reload_inhi"
3757 [(set (match_operand:SI 2 "" "=&r")
3758 (match_operand:HI 1 "inqhi_operand" ""))
3759 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3760 (truncate:HI (match_dup 3)))]
3761 "TARGET_SHMEDIA"
3762 "
3763{
3764 rtx inner = XEXP (operands[1], 0);
3765 int regno = REGNO (inner);
3766
3767 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3768 operands[1] = gen_rtx_REG (SImode, regno);
3769 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3770}")
3771
1245df60
R
3772;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3773;; compiled with -m2 -ml -O3 -funroll-loops
0113c3c0 3774(define_insn "*movdi_i"
1245df60 3775 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
735cb76e 3776 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
fa5322fa
AO
3777 "TARGET_SH1
3778 && (arith_reg_operand (operands[0], DImode)
3779 || arith_reg_operand (operands[1], DImode))"
0d7e008e 3780 "* return output_movedouble (insn, operands, DImode);"
22e1ebf1 3781 [(set_attr "length" "4")
1245df60 3782 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
bc45ade3 3783
d0aae509 3784;; If the output is a register and the input is memory or a register, we have
52702ae1 3785;; to be careful and see which word needs to be loaded first.
b9b7c1c9 3786
8e87e161
SC
3787(define_split
3788 [(set (match_operand:DI 0 "general_movdst_operand" "")
3789 (match_operand:DI 1 "general_movsrc_operand" ""))]
fa5322fa 3790 "TARGET_SH1 && reload_completed"
8e87e161
SC
3791 [(set (match_dup 2) (match_dup 3))
3792 (set (match_dup 4) (match_dup 5))]
3793 "
d0aae509
RK
3794{
3795 int regno;
3796
3797 if ((GET_CODE (operands[0]) == MEM
3798 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3799 || (GET_CODE (operands[1]) == MEM
3800 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3801 FAIL;
3802
3803 if (GET_CODE (operands[0]) == REG)
3804 regno = REGNO (operands[0]);
3805 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 3806 regno = subreg_regno (operands[0]);
d0aae509
RK
3807 else if (GET_CODE (operands[0]) == MEM)
3808 regno = -1;
533f5e0f
KG
3809 else
3810 abort ();
d0aae509
RK
3811
3812 if (regno == -1
3813 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
3814 {
3815 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3816 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3817 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3818 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3819 }
3820 else
3821 {
3822 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3823 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3824 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3825 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3826 }
3827
3828 if (operands[2] == 0 || operands[3] == 0
3829 || operands[4] == 0 || operands[5] == 0)
3830 FAIL;
3831}")
961c4780 3832
fa5322fa 3833(define_insn "*movdi_media"
735cb76e
R
3834 [(set (match_operand:DI 0 "general_movdst_operand"
3835 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3836 (match_operand:DI 1 "general_movsrc_operand"
3837 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
fa5322fa
AO
3838 "TARGET_SHMEDIA_FPU
3839 && (register_operand (operands[0], DImode)
d9da94a1 3840 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3841 "@
3842 add %1, r63, %0
3843 movi %1, %0
3844 #
3845 ld%M1.q %m1, %0
d9da94a1 3846 st%M0.q %m0, %N1
fa5322fa
AO
3847 fld%M1.d %m1, %0
3848 fst%M0.d %m0, %1
0ac78517 3849 fmov.qd %N1, %0
fa5322fa
AO
3850 fmov.dq %1, %0
3851 fmov.d %1, %0
3852 ptabs %1, %0
3853 gettr %1, %0
3854 pt %1, %0"
2ad65b0e 3855 [(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
3856 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3857
3858(define_insn "*movdi_media_nofpu"
b6d33983 3859 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
735cb76e 3860 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
fa5322fa
AO
3861 "TARGET_SHMEDIA
3862 && (register_operand (operands[0], DImode)
d9da94a1 3863 || sh_register_operand (operands[1], DImode))"
fa5322fa
AO
3864 "@
3865 add %1, r63, %0
3866 movi %1, %0
3867 #
3868 ld%M1.q %m1, %0
d9da94a1 3869 st%M0.q %m0, %N1
fa5322fa
AO
3870 ptabs %1, %0
3871 gettr %1, %0
3872 pt %1, %0"
2ad65b0e 3873 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
fa5322fa
AO
3874 (set_attr "length" "4,4,16,4,4,4,4,*")])
3875
3876(define_split
e69d1422
R
3877 [(set (match_operand:DI 0 "arith_reg_operand" "")
3878 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3879 "TARGET_SHMEDIA && reload_completed
3880 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3881 [(set (match_dup 0) (match_dup 1))]
3882 "
3883{
3884 rtx insn;
3885
3886 if (TARGET_SHMEDIA64)
3887 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3888 else
3889 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3890
3891 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3892 REG_NOTES (insn));
3893
3894 DONE;
3895}")
3896
3897(define_expand "movdi_const"
3898 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3899 (const:DI (sign_extend:DI
3900 (truncate:HI
3901 (ashiftrt:DI
3902 (match_operand:DI 1 "immediate_operand" "s")
3903 (const_int 48))))))
3904 (set (match_dup 0)
3905 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3906 (zero_extend:DI
3907 (truncate:HI
3908 (const:DI
3909 (sign_extend:DI
3910 (truncate:HI
3911 (ashiftrt:SI
3912 (match_dup 1)
3913 (const_int 32)))))))))
3914 (set (match_dup 0)
3915 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3916 (zero_extend:DI
3917 (truncate:HI
3918 (const:DI
3919 (sign_extend:DI
3920 (truncate:HI
3921 (ashiftrt:SI
3922 (match_dup 1)
3923 (const_int 16)))))))))
3924 (set (match_dup 0)
3925 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3926 (zero_extend:DI
3927 (truncate:HI
3928 (const:DI
3929 (sign_extend:DI
3930 (truncate:HI
3931 (match_dup 1))))))))]
3932 "TARGET_SHMEDIA64 && reload_completed
3933 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3934 "
3935{
ea4210ef 3936 sh_mark_label (operands[1], 4);
fa5322fa
AO
3937}")
3938
3939(define_expand "movdi_const_32bit"
3940 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3941 (const:DI (sign_extend:DI
3942 (truncate:HI
3943 (ashiftrt:DI
3944 (match_operand:DI 1 "immediate_operand" "s")
3945 (const_int 16))))))
3946 (set (match_dup 0)
3947 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3948 (zero_extend:DI
3949 (truncate:HI
3950 (const:DI
3951 (sign_extend:DI
3952 (truncate:HI
3953 (match_dup 1))))))))]
3954 "TARGET_SHMEDIA32 && reload_completed
3955 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3956 "
3957{
ea4210ef 3958 sh_mark_label (operands[1], 2);
fa5322fa
AO
3959}")
3960
3961(define_expand "movdi_const_16bit"
3962 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3963 (const:DI (sign_extend:DI
3964 (truncate:HI
3965 (match_operand:DI 1 "immediate_operand" "s")))))]
3966 "TARGET_SHMEDIA && flag_pic && reload_completed
3967 && GET_CODE (operands[1]) == SYMBOL_REF"
3968 "")
3969
3970(define_split
e69d1422
R
3971 [(set (match_operand:DI 0 "arith_reg_operand" "")
3972 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
3973 "TARGET_SHMEDIA && reload_completed
3974 && GET_CODE (operands[1]) == CONST_INT
735cb76e 3975 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
fa5322fa 3976 [(set (match_dup 0) (match_dup 2))
c1b92d09 3977 (match_dup 1)]
fa5322fa
AO
3978 "
3979{
c1b92d09
R
3980 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3981 unsigned HOST_WIDE_INT low = val;
3982 unsigned HOST_WIDE_INT high = val;
fa5322fa 3983 unsigned HOST_WIDE_INT sign;
c1b92d09 3984 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
fa5322fa
AO
3985
3986 /* Sign-extend the 16 least-significant bits. */
c1b92d09
R
3987 low &= 0xffff;
3988 low ^= 0x8000;
3989 low -= 0x8000;
fa5322fa
AO
3990
3991 /* Arithmetic shift right the word by 16 bits. */
c1b92d09 3992 high >>= 16;
fa5322fa
AO
3993 sign = 1;
3994 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
c1b92d09
R
3995 high ^= sign;
3996 high -= sign;
3997 do
3998 {
3999 /* If we can't generate the constant with a two-insn movi / shori
4000 sequence, try some other strategies. */
735cb76e 4001 if (! CONST_OK_FOR_I16 (high))
c1b92d09
R
4002 {
4003 /* Try constant load / left shift. We know VAL != 0. */
4004 val2 = val ^ (val-1);
4005 if (val2 > 0x1ffff)
4006 {
4007 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4008
735cb76e
R
4009 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4010 || (! CONST_OK_FOR_I16 (high >> 16)
4011 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
c1b92d09
R
4012 {
4013 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4014 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4015 GEN_INT (trailing_zeroes));
4016 break;
4017 }
4018 }
4019 /* Try constant load / right shift. */
4020 val2 = (val >> 15) + 1;
4021 if (val2 == (val2 & -val2))
4022 {
4023 int shift = 49 - exact_log2 (val2);
4024
4025 val2 = trunc_int_for_mode (val << shift, DImode);
735cb76e 4026 if (CONST_OK_FOR_I16 (val2))
c1b92d09
R
4027 {
4028 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4029 GEN_INT (shift));
4030 break;
4031 }
4032 }
4033 /* Try mperm.w . */
4034 val2 = val & 0xffff;
4035 if ((val >> 16 & 0xffff) == val2
4036 && (val >> 32 & 0xffff) == val2
4037 && (val >> 48 & 0xffff) == val2)
4038 {
4039 val2 = (HOST_WIDE_INT) val >> 48;
4040 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4041 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4042 break;
4043 }
4044 /* Try movi / mshflo.l */
4045 val2 = (HOST_WIDE_INT) val >> 32;
4046 if (val2 == trunc_int_for_mode (val, SImode))
4047 {
4048 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4049 operands[0]);
4050 break;
4051 }
4052 /* Try movi / mshflo.l w/ r63. */
4053 val2 = val + ((HOST_WIDE_INT) -1 << 32);
735cb76e 4054 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
c1b92d09
R
4055 {
4056 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4057 GEN_INT (0));
4058 break;
4059 }
4060 }
4061 val2 = high;
4062 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4063 }
4064 while (0);
4065 operands[2] = GEN_INT (val2);
fa5322fa
AO
4066}")
4067
4068(define_split
e69d1422
R
4069 [(set (match_operand:DI 0 "arith_reg_operand" "")
4070 (match_operand:DI 1 "immediate_operand" ""))]
fa5322fa
AO
4071 "TARGET_SHMEDIA && reload_completed
4072 && GET_CODE (operands[1]) == CONST_DOUBLE"
4073 [(set (match_dup 0) (match_dup 2))
4074 (set (match_dup 0)
4075 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4076 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4077 "
4078{
4079 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4080 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4081 unsigned HOST_WIDE_INT val = low;
4082 unsigned HOST_WIDE_INT sign;
4083
4084 /* Sign-extend the 16 least-significant bits. */
4085 val &= 0xffff;
4086 val ^= 0x8000;
4087 val -= 0x8000;
4088 operands[1] = GEN_INT (val);
4089
4090 /* Arithmetic shift right the double-word by 16 bits. */
4091 low >>= 16;
4092 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4093 high >>= 16;
4094 sign = 1;
4095 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4096 high ^= sign;
4097 high -= sign;
4098
4099 /* This will only be true if high is a sign-extension of low, i.e.,
4100 it must be either 0 or (unsigned)-1, and be zero iff the
4101 most-significant bit of low is set. */
4102 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4103 operands[2] = GEN_INT (low);
4104 else
4105 operands[2] = immed_double_const (low, high, DImode);
4106}")
4107
c1b92d09 4108(define_insn "shori_media"
fa5322fa
AO
4109 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4110 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4111 (const_int 16))
4112 (zero_extend:DI
4113 (truncate:HI
735cb76e 4114 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
fa5322fa
AO
4115 "TARGET_SHMEDIA"
4116 "@
4117 shori %u2, %0
2ad65b0e
SC
4118 #"
4119 [(set_attr "type" "arith_media,*")])
fa5322fa 4120
bc45ade3 4121(define_expand "movdi"
961c4780
SC
4122 [(set (match_operand:DI 0 "general_movdst_operand" "")
4123 (match_operand:DI 1 "general_movsrc_operand" ""))]
bc45ade3 4124 ""
a6f463a0 4125 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
ffae286a 4126
fa5322fa
AO
4127(define_insn "movdf_media"
4128 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 4129 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
4130 "TARGET_SHMEDIA_FPU
4131 && (register_operand (operands[0], DFmode)
d9da94a1 4132 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4133 "@
4134 fmov.d %1, %0
0ac78517 4135 fmov.qd %N1, %0
fa5322fa
AO
4136 fmov.dq %1, %0
4137 add %1, r63, %0
4138 #
4139 fld%M1.d %m1, %0
4140 fst%M0.d %m0, %1
4141 ld%M1.q %m1, %0
d9da94a1 4142 st%M0.q %m0, %N1"
2ad65b0e 4143 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4144
4145(define_insn "movdf_media_nofpu"
4146 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 4147 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
4148 "TARGET_SHMEDIA
4149 && (register_operand (operands[0], DFmode)
d9da94a1 4150 || sh_register_operand (operands[1], DFmode))"
fa5322fa
AO
4151 "@
4152 add %1, r63, %0
4153 #
4154 ld%M1.q %m1, %0
d9da94a1 4155 st%M0.q %m0, %N1"
2ad65b0e 4156 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4157
4158(define_split
4159 [(set (match_operand:DF 0 "arith_reg_operand" "")
4160 (match_operand:DF 1 "immediate_operand" ""))]
4161 "TARGET_SHMEDIA && reload_completed"
4162 [(set (match_dup 3) (match_dup 2))]
4163 "
4164{
4165 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4166 long values[2];
4167 REAL_VALUE_TYPE value;
4168
4169 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4170 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4171
4172 if (HOST_BITS_PER_WIDE_INT >= 64)
4173 operands[2] = immed_double_const ((unsigned long) values[endian]
4174 | ((HOST_WIDE_INT) values[1 - endian]
4175 << 32), 0, DImode);
4176 else if (HOST_BITS_PER_WIDE_INT == 32)
4177 operands[2] = immed_double_const (values[endian], values[1 - endian],
4178 DImode);
4179 else
4180 abort ();
4181
4182 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4183}")
4184
ffae286a 4185;; ??? This should be a define expand.
bc45ade3 4186
bc45ade3 4187(define_insn "movdf_k"
3e943b59
JR
4188 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4189 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
fa5322fa
AO
4190 "TARGET_SH1
4191 && (! TARGET_SH4 || reload_completed
4192 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4193 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4194 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
225e4f43
R
4195 && (arith_reg_operand (operands[0], DFmode)
4196 || arith_reg_operand (operands[1], DFmode))"
0d7e008e 4197 "* return output_movedouble (insn, operands, DFmode);"
b9654711 4198 [(set_attr "length" "4")
3e943b59 4199 (set_attr "type" "move,pcload,load,store")])
bc45ade3 4200
225e4f43
R
4201;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4202;; However, the d/F/c/z alternative cannot be split directly; it is converted
4203;; with special code in machine_dependent_reorg into a load of the R0_REG and
4204;; the d/m/c/X alternative, which is split later into single-precision
4205;; instructions. And when not optimizing, no splits are done before fixing
4206;; up pcloads, so we need usable length information for that.
4207(define_insn "movdf_i4"
4208 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4209 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4210 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4211 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4212 "TARGET_SH4
4213 && (arith_reg_operand (operands[0], DFmode)
4214 || arith_reg_operand (operands[1], DFmode))"
4215 "@
4216 fmov %1,%0
4217 #
4218 #
4219 fmov.d %1,%0
4220 fmov.d %1,%0
4221 #
4222 #
4223 #
4224 #
4225 #"
4226 [(set_attr_alternative "length"
4227 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4228 (const_int 4)
4229 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4230 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4231 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4232 (const_int 4)
4233 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
fa5322fa
AO
4234 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4235 ;; increment or decrement r15 explicitly.
4236 (if_then_else
4237 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4238 (const_int 10) (const_int 8))
4239 (if_then_else
4240 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4241 (const_int 10) (const_int 8))])
c49439f1
R
4242 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4243 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
d64264ff
R
4244 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4245 (const_string "double")
4246 (const_string "none")))])
225e4f43
R
4247
4248;; Moving DFmode between fp/general registers through memory
4249;; (the top of the stack) is faster than moving through fpul even for
4250;; little endian. Because the type of an instruction is important for its
4251;; scheduling, it is beneficial to split these operations, rather than
4252;; emitting them in one single chunk, even if this will expose a stack
4253;; use that will prevent scheduling of other stack accesses beyond this
4254;; instruction.
4255(define_split
4256 [(set (match_operand:DF 0 "register_operand" "")
4257 (match_operand:DF 1 "register_operand" ""))
e69d1422 4258 (use (match_operand:PSI 2 "fpscr_operand" ""))
225e4f43
R
4259 (clobber (match_scratch:SI 3 "=X"))]
4260 "TARGET_SH4 && reload_completed
4261 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4262 [(const_int 0)]
4263 "
4264{
4265 rtx insn, tos;
4266
fa5322fa
AO
4267 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4268 {
4269 emit_move_insn (stack_pointer_rtx,
4270 plus_constant (stack_pointer_rtx, -8));
4271 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4272 }
4273 else
4274 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
225e4f43 4275 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
fa5322fa
AO
4276 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4277 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4278 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4279 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4280 else
4281 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
225e4f43 4282 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
fa5322fa
AO
4283 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4284 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4285 else
4286 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
225e4f43
R
4287 DONE;
4288}")
4289
4290;; local-alloc sometimes allocates scratch registers even when not required,
4291;; so we must be prepared to handle these.
4292
4293;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4294(define_split
4295 [(set (match_operand:DF 0 "general_movdst_operand" "")
4296 (match_operand:DF 1 "general_movsrc_operand" ""))
e69d1422
R
4297 (use (match_operand:PSI 2 "fpscr_operand" ""))
4298 (clobber (match_scratch:SI 3 ""))]
225e4f43
R
4299 "TARGET_SH4
4300 && reload_completed
4301 && true_regnum (operands[0]) < 16
4302 && true_regnum (operands[1]) < 16"
4303 [(set (match_dup 0) (match_dup 1))]
4304 "
4305{
4306 /* If this was a reg <-> mem operation with base + index reg addressing,
4307 we have to handle this in a special way. */
4308 rtx mem = operands[0];
4309 int store_p = 1;
4310 if (! memory_operand (mem, DFmode))
4311 {
4312 mem = operands[1];
4313 store_p = 0;
4314 }
ddef6bc7 4315 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
225e4f43
R
4316 mem = SUBREG_REG (mem);
4317 if (GET_CODE (mem) == MEM)
4318 {
4319 rtx addr = XEXP (mem, 0);
4320 if (GET_CODE (addr) == PLUS
4321 && GET_CODE (XEXP (addr, 0)) == REG
4322 && GET_CODE (XEXP (addr, 1)) == REG)
4323 {
4324 int offset;
4325 rtx reg0 = gen_rtx (REG, Pmode, 0);
4326 rtx regop = operands[store_p], word0 ,word1;
4327
4328 if (GET_CODE (regop) == SUBREG)
4dd8c093 4329 alter_subreg (&regop);
225e4f43
R
4330 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4331 offset = 2;
4332 else
4333 offset = 4;
4334 mem = copy_rtx (mem);
4335 PUT_MODE (mem, SImode);
4dd8c093
AO
4336 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4337 alter_subreg (&word0);
4338 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4339 alter_subreg (&word1);
18a7c2a7
AO
4340 if (store_p || ! refers_to_regno_p (REGNO (word0),
4341 REGNO (word0) + 1, addr, 0))
4342 {
4343 emit_insn (store_p
4344 ? gen_movsi_ie (mem, word0)
4345 : gen_movsi_ie (word0, mem));
4346 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4347 mem = copy_rtx (mem);
4348 emit_insn (store_p
4349 ? gen_movsi_ie (mem, word1)
4350 : gen_movsi_ie (word1, mem));
4351 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4352 }
4353 else
4354 {
4355 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4356 emit_insn (gen_movsi_ie (word1, mem));
4357 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4358 mem = copy_rtx (mem);
4359 emit_insn (gen_movsi_ie (word0, mem));
4360 }
225e4f43
R
4361 DONE;
4362 }
4363 }
4364}")
4365
4366;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4367(define_split
4368 [(set (match_operand:DF 0 "register_operand" "")
4369 (match_operand:DF 1 "memory_operand" ""))
e69d1422 4370 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4371 (clobber (reg:SI R0_REG))]
225e4f43
R
4372 "TARGET_SH4 && reload_completed"
4373 [(parallel [(set (match_dup 0) (match_dup 1))
4374 (use (match_dup 2))
4375 (clobber (scratch:SI))])]
4376 "")
4377
4378(define_expand "reload_indf"
4379 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4380 (match_operand:DF 1 "immediate_operand" "FQ"))
4773afa4 4381 (use (reg:PSI FPSCR_REG))
225e4f43 4382 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 4383 "TARGET_SH1"
225e4f43
R
4384 "")
4385
4386(define_expand "reload_outdf"
4387 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4388 (match_operand:DF 1 "register_operand" "af,r"))
4389 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
fa5322fa 4390 "TARGET_SH1"
225e4f43
R
4391 "")
4392
4393;; Simplify no-op moves.
4394(define_split
4395 [(set (match_operand:SF 0 "register_operand" "")
4396 (match_operand:SF 1 "register_operand" ""))
4397 (use (match_operand:PSI 2 "fpscr_operand" ""))
40779a72 4398 (clobber (match_scratch:SI 3 ""))]
3a8699c7 4399 "TARGET_SH2E && reload_completed
225e4f43
R
4400 && true_regnum (operands[0]) == true_regnum (operands[1])"
4401 [(set (match_dup 0) (match_dup 0))]
4402 "")
4403
4404;; fmovd substitute post-reload splits
4405(define_split
4406 [(set (match_operand:DF 0 "register_operand" "")
4407 (match_operand:DF 1 "register_operand" ""))
e69d1422 4408 (use (match_operand:PSI 2 "fpscr_operand" ""))
40779a72 4409 (clobber (match_scratch:SI 3 ""))]
225e4f43 4410 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b
AO
4411 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4412 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4413 [(const_int 0)]
4414 "
4415{
4416 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4417 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4418 gen_rtx (REG, SFmode, src), operands[2]));
4419 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4420 gen_rtx (REG, SFmode, src + 1), operands[2]));
4421 DONE;
4422}")
4423
4424(define_split
4425 [(set (match_operand:DF 0 "register_operand" "")
4426 (mem:DF (match_operand:SI 1 "register_operand" "")))
e69d1422
R
4427 (use (match_operand:PSI 2 "fpscr_operand" ""))
4428 (clobber (match_scratch:SI 3 ""))]
225e4f43 4429 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
b6c02328 4430 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
225e4f43
R
4431 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4432 [(const_int 0)]
4433 "
4434{
4435 int regno = true_regnum (operands[0]);
4436 rtx insn;
4437 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4438
4439 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4440 regno + !! TARGET_LITTLE_ENDIAN),
4441 mem2, operands[2]));
4442 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4443 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4444 regno + ! TARGET_LITTLE_ENDIAN),
4445 gen_rtx (MEM, SFmode, operands[1]),
4446 operands[2]));
4447 DONE;
4448}")
4449
4450(define_split
4451 [(set (match_operand:DF 0 "register_operand" "")
4452 (match_operand:DF 1 "memory_operand" ""))
e69d1422
R
4453 (use (match_operand:PSI 2 "fpscr_operand" ""))
4454 (clobber (match_scratch:SI 3 ""))]
225e4f43 4455 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4456 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
225e4f43
R
4457 [(const_int 0)]
4458 "
4459{
4460 int regno = true_regnum (operands[0]);
4461 rtx addr, insn, adjust = NULL_RTX;
4462 rtx mem2 = copy_rtx (operands[1]);
4463 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4464 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4465
4466 PUT_MODE (mem2, SFmode);
4467 operands[1] = copy_rtx (mem2);
4468 addr = XEXP (mem2, 0);
4469 if (GET_CODE (addr) != POST_INC)
4470 {
4471 /* If we have to modify the stack pointer, the value that we have
4472 read with post-increment might be modified by an interrupt,
4473 so write it back. */
4474 if (REGNO (addr) == STACK_POINTER_REGNUM)
4475 adjust = gen_push_e (reg0);
4476 else
4477 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4478 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4479 }
4480 addr = XEXP (addr, 0);
4481 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4482 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4483 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4484 if (adjust)
4485 emit_insn (adjust);
4486 else
4487 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4488 DONE;
4489}")
4490
4491(define_split
4492 [(set (match_operand:DF 0 "memory_operand" "")
4493 (match_operand:DF 1 "register_operand" ""))
e69d1422
R
4494 (use (match_operand:PSI 2 "fpscr_operand" ""))
4495 (clobber (match_scratch:SI 3 ""))]
225e4f43 4496 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
104ee20b 4497 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
225e4f43
R
4498 [(const_int 0)]
4499 "
4500{
4501 int regno = true_regnum (operands[1]);
4502 rtx insn, addr, adjust = NULL_RTX;
4503
4504 operands[0] = copy_rtx (operands[0]);
4505 PUT_MODE (operands[0], SFmode);
4506 insn = emit_insn (gen_movsf_ie (operands[0],
4507 gen_rtx (REG, SFmode,
4508 regno + ! TARGET_LITTLE_ENDIAN),
4509 operands[2]));
4510 operands[0] = copy_rtx (operands[0]);
4511 addr = XEXP (operands[0], 0);
4512 if (GET_CODE (addr) != PRE_DEC)
4513 {
4514 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4515 emit_insn_before (adjust, insn);
4516 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4517 }
4518 addr = XEXP (addr, 0);
4519 if (! adjust)
4520 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4521 insn = emit_insn (gen_movsf_ie (operands[0],
4522 gen_rtx (REG, SFmode,
4523 regno + !! TARGET_LITTLE_ENDIAN),
4524 operands[2]));
4525 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4526 DONE;
4527}")
4528
d0aae509 4529;; If the output is a register and the input is memory or a register, we have
52702ae1 4530;; to be careful and see which word needs to be loaded first.
07a45e5c 4531
8e87e161
SC
4532(define_split
4533 [(set (match_operand:DF 0 "general_movdst_operand" "")
4534 (match_operand:DF 1 "general_movsrc_operand" ""))]
fa5322fa 4535 "TARGET_SH1 && reload_completed"
8e87e161
SC
4536 [(set (match_dup 2) (match_dup 3))
4537 (set (match_dup 4) (match_dup 5))]
4538 "
d0aae509
RK
4539{
4540 int regno;
4541
4542 if ((GET_CODE (operands[0]) == MEM
4543 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4544 || (GET_CODE (operands[1]) == MEM
4545 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4546 FAIL;
4547
4548 if (GET_CODE (operands[0]) == REG)
4549 regno = REGNO (operands[0]);
4550 else if (GET_CODE (operands[0]) == SUBREG)
ddef6bc7 4551 regno = subreg_regno (operands[0]);
d0aae509
RK
4552 else if (GET_CODE (operands[0]) == MEM)
4553 regno = -1;
533f5e0f
KG
4554 else
4555 abort ();
d0aae509
RK
4556
4557 if (regno == -1
4558 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
4559 {
4560 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4561 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4562 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4563 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4564 }
4565 else
4566 {
4567 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4568 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4569 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4570 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4571 }
4572
4573 if (operands[2] == 0 || operands[3] == 0
4574 || operands[4] == 0 || operands[5] == 0)
4575 FAIL;
4576}")
4577
653bd7a6
JW
4578;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4579;; used only once, let combine add in the index again.
4580
4581(define_split
4582 [(set (match_operand:SI 0 "register_operand" "")
4583 (match_operand:SI 1 "" ""))
4584 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4585 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4586 [(use (reg:SI R0_REG))]
653bd7a6
JW
4587 "
4588{
4589 rtx addr, reg, const_int;
4590
4591 if (GET_CODE (operands[1]) != MEM)
4592 FAIL;
4593 addr = XEXP (operands[1], 0);
4594 if (GET_CODE (addr) != PLUS)
4595 FAIL;
4596 reg = XEXP (addr, 0);
4597 const_int = XEXP (addr, 1);
f295bdb5
AH
4598 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4599 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4600 FAIL;
4601 emit_move_insn (operands[2], const_int);
4602 emit_move_insn (operands[0],
4603 change_address (operands[1], VOIDmode,
c5c76735 4604 gen_rtx_PLUS (SImode, reg, operands[2])));
653bd7a6
JW
4605 DONE;
4606}")
4607
4608(define_split
4609 [(set (match_operand:SI 1 "" "")
4610 (match_operand:SI 0 "register_operand" ""))
4611 (clobber (match_operand 2 "register_operand" ""))]
fa5322fa 4612 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4773afa4 4613 [(use (reg:SI R0_REG))]
653bd7a6
JW
4614 "
4615{
4616 rtx addr, reg, const_int;
4617
4618 if (GET_CODE (operands[1]) != MEM)
4619 FAIL;
4620 addr = XEXP (operands[1], 0);
4621 if (GET_CODE (addr) != PLUS)
4622 FAIL;
4623 reg = XEXP (addr, 0);
4624 const_int = XEXP (addr, 1);
f295bdb5
AH
4625 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4626 && GET_CODE (const_int) == CONST_INT))
653bd7a6
JW
4627 FAIL;
4628 emit_move_insn (operands[2], const_int);
4629 emit_move_insn (change_address (operands[1], VOIDmode,
c5c76735 4630 gen_rtx_PLUS (SImode, reg, operands[2])),
653bd7a6
JW
4631 operands[0]);
4632 DONE;
4633}")
4634
bc45ade3 4635(define_expand "movdf"
0d7e008e
SC
4636 [(set (match_operand:DF 0 "general_movdst_operand" "")
4637 (match_operand:DF 1 "general_movsrc_operand" ""))]
bc45ade3 4638 ""
1245df60
R
4639 "
4640{
4641 if (prepare_move_operands (operands, DFmode)) DONE;
fa5322fa
AO
4642 if (TARGET_SHMEDIA)
4643 {
4644 if (TARGET_SHMEDIA_FPU)
4645 emit_insn (gen_movdf_media (operands[0], operands[1]));
4646 else
4647 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4648 DONE;
4649 }
225e4f43
R
4650 if (TARGET_SH4)
4651 {
4652 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
4653 DONE;
4654 }
1245df60
R
4655}")
4656
0ac78517
R
4657;;This is incompatible with the way gcc uses subregs.
4658;;(define_insn "movv2sf_i"
4659;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4660;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4661;; "TARGET_SHMEDIA_FPU
4662;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4663;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4664;; "@
4665;; #
4666;; fld%M1.p %m1, %0
4667;; fst%M0.p %m0, %1"
4668;; [(set_attr "type" "*,fload_media,fstore_media")])
4669
4670(define_insn_and_split "movv2sf_i"
4671 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
735cb76e 4672 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
0ac78517
R
4673 "TARGET_SHMEDIA_FPU"
4674 "#"
4675 "TARGET_SHMEDIA_FPU && reload_completed"
4676 [(set (match_dup 0) (match_dup 1))]
4677 "
4678{
4679 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4680 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4681}")
fa5322fa
AO
4682
4683(define_expand "movv2sf"
0ac78517
R
4684 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4685 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
fa5322fa
AO
4686 "TARGET_SHMEDIA_FPU"
4687 "
4688{
4689 if (prepare_move_operands (operands, V2SFmode))
4690 DONE;
4691}")
4692
0ac78517
R
4693(define_expand "addv2sf3"
4694 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4695 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4696 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4697 "TARGET_SHMEDIA_FPU"
4698 "
4699{
4700 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4701 DONE;
4702}")
4703
4704(define_expand "subv2sf3"
4705 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4706 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4707 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4708 "TARGET_SHMEDIA_FPU"
4709 "
4710{
4711 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4712 DONE;
4713}")
4714
4715(define_expand "mulv2sf3"
4716 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4717 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4718 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4719 "TARGET_SHMEDIA_FPU"
4720 "
4721{
4722 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4723 DONE;
4724}")
4725
4726(define_expand "divv2sf3"
4727 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4728 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4729 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4730 "TARGET_SHMEDIA_FPU"
4731 "
4732{
4733 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4734 DONE;
4735}")
4736
fa5322fa
AO
4737(define_insn_and_split "*movv4sf_i"
4738 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
735cb76e 4739 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
fa5322fa
AO
4740 "TARGET_SHMEDIA_FPU"
4741 "#"
4742 "&& reload_completed"
4743 [(const_int 0)]
4744 "
4745{
4746 int i;
4747
4748 for (i = 0; i < 4/2; i++)
4749 {
4750 rtx x, y;
4751
4752 if (GET_CODE (operands[0]) == MEM)
4753 x = gen_rtx_MEM (V2SFmode,
4754 plus_constant (XEXP (operands[0], 0),
4755 i * GET_MODE_SIZE (V2SFmode)));
4756 else
0ac78517 4757 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
fa5322fa
AO
4758
4759 if (GET_CODE (operands[1]) == MEM)
4760 y = gen_rtx_MEM (V2SFmode,
4761 plus_constant (XEXP (operands[1], 0),
4762 i * GET_MODE_SIZE (V2SFmode)));
4763 else
0ac78517 4764 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
fa5322fa
AO
4765
4766 emit_insn (gen_movv2sf_i (x, y));
4767 }
4768
4769 DONE;
4770}"
4771 [(set_attr "length" "8")])
52702ae1 4772
fa5322fa 4773(define_expand "movv4sf"
0ac78517
R
4774 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4775 (match_operand:V4SF 1 "general_operand" ""))]
fa5322fa
AO
4776 "TARGET_SHMEDIA_FPU"
4777 "
4778{
4779 if (prepare_move_operands (operands, V4SFmode))
4780 DONE;
4781}")
4782
4783(define_insn_and_split "*movv16sf_i"
4784 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4785 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4786 "TARGET_SHMEDIA_FPU"
4787 "#"
4788 "&& reload_completed"
4789 [(const_int 0)]
4790 "
4791{
4792 int i;
4793
4794 for (i = 0; i < 16/2; i++)
4795 {
4796 rtx x,y;
4797
4798 if (GET_CODE (operands[0]) == MEM)
4799 x = gen_rtx_MEM (V2SFmode,
4800 plus_constant (XEXP (operands[0], 0),
4801 i * GET_MODE_SIZE (V2SFmode)));
4802 else
4803 {
40779a72 4804 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
fa5322fa
AO
4805 alter_subreg (&x);
4806 }
4807
4808 if (GET_CODE (operands[1]) == MEM)
4809 y = gen_rtx_MEM (V2SFmode,
4810 plus_constant (XEXP (operands[1], 0),
4811 i * GET_MODE_SIZE (V2SFmode)));
4812 else
4813 {
40779a72 4814 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
fa5322fa
AO
4815 alter_subreg (&y);
4816 }
4817
4818 emit_insn (gen_movv2sf_i (x, y));
4819 }
4820
4821 DONE;
4822}"
4823 [(set_attr "length" "32")])
52702ae1 4824
fa5322fa
AO
4825(define_expand "movv16sf"
4826 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4827 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4828 "TARGET_SHMEDIA_FPU"
4829 "
4830{
4831 if (prepare_move_operands (operands, V16SFmode))
4832 DONE;
4833}")
4834
4835(define_insn "movsf_media"
4836 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
735cb76e 4837 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
fa5322fa
AO
4838 "TARGET_SHMEDIA_FPU
4839 && (register_operand (operands[0], SFmode)
d9da94a1 4840 || sh_register_operand (operands[1], SFmode))"
fa5322fa
AO
4841 "@
4842 fmov.s %1, %0
0ac78517 4843 fmov.ls %N1, %0
fa5322fa 4844 fmov.sl %1, %0
b6d33983 4845 add.l %1, r63, %0
fa5322fa
AO
4846 #
4847 fld%M1.s %m1, %0
4848 fst%M0.s %m0, %1
4849 ld%M1.l %m1, %0
d9da94a1 4850 st%M0.l %m0, %N1"
b6d33983 4851 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
fa5322fa
AO
4852
4853(define_insn "movsf_media_nofpu"
4854 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
735cb76e 4855 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
fa5322fa
AO
4856 "TARGET_SHMEDIA
4857 && (register_operand (operands[0], SFmode)
d9da94a1 4858 || sh_register_operand (operands[1], SFmode))"
fa5322fa 4859 "@
b6d33983 4860 add.l %1, r63, %0
fa5322fa
AO
4861 #
4862 ld%M1.l %m1, %0
d9da94a1 4863 st%M0.l %m0, %N1"
b6d33983 4864 [(set_attr "type" "arith_media,*,load_media,store_media")])
fa5322fa
AO
4865
4866(define_split
4867 [(set (match_operand:SF 0 "arith_reg_operand" "")
4868 (match_operand:SF 1 "immediate_operand" ""))]
0ac78517
R
4869 "TARGET_SHMEDIA && reload_completed
4870 && ! FP_REGISTER_P (true_regnum (operands[0]))"
fa5322fa
AO
4871 [(set (match_dup 3) (match_dup 2))]
4872 "
4873{
4874 long values;
4875 REAL_VALUE_TYPE value;
4876
4877 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4878 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4879 operands[2] = GEN_INT (values);
52702ae1 4880
fa5322fa
AO
4881 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4882}")
bc45ade3 4883
bc45ade3 4884(define_insn "movsf_i"
3e943b59 4885 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
735cb76e 4886 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
fa5322fa 4887 "TARGET_SH1
3a8699c7 4888 && (! TARGET_SH2E
fa5322fa
AO
4889 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4890 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4891 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
1245df60
R
4892 && (arith_reg_operand (operands[0], SFmode)
4893 || arith_reg_operand (operands[1], SFmode))"
bc45ade3
SC
4894 "@
4895 mov %1,%0
735cb76e 4896 mov #0,%0
bc45ade3
SC
4897 mov.l %1,%0
4898 mov.l %1,%0
3e943b59 4899 mov.l %1,%0
b9654711 4900 lds %1,%0
0d7e008e 4901 sts %1,%0"
3e943b59 4902 [(set_attr "type" "move,move,pcload,load,store,move,move")])
bc45ade3 4903
4dff12bf
R
4904;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4905;; update_flow_info would not know where to put REG_EQUAL notes
4906;; when the destination changes mode.
45348d9e 4907(define_insn "movsf_ie"
7f74cc8d 4908 [(set (match_operand:SF 0 "general_movdst_operand"
a92facbb 4909 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
7f74cc8d 4910 (match_operand:SF 1 "general_movsrc_operand"
a92facbb
AO
4911 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4912 (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 4913 (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 4914
3a8699c7 4915 "TARGET_SH2E
45348d9e 4916 && (arith_reg_operand (operands[0], SFmode)
c2d10707
AO
4917 || arith_reg_operand (operands[1], SFmode)
4918 || arith_reg_operand (operands[3], SImode)
4919 || (fpul_operand (operands[0], SFmode)
4920 && memory_operand (operands[1], SFmode)
4921 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4922 || (fpul_operand (operands[1], SFmode)
4923 && memory_operand (operands[0], SFmode)
4924 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
45348d9e
JW
4925 "@
4926 fmov %1,%0
4927 mov %1,%0
4928 fldi0 %0
4929 fldi1 %0
7f74cc8d 4930 #
45348d9e
JW
4931 fmov.s %1,%0
4932 fmov.s %1,%0
4933 mov.l %1,%0
4934 mov.l %1,%0
3e943b59 4935 mov.l %1,%0
1245df60
R
4936 fsts fpul,%0
4937 flds %1,fpul
4938 lds.l %1,%0
4939 #
4dff12bf
R
4940 sts %1,%0
4941 lds %1,%0
a92facbb
AO
4942 sts.l %1,%0
4943 lds.l %1,%0
4dff12bf 4944 ! move optimized away"
c49439f1
R
4945 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4946 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
a92facbb 4947 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
d64264ff
R
4948 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4949 (const_string "single")
4950 (const_string "none")))])
79664856 4951
1245df60
R
4952(define_split
4953 [(set (match_operand:SF 0 "register_operand" "")
4954 (match_operand:SF 1 "register_operand" ""))
e69d1422 4955 (use (match_operand:PSI 2 "fpscr_operand" ""))
4773afa4 4956 (clobber (reg:SI FPUL_REG))]
fa5322fa 4957 "TARGET_SH1"
4773afa4 4958 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
225e4f43 4959 (use (match_dup 2))
1245df60 4960 (clobber (scratch:SI))])
4773afa4 4961 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
225e4f43 4962 (use (match_dup 2))
1245df60
R
4963 (clobber (scratch:SI))])]
4964 "")
4965
bc45ade3 4966(define_expand "movsf"
0d7e008e 4967 [(set (match_operand:SF 0 "general_movdst_operand" "")
3e943b59 4968 (match_operand:SF 1 "general_movsrc_operand" ""))]
bc45ade3 4969 ""
3e943b59
JR
4970 "
4971{
4972 if (prepare_move_operands (operands, SFmode))
4973 DONE;
fa5322fa
AO
4974 if (TARGET_SHMEDIA)
4975 {
4976 if (TARGET_SHMEDIA_FPU)
4977 emit_insn (gen_movsf_media (operands[0], operands[1]));
4978 else
4979 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4980 DONE;
4981 }
3a8699c7 4982 if (TARGET_SH2E)
3e943b59 4983 {
225e4f43 4984 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
3e943b59
JR
4985 DONE;
4986 }
4987}")
7f74cc8d 4988
225e4f43 4989(define_insn "mov_nop"
e69d1422 4990 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
3a8699c7 4991 "TARGET_SH2E"
225e4f43
R
4992 ""
4993 [(set_attr "length" "0")
4994 (set_attr "type" "nil")])
4995
7f74cc8d 4996(define_expand "reload_insf"
c2d10707 4997 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
7f74cc8d 4998 (match_operand:SF 1 "immediate_operand" "FQ"))
4773afa4 4999 (use (reg:PSI FPSCR_REG))
7f74cc8d 5000 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 5001 "TARGET_SH1"
7f74cc8d 5002 "")
225e4f43
R
5003
5004(define_expand "reload_insi"
5005 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5006 (match_operand:SF 1 "immediate_operand" "FQ"))
5007 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
fa5322fa 5008 "TARGET_SH1"
225e4f43
R
5009 "")
5010
5011(define_insn "*movsi_y"
5012 [(set (match_operand:SI 0 "register_operand" "=y,y")
735cb76e 5013 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
c77e04ae 5014 (clobber (match_scratch:SI 2 "=&z,r"))]
3a8699c7 5015 "TARGET_SH2E
225e4f43
R
5016 && (reload_in_progress || reload_completed)"
5017 "#"
5018 [(set_attr "length" "4")
5019 (set_attr "type" "pcload,move")])
5020
5021(define_split
997718c7
RH
5022 [(set (match_operand:SI 0 "register_operand" "")
5023 (match_operand:SI 1 "immediate_operand" ""))
5024 (clobber (match_operand:SI 2 "register_operand" ""))]
fa5322fa 5025 "TARGET_SH1"
225e4f43
R
5026 [(set (match_dup 2) (match_dup 1))
5027 (set (match_dup 0) (match_dup 2))]
5028 "")
5029
5030(define_split
997718c7
RH
5031 [(set (match_operand:SI 0 "register_operand" "")
5032 (match_operand:SI 1 "memory_operand" ""))
4773afa4 5033 (clobber (reg:SI R0_REG))]
fa5322fa 5034 "TARGET_SH1"
225e4f43
R
5035 [(set (match_dup 0) (match_dup 1))]
5036 "")
bc45ade3
SC
5037\f
5038;; ------------------------------------------------------------------------
5039;; Define the real conditional branch instructions.
5040;; ------------------------------------------------------------------------
5041
5042(define_insn "branch_true"
4773afa4 5043 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5044 (label_ref (match_operand 0 "" ""))
5045 (pc)))]
fa5322fa 5046 "TARGET_SH1"
51aea58d 5047 "* return output_branch (1, insn, operands);"
bc45ade3
SC
5048 [(set_attr "type" "cbranch")])
5049
5050(define_insn "branch_false"
4773afa4 5051 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5052 (label_ref (match_operand 0 "" ""))
5053 (pc)))]
fa5322fa 5054 "TARGET_SH1"
51aea58d 5055 "* return output_branch (0, insn, operands);"
bc45ade3
SC
5056 [(set_attr "type" "cbranch")])
5057
1245df60
R
5058;; Patterns to prevent reorg from re-combining a condbranch with a branch
5059;; which destination is too far away.
5060;; The const_int_operand is distinct for each branch target; it avoids
5061;; unwanted matches with redundant_insn.
5062(define_insn "block_branch_redirect"
e11cddec 5063 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
fa5322fa 5064 "TARGET_SH1"
1245df60
R
5065 ""
5066 [(set_attr "length" "0")])
bc45ade3 5067
1245df60
R
5068;; This one has the additional purpose to record a possible scratch register
5069;; for the following branch.
10f4f635
R
5070;; ??? Unfortunately, just setting the scratch register is not good enough,
5071;; because the insn then might be deemed dead and deleted. And we can't
5072;; make the use in the jump insn explicit because that would disable
5073;; delay slot scheduling from the target.
1245df60 5074(define_insn "indirect_jump_scratch"
e69d1422 5075 [(set (match_operand:SI 0 "register_operand" "=r")
73774972 5076 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
10f4f635 5077 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
fa5322fa 5078 "TARGET_SH1"
1245df60
R
5079 ""
5080 [(set_attr "length" "0")])
c608a684
R
5081
5082;; This one is used to preemt an insn from beyond the bra / braf / jmp
5083;; being pulled into the delay slot of a condbranch that has been made to
5084;; jump around the unconditional jump because it was out of range.
5085(define_insn "stuff_delay_slot"
5086 [(set (pc)
5087 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5088 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5089 "TARGET_SH1"
5090 ""
5091 [(set_attr "length" "0")
5092 (set_attr "cond_delay_slot" "yes")])
bc45ade3
SC
5093\f
5094;; Conditional branch insns
5095
fa5322fa 5096(define_expand "beq_media"
1245df60 5097 [(set (pc)
fa5322fa 5098 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5099 (match_operand:DI 2 "arith_operand" "r,I06"))
fa5322fa 5100 (label_ref:DI (match_operand 0 "" ""))
bc45ade3 5101 (pc)))]
fa5322fa
AO
5102 "TARGET_SHMEDIA"
5103 "")
bc45ade3 5104
c8cc4417 5105(define_insn "*beq_media_i"
1245df60 5106 [(set (pc)
c8cc4417
R
5107 (if_then_else (match_operator 3 "equality_comparison_operator"
5108 [(match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5109 (match_operand:DI 2 "arith_operand" "r,I06")])
fa5322fa 5110 (match_operand:DI 0 "target_operand" "b,b")
1245df60 5111 (pc)))]
fa5322fa
AO
5112 "TARGET_SHMEDIA"
5113 "@
c8cc4417
R
5114 b%o3%' %1, %2, %0
5115 b%o3i%' %1, %2, %0"
5116 [(set_attr "type" "cbranch_media")])
bc45ade3 5117
fa5322fa 5118(define_expand "bne_media"
1245df60 5119 [(set (pc)
fa5322fa 5120 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
735cb76e 5121 (match_operand:DI 2 "arith_operand" "r,I06"))
fa5322fa 5122 (label_ref:DI (match_operand 0 "" ""))
ffae286a 5123 (pc)))]
fa5322fa
AO
5124 "TARGET_SHMEDIA"
5125 "")
bc45ade3 5126
fa5322fa 5127(define_expand "bgt_media"
1245df60 5128 [(set (pc)
b6d33983
R
5129 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5130 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa 5131 (label_ref:DI (match_operand 0 "" ""))
1245df60 5132 (pc)))]
fa5322fa
AO
5133 "TARGET_SHMEDIA"
5134 "")
5135
fa5322fa
AO
5136(define_expand "bge_media"
5137 [(set (pc)
b6d33983
R
5138 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5139 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5140 (label_ref:DI (match_operand 0 "" ""))
5141 (pc)))]
5142 "TARGET_SHMEDIA"
5143 "")
5144
fa5322fa
AO
5145(define_expand "bgtu_media"
5146 [(set (pc)
b6d33983
R
5147 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5148 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5149 (label_ref:DI (match_operand 0 "" ""))
5150 (pc)))]
5151 "TARGET_SHMEDIA"
5152 "")
5153
fa5322fa
AO
5154(define_expand "bgeu_media"
5155 [(set (pc)
b6d33983
R
5156 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5157 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
fa5322fa
AO
5158 (label_ref:DI (match_operand 0 "" ""))
5159 (pc)))]
5160 "TARGET_SHMEDIA"
5161 "")
5162
c8cc4417 5163(define_insn "*bgt_media_i"
fa5322fa 5164 [(set (pc)
c8cc4417
R
5165 (if_then_else (match_operator 3 "greater_comparison_operator"
5166 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5167 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5168 (match_operand:DI 0 "target_operand" "b")
5169 (pc)))]
5170 "TARGET_SHMEDIA"
c8cc4417
R
5171 "b%o3%' %N1, %N2, %0"
5172 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5173
5174;; These are only needed to make invert_jump() happy.
b6d33983 5175(define_insn "*blt_media_i"
fa5322fa 5176 [(set (pc)
c8cc4417 5177 (if_then_else (match_operator 3 "less_comparison_operator"
b6d33983
R
5178 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5179 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
fa5322fa
AO
5180 (match_operand:DI 0 "target_operand" "b")
5181 (pc)))]
5182 "TARGET_SHMEDIA"
c8cc4417
R
5183 "b%o3%' %N2, %N1, %0"
5184 [(set_attr "type" "cbranch_media")])
fa5322fa
AO
5185
5186(define_expand "beq"
5187 [(set (pc)
5188 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5189 (label_ref (match_operand 0 "" ""))
5190 (pc)))]
5191 ""
5192 "
5193{
5194 if (TARGET_SHMEDIA)
5195 {
5196 if (GET_MODE (sh_compare_op0) != DImode)
5197 {
5198 rtx tmp = gen_reg_rtx (DImode);
5199
5200 emit_insn (gen_seq (tmp));
5201 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5202 DONE;
5203 }
5204
5205 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5206 emit_jump_insn (gen_beq_media (operands[0],
5207 sh_compare_op0, sh_compare_op1));
5208 DONE;
5209 }
5210
5211 from_compare (operands, EQ);
5212}")
5213
5214(define_expand "bne"
5215 [(set (pc)
5216 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5217 (label_ref (match_operand 0 "" ""))
5218 (pc)))]
5219 ""
5220 "
5221{
5222 if (TARGET_SHMEDIA)
5223 {
5224 if (GET_MODE (sh_compare_op0) != DImode)
5225 {
5226 rtx tmp = gen_reg_rtx (DImode);
5227
5228 emit_insn (gen_seq (tmp));
5229 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5230 DONE;
5231 }
5232
5233 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5234 emit_jump_insn (gen_bne_media (operands[0],
5235 sh_compare_op0, sh_compare_op1));
5236 DONE;
5237 }
5238
5239 from_compare (operands, EQ);
5240}")
5241
5242(define_expand "bgt"
5243 [(set (pc)
5244 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5245 (label_ref (match_operand 0 "" ""))
5246 (pc)))]
5247 ""
5248 "
5249{
5250 if (TARGET_SHMEDIA)
5251 {
5252 if (GET_MODE (sh_compare_op0) != DImode)
5253 {
5254 rtx tmp = gen_reg_rtx (DImode);
5255
5256 emit_insn (gen_sgt (tmp));
5257 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5258 DONE;
5259 }
5260
c8cc4417
R
5261 if (sh_compare_op0 != const0_rtx)
5262 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5263 if (sh_compare_op1 != const0_rtx)
5264 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5265 emit_jump_insn (gen_bgt_media (operands[0],
5266 sh_compare_op0, sh_compare_op1));
5267 DONE;
5268 }
5269
5270 from_compare (operands, GT);
5271}")
5272
5273(define_expand "blt"
5274 [(set (pc)
5275 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5276 (label_ref (match_operand 0 "" ""))
5277 (pc)))]
5278 ""
5279 "
5280{
5281 if (TARGET_SHMEDIA)
5282 {
5283 if (GET_MODE (sh_compare_op0) != DImode)
5284 {
5285 rtx tmp = gen_reg_rtx (DImode);
5286
5287 emit_insn (gen_slt (tmp));
5288 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5289 DONE;
5290 }
5291
c8cc4417
R
5292 if (sh_compare_op0 != const0_rtx)
5293 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5294 if (sh_compare_op1 != const0_rtx)
5295 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5296 emit_jump_insn (gen_bgt_media (operands[0],
5297 sh_compare_op1, sh_compare_op0));
5298 DONE;
5299 }
5300
5301 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5302 {
5303 rtx tmp = sh_compare_op0;
5304 sh_compare_op0 = sh_compare_op1;
5305 sh_compare_op1 = tmp;
5306 emit_insn (gen_bgt (operands[0]));
5307 DONE;
5308 }
5309 from_compare (operands, GE);
5310}")
5311
5312(define_expand "ble"
5313 [(set (pc)
5314 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5315 (label_ref (match_operand 0 "" ""))
5316 (pc)))]
5317 ""
5318 "
5319{
5320 if (TARGET_SHMEDIA)
5321 {
5322 if (GET_MODE (sh_compare_op0) != DImode)
5323 {
5324 rtx tmp = gen_reg_rtx (DImode);
5325
5326 emit_insn (gen_sle (tmp));
5327 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5328 DONE;
5329 }
5330
c8cc4417
R
5331 if (sh_compare_op0 != const0_rtx)
5332 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5333 if (sh_compare_op1 != const0_rtx)
5334 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5335 emit_jump_insn (gen_bge_media (operands[0],
5336 sh_compare_op1, sh_compare_op0));
5337 DONE;
5338 }
5339
3a8699c7 5340 if (TARGET_SH2E
fa5322fa 5341 && TARGET_IEEE
1245df60
R
5342 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5343 {
5344 rtx tmp = sh_compare_op0;
5345 sh_compare_op0 = sh_compare_op1;
5346 sh_compare_op1 = tmp;
5347 emit_insn (gen_bge (operands[0]));
5348 DONE;
5349 }
5350 from_compare (operands, GT);
5351}")
bc45ade3
SC
5352
5353(define_expand "bge"
1245df60 5354 [(set (pc)
4773afa4 5355 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5356 (label_ref (match_operand 0 "" ""))
ffae286a 5357 (pc)))]
bc45ade3 5358 ""
45348d9e
JW
5359 "
5360{
fa5322fa
AO
5361 if (TARGET_SHMEDIA)
5362 {
5363 if (GET_MODE (sh_compare_op0) != DImode)
5364 {
5365 rtx tmp = gen_reg_rtx (DImode);
5366
5367 emit_insn (gen_sge (tmp));
5368 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5369 DONE;
5370 }
5371
c8cc4417
R
5372 if (sh_compare_op0 != const0_rtx)
5373 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5374 if (sh_compare_op1 != const0_rtx)
5375 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5376 emit_jump_insn (gen_bge_media (operands[0],
5377 sh_compare_op0, sh_compare_op1));
5378 DONE;
5379 }
5380
3a8699c7 5381 if (TARGET_SH2E
1245df60
R
5382 && ! TARGET_IEEE
5383 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e
JW
5384 {
5385 rtx tmp = sh_compare_op0;
5386 sh_compare_op0 = sh_compare_op1;
5387 sh_compare_op1 = tmp;
5388 emit_insn (gen_ble (operands[0]));
5389 DONE;
5390 }
5391 from_compare (operands, GE);
5392}")
bc45ade3
SC
5393
5394(define_expand "bgtu"
1245df60 5395 [(set (pc)
4773afa4 5396 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3
SC
5397 (label_ref (match_operand 0 "" ""))
5398 (pc)))]
5399 ""
fa5322fa
AO
5400 "
5401{
5402 if (TARGET_SHMEDIA)
5403 {
c8cc4417
R
5404 if (sh_compare_op0 != const0_rtx)
5405 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5406 if (sh_compare_op1 != const0_rtx)
5407 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5408 emit_jump_insn (gen_bgtu_media (operands[0],
5409 sh_compare_op0, sh_compare_op1));
5410 DONE;
5411 }
5412
5413 from_compare (operands, GTU);
5414}")
bc45ade3
SC
5415
5416(define_expand "bltu"
1245df60 5417 [(set (pc)
4773afa4
AO
5418 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5419 (label_ref (match_operand 0 "" ""))
5420 (pc)))]
bc45ade3 5421 ""
fa5322fa
AO
5422 "
5423{
5424 if (TARGET_SHMEDIA)
5425 {
c8cc4417
R
5426 if (sh_compare_op0 != const0_rtx)
5427 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5428 if (sh_compare_op1 != const0_rtx)
5429 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5430 emit_jump_insn (gen_bgtu_media (operands[0],
5431 sh_compare_op1, sh_compare_op0));
5432 DONE;
5433 }
5434
5435 from_compare (operands, GEU);
5436}")
bc45ade3
SC
5437
5438(define_expand "bgeu"
1245df60 5439 [(set (pc)
4773afa4 5440 (if_then_else (ne (reg:SI T_REG) (const_int 0))
bc45ade3 5441 (label_ref (match_operand 0 "" ""))
ffae286a 5442 (pc)))]
bc45ade3 5443 ""
fa5322fa
AO
5444 "
5445{
5446 if (TARGET_SHMEDIA)
5447 {
c8cc4417
R
5448 if (sh_compare_op0 != const0_rtx)
5449 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5450 if (sh_compare_op1 != const0_rtx)
5451 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5452 emit_jump_insn (gen_bgeu_media (operands[0],
5453 sh_compare_op0, sh_compare_op1));
5454 DONE;
5455 }
5456
5457 from_compare (operands, GEU);
5458}")
bc45ade3
SC
5459
5460(define_expand "bleu"
1245df60 5461 [(set (pc)
4773afa4 5462 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1245df60
R
5463 (label_ref (match_operand 0 "" ""))
5464 (pc)))]
bc45ade3 5465 ""
fa5322fa
AO
5466 "
5467{
5468 if (TARGET_SHMEDIA)
5469 {
c8cc4417
R
5470 if (sh_compare_op0 != const0_rtx)
5471 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5472 if (sh_compare_op1 != const0_rtx)
5473 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
fa5322fa
AO
5474 emit_jump_insn (gen_bgeu_media (operands[0],
5475 sh_compare_op1, sh_compare_op0));
5476 DONE;
5477 }
5478
5479 from_compare (operands, GTU);
5480}")
5481
5482(define_expand "bunordered"
5483 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5484 (set (pc)
5485 (if_then_else (ne (match_dup 1) (const_int 0))
5486 (label_ref:DI (match_operand 0 "" ""))
5487 (pc)))]
5488 "TARGET_SHMEDIA"
5489 "
5490{
5491 operands[1] = gen_reg_rtx (DImode);
5492 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5493 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5494}")
bc45ade3
SC
5495\f
5496;; ------------------------------------------------------------------------
5497;; Jump and linkage insns
5498;; ------------------------------------------------------------------------
5499
fa5322fa 5500(define_insn "jump_compact"
bc45ade3
SC
5501 [(set (pc)
5502 (label_ref (match_operand 0 "" "")))]
fa5322fa 5503 "TARGET_SH1"
bc45ade3
SC
5504 "*
5505{
22e1ebf1 5506 /* The length is 16 if the delay slot is unfilled. */
1245df60 5507 if (get_attr_length(insn) > 4)
51aea58d 5508 return output_far_jump(insn, operands[0]);
bc45ade3 5509 else
51aea58d 5510 return \"bra %l0%#\";
bc45ade3
SC
5511}"
5512 [(set_attr "type" "jump")
5513 (set_attr "needs_delay_slot" "yes")])
5514
10f4f635
R
5515;; ??? It would be much saner to explicitly use the scratch register
5516;; in the jump insn, and have indirect_jump_scratch only set it,
5517;; but fill_simple_delay_slots would refuse to do delay slot filling
5518;; from the target then, as it uses simplejump_p.
5519;;(define_insn "jump_compact_far"
5520;; [(set (pc)
5521;; (label_ref (match_operand 0 "" "")))
5522;; (use (match_operand 1 "register_operand" "r")]
5523;; "TARGET_SH1"
5524;; "* return output_far_jump(insn, operands[0], operands[1]);"
5525;; [(set_attr "type" "jump")
5526;; (set_attr "needs_delay_slot" "yes")])
5527
fa5322fa
AO
5528(define_insn "jump_media"
5529 [(set (pc)
5530 (match_operand:DI 0 "target_operand" "b"))]
5531 "TARGET_SHMEDIA"
2ad65b0e
SC
5532 "blink %0, r63"
5533 [(set_attr "type" "jump_media")])
fa5322fa
AO
5534
5535(define_expand "jump"
5536 [(set (pc)
5537 (label_ref (match_operand 0 "" "")))]
5538 ""
5539 "
5540{
5541 if (TARGET_SH1)
8e831557 5542 emit_jump_insn (gen_jump_compact (operands[0]));
fa5322fa
AO
5543 else if (TARGET_SHMEDIA)
5544 {
5545 if (reload_in_progress || reload_completed)
5546 FAIL;
8e831557
KK
5547 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5548 operands[0])));
fa5322fa
AO
5549 }
5550 DONE;
5551}")
5552
5553(define_insn "force_mode_for_call"
5554 [(use (reg:PSI FPSCR_REG))]
5555 "TARGET_SHCOMPACT"
5556 ""
5557 [(set_attr "length" "0")
5558 (set (attr "fp_mode")
5559 (if_then_else (eq_attr "fpu_single" "yes")
5560 (const_string "single") (const_string "double")))])
5561
bc45ade3 5562(define_insn "calli"
aa684c94 5563 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
bc45ade3 5564 (match_operand 1 "" ""))
5d00b10a 5565 (use (reg:PSI FPSCR_REG))
4773afa4 5566 (clobber (reg:SI PR_REG))]
fa5322fa 5567 "TARGET_SH1"
bc45ade3 5568 "jsr @%0%#"
ffae286a 5569 [(set_attr "type" "call")
d64264ff
R
5570 (set (attr "fp_mode")
5571 (if_then_else (eq_attr "fpu_single" "yes")
5572 (const_string "single") (const_string "double")))
73774972
EC
5573 (set_attr "needs_delay_slot" "yes")
5574 (set_attr "fp_set" "unknown")])
961c4780 5575
1a66cd67
AO
5576;; This is a pc-rel call, using bsrf, for use with PIC.
5577
5578(define_insn "calli_pcrel"
5579 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5580 (match_operand 1 "" ""))
5d00b10a 5581 (use (reg:PSI FPSCR_REG))
2d01e445 5582 (use (reg:SI PIC_REG))
1a66cd67 5583 (use (match_operand 2 "" ""))
4773afa4 5584 (clobber (reg:SI PR_REG))]
eb69f95c 5585 "TARGET_SH2"
1a66cd67
AO
5586 "bsrf %0\\n%O2:%#"
5587 [(set_attr "type" "call")
5588 (set (attr "fp_mode")
5589 (if_then_else (eq_attr "fpu_single" "yes")
5590 (const_string "single") (const_string "double")))
73774972
EC
5591 (set_attr "needs_delay_slot" "yes")
5592 (set_attr "fp_set" "unknown")])
1a66cd67 5593
2d01e445
AO
5594(define_insn_and_split "call_pcrel"
5595 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5596 (match_operand 1 "" ""))
5597 (use (reg:PSI FPSCR_REG))
5598 (use (reg:SI PIC_REG))
5599 (clobber (reg:SI PR_REG))
5600 (clobber (match_scratch:SI 2 "=r"))]
cb51ecd2 5601 "TARGET_SH2"
2d01e445
AO
5602 "#"
5603 "reload_completed"
5604 [(const_int 0)]
5605 "
5606{
8e831557 5607 rtx lab = PATTERN (gen_call_site ());
2d01e445 5608
675ff4c7 5609 if (SYMBOL_REF_LOCAL_P (operands[0]))
2d01e445
AO
5610 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5611 else
5612 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5613 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5614 DONE;
5615}"
5616 [(set_attr "type" "call")
5617 (set (attr "fp_mode")
5618 (if_then_else (eq_attr "fpu_single" "yes")
5619 (const_string "single") (const_string "double")))
73774972
EC
5620 (set_attr "needs_delay_slot" "yes")
5621 (set_attr "fp_set" "unknown")])
2d01e445 5622
fa5322fa
AO
5623(define_insn "call_compact"
5624 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5625 (match_operand 1 "" ""))
5626 (match_operand 2 "immediate_operand" "n")
5627 (use (reg:SI R0_REG))
5628 (use (reg:SI R1_REG))
5629 (use (reg:PSI FPSCR_REG))
5630 (clobber (reg:SI PR_REG))]
5631 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5632 "jsr @%0%#"
5633 [(set_attr "type" "call")
5634 (set (attr "fp_mode")
5635 (if_then_else (eq_attr "fpu_single" "yes")
5636 (const_string "single") (const_string "double")))
5637 (set_attr "needs_delay_slot" "yes")])
5638
5639(define_insn "call_compact_rettramp"
5640 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5641 (match_operand 1 "" ""))
5642 (match_operand 2 "immediate_operand" "n")
5643 (use (reg:SI R0_REG))
5644 (use (reg:SI R1_REG))
5645 (use (reg:PSI FPSCR_REG))
5646 (clobber (reg:SI R10_REG))
5647 (clobber (reg:SI PR_REG))]
5648 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5649 "jsr @%0%#"
5650 [(set_attr "type" "call")
5651 (set (attr "fp_mode")
5652 (if_then_else (eq_attr "fpu_single" "yes")
5653 (const_string "single") (const_string "double")))
5654 (set_attr "needs_delay_slot" "yes")])
5655
5656(define_insn "call_media"
5657 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5658 (match_operand 1 "" ""))
5659 (clobber (reg:DI PR_MEDIA_REG))]
5660 "TARGET_SHMEDIA"
2ad65b0e
SC
5661 "blink %0, r18"
5662 [(set_attr "type" "jump_media")])
fa5322fa 5663
bc45ade3
SC
5664(define_insn "call_valuei"
5665 [(set (match_operand 0 "" "=rf")
aa684c94 5666 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
bc45ade3 5667 (match_operand 2 "" "")))
5d00b10a 5668 (use (reg:PSI FPSCR_REG))
4773afa4 5669 (clobber (reg:SI PR_REG))]
fa5322fa 5670 "TARGET_SH1"
bc45ade3 5671 "jsr @%1%#"
ffae286a 5672 [(set_attr "type" "call")
d64264ff
R
5673 (set (attr "fp_mode")
5674 (if_then_else (eq_attr "fpu_single" "yes")
5675 (const_string "single") (const_string "double")))
73774972
EC
5676 (set_attr "needs_delay_slot" "yes")
5677 (set_attr "fp_set" "unknown")])
bc45ade3 5678
1a66cd67
AO
5679(define_insn "call_valuei_pcrel"
5680 [(set (match_operand 0 "" "=rf")
5681 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5682 (match_operand 2 "" "")))
5d00b10a 5683 (use (reg:PSI FPSCR_REG))
2d01e445 5684 (use (reg:SI PIC_REG))
1a66cd67 5685 (use (match_operand 3 "" ""))
4773afa4 5686 (clobber (reg:SI PR_REG))]
eb69f95c 5687 "TARGET_SH2"
1a66cd67
AO
5688 "bsrf %1\\n%O3:%#"
5689 [(set_attr "type" "call")
5690 (set (attr "fp_mode")
5691 (if_then_else (eq_attr "fpu_single" "yes")
5692 (const_string "single") (const_string "double")))
73774972
EC
5693 (set_attr "needs_delay_slot" "yes")
5694 (set_attr "fp_set" "unknown")])
1a66cd67 5695
2d01e445
AO
5696(define_insn_and_split "call_value_pcrel"
5697 [(set (match_operand 0 "" "=rf")
5698 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5699 (match_operand 2 "" "")))
5700 (use (reg:PSI FPSCR_REG))
5701 (use (reg:SI PIC_REG))
5702 (clobber (reg:SI PR_REG))
5703 (clobber (match_scratch:SI 3 "=r"))]
cb51ecd2 5704 "TARGET_SH2"
2d01e445
AO
5705 "#"
5706 "reload_completed"
5707 [(const_int 0)]
5708 "
5709{
8e831557 5710 rtx lab = PATTERN (gen_call_site ());
2d01e445 5711
675ff4c7 5712 if (SYMBOL_REF_LOCAL_P (operands[1]))
2d01e445
AO
5713 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5714 else
5715 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5716 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5717 operands[2], lab));
5718 DONE;
5719}"
5720 [(set_attr "type" "call")
5721 (set (attr "fp_mode")
5722 (if_then_else (eq_attr "fpu_single" "yes")
5723 (const_string "single") (const_string "double")))
73774972
EC
5724 (set_attr "needs_delay_slot" "yes")
5725 (set_attr "fp_set" "unknown")])
2d01e445 5726
fa5322fa
AO
5727(define_insn "call_value_compact"
5728 [(set (match_operand 0 "" "=rf")
5729 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5730 (match_operand 2 "" "")))
5731 (match_operand 3 "immediate_operand" "n")
5732 (use (reg:SI R0_REG))
5733 (use (reg:SI R1_REG))
5734 (use (reg:PSI FPSCR_REG))
5735 (clobber (reg:SI PR_REG))]
5736 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5737 "jsr @%1%#"
5738 [(set_attr "type" "call")
5739 (set (attr "fp_mode")
5740 (if_then_else (eq_attr "fpu_single" "yes")
5741 (const_string "single") (const_string "double")))
5742 (set_attr "needs_delay_slot" "yes")])
5743
5744(define_insn "call_value_compact_rettramp"
5745 [(set (match_operand 0 "" "=rf")
5746 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5747 (match_operand 2 "" "")))
5748 (match_operand 3 "immediate_operand" "n")
5749 (use (reg:SI R0_REG))
5750 (use (reg:SI R1_REG))
5751 (use (reg:PSI FPSCR_REG))
5752 (clobber (reg:SI R10_REG))
5753 (clobber (reg:SI PR_REG))]
5754 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5755 "jsr @%1%#"
5756 [(set_attr "type" "call")
5757 (set (attr "fp_mode")
5758 (if_then_else (eq_attr "fpu_single" "yes")
5759 (const_string "single") (const_string "double")))
5760 (set_attr "needs_delay_slot" "yes")])
5761
5762(define_insn "call_value_media"
5763 [(set (match_operand 0 "" "=rf")
5764 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5765 (match_operand 2 "" "")))
5766 (clobber (reg:DI PR_MEDIA_REG))]
5767 "TARGET_SHMEDIA"
2ad65b0e
SC
5768 "blink %1, r18"
5769 [(set_attr "type" "jump_media")])
fa5322fa 5770
bc45ade3 5771(define_expand "call"
51aea58d
JW
5772 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5773 (match_operand 1 "" ""))
fa5322fa 5774 (match_operand 2 "" "")
5d00b10a 5775 (use (reg:PSI FPSCR_REG))
4773afa4 5776 (clobber (reg:SI PR_REG))])]
bc45ade3 5777 ""
1a66cd67 5778 "
827bdee4 5779{
fa5322fa
AO
5780 if (TARGET_SHMEDIA)
5781 {
5782 operands[0] = XEXP (operands[0], 0);
5783 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5784 {
675ff4c7 5785 if (! SYMBOL_REF_LOCAL_P (operands[0]))
fa5322fa
AO
5786 {
5787 rtx reg = gen_reg_rtx (Pmode);
52702ae1 5788
fa5322fa
AO
5789 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5790 operands[0] = reg;
5791 }
5792 else
5793 {
5794 operands[0] = gen_sym2PIC (operands[0]);
5795 PUT_MODE (operands[0], Pmode);
5796 }
5797 }
5798 if (GET_MODE (operands[0]) == SImode)
5799 {
5800 if (GET_CODE (operands[0]) == REG)
5801 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5802 else if (GET_CODE (operands[0]) == SUBREG)
5803 {
5804 operands[0] = SUBREG_REG (operands[0]);
5805 if (GET_MODE (operands[0]) != DImode)
5806 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5807 }
5808 else
5809 {
5810 operands[0] = shallow_copy_rtx (operands[0]);
5811 PUT_MODE (operands[0], DImode);
5812 }
5813 }
5814 if (! target_reg_operand (operands[0], DImode))
5815 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5816 emit_call_insn (gen_call_media (operands[0], operands[1]));
5817 DONE;
5818 }
5819 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5820 {
5821 rtx cookie_rtx = operands[2];
5822 long cookie = INTVAL (cookie_rtx);
5823 rtx func = XEXP (operands[0], 0);
5824 rtx r0, r1;
5825
5826 if (flag_pic)
5827 {
675ff4c7 5828 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
5829 {
5830 rtx reg = gen_reg_rtx (Pmode);
5831
5832 emit_insn (gen_symGOTPLT2reg (reg, func));
5833 func = reg;
5834 }
5835 else
5836 func = legitimize_pic_address (func, Pmode, 0);
5837 }
5838
5839 r0 = gen_rtx_REG (SImode, R0_REG);
5840 r1 = gen_rtx_REG (SImode, R1_REG);
5841
5842 /* Since such a call function may use all call-clobbered
5843 registers, we force a mode switch earlier, so that we don't
5844 run out of registers when adjusting fpscr for the call. */
5845 emit_insn (gen_force_mode_for_call ());
5846
90534361 5847 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
5848 if (flag_pic)
5849 {
5850 rtx reg = gen_reg_rtx (Pmode);
5851
5852 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5853 operands[0] = reg;
5854 }
5855 operands[0] = force_reg (SImode, operands[0]);
5856
5857 emit_move_insn (r0, func);
5858 emit_move_insn (r1, cookie_rtx);
5859
5860 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5861 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5862 operands[2]));
5863 else
5864 emit_call_insn (gen_call_compact (operands[0], operands[1],
5865 operands[2]));
5866
5867 DONE;
5868 }
5869 else if (TARGET_SHCOMPACT && flag_pic
5870 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 5871 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
5872 {
5873 rtx reg = gen_reg_rtx (Pmode);
5874
5875 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5876 XEXP (operands[0], 0) = reg;
5877 }
cb51ecd2 5878 if (flag_pic && TARGET_SH2
827bdee4
AO
5879 && GET_CODE (operands[0]) == MEM
5880 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5881 {
2d01e445 5882 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
827bdee4
AO
5883 DONE;
5884 }
5885 else
61f71b34 5886 {
827bdee4 5887 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
61f71b34
DD
5888 operands[1] = operands[2];
5889 }
fa5322fa
AO
5890
5891 emit_call_insn (gen_calli (operands[0], operands[1]));
5892 DONE;
5893}")
5894
5895(define_insn "call_pop_compact"
5896 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5897 (match_operand 1 "" ""))
5898 (match_operand 2 "immediate_operand" "n")
5899 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5900 (match_operand 3 "immediate_operand" "n")))
5901 (use (reg:SI R0_REG))
5902 (use (reg:SI R1_REG))
5903 (use (reg:PSI FPSCR_REG))
5904 (clobber (reg:SI PR_REG))]
5905 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5906 "jsr @%0%#"
5907 [(set_attr "type" "call")
5908 (set (attr "fp_mode")
5909 (if_then_else (eq_attr "fpu_single" "yes")
5910 (const_string "single") (const_string "double")))
5911 (set_attr "needs_delay_slot" "yes")])
5912
5913(define_insn "call_pop_compact_rettramp"
5914 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5915 (match_operand 1 "" ""))
5916 (match_operand 2 "immediate_operand" "n")
5917 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5918 (match_operand 3 "immediate_operand" "n")))
5919 (use (reg:SI R0_REG))
5920 (use (reg:SI R1_REG))
5921 (use (reg:PSI FPSCR_REG))
5922 (clobber (reg:SI R10_REG))
5923 (clobber (reg:SI PR_REG))]
5924 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5925 "jsr @%0%#"
5926 [(set_attr "type" "call")
5927 (set (attr "fp_mode")
5928 (if_then_else (eq_attr "fpu_single" "yes")
5929 (const_string "single") (const_string "double")))
5930 (set_attr "needs_delay_slot" "yes")])
5931
5932(define_expand "call_pop"
5933 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5934 (match_operand 1 "" ""))
5935 (match_operand 2 "" "")
5936 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5937 (match_operand 3 "" "")))])]
5938 "TARGET_SHCOMPACT"
5939 "
5940{
5941 if (operands[2] && INTVAL (operands[2]))
5942 {
5943 rtx cookie_rtx = operands[2];
5944 long cookie = INTVAL (cookie_rtx);
5945 rtx func = XEXP (operands[0], 0);
5946 rtx r0, r1;
5947
5948 if (flag_pic)
5949 {
675ff4c7 5950 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
5951 {
5952 rtx reg = gen_reg_rtx (Pmode);
5953
5954 emit_insn (gen_symGOTPLT2reg (reg, func));
5955 func = reg;
5956 }
5957 else
5958 func = legitimize_pic_address (func, Pmode, 0);
5959 }
5960
5961 r0 = gen_rtx_REG (SImode, R0_REG);
5962 r1 = gen_rtx_REG (SImode, R1_REG);
5963
5964 /* Since such a call function may use all call-clobbered
5965 registers, we force a mode switch earlier, so that we don't
5966 run out of registers when adjusting fpscr for the call. */
5967 emit_insn (gen_force_mode_for_call ());
5968
90534361 5969 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
5970 if (flag_pic)
5971 {
5972 rtx reg = gen_reg_rtx (Pmode);
5973
5974 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5975 operands[0] = reg;
5976 }
5977 operands[0] = force_reg (SImode, operands[0]);
5978
5979 emit_move_insn (r0, func);
5980 emit_move_insn (r1, cookie_rtx);
5981
5982 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5983 emit_call_insn (gen_call_pop_compact_rettramp
5984 (operands[0], operands[1], operands[2], operands[3]));
5985 else
5986 emit_call_insn (gen_call_pop_compact
5987 (operands[0], operands[1], operands[2], operands[3]));
5988
5989 DONE;
5990 }
5991
5992 abort ();
827bdee4 5993}")
bc45ade3
SC
5994
5995(define_expand "call_value"
51aea58d
JW
5996 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5997 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5998 (match_operand 2 "" "")))
fa5322fa 5999 (match_operand 3 "" "")
5d00b10a 6000 (use (reg:PSI FPSCR_REG))
4773afa4 6001 (clobber (reg:SI PR_REG))])]
bc45ade3 6002 ""
1a66cd67 6003 "
827bdee4 6004{
fa5322fa
AO
6005 if (TARGET_SHMEDIA)
6006 {
6007 operands[1] = XEXP (operands[1], 0);
6008 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6009 {
675ff4c7 6010 if (! SYMBOL_REF_LOCAL_P (operands[1]))
fa5322fa
AO
6011 {
6012 rtx reg = gen_reg_rtx (Pmode);
52702ae1 6013
fa5322fa
AO
6014 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6015 operands[1] = reg;
6016 }
6017 else
6018 {
6019 operands[1] = gen_sym2PIC (operands[1]);
6020 PUT_MODE (operands[1], Pmode);
6021 }
6022 }
6023 if (GET_MODE (operands[1]) == SImode)
6024 {
6025 if (GET_CODE (operands[1]) == REG)
6026 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6027 else if (GET_CODE (operands[1]) == SUBREG)
6028 {
6029 operands[1] = SUBREG_REG (operands[1]);
6030 if (GET_MODE (operands[1]) != DImode)
6031 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6032 }
6033 else
6034 {
6035 operands[1] = shallow_copy_rtx (operands[1]);
6036 PUT_MODE (operands[1], DImode);
6037 }
6038 }
6039 if (! target_reg_operand (operands[1], DImode))
6040 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6041 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6042 operands[2]));
6043 DONE;
6044 }
6045 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6046 {
6047 rtx cookie_rtx = operands[3];
6048 long cookie = INTVAL (cookie_rtx);
6049 rtx func = XEXP (operands[1], 0);
6050 rtx r0, r1;
6051
6052 if (flag_pic)
6053 {
675ff4c7 6054 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6055 {
6056 rtx reg = gen_reg_rtx (Pmode);
6057
6058 emit_insn (gen_symGOTPLT2reg (reg, func));
6059 func = reg;
6060 }
6061 else
6062 func = legitimize_pic_address (func, Pmode, 0);
6063 }
6064
6065 r0 = gen_rtx_REG (SImode, R0_REG);
6066 r1 = gen_rtx_REG (SImode, R1_REG);
6067
6068 /* Since such a call function may use all call-clobbered
6069 registers, we force a mode switch earlier, so that we don't
6070 run out of registers when adjusting fpscr for the call. */
6071 emit_insn (gen_force_mode_for_call ());
6072
90534361 6073 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6074 if (flag_pic)
6075 {
6076 rtx reg = gen_reg_rtx (Pmode);
6077
6078 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6079 operands[1] = reg;
6080 }
6081 operands[1] = force_reg (SImode, operands[1]);
6082
6083 emit_move_insn (r0, func);
6084 emit_move_insn (r1, cookie_rtx);
6085
6086 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6087 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6088 operands[1],
6089 operands[2],
6090 operands[3]));
6091 else
6092 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6093 operands[2], operands[3]));
6094
6095 DONE;
6096 }
6097 else if (TARGET_SHCOMPACT && flag_pic
6098 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
675ff4c7 6099 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
fa5322fa
AO
6100 {
6101 rtx reg = gen_reg_rtx (Pmode);
6102
6103 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6104 XEXP (operands[1], 0) = reg;
6105 }
cb51ecd2 6106 if (flag_pic && TARGET_SH2
827bdee4
AO
6107 && GET_CODE (operands[1]) == MEM
6108 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6109 {
2d01e445
AO
6110 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6111 operands[2]));
827bdee4
AO
6112 DONE;
6113 }
6114 else
6115 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
fa5322fa
AO
6116
6117 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6118 DONE;
827bdee4 6119}")
bc45ade3 6120
5db5a888 6121(define_insn "sibcalli"
cb51ecd2 6122 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5db5a888
AO
6123 (match_operand 1 "" ""))
6124 (use (reg:PSI FPSCR_REG))
6125 (return)]
fa5322fa 6126 "TARGET_SH1"
5db5a888
AO
6127 "jmp @%0%#"
6128 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6129 (set (attr "fp_mode")
6130 (if_then_else (eq_attr "fpu_single" "yes")
6131 (const_string "single") (const_string "double")))
5db5a888
AO
6132 (set_attr "type" "jump_ind")])
6133
6134(define_insn "sibcalli_pcrel"
cb51ecd2 6135 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5db5a888
AO
6136 (match_operand 1 "" ""))
6137 (use (match_operand 2 "" ""))
6138 (use (reg:PSI FPSCR_REG))
6139 (return)]
6140 "TARGET_SH2"
6141 "braf %0\\n%O2:%#"
6142 [(set_attr "needs_delay_slot" "yes")
cc0744d1
AO
6143 (set (attr "fp_mode")
6144 (if_then_else (eq_attr "fpu_single" "yes")
6145 (const_string "single") (const_string "double")))
5db5a888
AO
6146 (set_attr "type" "jump_ind")])
6147
6148(define_insn_and_split "sibcall_pcrel"
6149 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6150 (match_operand 1 "" ""))
6151 (use (reg:PSI FPSCR_REG))
cb51ecd2 6152 (clobber (match_scratch:SI 2 "=k"))
5db5a888 6153 (return)]
cb51ecd2 6154 "TARGET_SH2"
5db5a888
AO
6155 "#"
6156 "reload_completed"
6157 [(const_int 0)]
6158 "
6159{
8e831557 6160 rtx lab = PATTERN (gen_call_site ());
5db5a888
AO
6161 rtx call_insn;
6162
fa5322fa
AO
6163 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6164 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6165 lab));
6166 SIBLING_CALL_P (call_insn) = 1;
6167 DONE;
6168}"
6169 [(set_attr "needs_delay_slot" "yes")
6170 (set (attr "fp_mode")
6171 (if_then_else (eq_attr "fpu_single" "yes")
6172 (const_string "single") (const_string "double")))
6173 (set_attr "type" "jump_ind")])
6174
6175(define_insn "sibcall_compact"
6176 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6177 (match_operand 1 "" ""))
6178 (return)
e69d1422 6179 (use (match_operand:SI 2 "register_operand" "z,x"))
fa5322fa
AO
6180 (use (reg:SI R1_REG))
6181 (use (reg:PSI FPSCR_REG))
6182 ;; We want to make sure the `x' above will only match MACH_REG
6183 ;; because sibcall_epilogue may clobber MACL_REG.
6184 (clobber (reg:SI MACL_REG))]
6185 "TARGET_SHCOMPACT"
6186 "@
6187 jmp @%0%#
6188 jmp @%0\\n sts %2, r0"
6189 [(set_attr "needs_delay_slot" "yes,no")
6190 (set_attr "length" "2,4")
6191 (set (attr "fp_mode") (const_string "single"))
6192 (set_attr "type" "jump_ind")])
6193
6194(define_insn "sibcall_media"
6195 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6196 (match_operand 1 "" ""))
7d73a2ba 6197 (use (reg:SI PR_MEDIA_REG))
fa5322fa
AO
6198 (return)]
6199 "TARGET_SHMEDIA"
2ad65b0e
SC
6200 "blink %0, r63"
6201 [(set_attr "type" "jump_media")])
fa5322fa
AO
6202
6203(define_expand "sibcall"
6204 [(parallel
6205 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6206 (match_operand 1 "" ""))
6207 (match_operand 2 "" "")
6208 (use (reg:PSI FPSCR_REG))
6209 (return)])]
6210 ""
6211 "
6212{
6213 if (TARGET_SHMEDIA)
6214 {
6215 operands[0] = XEXP (operands[0], 0);
6216 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6217 {
675ff4c7 6218 if (! SYMBOL_REF_LOCAL_P (operands[0]))
fa5322fa
AO
6219 {
6220 rtx reg = gen_reg_rtx (Pmode);
52702ae1 6221
fa5322fa
AO
6222 /* We must not use GOTPLT for sibcalls, because PIC_REG
6223 must be restored before the PLT code gets to run. */
6224 emit_insn (gen_symGOT2reg (reg, operands[0]));
6225 operands[0] = reg;
6226 }
6227 else
6228 {
6229 operands[0] = gen_sym2PIC (operands[0]);
6230 PUT_MODE (operands[0], Pmode);
6231 }
6232 }
6233 if (GET_MODE (operands[0]) == SImode)
6234 {
6235 if (GET_CODE (operands[0]) == REG)
6236 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6237 else if (GET_CODE (operands[0]) == SUBREG)
6238 {
6239 operands[0] = SUBREG_REG (operands[0]);
6240 if (GET_MODE (operands[0]) != DImode)
6241 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6242 }
6243 else
6244 {
6245 operands[0] = shallow_copy_rtx (operands[0]);
6246 PUT_MODE (operands[0], DImode);
6247 }
6248 }
6249 if (! target_reg_operand (operands[0], DImode))
6250 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6251 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6252 DONE;
6253 }
6254 else if (TARGET_SHCOMPACT && operands[2]
6255 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6256 {
6257 rtx cookie_rtx = operands[2];
6258 long cookie = INTVAL (cookie_rtx);
6259 rtx func = XEXP (operands[0], 0);
6260 rtx mach, r1;
6261
6262 if (flag_pic)
6263 {
675ff4c7 6264 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6265 {
6266 rtx reg = gen_reg_rtx (Pmode);
6267
6268 emit_insn (gen_symGOT2reg (reg, func));
6269 func = reg;
6270 }
6271 else
6272 func = legitimize_pic_address (func, Pmode, 0);
6273 }
5db5a888 6274
fa5322fa
AO
6275 /* FIXME: if we could tell whether all argument registers are
6276 already taken, we could decide whether to force the use of
6277 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6278 simple way to tell. We could use the CALL_COOKIE, but we
6279 can't currently tell a register used for regular argument
6280 passing from one that is unused. If we leave it up to reload
6281 to decide which register to use, it seems to always choose
6282 R0_REG, which leaves no available registers in SIBCALL_REGS
6283 to hold the address of the trampoline. */
6284 mach = gen_rtx_REG (SImode, MACH_REG);
6285 r1 = gen_rtx_REG (SImode, R1_REG);
6286
6287 /* Since such a call function may use all call-clobbered
6288 registers, we force a mode switch earlier, so that we don't
6289 run out of registers when adjusting fpscr for the call. */
6290 emit_insn (gen_force_mode_for_call ());
6291
90534361 6292 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6293 if (flag_pic)
6294 {
6295 rtx reg = gen_reg_rtx (Pmode);
6296
6297 emit_insn (gen_symGOT2reg (reg, operands[0]));
6298 operands[0] = reg;
6299 }
6300 operands[0] = force_reg (SImode, operands[0]);
6301
6302 /* We don't need a return trampoline, since the callee will
6303 return directly to the upper caller. */
6304 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6305 {
6306 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6307 cookie_rtx = GEN_INT (cookie);
6308 }
6309
6310 emit_move_insn (mach, func);
6311 emit_move_insn (r1, cookie_rtx);
6312
6313 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6314 DONE;
6315 }
6316 else if (TARGET_SHCOMPACT && flag_pic
6317 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
675ff4c7 6318 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
fa5322fa
AO
6319 {
6320 rtx reg = gen_reg_rtx (Pmode);
6321
6322 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6323 XEXP (operands[0], 0) = reg;
6324 }
cb51ecd2 6325 if (flag_pic && TARGET_SH2
5db5a888
AO
6326 && GET_CODE (operands[0]) == MEM
6327 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6328 /* The PLT needs the PIC register, but the epilogue would have
6329 to restore it, so we can only use PC-relative PIC calls for
6330 static functions. */
675ff4c7 6331 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5db5a888
AO
6332 {
6333 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6334 DONE;
6335 }
6336 else
6337 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
fa5322fa
AO
6338
6339 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6340 DONE;
5db5a888
AO
6341}")
6342
6343(define_expand "sibcall_value"
6344 [(set (match_operand 0 "" "")
6345 (call (match_operand 1 "" "")
fa5322fa
AO
6346 (match_operand 2 "" "")))
6347 (match_operand 3 "" "")]
5db5a888
AO
6348 ""
6349 "
6350{
fa5322fa 6351 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5db5a888
AO
6352 DONE;
6353}")
6354
fa5322fa
AO
6355(define_insn "call_value_pop_compact"
6356 [(set (match_operand 0 "" "=rf")
6357 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6358 (match_operand 2 "" "")))
6359 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6360 (match_operand 4 "immediate_operand" "n")))
6361 (match_operand 3 "immediate_operand" "n")
6362 (use (reg:SI R0_REG))
6363 (use (reg:SI R1_REG))
6364 (use (reg:PSI FPSCR_REG))
6365 (clobber (reg:SI PR_REG))]
6366 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6367 "jsr @%1%#"
6368 [(set_attr "type" "call")
6369 (set (attr "fp_mode")
6370 (if_then_else (eq_attr "fpu_single" "yes")
6371 (const_string "single") (const_string "double")))
6372 (set_attr "needs_delay_slot" "yes")])
6373
6374(define_insn "call_value_pop_compact_rettramp"
6375 [(set (match_operand 0 "" "=rf")
6376 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6377 (match_operand 2 "" "")))
6378 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6379 (match_operand 4 "immediate_operand" "n")))
6380 (match_operand 3 "immediate_operand" "n")
6381 (use (reg:SI R0_REG))
6382 (use (reg:SI R1_REG))
6383 (use (reg:PSI FPSCR_REG))
6384 (clobber (reg:SI R10_REG))
6385 (clobber (reg:SI PR_REG))]
6386 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6387 "jsr @%1%#"
6388 [(set_attr "type" "call")
6389 (set (attr "fp_mode")
6390 (if_then_else (eq_attr "fpu_single" "yes")
6391 (const_string "single") (const_string "double")))
6392 (set_attr "needs_delay_slot" "yes")])
6393
6394(define_expand "call_value_pop"
6395 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6396 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6397 (match_operand 2 "" "")))
6398 (match_operand 3 "" "")
6399 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6400 (match_operand 4 "" "")))])]
6401 "TARGET_SHCOMPACT"
6402 "
6403{
6404 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6405 {
6406 rtx cookie_rtx = operands[3];
6407 long cookie = INTVAL (cookie_rtx);
6408 rtx func = XEXP (operands[1], 0);
6409 rtx r0, r1;
6410
6411 if (flag_pic)
6412 {
675ff4c7 6413 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
fa5322fa
AO
6414 {
6415 rtx reg = gen_reg_rtx (Pmode);
6416
6417 emit_insn (gen_symGOTPLT2reg (reg, func));
6418 func = reg;
6419 }
6420 else
6421 func = legitimize_pic_address (func, Pmode, 0);
6422 }
6423
6424 r0 = gen_rtx_REG (SImode, R0_REG);
6425 r1 = gen_rtx_REG (SImode, R1_REG);
6426
6427 /* Since such a call function may use all call-clobbered
6428 registers, we force a mode switch earlier, so that we don't
6429 run out of registers when adjusting fpscr for the call. */
6430 emit_insn (gen_force_mode_for_call ());
6431
90534361 6432 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
fa5322fa
AO
6433 if (flag_pic)
6434 {
6435 rtx reg = gen_reg_rtx (Pmode);
6436
6437 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6438 operands[1] = reg;
6439 }
6440 operands[1] = force_reg (SImode, operands[1]);
6441
6442 emit_move_insn (r0, func);
6443 emit_move_insn (r1, cookie_rtx);
6444
6445 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6446 emit_call_insn (gen_call_value_pop_compact_rettramp
6447 (operands[0], operands[1], operands[2],
6448 operands[3], operands[4]));
6449 else
6450 emit_call_insn (gen_call_value_pop_compact
6451 (operands[0], operands[1], operands[2],
6452 operands[3], operands[4]));
6453
6454 DONE;
6455 }
6456
6457 abort ();
6458}")
6459
5db5a888
AO
6460(define_expand "sibcall_epilogue"
6461 [(return)]
6462 ""
6463 "
6464{
6465 sh_expand_epilogue ();
fa5322fa
AO
6466 if (TARGET_SHCOMPACT)
6467 {
6468 rtx insn, set;
6469
6470 /* If epilogue clobbers r0, preserve it in macl. */
6471 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6472 if ((set = single_set (insn))
6473 && GET_CODE (SET_DEST (set)) == REG
6474 && REGNO (SET_DEST (set)) == R0_REG)
6475 {
6476 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6477 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6478 rtx i;
6479
6480 /* We can't tell at this point whether the sibcall is a
6481 sibcall_compact and, if it is, whether it uses r0 or
6482 mach as operand 2, so let the instructions that
6483 preserve r0 be optimized away if r0 turns out to be
6484 dead. */
6485 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6486 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6487 REG_NOTES (i));
6488 i = emit_move_insn (r0, tmp);
6489 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6490 REG_NOTES (i));
6491 break;
6492 }
6493 }
5db5a888
AO
6494 DONE;
6495}")
6496
fa5322fa 6497(define_insn "indirect_jump_compact"
bc45ade3 6498 [(set (pc)
aa684c94 6499 (match_operand:SI 0 "arith_reg_operand" "r"))]
fa5322fa 6500 "TARGET_SH1"
b9654711 6501 "jmp @%0%#"
1245df60
R
6502 [(set_attr "needs_delay_slot" "yes")
6503 (set_attr "type" "jump_ind")])
a1a0806a 6504
fa5322fa
AO
6505(define_expand "indirect_jump"
6506 [(set (pc)
6507 (match_operand 0 "register_operand" ""))]
6508 ""
6509 "
6510{
6511 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6512 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6513}")
6514
1245df60 6515;; The use of operand 1 / 2 helps us distinguish case table jumps
f1ffca1c
JW
6516;; which can be present in structured code from indirect jumps which can not
6517;; be present in structured code. This allows -fprofile-arcs to work.
6518
1245df60
R
6519;; For SH1 processors.
6520(define_insn "casesi_jump_1"
f1ffca1c 6521 [(set (pc)
1245df60 6522 (match_operand:SI 0 "register_operand" "r"))
f1ffca1c 6523 (use (label_ref (match_operand 1 "" "")))]
fa5322fa 6524 "TARGET_SH1"
1245df60
R
6525 "jmp @%0%#"
6526 [(set_attr "needs_delay_slot" "yes")
6527 (set_attr "type" "jump_ind")])
6528
6529;; For all later processors.
6530(define_insn "casesi_jump_2"
6531 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
eb3881bf 6532 (label_ref (match_operand 1 "" ""))))
1245df60 6533 (use (label_ref (match_operand 2 "" "")))]
e6dfd05f
AO
6534 "TARGET_SH2
6535 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
1245df60
R
6536 "braf %0%#"
6537 [(set_attr "needs_delay_slot" "yes")
6538 (set_attr "type" "jump_ind")])
6539
fa5322fa
AO
6540(define_insn "casesi_jump_media"
6541 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6542 (use (label_ref (match_operand 1 "" "")))]
6543 "TARGET_SHMEDIA"
2ad65b0e
SC
6544 "blink %0, r63"
6545 [(set_attr "type" "jump_media")])
52702ae1 6546
a1a0806a
JW
6547;; Call subroutine returning any type.
6548;; ??? This probably doesn't work.
6549
6550(define_expand "untyped_call"
6551 [(parallel [(call (match_operand 0 "" "")
6552 (const_int 0))
6553 (match_operand 1 "" "")
6554 (match_operand 2 "" "")])]
3a8699c7 6555 "TARGET_SH2E || TARGET_SHMEDIA"
a1a0806a
JW
6556 "
6557{
6558 int i;
6559
fa5322fa 6560 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
a1a0806a
JW
6561
6562 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6563 {
6564 rtx set = XVECEXP (operands[2], 0, i);
6565 emit_move_insn (SET_DEST (set), SET_SRC (set));
6566 }
6567
6568 /* The optimizer does not know that the call sets the function value
6569 registers we stored in the result block. We avoid problems by
6570 claiming that all hard registers are used and clobbered at this
6571 point. */
6572 emit_insn (gen_blockage ());
6573
6574 DONE;
6575}")
bc45ade3
SC
6576\f
6577;; ------------------------------------------------------------------------
6578;; Misc insns
6579;; ------------------------------------------------------------------------
6580
51bd623f 6581(define_insn "dect"
4773afa4 6582 [(set (reg:SI T_REG)
aff48e32
JR
6583 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6584 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
51bd623f 6585 "TARGET_SH2"
1245df60
R
6586 "dt %0"
6587 [(set_attr "type" "arith")])
bc45ade3
SC
6588
6589(define_insn "nop"
6590 [(const_int 0)]
6591 ""
51bd623f 6592 "nop")
0d7e008e 6593
1245df60
R
6594;; Load address of a label. This is only generated by the casesi expand,
6595;; and by machine_dependent_reorg (fixing up fp moves).
6596;; This must use unspec, because this only works for labels that are
6597;; within range,
0d7e008e
SC
6598
6599(define_insn "mova"
4773afa4 6600 [(set (reg:SI R0_REG)
e69d1422 6601 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
fa5322fa 6602 "TARGET_SH1"
0d7e008e 6603 "mova %O0,r0"
1245df60
R
6604 [(set_attr "in_delay_slot" "no")
6605 (set_attr "type" "arith")])
0d7e008e 6606
18dbd950 6607;; machine_dependent_reorg will make this a `mova'.
43c05634
AO
6608(define_insn "mova_const"
6609 [(set (reg:SI R0_REG)
e69d1422 6610 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
fa5322fa 6611 "TARGET_SH1"
43c05634
AO
6612 "#"
6613 [(set_attr "in_delay_slot" "no")
6614 (set_attr "type" "arith")])
6615
1a66cd67 6616(define_expand "GOTaddr2picreg"
4773afa4 6617 [(set (reg:SI R0_REG)
e69d1422
R
6618 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6619 UNSPEC_MOVA))
615cd49b 6620 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
4773afa4 6621 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
1a66cd67
AO
6622 "" "
6623{
fa5322fa 6624 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
1a66cd67 6625 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
fa5322fa
AO
6626
6627 if (TARGET_SH5)
6628 operands[1] = gen_datalabel_ref (operands[1]);
6629
6630 if (TARGET_SHMEDIA)
6631 {
6632 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6633 rtx dipic = operands[0];
8e831557 6634 rtx lab = PATTERN (gen_call_site ());
fa5322fa
AO
6635 rtx insn, equiv;
6636
6637 equiv = operands[1];
6638 operands[1] = gen_rtx_MINUS (DImode,
6639 operands[1],
6640 gen_rtx_CONST
6641 (DImode,
6642 gen_rtx_MINUS (DImode,
6643 gen_rtx_CONST (DImode,
6644 lab),
6645 pc_rtx)));
6646 operands[1] = gen_sym2PIC (operands[1]);
6647 PUT_MODE (operands[1], DImode);
6648
6649 if (GET_MODE (dipic) != DImode)
6650 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6651
6652 if (TARGET_SHMEDIA64)
6653 emit_insn (gen_movdi_const (dipic, operands[1]));
6654 else
6655 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6656
6657 emit_insn (gen_ptrel (tr, dipic, lab));
6658
6659 if (GET_MODE (operands[0]) != GET_MODE (tr))
90534361 6660 tr = gen_lowpart (GET_MODE (operands[0]), tr);
fa5322fa
AO
6661
6662 insn = emit_move_insn (operands[0], tr);
52702ae1 6663
fa5322fa
AO
6664 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6665 REG_NOTES (insn));
6666
6667 DONE;
6668 }
1a66cd67
AO
6669}
6670")
6671
fa5322fa 6672(define_insn "*ptb"
b6d33983 6673 [(set (match_operand:DI 0 "target_reg_operand" "=b")
735cb76e 6674 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
fa5322fa
AO
6675 UNSPEC_DATALABEL)))]
6676 "TARGET_SHMEDIA && flag_pic
735cb76e 6677 && EXTRA_CONSTRAINT_Csy (operands[1])"
fa5322fa 6678 "ptb/u datalabel %1, %0"
2ad65b0e 6679 [(set_attr "type" "pt_media")
fa5322fa
AO
6680 (set_attr "length" "*")])
6681
6682(define_insn "ptrel"
e69d1422
R
6683 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6684 (plus:DI (match_operand:DI 1 "register_operand" "r")
fa5322fa
AO
6685 (pc)))
6686 (match_operand:DI 2 "" "")]
6687 "TARGET_SHMEDIA"
6688 "%O2: ptrel/u %1, %0"
2ad65b0e 6689 [(set_attr "type" "ptabs_media")])
fa5322fa 6690
001643af
KK
6691(define_expand "builtin_setjmp_receiver"
6692 [(match_operand 0 "" "")]
6693 "flag_pic"
6694 "
6695{
6696 emit_insn (gen_GOTaddr2picreg ());
6697 DONE;
6698}")
6699
2d01e445
AO
6700(define_expand "call_site"
6701 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
fa5322fa 6702 "TARGET_SH1"
2d01e445
AO
6703 "
6704{
6705 static HOST_WIDE_INT i = 0;
6706 operands[0] = GEN_INT (i);
6707 i++;
6708}")
6709
1a66cd67
AO
6710(define_expand "sym_label2reg"
6711 [(set (match_operand:SI 0 "" "")
a4f76ef9
AO
6712 (const:SI (minus:SI
6713 (const:SI
6714 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6715 (const:SI
6716 (plus:SI
6717 (match_operand:SI 2 "" "")
6718 (const_int 2))))))]
fa5322fa 6719 "TARGET_SH1" "")
1a66cd67 6720
e1d71275
AO
6721(define_expand "symGOT_load"
6722 [(set (match_dup 2) (match_operand 1 "" ""))
6723 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6724 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6725 ""
6726 "
6727{
6728 rtx insn;
6729
6730 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6731 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6732
fa5322fa
AO
6733 if (TARGET_SHMEDIA)
6734 {
6735 rtx reg = operands[2];
52702ae1 6736
fa5322fa
AO
6737 if (GET_MODE (reg) != DImode)
6738 reg = gen_rtx_SUBREG (DImode, reg, 0);
52702ae1 6739
fa5322fa
AO
6740 if (flag_pic > 1)
6741 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6742 else
6743 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6744 }
6745 else
6746 emit_move_insn (operands[2], operands[1]);
e1d71275
AO
6747
6748 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6749 operands[2],
6750 gen_rtx_REG (Pmode, PIC_REG)));
6751
6752 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6753
6754 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6755 0), 0, 0),
6756 REG_NOTES (insn));
52702ae1 6757
e1d71275
AO
6758 DONE;
6759}")
6760
6761(define_expand "sym2GOT"
6762 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6763 ""
6764 "")
6765
1a66cd67 6766(define_expand "symGOT2reg"
e1d71275 6767 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6768 ""
6769 "
6770{
e1d71275
AO
6771 rtx gotsym, insn;
6772
6773 gotsym = gen_sym2GOT (operands[1]);
6774 PUT_MODE (gotsym, Pmode);
6775 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6776
6777 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6778
6779 DONE;
1a66cd67
AO
6780}")
6781
fa5322fa
AO
6782(define_expand "sym2GOTPLT"
6783 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6784 ""
6785 "")
6786
6787(define_expand "symGOTPLT2reg"
6788 [(match_operand 0 "" "") (match_operand 1 "" "")]
6789 ""
6790 "
6791{
6792 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6793 DONE;
6794}")
6795
e1d71275
AO
6796(define_expand "sym2GOTOFF"
6797 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6798 ""
6799 "")
6800
1a66cd67 6801(define_expand "symGOTOFF2reg"
e1d71275 6802 [(match_operand 0 "" "") (match_operand 1 "" "")]
1a66cd67
AO
6803 ""
6804 "
6805{
e1d71275
AO
6806 rtx gotoffsym, insn;
6807 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6808
6809 gotoffsym = gen_sym2GOTOFF (operands[1]);
6810 PUT_MODE (gotoffsym, Pmode);
6811 emit_move_insn (t, gotoffsym);
6812 insn = emit_move_insn (operands[0],
6813 gen_rtx_PLUS (Pmode, t,
6814 gen_rtx_REG (Pmode, PIC_REG)));
6815
6816 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6817 REG_NOTES (insn));
6818
6819 DONE;
1a66cd67
AO
6820}")
6821
6822(define_expand "symPLT_label2reg"
6823 [(set (match_operand:SI 0 "" "")
e1d71275
AO
6824 (const:SI (minus:SI
6825 (const:SI
6826 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6827 (const:SI
6828 (minus:SI
6829 (const:SI (plus:SI
6830 (match_operand:SI 2 "" "")
6831 (const_int 2)))
6832 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6915629f
AO
6833 ;; Even though the PIC register is not really used by the call
6834 ;; sequence in which this is expanded, the PLT code assumes the PIC
6835 ;; register is set, so we must not skip its initialization. Since
6836 ;; we only use this expand as part of calling sequences, and never
6837 ;; to take the address of a function, this is the best point to
6838 ;; insert the (use). Using the PLT to take the address of a
6839 ;; function would be wrong, not only because the PLT entry could
6840 ;; then be called from a function that doesn't initialize the PIC
6841 ;; register to the proper GOT, but also because pointers to the
6842 ;; same function might not compare equal, should they be set by
6843 ;; different shared libraries.
6844 (use (reg:SI PIC_REG))]
fa5322fa
AO
6845 "TARGET_SH1"
6846 "")
6847
6848(define_expand "sym2PIC"
6849 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6915629f
AO
6850 ""
6851 "")
1a66cd67 6852
463f02cd
KK
6853;; TLS code generation.
6854;; ??? this should be a define_insn_and_split
6855;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6856;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6857;; for details.
6858
6859(define_insn "tls_global_dynamic"
6860 [(set (match_operand:SI 0 "register_operand" "=&z")
6861 (unspec:SI [(match_operand:SI 1 "" "")]
6862 UNSPEC_TLSGD))
6863 (use (reg:PSI FPSCR_REG))
6864 (use (reg:SI PIC_REG))
6865 (clobber (reg:SI PR_REG))
6866 (clobber (scratch:SI))]
6867 "TARGET_SH1"
6868 "*
6869{
6870 return \"\\
6871mov.l\\t1f,r4\\n\\
6872\\tmova\\t2f,r0\\n\\
6873\\tmov.l\\t2f,r1\\n\\
6874\\tadd\\tr0,r1\\n\\
6875\\tjsr\\t@r1\\n\\
6876\\tadd\\tr12,r4\\n\\
6877\\tbra\\t3f\\n\\
6878\\tnop\\n\\
6879\\t.align\\t2\\n\\
68801:\\t.long\\t%a1@TLSGD\\n\\
68812:\\t.long\\t__tls_get_addr@PLT\\n\\
68823:\";
6883}"
6884 [(set_attr "type" "tls_load")
6885 (set_attr "length" "26")])
6886
6887(define_insn "tls_local_dynamic"
6888 [(set (match_operand:SI 0 "register_operand" "=&z")
6889 (unspec:SI [(match_operand:SI 1 "" "")]
6890 UNSPEC_TLSLDM))
6891 (use (reg:PSI FPSCR_REG))
6892 (use (reg:SI PIC_REG))
6893 (clobber (reg:SI PR_REG))
6894 (clobber (scratch:SI))]
6895 "TARGET_SH1"
6896 "*
6897{
6898 return \"\\
6899mov.l\\t1f,r4\\n\\
6900\\tmova\\t2f,r0\\n\\
6901\\tmov.l\\t2f,r1\\n\\
6902\\tadd\\tr0,r1\\n\\
6903\\tjsr\\t@r1\\n\\
6904\\tadd\\tr12,r4\\n\\
6905\\tbra\\t3f\\n\\
6906\\tnop\\n\\
6907\\t.align\\t2\\n\\
69081:\\t.long\\t%a1@TLSLDM\\n\\
69092:\\t.long\\t__tls_get_addr@PLT\\n\\
69103:\";
6911}"
6912 [(set_attr "type" "tls_load")
6913 (set_attr "length" "26")])
6914
6915(define_expand "sym2DTPOFF"
6916 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6917 ""
6918 "")
6919
6920(define_expand "symDTPOFF2reg"
6921 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6922 ""
6923 "
6924{
6925 rtx dtpoffsym, insn;
6926 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6927
6928 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6929 PUT_MODE (dtpoffsym, Pmode);
6930 emit_move_insn (t, dtpoffsym);
6931 insn = emit_move_insn (operands[0],
6932 gen_rtx_PLUS (Pmode, t, operands[2]));
6933 DONE;
6934}")
6935
6936(define_expand "sym2GOTTPOFF"
6937 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6938 ""
6939 "")
6940
6941(define_insn "tls_initial_exec"
6942 [(set (match_operand:SI 0 "register_operand" "=&r")
6943 (unspec:SI [(match_operand:SI 1 "" "")]
6944 UNSPEC_TLSIE))
6945 (use (reg:SI GBR_REG))
6946 (use (reg:SI PIC_REG))
6947 (clobber (reg:SI R0_REG))]
6948 ""
6949 "*
6950{
6951 return \"\\
6952mov.l\\t1f,r0\\n\\
6953\\tstc\\tgbr,%0\\n\\
6954\\tmov.l\\t@(r0,r12),r0\\n\\
6955\\tbra\\t2f\\n\\
6956\\tadd\\tr0,%0\\n\\
6957\\t.align\\t2\\n\\
69581:\\t.long\\t%a1\\n\\
69592:\";
6960}"
6961 [(set_attr "type" "tls_load")
6962 (set_attr "length" "16")])
6963
6964(define_expand "sym2TPOFF"
6965 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6966 ""
6967 "")
6968
6969(define_expand "symTPOFF2reg"
6970 [(match_operand 0 "" "") (match_operand 1 "" "")]
6971 ""
6972 "
6973{
6974 rtx tpoffsym, insn;
6975
6976 tpoffsym = gen_sym2TPOFF (operands[1]);
6977 PUT_MODE (tpoffsym, Pmode);
6978 insn = emit_move_insn (operands[0], tpoffsym);
6979 DONE;
6980}")
6981
6982(define_insn "load_gbr"
6983 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6984 (use (reg:SI GBR_REG))]
6985 ""
6986 "stc gbr,%0"
6987 [(set_attr "type" "tls_load")])
6988
0d7e008e
SC
6989;; case instruction for switch statements.
6990
6991;; Operand 0 is index
6992;; operand 1 is the minimum bound
6993;; operand 2 is the maximum bound - minimum bound + 1
6994;; operand 3 is CODE_LABEL for the table;
6995;; operand 4 is the CODE_LABEL to go to if index out of range.
6996
6997(define_expand "casesi"
1245df60
R
6998 [(match_operand:SI 0 "arith_reg_operand" "")
6999 (match_operand:SI 1 "arith_reg_operand" "")
7000 (match_operand:SI 2 "arith_reg_operand" "")
7001 (match_operand 3 "" "") (match_operand 4 "" "")]
7002 ""
7003 "
7004{
7005 rtx reg = gen_reg_rtx (SImode);
7006 rtx reg2 = gen_reg_rtx (SImode);
fa5322fa
AO
7007 if (TARGET_SHMEDIA)
7008 {
7009 rtx reg = gen_reg_rtx (DImode);
7010 rtx reg2 = gen_reg_rtx (DImode);
7011 rtx reg3 = gen_reg_rtx (DImode);
7012 rtx reg4 = gen_reg_rtx (DImode);
7013 rtx reg5 = gen_reg_rtx (DImode);
7014
7015 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7016 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7017 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7018
7019 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7020 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7021 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7022 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7023 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7024 (DImode, operands[3])));
7025 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7026 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7027 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7028 emit_barrier ();
7029 DONE;
7030 }
1245df60
R
7031 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7032 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7033 /* If optimizing, casesi_worker depends on the mode of the instruction
7034 before label it 'uses' - operands[3]. */
7035 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7036 reg));
7037 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7038 if (TARGET_SH2)
eb3881bf 7039 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
1245df60 7040 else
eb3881bf 7041 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
1245df60
R
7042 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7043 operands[3], but to lab. We will fix this up in
7044 machine_dependent_reorg. */
7045 emit_barrier ();
7046 DONE;
7047}")
7048
7049(define_expand "casesi_0"
7050 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7051 (set (match_dup 4) (minus:SI (match_dup 4)
0d7e008e 7052 (match_operand:SI 1 "arith_operand" "")))
4773afa4 7053 (set (reg:SI T_REG)
1245df60 7054 (gtu:SI (match_dup 4)
22e1ebf1 7055 (match_operand:SI 2 "arith_reg_operand" "")))
0d7e008e 7056 (set (pc)
4773afa4 7057 (if_then_else (ne (reg:SI T_REG)
7c225e88 7058 (const_int 0))
1245df60
R
7059 (label_ref (match_operand 3 "" ""))
7060 (pc)))]
fa5322fa 7061 "TARGET_SH1"
1245df60 7062 "")
0d7e008e 7063
1245df60
R
7064;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7065;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7066;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7067
7068(define_insn "casesi_worker_0"
7069 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422 7070 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
4773afa4 7071 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7072 (clobber (match_scratch:SI 3 "=X,1"))
7073 (clobber (match_scratch:SI 4 "=&z,z"))]
fa5322fa 7074 "TARGET_SH1"
1245df60
R
7075 "#")
7076
7077(define_split
7078 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
7079 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7080 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7081 (clobber (match_scratch:SI 3 ""))
7082 (clobber (match_scratch:SI 4 ""))]
fa5322fa 7083 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
e69d1422 7084 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 7085 (parallel [(set (match_dup 0)
e69d1422
R
7086 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7087 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 7088 (clobber (match_dup 3))])
4773afa4 7089 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
b6d33983 7090 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
7091
7092(define_split
7093 [(set (match_operand:SI 0 "register_operand" "")
e69d1422
R
7094 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7095 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60
R
7096 (clobber (match_scratch:SI 3 ""))
7097 (clobber (match_scratch:SI 4 ""))]
7098 "TARGET_SH2 && reload_completed"
e69d1422 7099 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
1245df60 7100 (parallel [(set (match_dup 0)
615cd49b 7101 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
e69d1422 7102 (label_ref (match_dup 2))] UNSPEC_CASESI))
1245df60 7103 (clobber (match_dup 3))])]
b6d33983 7104 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
1245df60
R
7105
7106(define_insn "*casesi_worker"
7107 [(set (match_operand:SI 0 "register_operand" "=r,r")
e69d1422
R
7108 (unspec:SI [(reg:SI R0_REG)
7109 (match_operand:SI 1 "register_operand" "0,r")
7110 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
1245df60 7111 (clobber (match_scratch:SI 3 "=X,1"))]
fa5322fa 7112 "TARGET_SH1"
4fdd1f85 7113 "*
ffae286a 7114{
33f7f353
JR
7115 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7116
7117 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7118 abort ();
7119
7120 switch (GET_MODE (diff_vec))
1245df60
R
7121 {
7122 case SImode:
7123 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7124 case HImode:
7125 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7126 case QImode:
33f7f353 7127 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
1245df60 7128 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
33f7f353 7129 return \"mov.b @(r0,%1),%0\";
1245df60
R
7130 default:
7131 abort ();
7132 }
ffae286a 7133}"
51bd623f 7134 [(set_attr "length" "4")])
0d7e008e 7135
fa5322fa 7136(define_insn "casesi_shift_media"
51214775
R
7137 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7138 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7139 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7140 UNSPEC_CASESI)))]
fa5322fa
AO
7141 "TARGET_SHMEDIA"
7142 "*
7143{
7144 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7145
7146 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7147 abort ();
7148
7149 switch (GET_MODE (diff_vec))
7150 {
7151 case SImode:
7152 return \"shlli %1, 2, %0\";
7153 case HImode:
7154 return \"shlli %1, 1, %0\";
7155 case QImode:
7156 if (rtx_equal_p (operands[0], operands[1]))
7157 return \"\";
7158 return \"add %1, r63, %0\";
7159 default:
7160 abort ();
7161 }
2ad65b0e
SC
7162}"
7163 [(set_attr "type" "arith_media")])
fa5322fa
AO
7164
7165(define_insn "casesi_load_media"
7166 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7167 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7168 (match_operand 2 "arith_reg_operand" "r")
7169 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7170 "TARGET_SHMEDIA"
7171 "*
7172{
7173 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7174
7175 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7176 abort ();
7177
7178 switch (GET_MODE (diff_vec))
7179 {
7180 case SImode:
7181 return \"ldx.l %1, %2, %0\";
7182 case HImode:
7183#if 0
7184 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7185 return \"ldx.uw %1, %2, %0\";
7186#endif
7187 return \"ldx.w %1, %2, %0\";
7188 case QImode:
7189 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7190 return \"ldx.ub %1, %2, %0\";
7191 return \"ldx.b %1, %2, %0\";
7192 default:
7193 abort ();
7194 }
2ad65b0e
SC
7195}"
7196 [(set_attr "type" "load_media")])
fa5322fa 7197
afbc2905
R
7198(define_expand "return"
7199 [(return)]
7200 "reload_completed && ! sh_need_epilogue ()"
fa5322fa
AO
7201 "
7202{
7203 if (TARGET_SHMEDIA)
7204 {
7205 emit_jump_insn (gen_return_media ());
7206 DONE;
7207 }
7208
7209 if (TARGET_SHCOMPACT
7210 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7211 {
7212 emit_jump_insn (gen_shcompact_return_tramp ());
7213 DONE;
7214 }
7215}")
afbc2905
R
7216
7217(define_insn "*return_i"
0d7e008e 7218 [(return)]
fa5322fa
AO
7219 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7220 && (current_function_args_info.call_cookie
7221 & CALL_COOKIE_RET_TRAMP (1)))
7222 && reload_completed"
961c4780 7223 "%@ %#"
51bd623f
JW
7224 [(set_attr "type" "return")
7225 (set_attr "needs_delay_slot" "yes")])
b9654711 7226
fa5322fa
AO
7227(define_expand "shcompact_return_tramp"
7228 [(return)]
7229 "TARGET_SHCOMPACT
7230 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7231 "
7232{
7233 rtx reg = gen_rtx_REG (Pmode, R0_REG);
90534361 7234 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
fa5322fa
AO
7235
7236 if (flag_pic)
7237 emit_insn (gen_symGOTPLT2reg (reg, sym));
7238 else
7239 emit_move_insn (reg, sym);
7240
7241 emit_jump_insn (gen_shcompact_return_tramp_i ());
7242 DONE;
7243}")
7244
7245(define_insn "shcompact_return_tramp_i"
7246 [(parallel [(return) (use (reg:SI R0_REG))])]
7247 "TARGET_SHCOMPACT
7248 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7249 "jmp @r0%#"
7250 [(set_attr "type" "jump_ind")
7251 (set_attr "needs_delay_slot" "yes")])
7252
7253(define_insn "return_media_i"
7254 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7255 "TARGET_SHMEDIA && reload_completed"
2ad65b0e
SC
7256 "blink %0, r63"
7257 [(set_attr "type" "jump_media")])
fa5322fa 7258
1bf93c14
R
7259(define_insn "return_media_rte"
7260 [(return)]
7261 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7262 "rte"
7263 [(set_attr "type" "jump_media")])
7264
fa5322fa
AO
7265(define_expand "return_media"
7266 [(return)]
7267 "TARGET_SHMEDIA && reload_completed"
7268 "
7269{
7270 int tr_regno = sh_media_register_for_return ();
7271 rtx tr;
7272
1bf93c14
R
7273 if (current_function_interrupt)
7274 {
7275 emit_jump_insn (gen_return_media_rte ());
7276 DONE;
7277 }
fa5322fa
AO
7278 if (tr_regno < 0)
7279 {
7280 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7281
fada1961
R
7282 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7283 abort ();
fa5322fa
AO
7284 tr_regno = TR0_REG;
7285 tr = gen_rtx_REG (DImode, tr_regno);
7286 emit_move_insn (tr, r18);
7287 }
7288 else
7289 tr = gen_rtx_REG (DImode, tr_regno);
7290
7291 emit_jump_insn (gen_return_media_i (tr));
7292 DONE;
7293}")
7294
7295(define_insn "shcompact_preserve_incoming_args"
e69d1422
R
7296 [(set (match_operand:SI 0 "register_operand" "+r")
7297 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
fa5322fa
AO
7298 "TARGET_SHCOMPACT"
7299 ""
7300 [(set_attr "length" "0")])
7301
7302(define_insn "shcompact_incoming_args"
e69d1422
R
7303 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7304 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7305 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7306 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7307 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7308 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7309 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7310 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa 7311 (set (mem:BLK (reg:SI MACL_REG))
e69d1422 7312 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
fa5322fa
AO
7313 (use (reg:SI R0_REG))
7314 (clobber (reg:SI R0_REG))
7315 (clobber (reg:SI MACL_REG))
7316 (clobber (reg:SI MACH_REG))
7317 (clobber (reg:SI PR_REG))]
7318 "TARGET_SHCOMPACT"
7319 "jsr @r0%#"
7320 [(set_attr "needs_delay_slot" "yes")])
7321
7322(define_insn "shmedia_save_restore_regs_compact"
7323 [(set (reg:SI SP_REG)
7324 (plus:SI (reg:SI SP_REG)
7325 (match_operand:SI 0 "immediate_operand" "i")))
7326 (use (reg:SI R0_REG))
7327 (clobber (reg:SI PR_REG))]
7328 "TARGET_SHCOMPACT
7329 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7330 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7331 "jsr @r0%#"
7332 [(set_attr "needs_delay_slot" "yes")])
7333
b9654711
SC
7334(define_expand "prologue"
7335 [(const_int 0)]
7336 ""
7337 "sh_expand_prologue (); DONE;")
7338
7339(define_expand "epilogue"
7340 [(return)]
7341 ""
fa5322fa
AO
7342 "
7343{
7344 sh_expand_epilogue ();
7345 emit_jump_insn (gen_return ());
7346 DONE;
7347}")
b9654711 7348
4977bab6 7349(define_expand "eh_return"
34dc173c 7350 [(use (match_operand 0 "register_operand" ""))]
4977bab6
ZW
7351 ""
7352{
34dc173c 7353 rtx tmp, ra = operands[0];
4977bab6
ZW
7354
7355 if (TARGET_SHMEDIA64)
7356 emit_insn (gen_eh_set_ra_di (ra));
7357 else
7358 emit_insn (gen_eh_set_ra_si (ra));
7359
4977bab6
ZW
7360 DONE;
7361})
7362
7363;; Clobber the return address on the stack. We can't expand this
7364;; until we know where it will be put in the stack frame.
7365
7366(define_insn "eh_set_ra_si"
7367 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7368 (clobber (match_scratch:SI 1 "=&r"))]
7369 "! TARGET_SHMEDIA64"
7370 "#")
7371
7372(define_insn "eh_set_ra_di"
7373 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7374 (clobber (match_scratch:DI 1 "=&r"))]
7375 "TARGET_SHMEDIA64"
7376 "#")
7377
7378(define_split
7379 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7380 (clobber (match_scratch 1 ""))]
7381 "reload_completed"
7382 [(const_int 0)]
7383 "
7384{
7385 sh_set_return_address (operands[0], operands[1]);
7386 DONE;
7387}")
7388
b9654711 7389(define_insn "blockage"
4773afa4 7390 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
b9654711
SC
7391 ""
7392 ""
7393 [(set_attr "length" "0")])
bc45ade3
SC
7394\f
7395;; ------------------------------------------------------------------------
7396;; Scc instructions
7397;; ------------------------------------------------------------------------
7398
0d7e008e 7399(define_insn "movt"
aa684c94 7400 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4773afa4 7401 (eq:SI (reg:SI T_REG) (const_int 1)))]
fa5322fa 7402 "TARGET_SH1"
1245df60
R
7403 "movt %0"
7404 [(set_attr "type" "arith")])
bc45ade3
SC
7405
7406(define_expand "seq"
aa684c94 7407 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7408 (match_dup 1))]
7409 ""
fa5322fa
AO
7410 "
7411{
7412 if (TARGET_SHMEDIA)
7413 {
7414 if (GET_MODE (operands[0]) != DImode)
7415 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7416 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7417 if (sh_compare_op1 != const0_rtx)
7418 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7419 ? GET_MODE (sh_compare_op0)
7420 : GET_MODE (sh_compare_op1),
7421 sh_compare_op1);
7422
7423 switch (GET_MODE (sh_compare_op0))
7424 {
7425 case DImode:
7426 emit_insn (gen_cmpeqdi_media (operands[0],
7427 sh_compare_op0, sh_compare_op1));
7428 break;
7429
7430 case SFmode:
7431 if (! TARGET_SHMEDIA_FPU)
7432 FAIL;
7433 emit_insn (gen_cmpeqsf_media (operands[0],
7434 sh_compare_op0, sh_compare_op1));
7435 break;
7436
7437 case DFmode:
7438 if (! TARGET_SHMEDIA_FPU)
7439 FAIL;
7440 emit_insn (gen_cmpeqdf_media (operands[0],
7441 sh_compare_op0, sh_compare_op1));
7442 break;
7443
7444 default:
7445 FAIL;
7446 }
7447 DONE;
7448 }
7449 operands[1] = prepare_scc_operands (EQ);
7450}")
bc45ade3
SC
7451
7452(define_expand "slt"
aa684c94 7453 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7454 (match_dup 1))]
7455 ""
fa5322fa
AO
7456 "
7457{
7458 if (TARGET_SHMEDIA)
7459 {
7460 if (GET_MODE (operands[0]) != DImode)
7461 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7462 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7463 if (sh_compare_op1 != const0_rtx)
7464 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7465 ? GET_MODE (sh_compare_op0)
7466 : GET_MODE (sh_compare_op1),
7467 sh_compare_op1);
7468
7469 switch (GET_MODE (sh_compare_op0))
7470 {
7471 case DImode:
7472 emit_insn (gen_cmpgtdi_media (operands[0],
7473 sh_compare_op1, sh_compare_op0));
7474 break;
7475
7476 case SFmode:
7477 if (! TARGET_SHMEDIA_FPU)
7478 FAIL;
7479 emit_insn (gen_cmpgtsf_media (operands[0],
7480 sh_compare_op1, sh_compare_op0));
7481 break;
7482
7483 case DFmode:
7484 if (! TARGET_SHMEDIA_FPU)
7485 FAIL;
7486 emit_insn (gen_cmpgtdf_media (operands[0],
7487 sh_compare_op1, sh_compare_op0));
7488 break;
7489
7490 default:
7491 FAIL;
7492 }
7493 DONE;
7494 }
7495 operands[1] = prepare_scc_operands (LT);
7496}")
bc45ade3
SC
7497
7498(define_expand "sle"
1245df60 7499 [(match_operand:SI 0 "arith_reg_operand" "")]
bc45ade3 7500 ""
45348d9e
JW
7501 "
7502{
1245df60 7503 rtx tmp = sh_compare_op0;
fa5322fa
AO
7504
7505 if (TARGET_SHMEDIA)
7506 {
7507 if (GET_MODE (operands[0]) != DImode)
7508 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7509 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7510 if (sh_compare_op1 != const0_rtx)
7511 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7512 ? GET_MODE (sh_compare_op0)
7513 : GET_MODE (sh_compare_op1),
7514 sh_compare_op1);
7515
7516 switch (GET_MODE (sh_compare_op0))
7517 {
7518 case DImode:
7519 {
7520 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7521
7522 emit_insn (gen_cmpgtdi_media (tmp,
7523 sh_compare_op0, sh_compare_op1));
7524 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7525 break;
7526 }
7527
7528 case SFmode:
7529 if (! TARGET_SHMEDIA_FPU)
7530 FAIL;
7531 emit_insn (gen_cmpgesf_media (operands[0],
7532 sh_compare_op1, sh_compare_op0));
7533 break;
7534
7535 case DFmode:
7536 if (! TARGET_SHMEDIA_FPU)
7537 FAIL;
7538 emit_insn (gen_cmpgedf_media (operands[0],
7539 sh_compare_op1, sh_compare_op0));
7540 break;
7541
7542 default:
7543 FAIL;
7544 }
7545 DONE;
7546 }
7547
1245df60
R
7548 sh_compare_op0 = sh_compare_op1;
7549 sh_compare_op1 = tmp;
7550 emit_insn (gen_sge (operands[0]));
7551 DONE;
45348d9e 7552}")
bc45ade3
SC
7553
7554(define_expand "sgt"
aa684c94 7555 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7556 (match_dup 1))]
7557 ""
fa5322fa
AO
7558 "
7559{
7560 if (TARGET_SHMEDIA)
7561 {
7562 if (GET_MODE (operands[0]) != DImode)
7563 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7564 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7565 if (sh_compare_op1 != const0_rtx)
7566 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7567 ? GET_MODE (sh_compare_op0)
7568 : GET_MODE (sh_compare_op1),
7569 sh_compare_op1);
7570
7571 switch (GET_MODE (sh_compare_op0))
7572 {
7573 case DImode:
7574 emit_insn (gen_cmpgtdi_media (operands[0],
7575 sh_compare_op0, sh_compare_op1));
7576 break;
7577
7578 case SFmode:
7579 if (! TARGET_SHMEDIA_FPU)
7580 FAIL;
7581 emit_insn (gen_cmpgtsf_media (operands[0],
7582 sh_compare_op0, sh_compare_op1));
7583 break;
7584
7585 case DFmode:
7586 if (! TARGET_SHMEDIA_FPU)
7587 FAIL;
7588 emit_insn (gen_cmpgtdf_media (operands[0],
7589 sh_compare_op0, sh_compare_op1));
7590 break;
7591
7592 default:
7593 FAIL;
7594 }
7595 DONE;
7596 }
7597 operands[1] = prepare_scc_operands (GT);
7598}")
bc45ade3
SC
7599
7600(define_expand "sge"
aa684c94 7601 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7602 (match_dup 1))]
7603 ""
45348d9e
JW
7604 "
7605{
fa5322fa
AO
7606 if (TARGET_SHMEDIA)
7607 {
7608 if (GET_MODE (operands[0]) != DImode)
7609 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7610 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7611 if (sh_compare_op1 != const0_rtx)
7612 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7613 ? GET_MODE (sh_compare_op0)
7614 : GET_MODE (sh_compare_op1),
7615 sh_compare_op1);
7616
7617 switch (GET_MODE (sh_compare_op0))
7618 {
7619 case DImode:
7620 {
7621 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7622
7623 emit_insn (gen_cmpgtdi_media (tmp,
7624 sh_compare_op1, sh_compare_op0));
7625 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7626 break;
7627 }
7628
7629 case SFmode:
7630 if (! TARGET_SHMEDIA_FPU)
7631 FAIL;
7632 emit_insn (gen_cmpgesf_media (operands[0],
7633 sh_compare_op0, sh_compare_op1));
7634 break;
7635
7636 case DFmode:
7637 if (! TARGET_SHMEDIA_FPU)
7638 FAIL;
7639 emit_insn (gen_cmpgedf_media (operands[0],
7640 sh_compare_op0, sh_compare_op1));
7641 break;
7642
7643 default:
7644 FAIL;
7645 }
7646 DONE;
7647 }
7648
225e4f43 7649 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e 7650 {
1245df60
R
7651 if (TARGET_IEEE)
7652 {
1245df60 7653 rtx lab = gen_label_rtx ();
225e4f43 7654 prepare_scc_operands (EQ);
1245df60 7655 emit_jump_insn (gen_branch_true (lab));
225e4f43 7656 prepare_scc_operands (GT);
1245df60
R
7657 emit_label (lab);
7658 emit_insn (gen_movt (operands[0]));
7659 }
7660 else
7661 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
45348d9e
JW
7662 DONE;
7663 }
7664 operands[1] = prepare_scc_operands (GE);
7665}")
bc45ade3
SC
7666
7667(define_expand "sgtu"
aa684c94 7668 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7669 (match_dup 1))]
7670 ""
fa5322fa
AO
7671 "
7672{
7673 if (TARGET_SHMEDIA)
7674 {
7675 if (GET_MODE (operands[0]) != DImode)
7676 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7677 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7678 if (sh_compare_op1 != const0_rtx)
7679 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7680 ? GET_MODE (sh_compare_op0)
7681 : GET_MODE (sh_compare_op1),
7682 sh_compare_op1);
7683
7684 emit_insn (gen_cmpgtudi_media (operands[0],
7685 sh_compare_op0, sh_compare_op1));
7686 DONE;
7687 }
7688 operands[1] = prepare_scc_operands (GTU);
7689}")
bc45ade3
SC
7690
7691(define_expand "sltu"
aa684c94 7692 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7693 (match_dup 1))]
7694 ""
fa5322fa
AO
7695 "
7696{
7697 if (TARGET_SHMEDIA)
7698 {
7699 if (GET_MODE (operands[0]) != DImode)
7700 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7701 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7702 if (sh_compare_op1 != const0_rtx)
7703 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7704 ? GET_MODE (sh_compare_op0)
7705 : GET_MODE (sh_compare_op1),
7706 sh_compare_op1);
7707
7708 emit_insn (gen_cmpgtudi_media (operands[0],
7709 sh_compare_op1, sh_compare_op0));
7710 DONE;
7711 }
7712 operands[1] = prepare_scc_operands (LTU);
7713}")
bc45ade3
SC
7714
7715(define_expand "sleu"
aa684c94 7716 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7717 (match_dup 1))]
7718 ""
fa5322fa
AO
7719 "
7720{
7721 if (TARGET_SHMEDIA)
7722 {
7723 rtx tmp;
7724
7725 if (GET_MODE (operands[0]) != DImode)
7726 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7727 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7728 if (sh_compare_op1 != const0_rtx)
7729 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7730 ? GET_MODE (sh_compare_op0)
7731 : GET_MODE (sh_compare_op1),
7732 sh_compare_op1);
7733
7734 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7735
7736 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7737 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7738
7739 DONE;
7740 }
7741 operands[1] = prepare_scc_operands (LEU);
7742}")
bc45ade3
SC
7743
7744(define_expand "sgeu"
aa684c94 7745 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
7746 (match_dup 1))]
7747 ""
fa5322fa
AO
7748 "
7749{
7750 if (TARGET_SHMEDIA)
7751 {
7752 rtx tmp;
7753
7754 if (GET_MODE (operands[0]) != DImode)
7755 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7756 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7757 if (sh_compare_op1 != const0_rtx)
7758 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7759 ? GET_MODE (sh_compare_op0)
7760 : GET_MODE (sh_compare_op1),
7761 sh_compare_op1);
7762
7763 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7764
7765 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7766 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7767
7768 DONE;
7769 }
7770
7771 operands[1] = prepare_scc_operands (GEU);
7772}")
bc45ade3 7773
8bca10f4
JW
7774;; sne moves the complement of the T reg to DEST like this:
7775;; cmp/eq ...
7776;; mov #-1,temp
7777;; negc temp,dest
7778;; This is better than xoring compare result with 1 because it does
7779;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7780;; loop.
7781
bc45ade3 7782(define_expand "sne"
8bca10f4
JW
7783 [(set (match_dup 2) (const_int -1))
7784 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7785 (neg:SI (plus:SI (match_dup 1)
7786 (match_dup 2))))
4773afa4 7787 (set (reg:SI T_REG)
8bca10f4 7788 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
52702ae1 7789 (const_int 0)))])]
8bca10f4
JW
7790 ""
7791 "
7792{
fa5322fa
AO
7793 if (TARGET_SHMEDIA)
7794 {
7795 rtx tmp;
7796
7797 if (GET_MODE (operands[0]) != DImode)
7798 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7799
7800 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7801 FAIL;
7802
7803 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7804 if (sh_compare_op1 != const0_rtx)
7805 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7806 ? GET_MODE (sh_compare_op0)
7807 : GET_MODE (sh_compare_op1),
7808 sh_compare_op1);
7809
7810 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7811
7812 emit_insn (gen_seq (tmp));
7813 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7814
7815 DONE;
7816 }
7817
8bca10f4
JW
7818 operands[1] = prepare_scc_operands (EQ);
7819 operands[2] = gen_reg_rtx (SImode);
7820}")
7821
fa5322fa
AO
7822(define_expand "sunordered"
7823 [(set (match_operand:DI 0 "arith_reg_operand" "")
7824 (unordered:DI (match_dup 1) (match_dup 2)))]
7825 "TARGET_SHMEDIA_FPU"
7826 "
7827{
7828 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7829 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7830}")
7831
1245df60
R
7832;; Use the same trick for FP sle / sge
7833(define_expand "movnegt"
7834 [(set (match_dup 2) (const_int -1))
7835 (parallel [(set (match_operand 0 "" "")
7836 (neg:SI (plus:SI (match_dup 1)
7837 (match_dup 2))))
4773afa4 7838 (set (reg:SI T_REG)
1245df60 7839 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
52702ae1 7840 (const_int 0)))])]
fa5322fa 7841 "TARGET_SH1"
1245df60
R
7842 "operands[2] = gen_reg_rtx (SImode);")
7843
8bca10f4 7844;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
956d6950 7845;; This prevents a regression that occurred when we switched from xor to
8bca10f4
JW
7846;; mov/neg for sne.
7847
7848(define_split
aa684c94 7849 [(set (match_operand:SI 0 "arith_reg_operand" "")
4773afa4 7850 (plus:SI (reg:SI T_REG)
8bca10f4 7851 (const_int -1)))]
fa5322fa 7852 "TARGET_SH1"
4773afa4 7853 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
8bca10f4
JW
7854 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7855 "")
bc45ade3 7856
0d7e008e
SC
7857;; -------------------------------------------------------------------------
7858;; Instructions to cope with inline literal tables
7859;; -------------------------------------------------------------------------
7860
7861; 2 byte integer in line
b9654711 7862
0d7e008e 7863(define_insn "consttable_2"
b91455de
KK
7864 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7865 (match_operand 1 "" "")]
4773afa4 7866 UNSPECV_CONST2)]
0d7e008e
SC
7867 ""
7868 "*
7869{
b91455de 7870 if (operands[1] != const0_rtx)
c8af3574 7871 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
0d7e008e
SC
7872 return \"\";
7873}"
7874 [(set_attr "length" "2")
7875 (set_attr "in_delay_slot" "no")])
7876
7877; 4 byte integer in line
7878
7879(define_insn "consttable_4"
b91455de
KK
7880 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7881 (match_operand 1 "" "")]
4773afa4 7882 UNSPECV_CONST4)]
0d7e008e
SC
7883 ""
7884 "*
7885{
b91455de 7886 if (operands[1] != const0_rtx)
c8af3574 7887 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
0d7e008e
SC
7888 return \"\";
7889}"
7890 [(set_attr "length" "4")
7891 (set_attr "in_delay_slot" "no")])
7892
7893; 8 byte integer in line
7894
7895(define_insn "consttable_8"
b91455de
KK
7896 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7897 (match_operand 1 "" "")]
4773afa4 7898 UNSPECV_CONST8)]
0d7e008e
SC
7899 ""
7900 "*
7901{
b91455de 7902 if (operands[1] != const0_rtx)
c8af3574 7903 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
0d7e008e
SC
7904 return \"\";
7905}"
7906 [(set_attr "length" "8")
7907 (set_attr "in_delay_slot" "no")])
7908
3e943b59
JR
7909; 4 byte floating point
7910
7911(define_insn "consttable_sf"
b91455de
KK
7912 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7913 (match_operand 1 "" "")]
4773afa4 7914 UNSPECV_CONST4)]
3e943b59
JR
7915 ""
7916 "*
7917{
b91455de
KK
7918 if (operands[1] != const0_rtx)
7919 {
85654444
ZW
7920 REAL_VALUE_TYPE d;
7921 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7922 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
b91455de 7923 }
3e943b59
JR
7924 return \"\";
7925}"
7926 [(set_attr "length" "4")
7927 (set_attr "in_delay_slot" "no")])
7928
7929; 8 byte floating point
7930
7931(define_insn "consttable_df"
b91455de
KK
7932 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7933 (match_operand 1 "" "")]
4773afa4 7934 UNSPECV_CONST8)]
3e943b59
JR
7935 ""
7936 "*
7937{
b91455de
KK
7938 if (operands[1] != const0_rtx)
7939 {
85654444
ZW
7940 REAL_VALUE_TYPE d;
7941 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7942 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
b91455de 7943 }
3e943b59
JR
7944 return \"\";
7945}"
7946 [(set_attr "length" "8")
7947 (set_attr "in_delay_slot" "no")])
7948
1245df60
R
7949;; Alignment is needed for some constant tables; it may also be added for
7950;; Instructions at the start of loops, or after unconditional branches.
7951;; ??? We would get more accurate lengths if we did instruction
7952;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7953;; here is too conservative.
7954
0d7e008e
SC
7955; align to a two byte boundary
7956
33f7f353 7957(define_expand "align_2"
4773afa4 7958 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
0d7e008e 7959 ""
33f7f353 7960 "")
0d7e008e
SC
7961
7962; align to a four byte boundary
1245df60
R
7963;; align_4 and align_log are instructions for the starts of loops, or
7964;; after unconditional branches, which may take up extra room.
7965
7966(define_expand "align_4"
4773afa4 7967 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
1245df60
R
7968 ""
7969 "")
7970
7971; align to a cache line boundary
0d7e008e 7972
1245df60 7973(define_insn "align_log"
4773afa4 7974 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
0d7e008e 7975 ""
33f7f353
JR
7976 ""
7977 [(set_attr "length" "0")
1245df60 7978 (set_attr "in_delay_slot" "no")])
0d7e008e
SC
7979
7980; emitted at the end of the literal table, used to emit the
7981; 32bit branch labels if needed.
7982
7983(define_insn "consttable_end"
4773afa4 7984 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
0d7e008e
SC
7985 ""
7986 "* return output_jump_label_table ();"
7987 [(set_attr "in_delay_slot" "no")])
7988
b91455de
KK
7989; emitted at the end of the window in the literal table.
7990
7991(define_insn "consttable_window_end"
7992 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7993 ""
7994 ""
7995 [(set_attr "length" "0")
7996 (set_attr "in_delay_slot" "no")])
7997
0d7e008e
SC
7998;; -------------------------------------------------------------------------
7999;; Misc
8000;; -------------------------------------------------------------------------
8001
07a45e5c 8002;; String/block move insn.
0d7e008e
SC
8003
8004(define_expand "movstrsi"
8005 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8006 (mem:BLK (match_operand:BLK 1 "" "")))
8007 (use (match_operand:SI 2 "nonmemory_operand" ""))
8008 (use (match_operand:SI 3 "immediate_operand" ""))
4773afa4
AO
8009 (clobber (reg:SI PR_REG))
8010 (clobber (reg:SI R4_REG))
8011 (clobber (reg:SI R5_REG))
8012 (clobber (reg:SI R0_REG))])]
fa5322fa 8013 "TARGET_SH1 && ! TARGET_SH5"
0d7e008e
SC
8014 "
8015{
8016 if(expand_block_move (operands))
8017 DONE;
8018 else FAIL;
8019}")
8020
8021(define_insn "block_move_real"
4773afa4
AO
8022 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8023 (mem:BLK (reg:SI R5_REG)))
0d7e008e 8024 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8025 (clobber (reg:SI PR_REG))
8026 (clobber (reg:SI R0_REG))])]
fa5322fa 8027 "TARGET_SH1 && ! TARGET_HARD_SH4"
0d7e008e 8028 "jsr @%0%#"
22e1ebf1 8029 [(set_attr "type" "sfunc")
0d7e008e
SC
8030 (set_attr "needs_delay_slot" "yes")])
8031
8032(define_insn "block_lump_real"
4773afa4
AO
8033 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8034 (mem:BLK (reg:SI R5_REG)))
0d7e008e 8035 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8036 (use (reg:SI R6_REG))
8037 (clobber (reg:SI PR_REG))
8038 (clobber (reg:SI T_REG))
8039 (clobber (reg:SI R4_REG))
8040 (clobber (reg:SI R5_REG))
8041 (clobber (reg:SI R6_REG))
8042 (clobber (reg:SI R0_REG))])]
fa5322fa 8043 "TARGET_SH1 && ! TARGET_HARD_SH4"
225e4f43
R
8044 "jsr @%0%#"
8045 [(set_attr "type" "sfunc")
8046 (set_attr "needs_delay_slot" "yes")])
8047
8048(define_insn "block_move_real_i4"
4773afa4
AO
8049 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8050 (mem:BLK (reg:SI R5_REG)))
225e4f43 8051 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8052 (clobber (reg:SI PR_REG))
8053 (clobber (reg:SI R0_REG))
8054 (clobber (reg:SI R1_REG))
8055 (clobber (reg:SI R2_REG))])]
225e4f43
R
8056 "TARGET_HARD_SH4"
8057 "jsr @%0%#"
8058 [(set_attr "type" "sfunc")
8059 (set_attr "needs_delay_slot" "yes")])
8060
8061(define_insn "block_lump_real_i4"
4773afa4
AO
8062 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8063 (mem:BLK (reg:SI R5_REG)))
225e4f43 8064 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4773afa4
AO
8065 (use (reg:SI R6_REG))
8066 (clobber (reg:SI PR_REG))
8067 (clobber (reg:SI T_REG))
8068 (clobber (reg:SI R4_REG))
8069 (clobber (reg:SI R5_REG))
8070 (clobber (reg:SI R6_REG))
8071 (clobber (reg:SI R0_REG))
8072 (clobber (reg:SI R1_REG))
8073 (clobber (reg:SI R2_REG))
8074 (clobber (reg:SI R3_REG))])]
225e4f43 8075 "TARGET_HARD_SH4"
0d7e008e 8076 "jsr @%0%#"
22e1ebf1 8077 [(set_attr "type" "sfunc")
0d7e008e 8078 (set_attr "needs_delay_slot" "yes")])
45348d9e
JW
8079\f
8080;; -------------------------------------------------------------------------
8081;; Floating point instructions.
8082;; -------------------------------------------------------------------------
8083
8084;; ??? All patterns should have a type attribute.
8085
225e4f43 8086(define_expand "fpu_switch0"
8845e874
AO
8087 [(set (match_operand:SI 0 "" "") (match_dup 2))
8088 (set (match_dup 1) (mem:PSI (match_dup 0)))]
ecfdeaeb 8089 "TARGET_SH4"
225e4f43
R
8090 "
8091{
8845e874
AO
8092 operands[1] = get_fpscr_rtx ();
8093 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
8094 if (flag_pic)
8095 operands[2] = legitimize_pic_address (operands[2], SImode,
8096 no_new_pseudos ? operands[0] : 0);
225e4f43
R
8097}")
8098
8099(define_expand "fpu_switch1"
8845e874
AO
8100 [(set (match_operand:SI 0 "" "") (match_dup 2))
8101 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8102 (set (match_dup 1) (mem:PSI (match_dup 3)))]
ecfdeaeb 8103 "TARGET_SH4"
225e4f43
R
8104 "
8105{
8845e874
AO
8106 operands[1] = get_fpscr_rtx ();
8107 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
1a66cd67
AO
8108 if (flag_pic)
8109 operands[2] = legitimize_pic_address (operands[2], SImode,
8110 no_new_pseudos ? operands[0] : 0);
8845e874 8111 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
225e4f43
R
8112}")
8113
8114(define_expand "movpsi"
8115 [(set (match_operand:PSI 0 "register_operand" "")
8116 (match_operand:PSI 1 "general_movsrc_operand" ""))]
ecfdeaeb 8117 "TARGET_SH4"
225e4f43
R
8118 "")
8119
8120;; The c / m alternative is a fake to guide reload to load directly into
8121;; fpscr, since reload doesn't know how to use post-increment.
8122;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8123;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8124;; predicate after reload.
c49439f1
R
8125;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8126;; like a mac -> gpr move.
225e4f43 8127(define_insn "fpu_switch"
7144b2d8
DD
8128 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8129 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
603ff6b5 8130 "TARGET_SH2E
ecfdeaeb
AO
8131 && (! reload_completed
8132 || true_regnum (operands[0]) != FPSCR_REG
8133 || GET_CODE (operands[1]) != MEM
8134 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
225e4f43
R
8135 "@
8136 ! precision stays the same
8137 lds.l %1,fpscr
8138 mov.l %1,%0
8139 #
8140 lds %1,fpscr
8141 mov %1,%0
8142 mov.l %1,%0
7144b2d8
DD
8143 sts fpscr,%0
8144 sts.l fpscr,%0"
8145 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8146 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
225e4f43
R
8147
8148(define_split
4773afa4 8149 [(set (reg:PSI FPSCR_REG)
c1b92d09 8150 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 8151 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
225e4f43
R
8152 [(set (match_dup 0) (match_dup 0))]
8153 "
8154{
8155 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8156 gen_rtx (MEM, PSImode,
8157 gen_rtx (POST_INC, Pmode,
8158 operands[0]))));
8159 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8160}")
8161
8162(define_split
4773afa4 8163 [(set (reg:PSI FPSCR_REG)
c1b92d09 8164 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
ecfdeaeb 8165 "TARGET_SH4"
225e4f43
R
8166 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8167 "
8168{
8169 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8170 gen_rtx (MEM, PSImode,
8171 gen_rtx (POST_INC, Pmode,
8172 operands[0]))));
8173 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8174}")
8175
8176;; ??? This uses the fp unit, but has no type indicating that.
8177;; If we did that, this would either give a bogus latency or introduce
8178;; a bogus FIFO constraint.
8179;; Since this insn is currently only used for prologues/epilogues,
8180;; it is probably best to claim no function unit, which matches the
8181;; current setting.
8182(define_insn "toggle_sz"
4773afa4
AO
8183 [(set (reg:PSI FPSCR_REG)
8184 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
225e4f43 8185 "TARGET_SH4"
73774972
EC
8186 "fschg"
8187 [(set_attr "fp_set" "unknown")])
225e4f43
R
8188
8189(define_expand "addsf3"
fa5322fa
AO
8190 [(set (match_operand:SF 0 "arith_reg_operand" "")
8191 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8192 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 8193 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8194 "
8195{
3a8699c7 8196 if (TARGET_SH2E)
fa5322fa
AO
8197 {
8198 expand_sf_binop (&gen_addsf3_i, operands);
8199 DONE;
8200 }
8201}")
8202
8203(define_insn "*addsf3_media"
8204 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8205 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8206 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8207 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8208 "fadd.s %1, %2, %0"
8209 [(set_attr "type" "fparith_media")])
225e4f43 8210
0ac78517
R
8211(define_insn_and_split "unary_sf_op"
8212 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8213 (vec_select:V2SF
8214 (vec_concat:V2SF
8215 (vec_select:SF
8216 (match_dup 0)
8217 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8218 (match_operator:SF 2 "unary_float_operator"
8219 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8220 (parallel [(match_operand 4
8221 "const_int_operand" "n")]))]))
8222 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8223 "TARGET_SHMEDIA_FPU"
8224 "#"
8225 "TARGET_SHMEDIA_FPU && reload_completed"
8226 [(set (match_dup 5) (match_dup 6))]
8227 "
8228{
8229 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8230 rtx op1 = gen_rtx_REG (SFmode,
8231 (true_regnum (operands[1])
8232 + (INTVAL (operands[4]) ^ endian)));
8233
8234 operands[7] = gen_rtx_REG (SFmode,
8235 (true_regnum (operands[0])
8236 + (INTVAL (operands[3]) ^ endian)));
8237 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8238}"
8239 [(set_attr "type" "fparith_media")])
8240
8241(define_insn_and_split "binary_sf_op"
8242 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8243 (vec_select:V2SF
8244 (vec_concat:V2SF
8245 (vec_select:SF
8246 (match_dup 0)
a93d1ba2 8247 (parallel [(match_operand 7 "const_int_operand" "n")]))
0ac78517
R
8248 (match_operator:SF 3 "binary_float_operator"
8249 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8250 (parallel [(match_operand 5
8251 "const_int_operand" "n")]))
8252 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8253 (parallel [(match_operand 6
8254 "const_int_operand" "n")]))]))
a93d1ba2
R
8255 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8256 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
0ac78517 8257 "#"
a93d1ba2
R
8258 "&& reload_completed"
8259 [(set (match_dup 8) (match_dup 9))]
0ac78517
R
8260 "
8261{
8262 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8263 rtx op1 = gen_rtx_REG (SFmode,
8264 (true_regnum (operands[1])
8265 + (INTVAL (operands[5]) ^ endian)));
8266 rtx op2 = gen_rtx_REG (SFmode,
8267 (true_regnum (operands[2])
8268 + (INTVAL (operands[6]) ^ endian)));
8269
a93d1ba2 8270 operands[8] = gen_rtx_REG (SFmode,
0ac78517
R
8271 (true_regnum (operands[0])
8272 + (INTVAL (operands[4]) ^ endian)));
a93d1ba2 8273 operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
0ac78517
R
8274}"
8275 [(set_attr "type" "fparith_media")])
8276
225e4f43 8277(define_insn "addsf3_i"
45348d9e
JW
8278 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8279 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
225e4f43
R
8280 (match_operand:SF 2 "arith_reg_operand" "f")))
8281 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8282 "TARGET_SH2E"
c1aef54d 8283 "fadd %2,%0"
d64264ff
R
8284 [(set_attr "type" "fp")
8285 (set_attr "fp_mode" "single")])
45348d9e 8286
225e4f43 8287(define_expand "subsf3"
fa5322fa
AO
8288 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8289 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8290 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 8291 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8292 "
8293{
3a8699c7 8294 if (TARGET_SH2E)
fa5322fa
AO
8295 {
8296 expand_sf_binop (&gen_subsf3_i, operands);
8297 DONE;
8298 }
8299}")
8300
8301(define_insn "*subsf3_media"
8302 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8303 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8304 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8305 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8306 "fsub.s %1, %2, %0"
8307 [(set_attr "type" "fparith_media")])
225e4f43
R
8308
8309(define_insn "subsf3_i"
66c0b347
R
8310 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8311 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8312 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8313 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8314 "TARGET_SH2E"
c1aef54d 8315 "fsub %2,%0"
d64264ff
R
8316 [(set_attr "type" "fp")
8317 (set_attr "fp_mode" "single")])
45348d9e 8318
225e4f43
R
8319;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8320;; register in feeding fp instructions. Thus, we cannot generate fmac for
8321;; mixed-precision SH4 targets. To allow it to be still generated for the
8322;; SH3E, we use a separate insn for SH3E mulsf3.
8323
8324(define_expand "mulsf3"
fa5322fa
AO
8325 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8326 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8327 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
3a8699c7 8328 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8329 "
8330{
8331 if (TARGET_SH4)
8332 expand_sf_binop (&gen_mulsf3_i4, operands);
3a8699c7 8333 else if (TARGET_SH2E)
225e4f43 8334 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
fa5322fa
AO
8335 if (! TARGET_SHMEDIA)
8336 DONE;
225e4f43
R
8337}")
8338
fa5322fa
AO
8339(define_insn "*mulsf3_media"
8340 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8341 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8342 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8343 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8344 "fmul.s %1, %2, %0"
8345 [(set_attr "type" "fparith_media")])
fa5322fa 8346
225e4f43 8347(define_insn "mulsf3_i4"
4b9580a5
R
8348 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8349 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8350 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
225e4f43 8351 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8352 "TARGET_SH2E"
c1aef54d 8353 "fmul %2,%0"
d64264ff
R
8354 [(set_attr "type" "fp")
8355 (set_attr "fp_mode" "single")])
45348d9e 8356
225e4f43 8357(define_insn "mulsf3_ie"
4b9580a5
R
8358 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8359 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8360 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
3a8699c7 8361 "TARGET_SH2E && ! TARGET_SH4"
225e4f43
R
8362 "fmul %2,%0"
8363 [(set_attr "type" "fp")])
8364
fa5322fa
AO
8365(define_insn "*mac_media"
8366 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8367 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8368 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8369 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8370 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8371 "fmac.s %1, %2, %0"
8372 [(set_attr "type" "fparith_media")])
fa5322fa 8373
45348d9e 8374(define_insn "*macsf3"
4b9580a5
R
8375 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8376 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8377 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
225e4f43
R
8378 (match_operand:SF 3 "arith_reg_operand" "0")))
8379 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
3a8699c7 8380 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8381 "fmac fr0,%2,%0"
d64264ff
R
8382 [(set_attr "type" "fp")
8383 (set_attr "fp_mode" "single")])
45348d9e 8384
225e4f43 8385(define_expand "divsf3"
fa5322fa
AO
8386 [(set (match_operand:SF 0 "arith_reg_operand" "")
8387 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8388 (match_operand:SF 2 "arith_reg_operand" "")))]
3a8699c7 8389 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8390 "
8391{
3a8699c7 8392 if (TARGET_SH2E)
fa5322fa
AO
8393 {
8394 expand_sf_binop (&gen_divsf3_i, operands);
8395 DONE;
8396 }
8397}")
8398
8399(define_insn "*divsf3_media"
8400 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8401 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8402 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8403 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8404 "fdiv.s %1, %2, %0"
8405 [(set_attr "type" "fdiv_media")])
225e4f43
R
8406
8407(define_insn "divsf3_i"
45348d9e
JW
8408 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8409 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
225e4f43
R
8410 (match_operand:SF 2 "arith_reg_operand" "f")))
8411 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3a8699c7 8412 "TARGET_SH2E"
c1aef54d 8413 "fdiv %2,%0"
d64264ff
R
8414 [(set_attr "type" "fdiv")
8415 (set_attr "fp_mode" "single")])
45348d9e 8416
fa5322fa
AO
8417(define_insn "floatdisf2"
8418 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8419 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8420 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8421 "float.qs %1, %0"
8422 [(set_attr "type" "fpconv_media")])
fa5322fa 8423
1245df60 8424(define_expand "floatsisf2"
4b9580a5
R
8425 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8426 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
3a8699c7 8427 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8428 "
8429{
8430 if (TARGET_SH4)
8431 {
0c4c9b16 8432 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8433 DONE;
8434 }
225e4f43
R
8435}")
8436
fa5322fa
AO
8437(define_insn "*floatsisf2_media"
8438 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8439 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8440 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8441 "float.ls %1, %0"
8442 [(set_attr "type" "fpconv_media")])
fa5322fa 8443
225e4f43 8444(define_insn "floatsisf2_i4"
4b9580a5
R
8445 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8446 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8447 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
0f805606 8448 "TARGET_SH4"
0c4c9b16 8449 "float %1,%0"
d64264ff
R
8450 [(set_attr "type" "fp")
8451 (set_attr "fp_mode" "single")])
45348d9e 8452
0f805606 8453(define_insn "*floatsisf2_ie"
4b9580a5
R
8454 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8455 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
3a8699c7 8456 "TARGET_SH2E && ! TARGET_SH4"
0f805606
BS
8457 "float %1,%0"
8458 [(set_attr "type" "fp")])
45348d9e 8459
fa5322fa
AO
8460(define_insn "fix_truncsfdi2"
8461 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8462 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8463 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8464 "ftrc.sq %1, %0"
8465 [(set_attr "type" "fpconv_media")])
fa5322fa 8466
1245df60 8467(define_expand "fix_truncsfsi2"
4b9580a5
R
8468 [(set (match_operand:SI 0 "fpul_operand" "=y")
8469 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8470 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
225e4f43
R
8471 "
8472{
8473 if (TARGET_SH4)
8474 {
0c4c9b16 8475 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
225e4f43
R
8476 DONE;
8477 }
8478}")
8479
fa5322fa
AO
8480(define_insn "*fix_truncsfsi2_media"
8481 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8482 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8483 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8484 "ftrc.sl %1, %0"
8485 [(set_attr "type" "fpconv_media")])
fa5322fa 8486
225e4f43 8487(define_insn "fix_truncsfsi2_i4"
4b9580a5
R
8488 [(set (match_operand:SI 0 "fpul_operand" "=y")
8489 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8490 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8491 "TARGET_SH4"
0c4c9b16 8492 "ftrc %1,%0"
c49439f1 8493 [(set_attr "type" "ftrc_s")
d64264ff 8494 (set_attr "fp_mode" "single")])
225e4f43 8495
0c4c9b16
BS
8496;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8497;; fix_truncsfsi2_i4.
8498;; (define_insn "fix_truncsfsi2_i4_2"
8499;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8500;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
5d00b10a 8501;; (use (reg:PSI FPSCR_REG))
4773afa4 8502;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8503;; "TARGET_SH4"
8504;; "#"
8505;; [(set_attr "length" "4")
8506;; (set_attr "fp_mode" "single")])
8507
8508;;(define_split
8509;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8510;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8511;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8512;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8513;; "TARGET_SH4"
4773afa4 8514;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8515;; (use (match_dup 2))])
4773afa4 8516;; (set (match_dup 0) (reg:SI FPUL_REG))])
45348d9e 8517
1245df60 8518(define_insn "*fixsfsi"
4b9580a5
R
8519 [(set (match_operand:SI 0 "fpul_operand" "=y")
8520 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8521 "TARGET_SH2E && ! TARGET_SH4"
0c4c9b16 8522 "ftrc %1,%0"
1245df60 8523 [(set_attr "type" "fp")])
45348d9e 8524
1245df60 8525(define_insn "cmpgtsf_t"
4773afa4
AO
8526 [(set (reg:SI T_REG)
8527 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8528 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8529 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8530 "fcmp/gt %1,%0"
d64264ff
R
8531 [(set_attr "type" "fp")
8532 (set_attr "fp_mode" "single")])
45348d9e 8533
1245df60 8534(define_insn "cmpeqsf_t"
4773afa4
AO
8535 [(set (reg:SI T_REG)
8536 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8537 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
3a8699c7 8538 "TARGET_SH2E && ! TARGET_SH4"
c1aef54d 8539 "fcmp/eq %1,%0"
d64264ff
R
8540 [(set_attr "type" "fp")
8541 (set_attr "fp_mode" "single")])
45348d9e 8542
1245df60 8543(define_insn "ieee_ccmpeqsf_t"
4773afa4
AO
8544 [(set (reg:SI T_REG)
8545 (ior:SI (reg:SI T_REG)
4b9580a5
R
8546 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8547 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
3a8699c7 8548 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
1245df60
R
8549 "* return output_ieee_ccmpeq (insn, operands);"
8550 [(set_attr "length" "4")])
8551
8552
225e4f43 8553(define_insn "cmpgtsf_t_i4"
4773afa4
AO
8554 [(set (reg:SI T_REG)
8555 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8556 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8557 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8558 "TARGET_SH4"
8559 "fcmp/gt %1,%0"
d64264ff
R
8560 [(set_attr "type" "fp")
8561 (set_attr "fp_mode" "single")])
225e4f43
R
8562
8563(define_insn "cmpeqsf_t_i4"
4773afa4
AO
8564 [(set (reg:SI T_REG)
8565 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8566 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
225e4f43
R
8567 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8568 "TARGET_SH4"
8569 "fcmp/eq %1,%0"
d64264ff
R
8570 [(set_attr "type" "fp")
8571 (set_attr "fp_mode" "single")])
225e4f43
R
8572
8573(define_insn "*ieee_ccmpeqsf_t_4"
4773afa4
AO
8574 [(set (reg:SI T_REG)
8575 (ior:SI (reg:SI T_REG)
4b9580a5
R
8576 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8577 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
225e4f43
R
8578 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8579 "TARGET_IEEE && TARGET_SH4"
8580 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8581 [(set_attr "length" "4")
8582 (set_attr "fp_mode" "single")])
225e4f43 8583
fa5322fa
AO
8584(define_insn "cmpeqsf_media"
8585 [(set (match_operand:DI 0 "register_operand" "=r")
8586 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8587 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8588 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8589 "fcmpeq.s %1, %2, %0"
8590 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8591
8592(define_insn "cmpgtsf_media"
8593 [(set (match_operand:DI 0 "register_operand" "=r")
8594 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8595 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8596 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8597 "fcmpgt.s %1, %2, %0"
8598 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8599
8600(define_insn "cmpgesf_media"
8601 [(set (match_operand:DI 0 "register_operand" "=r")
8602 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8603 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8604 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8605 "fcmpge.s %1, %2, %0"
8606 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8607
8608(define_insn "cmpunsf_media"
8609 [(set (match_operand:DI 0 "register_operand" "=r")
8610 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8611 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8612 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8613 "fcmpun.s %1, %2, %0"
8614 [(set_attr "type" "fcmp_media")])
fa5322fa 8615
45348d9e 8616(define_expand "cmpsf"
4773afa4
AO
8617 [(set (reg:SI T_REG)
8618 (compare (match_operand:SF 0 "arith_operand" "")
8619 (match_operand:SF 1 "arith_operand" "")))]
3a8699c7 8620 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
45348d9e
JW
8621 "
8622{
8623 sh_compare_op0 = operands[0];
8624 sh_compare_op1 = operands[1];
8625 DONE;
8626}")
b9654711 8627
225e4f43 8628(define_expand "negsf2"
fa5322fa
AO
8629 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8630 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 8631 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8632 "
8633{
3a8699c7 8634 if (TARGET_SH2E)
fa5322fa
AO
8635 {
8636 expand_sf_unop (&gen_negsf2_i, operands);
8637 DONE;
8638 }
8639}")
8640
8641(define_insn "*negsf2_media"
8642 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8643 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8644 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8645 "fneg.s %1, %0"
8646 [(set_attr "type" "fmove_media")])
225e4f43
R
8647
8648(define_insn "negsf2_i"
4b9580a5
R
8649 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8650 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8651 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 8652 "TARGET_SH2E"
c1aef54d 8653 "fneg %0"
d64264ff
R
8654 [(set_attr "type" "fmove")
8655 (set_attr "fp_mode" "single")])
45348d9e 8656
225e4f43 8657(define_expand "sqrtsf2"
fa5322fa
AO
8658 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8659 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8660 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8661 "
8662{
8663 if (TARGET_SH3E)
8664 {
8665 expand_sf_unop (&gen_sqrtsf2_i, operands);
8666 DONE;
8667 }
8668}")
8669
8670(define_insn "*sqrtsf2_media"
8671 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8672 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8673 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8674 "fsqrt.s %1, %0"
8675 [(set_attr "type" "fdiv_media")])
225e4f43
R
8676
8677(define_insn "sqrtsf2_i"
4b9580a5
R
8678 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8679 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8680 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
45348d9e 8681 "TARGET_SH3E"
c1aef54d 8682 "fsqrt %0"
d64264ff
R
8683 [(set_attr "type" "fdiv")
8684 (set_attr "fp_mode" "single")])
45348d9e 8685
225e4f43 8686(define_expand "abssf2"
fa5322fa
AO
8687 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8688 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
3a8699c7 8689 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
fa5322fa
AO
8690 "
8691{
3a8699c7 8692 if (TARGET_SH2E)
fa5322fa
AO
8693 {
8694 expand_sf_unop (&gen_abssf2_i, operands);
8695 DONE;
8696 }
8697}")
8698
8699(define_insn "*abssf2_media"
8700 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8701 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8702 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8703 "fabs.s %1, %0"
8704 [(set_attr "type" "fmove_media")])
225e4f43
R
8705
8706(define_insn "abssf2_i"
4b9580a5
R
8707 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8708 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
225e4f43 8709 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
3a8699c7 8710 "TARGET_SH2E"
c1aef54d 8711 "fabs %0"
d64264ff
R
8712 [(set_attr "type" "fmove")
8713 (set_attr "fp_mode" "single")])
225e4f43
R
8714
8715(define_expand "adddf3"
fa5322fa
AO
8716 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8717 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8718 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8719 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8720 "
8721{
8722 if (TARGET_SH4)
8723 {
8724 expand_df_binop (&gen_adddf3_i, operands);
8725 DONE;
8726 }
8727}")
8728
8729(define_insn "*adddf3_media"
8730 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8731 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8732 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8733 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8734 "fadd.d %1, %2, %0"
8735 [(set_attr "type" "dfparith_media")])
225e4f43
R
8736
8737(define_insn "adddf3_i"
4b9580a5
R
8738 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8739 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8740 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8741 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8742 "TARGET_SH4"
8743 "fadd %2,%0"
d64264ff
R
8744 [(set_attr "type" "dfp_arith")
8745 (set_attr "fp_mode" "double")])
225e4f43
R
8746
8747(define_expand "subdf3"
fa5322fa
AO
8748 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8749 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8750 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8751 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8752 "
8753{
8754 if (TARGET_SH4)
8755 {
8756 expand_df_binop (&gen_subdf3_i, operands);
8757 DONE;
8758 }
8759}")
8760
8761(define_insn "*subdf3_media"
8762 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8763 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8764 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8765 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8766 "fsub.d %1, %2, %0"
8767 [(set_attr "type" "dfparith_media")])
225e4f43
R
8768
8769(define_insn "subdf3_i"
4b9580a5
R
8770 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8771 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8772 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8773 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8774 "TARGET_SH4"
8775 "fsub %2,%0"
d64264ff
R
8776 [(set_attr "type" "dfp_arith")
8777 (set_attr "fp_mode" "double")])
225e4f43
R
8778
8779(define_expand "muldf3"
fa5322fa
AO
8780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8781 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8782 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8783 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8784 "
8785{
8786 if (TARGET_SH4)
8787 {
8788 expand_df_binop (&gen_muldf3_i, operands);
8789 DONE;
8790 }
8791}")
8792
8793(define_insn "*muldf3_media"
8794 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8795 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8796 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8797 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8798 "fmul.d %1, %2, %0"
8799 [(set_attr "type" "dfmul_media")])
225e4f43
R
8800
8801(define_insn "muldf3_i"
4b9580a5
R
8802 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8803 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8804 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8805 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8806 "TARGET_SH4"
8807 "fmul %2,%0"
d64264ff
R
8808 [(set_attr "type" "dfp_arith")
8809 (set_attr "fp_mode" "double")])
225e4f43
R
8810
8811(define_expand "divdf3"
fa5322fa
AO
8812 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8813 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8814 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8815 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8816 "
8817{
8818 if (TARGET_SH4)
8819 {
8820 expand_df_binop (&gen_divdf3_i, operands);
8821 DONE;
8822 }
8823}")
8824
8825(define_insn "*divdf3_media"
8826 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8827 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8828 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8829 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8830 "fdiv.d %1, %2, %0"
8831 [(set_attr "type" "dfdiv_media")])
225e4f43
R
8832
8833(define_insn "divdf3_i"
4b9580a5
R
8834 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8835 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8836 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
225e4f43
R
8837 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8838 "TARGET_SH4"
8839 "fdiv %2,%0"
d64264ff
R
8840 [(set_attr "type" "dfdiv")
8841 (set_attr "fp_mode" "double")])
225e4f43 8842
fa5322fa
AO
8843(define_insn "floatdidf2"
8844 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8845 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8846 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8847 "float.qd %1, %0"
8848 [(set_attr "type" "dfpconv_media")])
fa5322fa 8849
225e4f43 8850(define_expand "floatsidf2"
fa5322fa
AO
8851 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8852 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8853 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8854 "
8855{
fa5322fa
AO
8856 if (TARGET_SH4)
8857 {
8858 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8859 get_fpscr_rtx ()));
8860 DONE;
8861 }
225e4f43
R
8862}")
8863
fa5322fa
AO
8864(define_insn "*floatsidf2_media"
8865 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8866 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8867 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8868 "float.ld %1, %0"
8869 [(set_attr "type" "dfpconv_media")])
fa5322fa 8870
225e4f43 8871(define_insn "floatsidf2_i"
4b9580a5
R
8872 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8873 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
0c4c9b16 8874 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8875 "TARGET_SH4"
0c4c9b16 8876 "float %1,%0"
d64264ff
R
8877 [(set_attr "type" "dfp_conv")
8878 (set_attr "fp_mode" "double")])
225e4f43 8879
fa5322fa
AO
8880(define_insn "fix_truncdfdi2"
8881 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8882 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8883 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8884 "ftrc.dq %1, %0"
8885 [(set_attr "type" "dfpconv_media")])
fa5322fa 8886
225e4f43 8887(define_expand "fix_truncdfsi2"
fa5322fa
AO
8888 [(set (match_operand:SI 0 "fpul_operand" "")
8889 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8890 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
8891 "
8892{
fa5322fa
AO
8893 if (TARGET_SH4)
8894 {
8895 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8896 get_fpscr_rtx ()));
8897 DONE;
8898 }
225e4f43
R
8899}")
8900
fa5322fa
AO
8901(define_insn "*fix_truncdfsi2_media"
8902 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8903 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8904 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8905 "ftrc.dl %1, %0"
8906 [(set_attr "type" "dfpconv_media")])
fa5322fa 8907
225e4f43 8908(define_insn "fix_truncdfsi2_i"
4b9580a5
R
8909 [(set (match_operand:SI 0 "fpul_operand" "=y")
8910 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 8911 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 8912 "TARGET_SH4"
0c4c9b16
BS
8913 "ftrc %1,%0"
8914 [(set_attr "type" "dfp_conv")
c49439f1 8915 (set_attr "dfp_comp" "no")
d64264ff 8916 (set_attr "fp_mode" "double")])
225e4f43 8917
0c4c9b16
BS
8918;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8919;; fix_truncdfsi2_i.
8920;; (define_insn "fix_truncdfsi2_i4"
8921;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8922;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8923;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8924;; (clobber (reg:SI FPUL_REG))]
0c4c9b16
BS
8925;; "TARGET_SH4"
8926;; "#"
8927;; [(set_attr "length" "4")
8928;; (set_attr "fp_mode" "double")])
52702ae1 8929;;
0c4c9b16
BS
8930;; (define_split
8931;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8932;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8933;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4773afa4 8934;; (clobber (reg:SI FPUL_REG))]
0c4c9b16 8935;; "TARGET_SH4"
4773afa4 8936;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
0c4c9b16 8937;; (use (match_dup 2))])
4773afa4 8938;; (set (match_dup 0) (reg:SI FPUL_REG))])
225e4f43
R
8939
8940(define_insn "cmpgtdf_t"
4773afa4
AO
8941 [(set (reg:SI T_REG)
8942 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8943 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
8944 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8945 "TARGET_SH4"
8946 "fcmp/gt %1,%0"
d64264ff
R
8947 [(set_attr "type" "dfp_cmp")
8948 (set_attr "fp_mode" "double")])
225e4f43
R
8949
8950(define_insn "cmpeqdf_t"
4773afa4
AO
8951 [(set (reg:SI T_REG)
8952 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8953 (match_operand:DF 1 "arith_reg_operand" "f")))
225e4f43
R
8954 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8955 "TARGET_SH4"
8956 "fcmp/eq %1,%0"
d64264ff
R
8957 [(set_attr "type" "dfp_cmp")
8958 (set_attr "fp_mode" "double")])
225e4f43
R
8959
8960(define_insn "*ieee_ccmpeqdf_t"
4773afa4
AO
8961 [(set (reg:SI T_REG)
8962 (ior:SI (reg:SI T_REG)
8963 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8964 (match_operand:DF 1 "arith_reg_operand" "f"))))
225e4f43
R
8965 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8966 "TARGET_IEEE && TARGET_SH4"
8967 "* return output_ieee_ccmpeq (insn, operands);"
d64264ff
R
8968 [(set_attr "length" "4")
8969 (set_attr "fp_mode" "double")])
52702ae1 8970
fa5322fa
AO
8971(define_insn "cmpeqdf_media"
8972 [(set (match_operand:DI 0 "register_operand" "=r")
8973 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8974 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8975 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8976 "fcmpeq.d %1,%2,%0"
8977 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8978
8979(define_insn "cmpgtdf_media"
8980 [(set (match_operand:DI 0 "register_operand" "=r")
8981 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8982 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8983 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8984 "fcmpgt.d %1,%2,%0"
8985 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8986
8987(define_insn "cmpgedf_media"
8988 [(set (match_operand:DI 0 "register_operand" "=r")
8989 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8990 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8991 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
8992 "fcmpge.d %1,%2,%0"
8993 [(set_attr "type" "fcmp_media")])
fa5322fa
AO
8994
8995(define_insn "cmpundf_media"
8996 [(set (match_operand:DI 0 "register_operand" "=r")
8997 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8998 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8999 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9000 "fcmpun.d %1,%2,%0"
9001 [(set_attr "type" "fcmp_media")])
fa5322fa 9002
225e4f43 9003(define_expand "cmpdf"
4773afa4
AO
9004 [(set (reg:SI T_REG)
9005 (compare (match_operand:DF 0 "arith_operand" "")
9006 (match_operand:DF 1 "arith_operand" "")))]
fa5322fa 9007 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9008 "
9009{
9010 sh_compare_op0 = operands[0];
9011 sh_compare_op1 = operands[1];
9012 DONE;
9013}")
9014
9015(define_expand "negdf2"
fa5322fa
AO
9016 [(set (match_operand:DF 0 "arith_reg_operand" "")
9017 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9018 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9019 "
9020{
9021 if (TARGET_SH4)
9022 {
9023 expand_df_unop (&gen_negdf2_i, operands);
9024 DONE;
9025 }
9026}")
9027
9028(define_insn "*negdf2_media"
9029 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9030 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9031 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9032 "fneg.d %1, %0"
9033 [(set_attr "type" "fmove_media")])
225e4f43
R
9034
9035(define_insn "negdf2_i"
9036 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9037 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9038 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9039 "TARGET_SH4"
9040 "fneg %0"
d64264ff
R
9041 [(set_attr "type" "fmove")
9042 (set_attr "fp_mode" "double")])
225e4f43
R
9043
9044(define_expand "sqrtdf2"
fa5322fa
AO
9045 [(set (match_operand:DF 0 "arith_reg_operand" "")
9046 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9047 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9048 "
9049{
9050 if (TARGET_SH4)
9051 {
9052 expand_df_unop (&gen_sqrtdf2_i, operands);
9053 DONE;
9054 }
9055}")
9056
9057(define_insn "*sqrtdf2_media"
9058 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9059 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9060 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9061 "fsqrt.d %1, %0"
9062 [(set_attr "type" "dfdiv_media")])
225e4f43
R
9063
9064(define_insn "sqrtdf2_i"
9065 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9066 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9067 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9068 "TARGET_SH4"
9069 "fsqrt %0"
d64264ff
R
9070 [(set_attr "type" "dfdiv")
9071 (set_attr "fp_mode" "double")])
225e4f43
R
9072
9073(define_expand "absdf2"
fa5322fa
AO
9074 [(set (match_operand:DF 0 "arith_reg_operand" "")
9075 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9076 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9077 "
9078{
9079 if (TARGET_SH4)
9080 {
9081 expand_df_unop (&gen_absdf2_i, operands);
9082 DONE;
9083 }
9084}")
9085
9086(define_insn "*absdf2_media"
9087 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9088 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9089 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9090 "fabs.d %1, %0"
9091 [(set_attr "type" "fmove_media")])
225e4f43
R
9092
9093(define_insn "absdf2_i"
9094 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9095 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9096 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9097 "TARGET_SH4"
9098 "fabs %0"
d64264ff
R
9099 [(set_attr "type" "fmove")
9100 (set_attr "fp_mode" "double")])
225e4f43
R
9101
9102(define_expand "extendsfdf2"
fa5322fa
AO
9103 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9104 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9105 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9106 "
9107{
fa5322fa
AO
9108 if (TARGET_SH4)
9109 {
9110 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9111 get_fpscr_rtx ()));
9112 DONE;
9113 }
225e4f43
R
9114}")
9115
fa5322fa
AO
9116(define_insn "*extendsfdf2_media"
9117 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9118 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9119 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9120 "fcnv.sd %1, %0"
9121 [(set_attr "type" "dfpconv_media")])
fa5322fa 9122
225e4f43 9123(define_insn "extendsfdf2_i4"
4b9580a5
R
9124 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9125 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
0c4c9b16 9126 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 9127 "TARGET_SH4"
0c4c9b16 9128 "fcnvsd %1,%0"
d64264ff
R
9129 [(set_attr "type" "fp")
9130 (set_attr "fp_mode" "double")])
225e4f43
R
9131
9132(define_expand "truncdfsf2"
fa5322fa
AO
9133 [(set (match_operand:SF 0 "fpul_operand" "")
9134 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9135 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
225e4f43
R
9136 "
9137{
fa5322fa
AO
9138 if (TARGET_SH4)
9139 {
9140 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9141 get_fpscr_rtx ()));
9142 DONE;
9143 }
225e4f43
R
9144}")
9145
fa5322fa
AO
9146(define_insn "*truncdfsf2_media"
9147 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9148 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9149 "TARGET_SHMEDIA_FPU"
2ad65b0e
SC
9150 "fcnv.ds %1, %0"
9151 [(set_attr "type" "dfpconv_media")])
fa5322fa 9152
225e4f43 9153(define_insn "truncdfsf2_i4"
4b9580a5
R
9154 [(set (match_operand:SF 0 "fpul_operand" "=y")
9155 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
0c4c9b16 9156 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
225e4f43 9157 "TARGET_SH4"
0c4c9b16 9158 "fcnvds %1,%0"
d64264ff
R
9159 [(set_attr "type" "fp")
9160 (set_attr "fp_mode" "double")])
45348d9e 9161\f
725de644
JW
9162;; Bit field extract patterns. These give better code for packed bitfields,
9163;; because they allow auto-increment addresses to be generated.
9164
9165(define_expand "insv"
9166 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9167 (match_operand:SI 1 "immediate_operand" "")
9168 (match_operand:SI 2 "immediate_operand" ""))
9169 (match_operand:SI 3 "general_operand" ""))]
fa5322fa 9170 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
725de644
JW
9171 "
9172{
a7f52356
R
9173 rtx addr_target, orig_address, shift_reg, qi_val;
9174 HOST_WIDE_INT bitsize, size, v;
9175 rtx x = operands[3];
725de644
JW
9176
9177 /* ??? expmed doesn't care for non-register predicates. */
9178 if (! memory_operand (operands[0], VOIDmode)
9179 || ! immediate_operand (operands[1], VOIDmode)
9180 || ! immediate_operand (operands[2], VOIDmode)
a7f52356 9181 || ! general_operand (x, VOIDmode))
725de644
JW
9182 FAIL;
9183 /* If this isn't a 16 / 24 / 32 bit field, or if
9184 it doesn't start on a byte boundary, then fail. */
a7f52356
R
9185 bitsize = INTVAL (operands[1]);
9186 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
725de644
JW
9187 || (INTVAL (operands[2]) % 8) != 0)
9188 FAIL;
9189
a7f52356 9190 size = bitsize / 8;
725de644 9191 orig_address = XEXP (operands[0], 0);
725de644 9192 shift_reg = gen_reg_rtx (SImode);
a7f52356
R
9193 if (GET_CODE (x) == CONST_INT)
9194 {
9195 v = INTVAL (x);
9196 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9197 }
9198 else
9199 {
9200 emit_insn (gen_movsi (shift_reg, operands[3]));
9201 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9202 }
ea3cbda5 9203 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
725de644 9204
792760b9 9205 operands[0] = replace_equiv_address (operands[0], addr_target);
a7f52356 9206 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9207
9208 while (size -= 1)
9209 {
a7f52356
R
9210 if (GET_CODE (x) == CONST_INT)
9211 qi_val
9212 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9213 else
9214 {
9215 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9216 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9217 }
725de644 9218 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
a7f52356 9219 emit_insn (gen_movqi (operands[0], qi_val));
725de644
JW
9220 }
9221
9222 DONE;
9223}")
9224\f
51bd623f
JW
9225;; -------------------------------------------------------------------------
9226;; Peepholes
9227;; -------------------------------------------------------------------------
961c4780 9228
51bd623f
JW
9229;; This matches cases where a stack pointer increment at the start of the
9230;; epilogue combines with a stack slot read loading the return value.
aa684c94 9231
07a45e5c 9232(define_peephole
51bd623f
JW
9233 [(set (match_operand:SI 0 "arith_reg_operand" "")
9234 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9235 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
fa5322fa 9236 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
51bd623f 9237 "mov.l @%1+,%0")
00f8ff66 9238
51bd623f 9239;; See the comment on the dt combiner pattern above.
00f8ff66 9240
07a45e5c
JW
9241(define_peephole
9242 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
00f8ff66
SC
9243 (plus:SI (match_dup 0)
9244 (const_int -1)))
4773afa4 9245 (set (reg:SI T_REG)
00f8ff66
SC
9246 (eq:SI (match_dup 0)
9247 (const_int 0)))]
9248 "TARGET_SH2"
9249 "dt %0")
e4931540
RK
9250
9251;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9252;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9253;; reload when the constant is too large for a reg+offset address.
9254
9255;; ??? We would get much better code if this was done in reload. This would
9256;; require modifying find_reloads_address to recognize that if the constant
9257;; is out-of-range for an immediate add, then we get better code by reloading
9258;; the constant into a register than by reloading the sum into a register,
9259;; since the former is one instruction shorter if the address does not need
9260;; to be offsettable. Unfortunately this does not work, because there is
9261;; only one register, r0, that can be used as an index register. This register
9262;; is also the function return value register. So, if we try to force reload
9263;; to use double-reg addresses, then we end up with some instructions that
9264;; need to use r0 twice. The only way to fix this is to change the calling
9265;; convention so that r0 is not used to return values.
9266
9267(define_peephole
9268 [(set (match_operand:SI 0 "register_operand" "=r")
9269 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9270 (set (mem:SI (match_dup 0))
9271 (match_operand:SI 2 "general_movsrc_operand" ""))]
fa5322fa 9272 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9273 "mov.l %2,@(%0,%1)")
9274
9275(define_peephole
9276 [(set (match_operand:SI 0 "register_operand" "=r")
9277 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9278 (set (match_operand:SI 2 "general_movdst_operand" "")
9279 (mem:SI (match_dup 0)))]
fa5322fa 9280 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9281 "mov.l @(%0,%1),%2")
9282
9283(define_peephole
9284 [(set (match_operand:SI 0 "register_operand" "=r")
9285 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9286 (set (mem:HI (match_dup 0))
9287 (match_operand:HI 2 "general_movsrc_operand" ""))]
fa5322fa 9288 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9289 "mov.w %2,@(%0,%1)")
9290
9291(define_peephole
9292 [(set (match_operand:SI 0 "register_operand" "=r")
9293 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9294 (set (match_operand:HI 2 "general_movdst_operand" "")
9295 (mem:HI (match_dup 0)))]
fa5322fa 9296 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9297 "mov.w @(%0,%1),%2")
9298
9299(define_peephole
9300 [(set (match_operand:SI 0 "register_operand" "=r")
9301 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9302 (set (mem:QI (match_dup 0))
9303 (match_operand:QI 2 "general_movsrc_operand" ""))]
fa5322fa 9304 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9305 "mov.b %2,@(%0,%1)")
9306
9307(define_peephole
9308 [(set (match_operand:SI 0 "register_operand" "=r")
9309 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9310 (set (match_operand:QI 2 "general_movdst_operand" "")
9311 (mem:QI (match_dup 0)))]
fa5322fa 9312 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
e4931540
RK
9313 "mov.b @(%0,%1),%2")
9314
9315(define_peephole
9316 [(set (match_operand:SI 0 "register_operand" "=r")
9317 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9318 (set (mem:SF (match_dup 0))
9319 (match_operand:SF 2 "general_movsrc_operand" ""))]
fa5322fa 9320 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9321 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9322 || (GET_CODE (operands[2]) == SUBREG
9323 && REGNO (SUBREG_REG (operands[2])) < 16))
9324 && reg_unused_after (operands[0], insn)"
e4931540
RK
9325 "mov.l %2,@(%0,%1)")
9326
9327(define_peephole
9328 [(set (match_operand:SI 0 "register_operand" "=r")
9329 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9330 (set (match_operand:SF 2 "general_movdst_operand" "")
9331
9332 (mem:SF (match_dup 0)))]
fa5322fa 9333 "TARGET_SH1 && REGNO (operands[0]) == 0
45348d9e
JW
9334 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9335 || (GET_CODE (operands[2]) == SUBREG
9336 && REGNO (SUBREG_REG (operands[2])) < 16))
9337 && reg_unused_after (operands[0], insn)"
e4931540 9338 "mov.l @(%0,%1),%2")
45348d9e
JW
9339
9340(define_peephole
9341 [(set (match_operand:SI 0 "register_operand" "=r")
9342 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9343 (set (mem:SF (match_dup 0))
9344 (match_operand:SF 2 "general_movsrc_operand" ""))]
3a8699c7 9345 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
9346 && ((GET_CODE (operands[2]) == REG
9347 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9348 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9349 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9350 && reg_unused_after (operands[0], insn)"
1245df60 9351 "fmov{.s|} %2,@(%0,%1)")
45348d9e
JW
9352
9353(define_peephole
9354 [(set (match_operand:SI 0 "register_operand" "=r")
9355 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9356 (set (match_operand:SF 2 "general_movdst_operand" "")
9357
9358 (mem:SF (match_dup 0)))]
3a8699c7 9359 "TARGET_SH2E && REGNO (operands[0]) == 0
104ee20b
AO
9360 && ((GET_CODE (operands[2]) == REG
9361 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
45348d9e 9362 || (GET_CODE (operands[2]) == SUBREG
104ee20b 9363 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
45348d9e 9364 && reg_unused_after (operands[0], insn)"
1245df60 9365 "fmov{.s|} @(%0,%1),%2")
4408efce
JL
9366
9367;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9368(define_insn "sp_switch_1"
9369 [(const_int 1)]
fa5322fa 9370 "TARGET_SH1"
4408efce
JL
9371 "*
9372{
9373 rtx xoperands[1];
9374
9375 xoperands[0] = sp_switch;
9376 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9377 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9378 return \"mov r0,r15\";
9379}"
9380 [(set_attr "length" "10")])
4408efce 9381
956d6950 9382;; Switch back to the original stack for interrupt functions with the
4408efce
JL
9383;; sp_switch attribute. */
9384(define_insn "sp_switch_2"
9385 [(const_int 2)]
fa5322fa 9386 "TARGET_SH1"
4408efce
JL
9387 "mov.l @r15+,r15\;mov.l @r15+,r0"
9388 [(set_attr "length" "4")])
fae15c93 9389
c1b92d09
R
9390;; Integer vector moves
9391
9392(define_expand "movv8qi"
9393 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9394 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9395 "TARGET_SHMEDIA"
9396 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9397
9398(define_insn "movv8qi_i"
9399 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9400 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9401 "TARGET_SHMEDIA
9402 && (register_operand (operands[0], V8QImode)
d9da94a1 9403 || sh_register_operand (operands[1], V8QImode))"
c1b92d09
R
9404 "@
9405 add %1, r63, %0
9406 movi %1, %0
9407 #
9408 ld%M1.q %m1, %0
d9da94a1 9409 st%M0.q %m0, %N1"
c1b92d09
R
9410 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9411 (set_attr "length" "4,4,16,4,4")])
9412
9413(define_split
9414 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9415 (subreg:V8QI (const_int 0) 0))]
9416 "TARGET_SHMEDIA"
9417 [(set (match_dup 0)
9418 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9419 (const_int 0) (const_int 0) (const_int 0)
9420 (const_int 0) (const_int 0)]))])
9421
9422(define_split
9423 [(set (match_operand 0 "arith_reg_dest" "")
9424 (match_operand 1 "sh_rep_vec" ""))]
9425 "TARGET_SHMEDIA && reload_completed
9426 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9427 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9428 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9429 && (XVECEXP (operands[1], 0, 0) != const0_rtx
c034672a
R
9430 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9431 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9432 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
c1b92d09
R
9433 [(set (match_dup 0) (match_dup 1))
9434 (match_dup 2)]
9435 "
9436{
9437 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9438 rtx elt1 = XVECEXP (operands[1], 0, 1);
9439
9440 if (unit_size > 2)
9441 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9442 else
750afc12
R
9443 {
9444 if (unit_size < 2)
9445 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9446 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9447 }
c1b92d09
R
9448 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9449 operands[1] = XVECEXP (operands[1], 0, 0);
9450 if (unit_size < 2)
9451 {
9452 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
40779a72
R
9453 operands[1]
9454 = GEN_INT (TARGET_LITTLE_ENDIAN
9455 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9456 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
c1b92d09
R
9457 else
9458 {
9459 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9460 operands[1]
9461 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9462 }
9463 }
9464}")
9465
9466(define_split
9467 [(set (match_operand 0 "arith_reg_dest" "")
9468 (match_operand 1 "sh_const_vec" ""))]
9469 "TARGET_SHMEDIA && reload_completed
9470 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9471 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
0ac78517 9472 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
c1b92d09
R
9473 [(set (match_dup 0) (match_dup 1))]
9474 "
9475{
9476 rtx v = operands[1];
9477 enum machine_mode new_mode
9478 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9479
9480 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9481 operands[1]
52702ae1 9482 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
c1b92d09
R
9483}")
9484
9485(define_expand "movv2hi"
9486 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9487 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9488 "TARGET_SHMEDIA"
9489 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9490
9491(define_insn "movv2hi_i"
9492 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9493 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9494 "TARGET_SHMEDIA
9495 && (register_operand (operands[0], V2HImode)
d9da94a1 9496 || sh_register_operand (operands[1], V2HImode))"
c1b92d09
R
9497 "@
9498 addz.l %1, r63, %0
9499 movi %1, %0
9500 #
9501 ld%M1.l %m1, %0
d9da94a1 9502 st%M0.l %m0, %N1"
c1b92d09
R
9503 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9504 (set_attr "length" "4,4,16,4,4")])
9505
9506(define_expand "movv4hi"
9507 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9508 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9509 "TARGET_SHMEDIA"
9510 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9511
9512(define_insn "movv4hi_i"
9513 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9514 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9515 "TARGET_SHMEDIA
9516 && (register_operand (operands[0], V4HImode)
d9da94a1 9517 || sh_register_operand (operands[1], V4HImode))"
c1b92d09
R
9518 "@
9519 add %1, r63, %0
9520 movi %1, %0
9521 #
9522 ld%M1.q %m1, %0
d9da94a1 9523 st%M0.q %m0, %N1"
c1b92d09
R
9524 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9525 (set_attr "length" "4,4,16,4,4")])
9526
9527(define_expand "movv2si"
9528 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9529 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9530 "TARGET_SHMEDIA"
9531 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9532
9533(define_insn "movv2si_i"
9534 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
735cb76e 9535 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
c1b92d09
R
9536 "TARGET_SHMEDIA
9537 && (register_operand (operands[0], V2SImode)
d9da94a1 9538 || sh_register_operand (operands[1], V2SImode))"
c1b92d09
R
9539 "@
9540 add %1, r63, %0
52702ae1 9541 #
c1b92d09
R
9542 #
9543 ld%M1.q %m1, %0
d9da94a1 9544 st%M0.q %m0, %N1"
c1b92d09
R
9545 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9546 (set_attr "length" "4,4,16,4,4")])
9547
9548;; Multimedia Intrinsics
9549
9550(define_insn "absv2si2"
9551 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9552 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9553 "TARGET_SHMEDIA"
9554 "mabs.l %1, %0"
9555 [(set_attr "type" "mcmp_media")])
9556
9557(define_insn "absv4hi2"
9558 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9559 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9560 "TARGET_SHMEDIA"
9561 "mabs.w %1, %0"
9562 [(set_attr "type" "mcmp_media")])
9563
9564(define_insn "addv2si3"
9565 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9566 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9567 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9568 "TARGET_SHMEDIA"
9569 "madd.l %1, %2, %0"
9570 [(set_attr "type" "arith_media")])
9571
9572(define_insn "addv4hi3"
9573 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9574 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9575 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9576 "TARGET_SHMEDIA"
9577 "madd.w %1, %2, %0"
9578 [(set_attr "type" "arith_media")])
9579
9580(define_insn "ssaddv2si3"
9581 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9582 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9583 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9584 "TARGET_SHMEDIA"
9585 "madds.l %1, %2, %0"
9586 [(set_attr "type" "mcmp_media")])
9587
9588(define_insn "usaddv8qi3"
9589 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9590 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9591 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9592 "TARGET_SHMEDIA"
9593 "madds.ub %1, %2, %0"
9594 [(set_attr "type" "mcmp_media")])
9595
9596(define_insn "ssaddv4hi3"
9597 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9598 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9599 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9600 "TARGET_SHMEDIA"
9601 "madds.w %1, %2, %0"
9602 [(set_attr "type" "mcmp_media")])
9603
9604(define_insn "negcmpeqv8qi"
9605 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
9606 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9607 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9608 "TARGET_SHMEDIA"
9609 "mcmpeq.b %N1, %N2, %0"
9610 [(set_attr "type" "mcmp_media")])
9611
9612(define_insn "negcmpeqv2si"
9613 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
9614 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9615 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9616 "TARGET_SHMEDIA"
9617 "mcmpeq.l %N1, %N2, %0"
9618 [(set_attr "type" "mcmp_media")])
9619
9620(define_insn "negcmpeqv4hi"
9621 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
9622 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9623 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9624 "TARGET_SHMEDIA"
9625 "mcmpeq.w %N1, %N2, %0"
9626 [(set_attr "type" "mcmp_media")])
9627
9628(define_insn "negcmpgtuv8qi"
9629 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
735cb76e
R
9630 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9631 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9632 "TARGET_SHMEDIA"
9633 "mcmpgt.ub %N1, %N2, %0"
9634 [(set_attr "type" "mcmp_media")])
9635
9636(define_insn "negcmpgtv2si"
9637 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e
R
9638 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9639 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9640 "TARGET_SHMEDIA"
9641 "mcmpgt.l %N1, %N2, %0"
9642 [(set_attr "type" "mcmp_media")])
9643
9644(define_insn "negcmpgtv4hi"
9645 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e
R
9646 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9647 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9648 "TARGET_SHMEDIA"
9649 "mcmpgt.w %N1, %N2, %0"
9650 [(set_attr "type" "mcmp_media")])
9651
9652(define_insn "mcmv"
9653 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9654 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9655 (match_operand:DI 2 "arith_reg_operand" "r"))
9656 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9657 (not:DI (match_dup 2)))))]
9658 "TARGET_SHMEDIA"
9659 "mcmv %N1, %2, %0"
9660 [(set_attr "type" "arith_media")])
9661
9662(define_insn "mcnvs_lw"
9663 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9664 (vec_concat:V4HI
735cb76e
R
9665 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9666 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9667 "TARGET_SHMEDIA"
9668 "mcnvs.lw %N1, %N2, %0"
9669 [(set_attr "type" "mcmp_media")])
9670
9671(define_insn "mcnvs_wb"
9672 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9673 (vec_concat:V8QI
735cb76e
R
9674 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9675 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9676 "TARGET_SHMEDIA"
9677 "mcnvs.wb %N1, %N2, %0"
9678 [(set_attr "type" "mcmp_media")])
9679
9680(define_insn "mcnvs_wub"
9681 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9682 (vec_concat:V8QI
735cb76e
R
9683 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9684 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
9685 "TARGET_SHMEDIA"
9686 "mcnvs.wub %N1, %N2, %0"
9687 [(set_attr "type" "mcmp_media")])
9688
9689(define_insn "mextr_rl"
9690 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9691 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 9692 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 9693 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9694 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9695 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9696 "*
9697{
9698 static char templ[16];
9699
9700 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9701 (int) INTVAL (operands[3]) >> 3);
9702 return templ;
9703}"
9704 [(set_attr "type" "arith_media")])
9705
9706(define_insn "*mextr_lr"
9707 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 9708 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 9709 (match_operand:HI 3 "mextr_bit_offset" "i"))
735cb76e 9710 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
9711 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9712 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9713 "*
9714{
9715 static char templ[16];
9716
9717 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9718 (int) INTVAL (operands[4]) >> 3);
9719 return templ;
9720}"
9721 [(set_attr "type" "arith_media")])
9722
9723; mextrN can be modelled with vec_select / vec_concat, but the selection
9724; vector then varies depending on endianness.
9725(define_expand "mextr1"
0ac78517 9726 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9727 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9728 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9729 "TARGET_SHMEDIA"
9730 "
9731{
0ac78517 9732 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9733 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9734 DONE;
9735}")
9736
9737(define_expand "mextr2"
0ac78517 9738 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9739 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9740 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9741 "TARGET_SHMEDIA"
9742 "
9743{
0ac78517 9744 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9745 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9746 DONE;
9747}")
9748
9749(define_expand "mextr3"
0ac78517 9750 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9751 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9752 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9753 "TARGET_SHMEDIA"
9754 "
9755{
0ac78517 9756 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9757 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9758 DONE;
9759}")
9760
9761(define_expand "mextr4"
0ac78517 9762 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9763 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9764 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9765 "TARGET_SHMEDIA"
9766 "
9767{
0ac78517 9768 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9769 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9770 DONE;
9771}")
9772
9773(define_expand "mextr5"
0ac78517 9774 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9775 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9776 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9777 "TARGET_SHMEDIA"
9778 "
9779{
0ac78517 9780 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9781 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9782 DONE;
9783}")
9784
9785(define_expand "mextr6"
0ac78517 9786 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9787 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9788 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9789 "TARGET_SHMEDIA"
9790 "
9791{
0ac78517 9792 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9793 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9794 DONE;
9795}")
9796
9797(define_expand "mextr7"
0ac78517 9798 [(match_operand:DI 0 "arith_reg_dest" "")
735cb76e
R
9799 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9800 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
9801 "TARGET_SHMEDIA"
9802 "
9803{
0ac78517 9804 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
c1b92d09
R
9805 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9806 DONE;
9807}")
9808
9809(define_expand "mmacfx_wl"
9810 [(match_operand:V2SI 0 "arith_reg_dest" "")
9811 (match_operand:V2HI 1 "extend_reg_operand" "")
9812 (match_operand:V2HI 2 "extend_reg_operand" "")
9813 (match_operand:V2SI 3 "arith_reg_operand" "")]
9814 "TARGET_SHMEDIA"
9815 "
9816{
9817 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9818 operands[1], operands[2]));
9819 DONE;
9820}")
9821
9822(define_insn "mmacfx_wl_i"
9823 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9824 (ss_plus:V2SI
9825 (match_operand:V2SI 1 "arith_reg_operand" "0")
9826 (ss_truncate:V2SI
9827 (ashift:V2DI
9828 (sign_extend:V2DI
9829 (mult:V2SI
9830 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9831 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9832 (const_int 1)))))]
9833 "TARGET_SHMEDIA"
9834 "mmacfx.wl %2, %3, %0"
9835 [(set_attr "type" "mac_media")])
9836
9837(define_expand "mmacnfx_wl"
9838 [(match_operand:V2SI 0 "arith_reg_dest" "")
9839 (match_operand:V2HI 1 "extend_reg_operand" "")
9840 (match_operand:V2HI 2 "extend_reg_operand" "")
9841 (match_operand:V2SI 3 "arith_reg_operand" "")]
9842 "TARGET_SHMEDIA"
9843 "
9844{
9845 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9846 operands[1], operands[2]));
9847 DONE;
9848}")
9849
9850(define_insn "mmacnfx_wl_i"
9851 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9852 (ss_minus:V2SI
9853 (match_operand:V2SI 1 "arith_reg_operand" "0")
9854 (ss_truncate:V2SI
9855 (ashift:V2DI
9856 (sign_extend:V2DI
9857 (mult:V2SI
9858 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9859 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9860 (const_int 1)))))]
9861 "TARGET_SHMEDIA"
9862 "mmacnfx.wl %2, %3, %0"
9863 [(set_attr "type" "mac_media")])
9864
9865(define_insn "mulv2si3"
9866 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9867 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9868 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9869 "TARGET_SHMEDIA"
9870 "mmul.l %1, %2, %0"
9871 [(set_attr "type" "d2mpy_media")])
9872
9873(define_insn "mulv4hi3"
9874 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9875 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9876 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9877 "TARGET_SHMEDIA"
9878 "mmul.w %1, %2, %0"
9879 [(set_attr "type" "dmpy_media")])
9880
9881(define_insn "mmulfx_l"
9882 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9883 (ss_truncate:V2SI
9884 (ashiftrt:V2DI
9885 (mult:V2DI
9886 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9887 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9888 (const_int 31))))]
9889 "TARGET_SHMEDIA"
9890 "mmulfx.l %1, %2, %0"
9891 [(set_attr "type" "d2mpy_media")])
9892
9893(define_insn "mmulfx_w"
9894 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9895 (ss_truncate:V4HI
9896 (ashiftrt:V4SI
9897 (mult:V4SI
9898 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9899 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9900 (const_int 15))))]
9901 "TARGET_SHMEDIA"
9902 "mmulfx.w %1, %2, %0"
9903 [(set_attr "type" "dmpy_media")])
9904
9905(define_insn "mmulfxrp_w"
9906 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9907 (ss_truncate:V4HI
9908 (ashiftrt:V4SI
9909 (plus:V4SI
9910 (mult:V4SI
9911 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9912 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9913 (const_int 16384))
9914 (const_int 15))))]
9915 "TARGET_SHMEDIA"
9916 "mmulfxrp.w %1, %2, %0"
9917 [(set_attr "type" "dmpy_media")])
9918
9919(define_expand "mmulhi_wl"
9920 [(match_operand:V2SI 0 "arith_reg_dest" "")
9921 (match_operand:V4HI 1 "arith_reg_operand" "")
9922 (match_operand:V4HI 2 "arith_reg_operand" "")]
9923 "TARGET_SHMEDIA"
9924 "
9925{
9926 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9927 (operands[0], operands[1], operands[2]));
9928 DONE;
9929}")
9930
9931(define_expand "mmullo_wl"
9932 [(match_operand:V2SI 0 "arith_reg_dest" "")
9933 (match_operand:V4HI 1 "arith_reg_operand" "")
9934 (match_operand:V4HI 2 "arith_reg_operand" "")]
9935 "TARGET_SHMEDIA"
9936 "
9937{
9938 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9939 (operands[0], operands[1], operands[2]));
9940 DONE;
9941}")
9942
9943(define_insn "mmul23_wl"
9944 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9945 (vec_select:V2SI
9946 (mult:V4SI
9947 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9948 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 9949 (parallel [(const_int 2) (const_int 3)])))]
c1b92d09
R
9950 "TARGET_SHMEDIA"
9951 "* return (TARGET_LITTLE_ENDIAN
9952 ? \"mmulhi.wl %1, %2, %0\"
9953 : \"mmullo.wl %1, %2, %0\");"
9954 [(set_attr "type" "dmpy_media")])
9955
9956(define_insn "mmul01_wl"
9957 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9958 (vec_select:V2SI
9959 (mult:V4SI
9960 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9961 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
0ac78517 9962 (parallel [(const_int 0) (const_int 1)])))]
c1b92d09
R
9963 "TARGET_SHMEDIA"
9964 "* return (TARGET_LITTLE_ENDIAN
9965 ? \"mmullo.wl %1, %2, %0\"
9966 : \"mmulhi.wl %1, %2, %0\");"
9967 [(set_attr "type" "dmpy_media")])
9968
9969(define_expand "mmulsum_wq"
9970 [(match_operand:DI 0 "arith_reg_dest" "")
9971 (match_operand:V4HI 1 "arith_reg_operand" "")
9972 (match_operand:V4HI 2 "arith_reg_operand" "")
9973 (match_operand:DI 3 "arith_reg_operand" "")]
9974 "TARGET_SHMEDIA"
9975 "
9976{
9977 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9978 operands[1], operands[2]));
9979 DONE;
9980}")
9981
9982(define_insn "mmulsum_wq_i"
9983 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9984 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9985 (plus:DI
9986 (plus:DI
9987 (vec_select:DI
9988 (mult:V4DI
9989 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9990 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
0ac78517 9991 (parallel [(const_int 0)]))
c1b92d09
R
9992 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9993 (sign_extend:V4DI (match_dup 3)))
0ac78517 9994 (parallel [(const_int 1)])))
c1b92d09
R
9995 (plus:DI
9996 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9997 (sign_extend:V4DI (match_dup 3)))
0ac78517 9998 (parallel [(const_int 2)]))
c1b92d09
R
9999 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10000 (sign_extend:V4DI (match_dup 3)))
0ac78517 10001 (parallel [(const_int 3)]))))))]
c1b92d09
R
10002 "TARGET_SHMEDIA"
10003 "mmulsum.wq %2, %3, %0"
10004 [(set_attr "type" "mac_media")])
10005
10006(define_expand "mperm_w"
10007 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10008 (match_operand:V4HI 1 "arith_reg_operand" "r")
735cb76e 10009 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
c1b92d09
R
10010 "TARGET_SHMEDIA"
10011 "
10012{
10013 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10014 (operands[0], operands[1], operands[2]));
c49439f1 10015 DONE;
c1b92d09
R
10016}")
10017
10018; This use of vec_select isn't exactly correct according to rtl.texi
10019; (because not constant), but it seems a straightforward extension.
10020(define_insn "mperm_w_little"
10021 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10022 (vec_select:V4HI
10023 (match_operand:V4HI 1 "arith_reg_operand" "r")
10024 (parallel
735cb76e 10025 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
502e6d5a
R
10026 (const_int 2) (const_int 0))
10027 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10028 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10029 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
c1b92d09
R
10030 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10031 "mperm.w %1, %N2, %0"
10032 [(set_attr "type" "arith_media")])
10033
10034(define_insn "mperm_w_big"
10035 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10036 (vec_select:V4HI
10037 (match_operand:V4HI 1 "arith_reg_operand" "r")
10038 (parallel
502e6d5a 10039 [(zero_extract:QI (not:QI (match_operand:QI 2
735cb76e 10040 "extend_reg_or_0_operand" "rZ"))
502e6d5a
R
10041 (const_int 2) (const_int 0))
10042 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10043 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10044 (zero_extract:QI (not:QI (match_dup 2))
10045 (const_int 2) (const_int 6))])))]
c1b92d09
R
10046 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10047 "mperm.w %1, %N2, %0"
10048 [(set_attr "type" "arith_media")])
10049
10050(define_insn "mperm_w0"
10051 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10052 (vec_duplicate:V4HI (truncate:HI (match_operand 1
e69d1422 10053 "trunc_hi_operand" "r"))))]
c1b92d09
R
10054 "TARGET_SHMEDIA"
10055 "mperm.w %1, r63, %0"
10056 [(set_attr "type" "arith_media")])
10057
10058(define_expand "msad_ubq"
10059 [(match_operand:DI 0 "arith_reg_dest" "")
10060 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10061 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10062 (match_operand:DI 3 "arith_reg_operand" "")]
10063 "TARGET_SHMEDIA"
10064 "
10065{
10066 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10067 operands[1], operands[2]));
10068 DONE;
10069}")
10070
10071(define_insn "msad_ubq_i"
10072 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10073 (plus:DI
10074 (plus:DI
10075 (plus:DI
10076 (plus:DI
10077 (match_operand:DI 1 "arith_reg_operand" "0")
10078 (abs:DI (vec_select:DI
10079 (minus:V8DI
10080 (zero_extend:V8DI
735cb76e 10081 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
c1b92d09 10082 (zero_extend:V8DI
735cb76e 10083 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
0ac78517 10084 (parallel [(const_int 0)]))))
c1b92d09
R
10085 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10086 (zero_extend:V8DI (match_dup 3)))
0ac78517 10087 (parallel [(const_int 1)]))))
c1b92d09
R
10088 (plus:DI
10089 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10090 (zero_extend:V8DI (match_dup 3)))
0ac78517 10091 (parallel [(const_int 2)])))
c1b92d09
R
10092 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10093 (zero_extend:V8DI (match_dup 3)))
0ac78517 10094 (parallel [(const_int 3)])))))
c1b92d09
R
10095 (plus:DI
10096 (plus:DI
10097 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10098 (zero_extend:V8DI (match_dup 3)))
0ac78517 10099 (parallel [(const_int 4)])))
c1b92d09
R
10100 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10101 (zero_extend:V8DI (match_dup 3)))
0ac78517 10102 (parallel [(const_int 5)]))))
c1b92d09
R
10103 (plus:DI
10104 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10105 (zero_extend:V8DI (match_dup 3)))
0ac78517 10106 (parallel [(const_int 6)])))
c1b92d09
R
10107 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10108 (zero_extend:V8DI (match_dup 3)))
0ac78517 10109 (parallel [(const_int 7)])))))))]
c1b92d09
R
10110 "TARGET_SHMEDIA"
10111 "msad.ubq %N2, %N3, %0"
10112 [(set_attr "type" "mac_media")])
10113
10114(define_insn "mshalds_l"
10115 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10116 (ss_truncate:V2SI
10117 (ashift:V2DI
10118 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10119 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10120 (const_int 31)))))]
10121 "TARGET_SHMEDIA"
10122 "mshalds.l %1, %2, %0"
10123 [(set_attr "type" "mcmp_media")])
10124
10125(define_insn "mshalds_w"
10126 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10127 (ss_truncate:V4HI
10128 (ashift:V4SI
10129 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10130 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10131 (const_int 15)))))]
10132 "TARGET_SHMEDIA"
10133 "mshalds.w %1, %2, %0"
10134 [(set_attr "type" "mcmp_media")])
10135
10136(define_insn "ashrv2si3"
10137 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10138 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10139 (match_operand:DI 2 "arith_reg_operand" "r")))]
10140 "TARGET_SHMEDIA"
10141 "mshard.l %1, %2, %0"
10142 [(set_attr "type" "arith_media")])
10143
10144(define_insn "ashrv4hi3"
10145 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10146 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10147 (match_operand:DI 2 "arith_reg_operand" "r")))]
10148 "TARGET_SHMEDIA"
10149 "mshard.w %1, %2, %0"
10150 [(set_attr "type" "arith_media")])
10151
10152(define_insn "mshards_q"
10153 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10154 (ss_truncate:HI
10155 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
735cb76e 10156 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
c1b92d09
R
10157 "TARGET_SHMEDIA"
10158 "mshards.q %1, %N2, %0"
10159 [(set_attr "type" "mcmp_media")])
10160
10161(define_expand "mshfhi_b"
10162 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
10163 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10164 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10165 "TARGET_SHMEDIA"
10166 "
10167{
10168 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10169 (operands[0], operands[1], operands[2]));
8721e3df 10170 DONE;
c1b92d09
R
10171}")
10172
10173(define_expand "mshflo_b"
10174 [(match_operand:V8QI 0 "arith_reg_dest" "")
735cb76e
R
10175 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10176 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10177 "TARGET_SHMEDIA"
10178 "
10179{
10180 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10181 (operands[0], operands[1], operands[2]));
8721e3df 10182 DONE;
c1b92d09
R
10183}")
10184
10185(define_insn "mshf4_b"
10186 [(set
10187 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10188 (vec_select:V8QI
735cb76e
R
10189 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10190 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
10191 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10192 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
c1b92d09
R
10193 "TARGET_SHMEDIA"
10194 "* return (TARGET_LITTLE_ENDIAN
10195 ? \"mshfhi.b %N1, %N2, %0\"
10196 : \"mshflo.b %N1, %N2, %0\");"
10197 [(set_attr "type" "arith_media")])
10198
10199(define_insn "mshf0_b"
10200 [(set
10201 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10202 (vec_select:V8QI
735cb76e
R
10203 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10204 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517
R
10205 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10206 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
c1b92d09
R
10207 "TARGET_SHMEDIA"
10208 "* return (TARGET_LITTLE_ENDIAN
10209 ? \"mshflo.b %N1, %N2, %0\"
10210 : \"mshfhi.b %N1, %N2, %0\");"
10211 [(set_attr "type" "arith_media")])
10212
10213(define_expand "mshfhi_l"
10214 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
10215 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10216 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10217 "TARGET_SHMEDIA"
10218 "
10219{
10220 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10221 (operands[0], operands[1], operands[2]));
8721e3df 10222 DONE;
c1b92d09
R
10223}")
10224
10225(define_expand "mshflo_l"
10226 [(match_operand:V2SI 0 "arith_reg_dest" "")
735cb76e
R
10227 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10228 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10229 "TARGET_SHMEDIA"
10230 "
10231{
10232 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10233 (operands[0], operands[1], operands[2]));
8721e3df 10234 DONE;
c1b92d09
R
10235}")
10236
10237(define_insn "mshf4_l"
10238 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10239 (vec_select:V2SI
735cb76e
R
10240 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10241 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10242 (parallel [(const_int 1) (const_int 3)])))]
c1b92d09
R
10243 "TARGET_SHMEDIA"
10244 "* return (TARGET_LITTLE_ENDIAN
10245 ? \"mshfhi.l %N1, %N2, %0\"
10246 : \"mshflo.l %N1, %N2, %0\");"
10247 [(set_attr "type" "arith_media")])
10248
10249(define_insn "mshf0_l"
10250 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10251 (vec_select:V2SI
735cb76e
R
10252 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10253 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10254 (parallel [(const_int 0) (const_int 2)])))]
c1b92d09
R
10255 "TARGET_SHMEDIA"
10256 "* return (TARGET_LITTLE_ENDIAN
10257 ? \"mshflo.l %N1, %N2, %0\"
10258 : \"mshfhi.l %N1, %N2, %0\");"
10259 [(set_attr "type" "arith_media")])
10260
10261(define_expand "mshfhi_w"
10262 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
10263 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10264 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10265 "TARGET_SHMEDIA"
10266 "
10267{
10268 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10269 (operands[0], operands[1], operands[2]));
8721e3df 10270 DONE;
c1b92d09
R
10271}")
10272
10273(define_expand "mshflo_w"
10274 [(match_operand:V4HI 0 "arith_reg_dest" "")
735cb76e
R
10275 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10276 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
c1b92d09
R
10277 "TARGET_SHMEDIA"
10278 "
10279{
10280 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10281 (operands[0], operands[1], operands[2]));
8721e3df 10282 DONE;
c1b92d09
R
10283}")
10284
10285(define_insn "mshf4_w"
10286 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10287 (vec_select:V4HI
735cb76e
R
10288 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10289 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10290 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
c1b92d09
R
10291 "TARGET_SHMEDIA"
10292 "* return (TARGET_LITTLE_ENDIAN
10293 ? \"mshfhi.w %N1, %N2, %0\"
10294 : \"mshflo.w %N1, %N2, %0\");"
10295 [(set_attr "type" "arith_media")])
10296
10297(define_insn "mshf0_w"
10298 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10299 (vec_select:V4HI
735cb76e
R
10300 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10301 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
0ac78517 10302 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
c1b92d09
R
10303 "TARGET_SHMEDIA"
10304 "* return (TARGET_LITTLE_ENDIAN
10305 ? \"mshflo.w %N1, %N2, %0\"
10306 : \"mshfhi.w %N1, %N2, %0\");"
10307 [(set_attr "type" "arith_media")])
10308
0ac78517
R
10309(define_insn "mshflo_w_x"
10310 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10311 (vec_select:V4HI
735cb76e
R
10312 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10313 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
08c43ea7 10314 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
0ac78517
R
10315 "TARGET_SHMEDIA"
10316 "mshflo.w %N1, %N2, %0"
10317 [(set_attr "type" "arith_media")])
10318
c1b92d09 10319/* These are useful to expand ANDs and as combiner patterns. */
0ac78517
R
10320(define_insn_and_split "mshfhi_l_di"
10321 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
735cb76e 10322 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
c1b92d09 10323 (const_int 32))
735cb76e 10324 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
c1b92d09
R
10325 (const_int -4294967296))))]
10326 "TARGET_SHMEDIA"
0ac78517
R
10327 "@
10328 mshfhi.l %N1, %N2, %0
10329 #"
10330 "TARGET_SHMEDIA && reload_completed
10331 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10332 [(set (match_dup 3) (match_dup 4))
10333 (set (match_dup 5) (match_dup 6))]
10334 "
10335{
10336 operands[3] = gen_lowpart (SImode, operands[0]);
10337 operands[4] = gen_highpart (SImode, operands[1]);
10338 operands[5] = gen_highpart (SImode, operands[0]);
10339 operands[6] = gen_highpart (SImode, operands[2]);
10340}"
c1b92d09
R
10341 [(set_attr "type" "arith_media")])
10342
10343(define_insn "*mshfhi_l_di_rev"
10344 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10345 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10346 (const_int -4294967296))
735cb76e 10347 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10348 (const_int 32))))]
10349 "TARGET_SHMEDIA"
10350 "mshfhi.l %N2, %N1, %0"
10351 [(set_attr "type" "arith_media")])
10352
52702ae1
R
10353(define_split
10354 [(set (match_operand:DI 0 "arith_reg_dest" "")
10355 (ior:DI (zero_extend:DI (match_operand:SI 1
10356 "extend_reg_or_0_operand" ""))
10357 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10358 (const_int -4294967296))))
10359 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10360 "TARGET_SHMEDIA"
10361 [(const_int 0)]
10362 "
10363{
10364 emit_insn (gen_ashldi3_media (operands[3],
10365 simplify_gen_subreg (DImode, operands[1],
10366 SImode, 0),
10367 GEN_INT (32)));
10368 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10369 DONE;
10370}")
10371
c1b92d09
R
10372(define_insn "mshflo_l_di"
10373 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10374 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10375 (const_int 4294967295))
735cb76e 10376 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 10377 (const_int 32))))]
73774972 10378
c1b92d09
R
10379 "TARGET_SHMEDIA"
10380 "mshflo.l %N1, %N2, %0"
10381 [(set_attr "type" "arith_media")])
10382
10383(define_insn "*mshflo_l_di_rev"
10384 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10385 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10386 (const_int 32))
735cb76e 10387 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 10388 (const_int 4294967295))))]
73774972 10389
c1b92d09
R
10390 "TARGET_SHMEDIA"
10391 "mshflo.l %N2, %N1, %0"
10392 [(set_attr "type" "arith_media")])
10393
ca903bba
R
10394;; Combiner pattern for trampoline initialization.
10395(define_insn_and_split "*double_shori"
10396 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10397 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10398 (const_int 32))
10399 (match_operand:DI 2 "const_int_operand" "n")))]
10400 "TARGET_SHMEDIA
10401 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10402 "#"
10403 "rtx_equal_p (operands[0], operands[1])"
10404 [(const_int 0)]
10405 "
10406{
10407 HOST_WIDE_INT v = INTVAL (operands[2]);
10408
10409 emit_insn (gen_shori_media (operands[0], operands[0],
10410 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10411 emit_insn (gen_shori_media (operands[0], operands[0],
10412 gen_int_mode (v, HImode)));
10413 DONE;
10414}")
10415
10416
c1b92d09
R
10417(define_insn "*mshflo_l_di_x"
10418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
0ac78517 10419 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
735cb76e
R
10420 "rZ"))
10421 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
c1b92d09 10422 (const_int 32))))]
73774972 10423
c1b92d09
R
10424 "TARGET_SHMEDIA"
10425 "mshflo.l %N1, %N2, %0"
10426 [(set_attr "type" "arith_media")])
10427
0ac78517
R
10428(define_insn_and_split "concat_v2sf"
10429 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
735cb76e
R
10430;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10431 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10432 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
73774972 10433
0ac78517
R
10434 "TARGET_SHMEDIA"
10435 "@
10436 mshflo.l %N1, %N2, %0
10437 #
10438 #"
10439 "TARGET_SHMEDIA && reload_completed
10440 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10441 [(set (match_dup 3) (match_dup 1))
10442 (set (match_dup 4) (match_dup 2))]
10443 "
10444{
10445 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10446 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10447}"
10448 [(set_attr "type" "arith_media")])
10449
c1b92d09
R
10450(define_insn "*mshflo_l_di_x_rev"
10451 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
735cb76e 10452 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09 10453 (const_int 32))
735cb76e 10454 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
73774972 10455
c1b92d09
R
10456 "TARGET_SHMEDIA"
10457 "mshflo.l %N2, %N1, %0"
10458 [(set_attr "type" "arith_media")])
10459
10460(define_insn "ashlv2si3"
10461 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10462 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10463 (match_operand:DI 2 "arith_reg_operand" "r")))]
10464 "TARGET_SHMEDIA"
10465 "mshlld.l %1, %2, %0"
10466 [(set_attr "type" "arith_media")])
10467
10468(define_insn "ashlv4hi3"
10469 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10470 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10471 (match_operand:DI 2 "arith_reg_operand" "r")))]
10472 "TARGET_SHMEDIA"
10473 "mshlld.w %1, %2, %0"
10474 [(set_attr "type" "arith_media")])
10475
10476(define_insn "lshrv2si3"
10477 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10478 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10479 (match_operand:DI 2 "arith_reg_operand" "r")))]
10480 "TARGET_SHMEDIA"
10481 "mshlrd.l %1, %2, %0"
10482 [(set_attr "type" "arith_media")])
10483
10484(define_insn "lshrv4hi3"
10485 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10486 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10487 (match_operand:DI 2 "arith_reg_operand" "r")))]
10488 "TARGET_SHMEDIA"
10489 "mshlrd.w %1, %2, %0"
10490 [(set_attr "type" "arith_media")])
10491
10492(define_insn "subv2si3"
10493 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 10494 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10495 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10496 "TARGET_SHMEDIA"
10497 "msub.l %N1, %2, %0"
10498 [(set_attr "type" "arith_media")])
10499
10500(define_insn "subv4hi3"
10501 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 10502 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10503 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10504 "TARGET_SHMEDIA"
10505 "msub.w %N1, %2, %0"
10506 [(set_attr "type" "arith_media")])
10507
10508(define_insn "sssubv2si3"
10509 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
735cb76e 10510 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10511 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10512 "TARGET_SHMEDIA"
10513 "msubs.l %N1, %2, %0"
10514 [(set_attr "type" "mcmp_media")])
10515
10516(define_insn "ussubv8qi3"
10517 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10518 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10519 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10520 "TARGET_SHMEDIA"
10521 "msubs.ub %1, %2, %0"
10522 [(set_attr "type" "mcmp_media")])
10523
10524(define_insn "sssubv4hi3"
10525 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
735cb76e 10526 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
c1b92d09
R
10527 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10528 "TARGET_SHMEDIA"
10529 "msubs.w %N1, %2, %0"
10530 [(set_attr "type" "mcmp_media")])
10531
10532;; Floating Point Intrinsics
10533
10534(define_insn "fcosa_s"
10535 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10537 UNSPEC_FCOSA))]
10538 "TARGET_SHMEDIA"
10539 "fcosa.s %1, %0"
10540 [(set_attr "type" "atrans_media")])
10541
10542(define_insn "fsina_s"
10543 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10544 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10545 UNSPEC_FSINA))]
10546 "TARGET_SHMEDIA"
10547 "fsina.s %1, %0"
10548 [(set_attr "type" "atrans_media")])
10549
10550(define_insn "fipr"
10551 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10552 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10553 "fp_arith_reg_operand" "f")
10554 (match_operand:V4SF 2
10555 "fp_arith_reg_operand" "f"))
0ac78517 10556 (parallel [(const_int 0)]))
c1b92d09 10557 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10558 (parallel [(const_int 1)])))
c1b92d09 10559 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10560 (parallel [(const_int 2)]))
c1b92d09 10561 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
0ac78517 10562 (parallel [(const_int 3)])))))]
c1b92d09 10563 "TARGET_SHMEDIA"
40779a72 10564 "fipr.s %1, %2, %0"
c1b92d09
R
10565 [(set_attr "type" "fparith_media")])
10566
10567(define_insn "fsrra_s"
10568 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10569 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10570 UNSPEC_FSRRA))]
10571 "TARGET_SHMEDIA"
10572 "fsrra.s %1, %0"
10573 [(set_attr "type" "atrans_media")])
10574
10575(define_insn "ftrv"
10576 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10577 (plus:V4SF
10578 (plus:V4SF
10579 (mult:V4SF
10580 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
0ac78517
R
10581 (parallel [(const_int 0) (const_int 5)
10582 (const_int 10) (const_int 15)]))
c1b92d09
R
10583 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10584 (mult:V4SF
10585 (vec_select:V4SF (match_dup 1)
0ac78517
R
10586 (parallel [(const_int 4) (const_int 9)
10587 (const_int 14) (const_int 3)]))
c1b92d09 10588 (vec_select:V4SF (match_dup 2)
0ac78517 10589 (parallel [(const_int 1) (const_int 2)
40779a72 10590 (const_int 3) (const_int 0)]))))
c1b92d09
R
10591 (plus:V4SF
10592 (mult:V4SF
10593 (vec_select:V4SF (match_dup 1)
0ac78517
R
10594 (parallel [(const_int 8) (const_int 13)
10595 (const_int 2) (const_int 7)]))
c1b92d09 10596 (vec_select:V4SF (match_dup 2)
0ac78517
R
10597 (parallel [(const_int 2) (const_int 3)
10598 (const_int 0) (const_int 1)])))
c1b92d09
R
10599 (mult:V4SF
10600 (vec_select:V4SF (match_dup 1)
0ac78517
R
10601 (parallel [(const_int 12) (const_int 1)
10602 (const_int 6) (const_int 11)]))
c1b92d09 10603 (vec_select:V4SF (match_dup 2)
0ac78517
R
10604 (parallel [(const_int 3) (const_int 0)
10605 (const_int 1) (const_int 2)]))))))]
c1b92d09 10606 "TARGET_SHMEDIA"
40779a72 10607 "ftrv.s %1, %2, %0"
c1b92d09
R
10608 [(set_attr "type" "fparith_media")])
10609
b6d33983
R
10610(define_insn "nsb"
10611 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10612 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10613 UNSPEC_NSB))]
10614 "TARGET_SHMEDIA"
10615 "nsb %1, %0"
10616 [(set_attr "type" "arith_media")])
10617
10618(define_insn "nsbsi"
10619 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10620 (zero_extend:SI
10621 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10622 UNSPEC_NSB)))]
10623 "TARGET_SHMEDIA"
10624 "nsb %1, %0"
10625 [(set_attr "type" "arith_media")])
10626
10627(define_insn "nsbdi"
10628 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10629 (zero_extend:DI
10630 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10631 UNSPEC_NSB)))]
10632 "TARGET_SHMEDIA"
10633 "nsb %1, %0"
10634 [(set_attr "type" "arith_media")])
10635
10636(define_expand "ffsdi2"
10637 [(set (match_operand:DI 0 "arith_reg_dest" "")
10638 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10639 "TARGET_SHMEDIA"
10640 "
10641{
10642 rtx scratch = gen_reg_rtx (DImode);
10643 rtx last;
10644
10645 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10646 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10647 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10648 emit_insn (gen_nsbdi (scratch, scratch));
10649 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10650 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10651 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10652 REG_NOTES (last)
10653 = gen_rtx_EXPR_LIST (REG_EQUAL,
10654 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10655 DONE;
10656}")
10657
10658(define_expand "ffssi2"
10659 [(set (match_operand:SI 0 "arith_reg_dest" "")
10660 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10661 "TARGET_SHMEDIA"
10662 "
10663{
10664 rtx scratch = gen_reg_rtx (SImode);
10665 rtx discratch = gen_reg_rtx (DImode);
10666 rtx last;
10667
e3c62520
R
10668 emit_insn (gen_adddi3 (discratch,
10669 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10670 GEN_INT (-1)));
10671 emit_insn (gen_andcdi3 (discratch,
10672 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10673 discratch));
b6d33983
R
10674 emit_insn (gen_nsbsi (scratch, discratch));
10675 last = emit_insn (gen_subsi3 (operands[0],
e3c62520 10676 force_reg (SImode, GEN_INT (63)), scratch));
b6d33983
R
10677 REG_NOTES (last)
10678 = gen_rtx_EXPR_LIST (REG_EQUAL,
10679 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10680 DONE;
10681}")
10682
10683(define_insn "byterev"
10684 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10685 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10686 (parallel [(const_int 7) (const_int 6) (const_int 5)
10687 (const_int 4) (const_int 3) (const_int 2)
10688 (const_int 1) (const_int 0)])))]
10689 "TARGET_SHMEDIA"
10690 "byterev %1, %0"
10691 [(set_attr "type" "arith_media")])
10692
88f08cca
R
10693(define_insn "prefetch"
10694 [(prefetch (match_operand:QI 0 "address_operand" "p")
10695 (match_operand:SI 1 "const_int_operand" "n")
10696 (match_operand:SI 2 "const_int_operand" "n"))]
10697 "TARGET_SHMEDIA"
10698 "*
10699{
10700 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10701 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10702 return \"\";
10703}"
10704 [(set_attr "type" "other")])
10705
fae15c93 10706;; The following description models the
73774972
EC
10707;; SH4 pipeline using the DFA based scheduler.
10708;; The DFA based description is better way to model
fae15c93 10709;; a superscalar pipeline as compared to function unit
73774972
EC
10710;; reservation model.
10711;; 1. The function unit based model is oriented to describe at most one
10712;; unit reservation by each insn. It is difficult to model unit reservations in multiple
fae15c93
VM
10713;; pipeline units by same insn. This can be done using DFA based description.
10714;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
73774972
EC
10715;; 3. Writing all unit reservations for an instruction class is more natural description
10716;; of the pipeline and makes interface of the hazard recognizer simpler than the
fae15c93
VM
10717;; old function unit based model.
10718;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10719
10720
10721;; Two automata are defined to reduce number of states
10722;; which a single large automaton will have.(Factoring)
10723
10724(define_automaton "inst_pipeline,fpu_pipe")
10725
10726;; This unit is basically the decode unit of the processor.
73774972 10727;; Since SH4 is a dual issue machine,it is as if there are two
fae15c93
VM
10728;; units so that any insn can be processed by either one
10729;; of the decoding unit.
10730
10731(define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10732
10733
10734;; The fixed point arithmetic calculator(?? EX Unit).
10735
10736(define_cpu_unit "int" "inst_pipeline")
10737
10738;; f1_1 and f1_2 are floating point units.Actually there is
10739;; a f1 unit which can overlap with other f1 unit but
10740;; not another F1 unit.It is as though there were two
10741;; f1 units.
10742
10743(define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10744
c49439f1 10745;; The floating point units (except FS - F2 always precedes it.)
fae15c93 10746
c49439f1 10747(define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
fae15c93
VM
10748
10749;; This is basically the MA unit of SH4
10750;; used in LOAD/STORE pipeline.
10751
10752(define_cpu_unit "memory" "inst_pipeline")
10753
c49439f1
R
10754;; However, there are LS group insns that don't use it, even ones that
10755;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10756(define_cpu_unit "load_store" "inst_pipeline")
10757
fae15c93 10758;; The address calculator used for branch instructions.
c49439f1 10759;; This will be reserved after "issue" of branch instructions
73774972
EC
10760;; and this is to make sure that no two branch instructions
10761;; can be issued in parallel.
fae15c93
VM
10762
10763(define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10764
10765;; ----------------------------------------------------
10766;; This reservation is to simplify the dual issue description.
10767
10768(define_reservation "issue" "pipe_01|pipe_02")
10769
10770;; This is to express the locking of D stage.
c49439f1 10771;; Note that the issue of a CO group insn also effectively locks the D stage.
fae15c93
VM
10772
10773(define_reservation "d_lock" "pipe_01+pipe_02")
10774
c49439f1
R
10775;; Every FE instruction but fipr / ftrv starts with issue and this.
10776(define_reservation "F01" "F0+F1")
10777
fae15c93
VM
10778;; This is to simplify description where F1,F2,FS
10779;; are used simultaneously.
10780
c49439f1 10781(define_reservation "fpu" "F1+F2")
fae15c93 10782
73774972 10783;; This is to highlight the fact that f1
fae15c93
VM
10784;; cannot overlap with F1.
10785
10786(exclusion_set "f1_1,f1_2" "F1")
10787
c49439f1
R
10788(define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10789
73774972 10790;; Although reg moves have a latency of zero
fae15c93
VM
10791;; we need to highlight that they use D stage
10792;; for one cycle.
10793
c49439f1
R
10794;; Group: MT
10795
fae15c93 10796(define_insn_reservation "reg_mov" 0
c49439f1
R
10797 (and (eq_attr "pipe_model" "sh4")
10798 (eq_attr "type" "move"))
10799 "issue")
10800
10801;; Group: LS
10802
10803(define_insn_reservation "freg_mov" 0
10804 (and (eq_attr "pipe_model" "sh4")
10805 (eq_attr "type" "fmove"))
10806 "issue+load_store")
10807
10808;; We don't model all pipeline stages; we model the issue ('D') stage
825db093
KH
10809;; inasmuch as we allow only two instructions to issue simultaneously,
10810;; and CO instructions prevent any simultaneous issue of another instruction.
c49439f1
R
10811;; (This uses pipe_01 and pipe_02).
10812;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10813;; Double issue of EX / BR insns is prevented by using the int unit /
10814;; pcr_addrcalc unit in the EX stage.
10815;; Double issue of BR / LS instructions is prevented by using the
10816;; pcr_addrcalc / load_store unit in the issue cycle.
10817;; Double issue of FE instructions is prevented by using F0 in the first
10818;; pipeline stage after the first D stage.
10819;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10820;; (except in the cases outlined above), nor to describe the FS stage after
10821;; the F2 stage.
fae15c93 10822
825db093 10823;; Other MT group instructions(1 step operations)
fae15c93
VM
10824;; Group: MT
10825;; Latency: 1
10826;; Issue Rate: 1
10827
10828(define_insn_reservation "mt" 1
c49439f1
R
10829 (and (eq_attr "pipe_model" "sh4")
10830 (eq_attr "type" "mt_group"))
10831 "issue")
fae15c93
VM
10832
10833;; Fixed Point Arithmetic Instructions(1 step operations)
10834;; Group: EX
10835;; Latency: 1
10836;; Issue Rate: 1
10837
73774972 10838(define_insn_reservation "sh4_simple_arith" 1
c49439f1
R
10839 (and (eq_attr "pipe_model" "sh4")
10840 (eq_attr "insn_class" "ex_group"))
10841 "issue,int")
10842
10843;; Load and store instructions have no alignment peculiarities for the SH4,
10844;; but they use the load-store unit, which they share with the fmove type
10845;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10846;; Loads have a latency of two.
10847;; However, call insns can only paired with a preceding insn, and have
10848;; a delay slot, so that we want two more insns to be scheduled between the
10849;; load of the function address and the call. This is equivalent to a
10850;; latency of three.
10851;; ADJUST_COST can only properly handle reductions of the cost, so we
10852;; use a latency of three here, which gets multiplied by 10 to yield 30.
10853;; We only do this for SImode loads of general registers, to make the work
10854;; for ADJUST_COST easier.
fae15c93
VM
10855
10856;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10857;; Group: LS
10858;; Latency: 2
10859;; Issue Rate: 1
10860
c49439f1
R
10861(define_insn_reservation "sh4_load" 2
10862 (and (eq_attr "pipe_model" "sh4")
10863 (eq_attr "type" "load,pcload"))
10864 "issue+load_store,nothing,memory")
10865
10866;; calls / sfuncs need an extra instruction for their delay slot.
10867;; Moreover, estimating the latency for SImode loads as 3 will also allow
10868;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10869;; count of a dynamic shift.
10870(define_insn_reservation "sh4_load_si" 3
10871 (and (eq_attr "pipe_model" "sh4")
10872 (eq_attr "type" "load_si,pcload_si"))
10873 "issue+load_store,nothing,memory")
10874
10875;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10876
10877;; The load latency is upped to three higher if the dependent insn does
10878;; double precision computation. We want the 'default' latency to reflect
10879;; that increased latency because otherwise the insn priorities won't
10880;; allow proper scheduling.
10881(define_insn_reservation "sh4_fload" 3
10882 (and (eq_attr "pipe_model" "sh4")
10883 (eq_attr "type" "fload,pcfload"))
10884 "issue+load_store,nothing,memory")
10885
10886;; (define_bypass 2 "sh4_fload" "!")
10887
10888(define_insn_reservation "sh4_store" 1
10889 (and (eq_attr "pipe_model" "sh4")
10890 (eq_attr "type" "store"))
10891 "issue+load_store,nothing,memory")
10892
10893;; Load Store instructions.
10894;; Group: LS
10895;; Latency: 1
10896;; Issue Rate: 1
10897
10898(define_insn_reservation "sh4_gp_fpul" 1
10899 (and (eq_attr "pipe_model" "sh4")
10900 (eq_attr "type" "gp_fpul"))
10901 "issue+load_store")
10902
10903;; Load Store instructions.
10904;; Group: LS
10905;; Latency: 3
10906;; Issue Rate: 1
10907
10908(define_insn_reservation "sh4_fpul_gp" 3
10909 (and (eq_attr "pipe_model" "sh4")
10910 (eq_attr "type" "fpul_gp"))
10911 "issue+load_store")
fae15c93
VM
10912
10913;; Branch (BF,BF/S,BT,BT/S,BRA)
10914;; Group: BR
c49439f1 10915;; Latency when taken: 2 (or 1)
fae15c93
VM
10916;; Issue Rate: 1
10917;; The latency is 1 when displacement is 0.
c49439f1
R
10918;; We can't really do much with the latency, even if we could express it,
10919;; but the pairing restrictions are useful to take into account.
10920;; ??? If the branch is likely, we might want to fill the delay slot;
10921;; if the branch is likely, but not very likely, should we pretend to use
10922;; a resource that CO instructions use, to get a pairable delay slot insn?
fae15c93 10923
c49439f1
R
10924(define_insn_reservation "sh4_branch" 1
10925 (and (eq_attr "pipe_model" "sh4")
10926 (eq_attr "type" "cbranch,jump"))
10927 "issue+pcr_addrcalc")
fae15c93
VM
10928
10929;; Branch Far (JMP,RTS,BRAF)
10930;; Group: CO
10931;; Latency: 3
10932;; Issue Rate: 2
c49439f1
R
10933;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10934;; can't be distinguished from bra for the "jump" pattern.
fae15c93 10935
c49439f1
R
10936(define_insn_reservation "sh4_return" 3
10937 (and (eq_attr "pipe_model" "sh4")
10938 (eq_attr "type" "return,jump_ind"))
10939 "d_lock*2")
fae15c93
VM
10940
10941;; RTE
10942;; Group: CO
c49439f1 10943;; Latency: 5
fae15c93 10944;; Issue Rate: 5
73774972 10945;; this instruction can be executed in any of the pipelines
fae15c93
VM
10946;; and blocks the pipeline for next 4 stages.
10947
c49439f1
R
10948(define_insn_reservation "sh4_return_from_exp" 5
10949 (and (eq_attr "pipe_model" "sh4")
10950 (eq_attr "type" "rte"))
10951 "d_lock*5")
fae15c93
VM
10952
10953;; OCBP, OCBWB
10954;; Group: CO
c49439f1 10955;; Latency: 1-5
fae15c93
VM
10956;; Issue Rate: 1
10957
c49439f1
R
10958;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10959;; ocbwb on its own would be "d_lock,nothing,memory*5"
10960(define_insn_reservation "ocbwb" 6
10961 (and (eq_attr "pipe_model" "sh4")
10962 (eq_attr "type" "cwb"))
10963 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
73774972 10964
fae15c93
VM
10965;; LDS to PR,JSR
10966;; Group: CO
10967;; Latency: 3
10968;; Issue Rate: 2
10969;; The SX stage is blocked for last 2 cycles.
c49439f1
R
10970;; OTOH, the only time that has an effect for insns generated by the compiler
10971;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10972;; or when we are doing a function call - and we don't do inter-function
10973;; scheduling. For the function call case, it's really best that we end with
10974;; something that models an rts.
fae15c93 10975
73774972 10976(define_insn_reservation "sh4_lds_to_pr" 3
c49439f1
R
10977 (and (eq_attr "pipe_model" "sh4")
10978 (eq_attr "type" "prset") )
10979 "d_lock*2")
10980
10981;; calls introduce a longisch delay that is likely to flush the pipelines
10982;; of the caller's instructions. Ordinary functions tend to end with a
10983;; load to restore a register (in the delay slot of rts), while sfuncs
10984;; tend to end with an EX or MT insn. But that is not actually relevant,
10985;; since there are no instructions that contend for memory access early.
10986;; We could, of course, provide exact scheduling information for specific
10987;; sfuncs, if that should prove useful.
10988
73774972 10989(define_insn_reservation "sh4_call" 16
c49439f1
R
10990 (and (eq_attr "pipe_model" "sh4")
10991 (eq_attr "type" "call,sfunc"))
10992 "d_lock*16")
fae15c93 10993
73774972 10994;; LDS.L to PR
fae15c93
VM
10995;; Group: CO
10996;; Latency: 3
10997;; Issue Rate: 2
10998;; The SX unit is blocked for last 2 cycles.
73774972 10999
fae15c93 11000(define_insn_reservation "ldsmem_to_pr" 3
c49439f1
R
11001 (and (eq_attr "pipe_model" "sh4")
11002 (eq_attr "type" "pload"))
11003 "d_lock*2")
fae15c93
VM
11004
11005;; STS from PR
11006;; Group: CO
11007;; Latency: 2
11008;; Issue Rate: 2
11009;; The SX unit in second and third cycles.
11010
11011(define_insn_reservation "sts_from_pr" 2
c49439f1
R
11012 (and (eq_attr "pipe_model" "sh4")
11013 (eq_attr "type" "prget"))
11014 "d_lock*2")
fae15c93
VM
11015
11016;; STS.L from PR
11017;; Group: CO
11018;; Latency: 2
11019;; Issue Rate: 2
11020
73774972 11021(define_insn_reservation "sh4_prstore_mem" 2
c49439f1
R
11022 (and (eq_attr "pipe_model" "sh4")
11023 (eq_attr "type" "pstore"))
11024 "d_lock*2,nothing,memory")
fae15c93
VM
11025
11026;; LDS to FPSCR
11027;; Group: CO
11028;; Latency: 4
11029;; Issue Rate: 1
73774972 11030;; F1 is blocked for last three cycles.
fae15c93 11031
c49439f1
R
11032(define_insn_reservation "fpscr_load" 4
11033 (and (eq_attr "pipe_model" "sh4")
11034 (eq_attr "type" "gp_fpscr"))
11035 "d_lock,nothing,F1*3")
fae15c93
VM
11036
11037;; LDS.L to FPSCR
11038;; Group: CO
11039;; Latency: 1 / 4
11040;; Latency to update Rn is 1 and latency to update FPSCR is 4
11041;; Issue Rate: 1
11042;; F1 is blocked for last three cycles.
11043
c49439f1
R
11044(define_insn_reservation "fpscr_load_mem" 4
11045 (and (eq_attr "pipe_model" "sh4")
11046 (eq_attr "type" "mem_fpscr"))
11047 "d_lock,nothing,(F1+memory),F1*2")
fae15c93
VM
11048
11049\f
11050;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11051;; Group: CO
11052;; Latency: 4 / 4
11053;; Issue Rate: 1
11054
11055(define_insn_reservation "multi" 4
c49439f1
R
11056 (and (eq_attr "pipe_model" "sh4")
11057 (eq_attr "type" "smpy,dmpy"))
11058 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11059
11060;; Fixed STS from MACL / MACH
11061;; Group: CO
11062;; Latency: 3
11063;; Issue Rate: 1
11064
11065(define_insn_reservation "sh4_mac_gp" 3
11066 (and (eq_attr "pipe_model" "sh4")
11067 (eq_attr "type" "mac_gp"))
11068 "d_lock")
fae15c93
VM
11069
11070
11071;; Single precision floating point computation FCMP/EQ,
c49439f1 11072;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
fae15c93 11073;; Group: FE
c49439f1 11074;; Latency: 3/4
fae15c93
VM
11075;; Issue Rate: 1
11076
c49439f1
R
11077(define_insn_reservation "fp_arith" 3
11078 (and (eq_attr "pipe_model" "sh4")
11079 (eq_attr "type" "fp"))
11080 "issue,F01,F2")
11081
11082(define_insn_reservation "fp_arith_ftrc" 3
11083 (and (eq_attr "pipe_model" "sh4")
11084 (eq_attr "type" "ftrc_s"))
11085 "issue,F01,F2")
11086
11087(define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
fae15c93
VM
11088
11089;; Single Precision FDIV/SQRT
11090;; Group: FE
c49439f1 11091;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
fae15c93 11092;; Issue Rate: 1
c49439f1 11093;; We describe fdiv here; fsqrt is actually one cycle faster.
fae15c93 11094
c49439f1
R
11095(define_insn_reservation "fp_div" 12
11096 (and (eq_attr "pipe_model" "sh4")
11097 (eq_attr "type" "fdiv"))
11098 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
fae15c93
VM
11099
11100;; Double Precision floating point computation
11101;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11102;; Group: FE
11103;; Latency: (3,4)/5
11104;; Issue Rate: 1
11105
c49439f1
R
11106(define_insn_reservation "dp_float" 4
11107 (and (eq_attr "pipe_model" "sh4")
11108 (eq_attr "type" "dfp_conv"))
11109 "issue,F01,F1+F2,F2")
fae15c93 11110
73774972 11111;; Double-precision floating-point (FADD,FMUL,FSUB)
fae15c93
VM
11112;; Group: FE
11113;; Latency: (7,8)/9
11114;; Issue Rate: 1
11115
c49439f1
R
11116(define_insn_reservation "fp_double_arith" 8
11117 (and (eq_attr "pipe_model" "sh4")
11118 (eq_attr "type" "dfp_arith"))
11119 "issue,F01,F1+F2,fpu*4,F2")
fae15c93 11120
73774972 11121;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
c49439f1 11122;; Group: CO
fae15c93
VM
11123;; Latency: 3/5
11124;; Issue Rate: 2
11125
73774972 11126(define_insn_reservation "fp_double_cmp" 3
c49439f1
R
11127 (and (eq_attr "pipe_model" "sh4")
11128 (eq_attr "type" "dfp_cmp"))
11129 "d_lock,(d_lock+F01),F1+F2,F2")
fae15c93
VM
11130
11131;; Double precision FDIV/SQRT
11132;; Group: FE
11133;; Latency: (24,25)/26
11134;; Issue Rate: 1
11135
c49439f1
R
11136(define_insn_reservation "dp_div" 25
11137 (and (eq_attr "pipe_model" "sh4")
11138 (eq_attr "type" "dfdiv"))
11139 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11140
fae15c93 11141
c49439f1
R
11142;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11143;; case, we'd get a d_lock instead of issue at the end.
11144(define_insn_reservation "arith3" 3
11145 (and (eq_attr "pipe_model" "sh4")
11146 (eq_attr "type" "arith3"))
11147 "issue,d_lock+pcr_addrcalc,issue")
11148
11149;; arith3b insns schedule the same no matter if the branch is taken or not.
11150(define_insn_reservation "arith3b" 2
11151 (and (eq_attr "pipe_model" "sh4")
11152 (eq_attr "type" "arith3"))
11153 "issue,d_lock+pcr_addrcalc")
This page took 3.258593 seconds and 5 git commands to generate.