]> gcc.gnu.org Git - gcc.git/blame - gcc/config/sh/sh.md
Undo this change (the problem was actually in reload):
[gcc.git] / gcc / config / sh / sh.md
CommitLineData
51aea58d 1;;- Machine description for the Hitachi SH.
d38fbd28 2;; Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
51aea58d
JW
3;; Contributed by Steve Chamberlain (sac@cygnus.com).
4;; Improved by Jim Wilson (wilson@cygnus.com).
bc45ade3
SC
5
6;; This file is part of GNU CC.
7
8;; GNU CC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2, or (at your option)
11;; any later version.
12
13;; GNU CC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GNU CC; see the file COPYING. If not, write to
3f63df56
RK
20;; the Free Software Foundation, 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
bc45ade3 22
bc45ade3 23
d0aae509
RK
24;; ??? Should prepend a * to all pattern names which are not used.
25;; This will make the compiler smaller, and rebuilds after changes faster.
26
ffae286a
JW
27;; ??? Should be enhanced to include support for many more GNU superoptimizer
28;; sequences. Especially the sequences for arithmetic right shifts.
29
30;; ??? Should check all DImode patterns for consistency and usefulness.
31
51bd623f
JW
32;; ??? The MAC.W and MAC.L instructions are not supported. There is no
33;; way to generate them.
34
ffae286a
JW
35;; ??? The cmp/str instruction is not supported. Perhaps it can be used
36;; for a str* inline function.
37
4ed4cb9a
JR
38;; BSR is not generated by the compiler proper, but when relaxing, it
39;; generates .uses pseudo-ops that allow linker relaxation to create
40;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
41
0d7e008e
SC
42;; Special constraints for SH machine description:
43;;
07a45e5c
JW
44;; t -- T
45;; x -- mac
46;; l -- pr
0d7e008e
SC
47;; z -- r0
48;;
49;; Special formats used for outputting SH instructions:
50;;
51;; %. -- print a .s if insn needs delay slot
51aea58d 52;; %@ -- print rte/rts if is/isn't an interrupt function
0d7e008e 53;; %# -- output a nop if there is nothing to put in the delay slot
0d7e008e 54;; %O -- print a constant without the #
51aea58d
JW
55;; %R -- print the lsw reg of a double
56;; %S -- print the msw reg of a double
57;; %T -- print next word of a double REG or MEM
0d7e008e
SC
58;;
59;; Special predicates:
60;;
61;; arith_operand -- operand is valid source for arithmetic op
62;; arith_reg_operand -- operand is valid register for arithmetic op
0d7e008e
SC
63;; general_movdst_operand -- operand is valid move destination
64;; general_movsrc_operand -- operand is valid move source
65;; logical_operand -- operand is valid source for logical op
bc45ade3
SC
66;; -------------------------------------------------------------------------
67;; Attributes
68;; -------------------------------------------------------------------------
69
eeb531d5 70;; Target CPU.
b9654711 71
1245df60
R
72(define_attr "cpu"
73 "sh1,sh2,sh3,sh3e"
07a45e5c 74 (const (symbol_ref "sh_cpu_attr")))
961c4780 75
1245df60
R
76(define_attr "endian" "big,little"
77 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
78 (const_string "little") (const_string "big"))))
79
0d7e008e
SC
80;; cbranch conditional branch instructions
81;; jump unconditional jumps
82;; arith ordinary arithmetic
956d6950 83;; arith3 a compound insn that behaves similarly to a sequence of
1245df60
R
84;; three insns of type arith
85;; arith3b like above, but might end with a redirected branch
0d7e008e 86;; load from memory
1245df60 87;; load_si Likewise, SImode variant for general register.
0d7e008e
SC
88;; store to memory
89;; move register to register
1245df60 90;; fmove register to register, floating point
51bd623f
JW
91;; smpy word precision integer multiply
92;; dmpy longword or doublelongword precision integer multiply
0d7e008e 93;; return rts
ffae286a
JW
94;; pload load of pr reg, which can't be put into delay slot of rts
95;; pstore store of pr reg, which can't be put into delay slot of jsr
22e1ebf1 96;; pcload pc relative load of constant value
1245df60 97;; pcload_si Likewise, SImode variant for general register.
0d7e008e
SC
98;; rte return from exception
99;; sfunc special function call with known used registers
ffae286a 100;; call function call
c1aef54d
ILT
101;; fp floating point
102;; fdiv floating point divide (or square root)
1245df60 103;; gp_fpul move between general purpose register and fpul
4dff12bf 104;; nil no-op move, will be deleted.
0d7e008e 105
07a45e5c 106(define_attr "type"
4dff12bf 107 "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,pstore,pcload,pcload_si,rte,sfunc,call,fp,fdiv,gp_fpul,nil"
bc45ade3
SC
108 (const_string "other"))
109
07a45e5c 110; If a conditional branch destination is within -252..258 bytes away
bc45ade3 111; from the instruction it can be 2 bytes long. Something in the
22e1ebf1 112; range -4090..4100 bytes can be 6 bytes long. All other conditional
1245df60
R
113; branches are initially assumed to be 16 bytes long.
114; In machine_dependent_reorg, we split all branches that are longer than
115; 2 bytes.
bc45ade3 116
22e1ebf1 117; An unconditional jump in the range -4092..4098 can be 2 bytes long.
1245df60
R
118; For wider ranges, we need a combination of a code and a data part.
119; If we can get a scratch register for a long range jump, the code
120; part can be 4 bytes long; otherwise, it must be 8 bytes long.
121; If the jump is in the range -32764..32770, the data part can be 2 bytes
122; long; otherwise, it must be 6 bytes long.
bc45ade3
SC
123
124; All other instructions are two bytes long by default.
125
07a45e5c 126(define_attr "length" ""
bc45ade3 127 (cond [(eq_attr "type" "cbranch")
1245df60
R
128 (cond [(ne (symbol_ref "short_cbranch_p (insn)") (const_int 0))
129 (const_int 2)
130 (ne (symbol_ref "med_branch_p (insn, 2)") (const_int 0))
131 (const_int 6)
132 (ne (symbol_ref "braf_branch_p (insn, 2)") (const_int 0))
133 (const_int 10)
134 (ne (pc) (pc))
135 (const_int 12)
136 ] (const_int 16))
bc45ade3 137 (eq_attr "type" "jump")
1245df60
R
138 (cond [(ne (symbol_ref "med_branch_p (insn, 0)") (const_int 0))
139 (const_int 2)
140 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
141 (symbol_ref "INSN"))
142 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
143 (symbol_ref "code_for_indirect_jump_scratch")))
144 (if_then_else (ne (symbol_ref "braf_branch_p (insn, 0)")
145 (const_int 0))
146 (const_int 6)
147 (const_int 10))
148 (ne (symbol_ref "braf_branch_p (insn, 0)") (const_int 0))
149 (const_int 10)
150 (ne (pc) (pc))
151 (const_int 12)
152 ] (const_int 14))
bc45ade3 153 ] (const_int 2)))
b9654711
SC
154
155;; (define_function_unit {name} {num-units} {n-users} {test}
156;; {ready-delay} {issue-delay} [{conflict-list}])
07a45e5c 157
c1aef54d
ILT
158;; Load and store instructions save a cycle if they are aligned on a
159;; four byte boundary. Using a function unit for stores encourages
160;; gcc to separate load and store instructions by one instruction,
161;; which makes it more likely that the linker will be able to word
162;; align them when relaxing.
1245df60
R
163
164;; Loads have a latency of two.
deeef0ac 165;; However, call insns can have a delay slot, so that we want one more
1245df60
R
166;; insn to be scheduled between the load of the function address and the call.
167;; This is equivalent to a latency of three.
168;; We cannot use a conflict list for this, because we need to distinguish
169;; between the actual call address and the function arguments.
170;; ADJUST_COST can only properly handle reductions of the cost, so we
171;; use a latency of three here.
956d6950 172;; We only do this for SImode loads of general registers, to make the work
1245df60
R
173;; for ADJUST_COST easier.
174(define_function_unit "memory" 1 0
175 (eq_attr "type" "load_si,pcload_si")
176 3 2)
c1aef54d 177(define_function_unit "memory" 1 0
1245df60
R
178 (eq_attr "type" "load,pcload,pload,store,pstore")
179 2 2)
180
181(define_function_unit "int" 1 0
182 (eq_attr "type" "arith3,arith3b") 3 3)
183
184(define_function_unit "int" 1 0
185 (eq_attr "type" "dyn_shift") 2 2)
186
187(define_function_unit "int" 1 0
188 (eq_attr "type" "arith,arith3b,dyn_shift") 2 2)
c1aef54d
ILT
189
190;; ??? These are approximations.
51bd623f
JW
191(define_function_unit "mpy" 1 0 (eq_attr "type" "smpy") 2 2)
192(define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy") 3 3)
bc45ade3 193
1245df60 194(define_function_unit "fp" 1 0 (eq_attr "type" "fp,fmove") 2 1)
c1aef54d 195(define_function_unit "fp" 1 0 (eq_attr "type" "fdiv") 13 12)
45348d9e 196
1245df60 197
51bd623f 198; Definitions for filling branch delay slots.
bc45ade3 199
51bd623f
JW
200(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
201
202(define_attr "hit_stack" "yes,no" (const_string "no"))
203
204(define_attr "interrupt_function" "no,yes"
205 (const (symbol_ref "pragma_interrupt")))
206
07a45e5c 207(define_attr "in_delay_slot" "yes,no"
51bd623f 208 (cond [(eq_attr "type" "cbranch") (const_string "no")
1245df60 209 (eq_attr "type" "pcload,pcload_si") (const_string "no")
51bd623f
JW
210 (eq_attr "needs_delay_slot" "yes") (const_string "no")
211 (eq_attr "length" "2") (const_string "yes")
212 ] (const_string "no")))
213
214(define_delay
0d7e008e 215 (eq_attr "needs_delay_slot" "yes")
b9654711
SC
216 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
217
51aea58d
JW
218;; On the SH and SH2, the rte instruction reads the return pc from the stack,
219;; and thus we can't put a pop instruction in its delay slot.
6b005b88
JW
220;; ??? On the SH3, the rte instruction does not use the stack, so a pop
221;; instruction can go in the delay slot.
51aea58d 222
ffae286a
JW
223;; Since a normal return (rts) implicitly uses the PR register,
224;; we can't allow PR register loads in an rts delay slot.
225
07a45e5c 226(define_delay
961c4780 227 (eq_attr "type" "return")
07a45e5c 228 [(and (eq_attr "in_delay_slot" "yes")
ffae286a
JW
229 (ior (and (eq_attr "interrupt_function" "no")
230 (eq_attr "type" "!pload"))
231 (and (eq_attr "interrupt_function" "yes")
232 (eq_attr "hit_stack" "no")))) (nil) (nil)])
233
234;; Since a call implicitly uses the PR register, we can't allow
235;; a PR register store in a jsr delay slot.
236
237(define_delay
238 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
239 [(and (eq_attr "in_delay_slot" "yes")
240 (eq_attr "type" "!pstore")) (nil) (nil)])
241
242;; Say that we have annulled true branches, since this gives smaller and
243;; faster code when branches are predicted as not taken.
244
07a45e5c
JW
245(define_delay
246 (and (eq_attr "type" "cbranch")
1245df60 247 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
2fad984b 248 [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
bc45ade3
SC
249\f
250;; -------------------------------------------------------------------------
251;; SImode signed integer comparisons
252;; -------------------------------------------------------------------------
253
51bd623f
JW
254(define_insn ""
255 [(set (reg:SI 18)
256 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
257 (match_operand:SI 1 "arith_operand" "L,r"))
258 (const_int 0)))]
259 ""
260 "tst %1,%0")
0d7e008e 261
07a45e5c
JW
262;; ??? Perhaps should only accept reg/constant if the register is reg 0.
263;; That would still allow reload to create cmpi instructions, but would
264;; perhaps allow forcing the constant into a register when that is better.
ffae286a
JW
265;; Probably should use r0 for mem/imm compares, but force constant into a
266;; register for pseudo/imm compares.
07a45e5c 267
0d7e008e 268(define_insn "cmpeqsi_t"
22e1ebf1
JW
269 [(set (reg:SI 18) (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
270 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
0d7e008e
SC
271 ""
272 "@
51bd623f 273 tst %0,%0
0d7e008e
SC
274 cmp/eq %1,%0
275 cmp/eq %1,%0")
bc45ade3
SC
276
277(define_insn "cmpgtsi_t"
0d7e008e 278 [(set (reg:SI 18) (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
22e1ebf1 279 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
bc45ade3 280 ""
0d7e008e 281 "@
22e1ebf1
JW
282 cmp/gt %1,%0
283 cmp/pl %0")
bc45ade3
SC
284
285(define_insn "cmpgesi_t"
0d7e008e 286 [(set (reg:SI 18) (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
22e1ebf1 287 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
bc45ade3 288 ""
0d7e008e 289 "@
22e1ebf1
JW
290 cmp/ge %1,%0
291 cmp/pz %0")
bc45ade3
SC
292\f
293;; -------------------------------------------------------------------------
294;; SImode unsigned integer comparisons
295;; -------------------------------------------------------------------------
296
297(define_insn "cmpgeusi_t"
22e1ebf1
JW
298 [(set (reg:SI 18) (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
299 (match_operand:SI 1 "arith_reg_operand" "r")))]
bc45ade3 300 ""
22e1ebf1 301 "cmp/hs %1,%0")
bc45ade3
SC
302
303(define_insn "cmpgtusi_t"
22e1ebf1
JW
304 [(set (reg:SI 18) (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
305 (match_operand:SI 1 "arith_reg_operand" "r")))]
bc45ade3 306 ""
22e1ebf1 307 "cmp/hi %1,%0")
bc45ade3
SC
308
309;; We save the compare operands in the cmpxx patterns and use them when
310;; we generate the branch.
311
312(define_expand "cmpsi"
0d7e008e
SC
313 [(set (reg:SI 18) (compare (match_operand:SI 0 "arith_operand" "")
314 (match_operand:SI 1 "arith_operand" "")))]
bc45ade3
SC
315 ""
316 "
0d7e008e
SC
317{
318 sh_compare_op0 = operands[0];
bc45ade3
SC
319 sh_compare_op1 = operands[1];
320 DONE;
321}")
bc45ade3
SC
322\f
323;; -------------------------------------------------------------------------
1245df60
R
324;; DImode signed integer comparisons
325;; -------------------------------------------------------------------------
326
327;; ??? Could get better scheduling by splitting the initial test from the
328;; rest of the insn after reload. However, the gain would hardly justify
329;; the sh.md size increase necessary to do that.
330
331(define_insn ""
332 [(set (reg:SI 18)
333 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
334 (match_operand:DI 1 "arith_operand" "r"))
335 (const_int 0)))]
336 ""
337 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
338 insn, operands);"
339 [(set_attr "length" "6")
340 (set_attr "type" "arith3b")])
341
342(define_insn "cmpeqdi_t"
343 [(set (reg:SI 18) (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
344 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
345 ""
346 "*
347 return output_branchy_insn
348 (EQ,
349 (which_alternative
350 ? \"cmp/eq\\t%S1,%S0\;bf\\t%l9\;cmp/eq\\t%R1,%R0\"
351 : \"tst\\t%S0,%S0\;bf\\t%l9\;tst\\t%R0,%R0\"),
352 insn, operands);"
353 [(set_attr "length" "6")
354 (set_attr "type" "arith3b")])
355
356(define_insn "cmpgtdi_t"
357 [(set (reg:SI 18) (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
358 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
359 "TARGET_SH2"
360 "@
361 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
362 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
363 [(set_attr "length" "8")
364 (set_attr "type" "arith3")])
365
366(define_insn "cmpgedi_t"
367 [(set (reg:SI 18) (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
368 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
369 "TARGET_SH2"
370 "@
371 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
372 cmp/pz\\t%S0"
373 [(set_attr "length" "8,2")
374 (set_attr "type" "arith3,arith")])
375\f
376;; -------------------------------------------------------------------------
377;; DImode unsigned integer comparisons
378;; -------------------------------------------------------------------------
379
380(define_insn "cmpgeudi_t"
381 [(set (reg:SI 18) (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
382 (match_operand:DI 1 "arith_reg_operand" "r")))]
383 "TARGET_SH2"
384 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
385 [(set_attr "length" "8")
386 (set_attr "type" "arith3")])
387
388(define_insn "cmpgtudi_t"
389 [(set (reg:SI 18) (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
390 (match_operand:DI 1 "arith_reg_operand" "r")))]
391 "TARGET_SH2"
392 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
393 [(set_attr "length" "8")
394 (set_attr "type" "arith3")])
395
396;; We save the compare operands in the cmpxx patterns and use them when
397;; we generate the branch.
398
399(define_expand "cmpdi"
400 [(set (reg:SI 18) (compare (match_operand:DI 0 "arith_operand" "")
401 (match_operand:DI 1 "arith_operand" "")))]
402 "TARGET_SH2"
403 "
404{
405 sh_compare_op0 = operands[0];
406 sh_compare_op1 = operands[1];
407 DONE;
408}")
409\f
410;; -------------------------------------------------------------------------
bc45ade3
SC
411;; Addition instructions
412;; -------------------------------------------------------------------------
413
ffae286a 414;; ??? This should be a define expand.
0d7e008e 415
4fdd1f85 416(define_insn "adddi3"
07a45e5c
JW
417 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
418 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
419 (match_operand:DI 2 "arith_reg_operand" "r")))
8e87e161
SC
420 (clobber (reg:SI 18))]
421 ""
1245df60 422 "#"
4fdd1f85 423 [(set_attr "length" "6")])
961c4780 424
1245df60
R
425(define_split
426 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
427 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
428 (match_operand:DI 2 "arith_reg_operand" "r")))
429 (clobber (reg:SI 18))]
430 "reload_completed"
431 [(const_int 0)]
432 "
433{
434 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
435 high0 = gen_rtx (REG, SImode,
436 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
437 high2 = gen_rtx (REG, SImode,
438 true_regnum (operands[2]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
439 emit_insn (gen_clrt ());
440 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
441 emit_insn (gen_addc1 (high0, high0, high2));
442 DONE;
443}")
444
445(define_insn "addc"
446 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
447 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
448 (match_operand:SI 2 "arith_reg_operand" "r"))
449 (reg:SI 18)))
450 (set (reg:SI 18)
451 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
452 ""
453 "addc %2,%0"
454 [(set_attr "type" "arith")])
455
456(define_insn "addc1"
457 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
458 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
459 (match_operand:SI 2 "arith_reg_operand" "r"))
460 (reg:SI 18)))
461 (clobber (reg:SI 18))]
462 ""
463 "addc %2,%0"
464 [(set_attr "type" "arith")])
465
51bd623f 466(define_insn "addsi3"
aa684c94 467 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f 468 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
bc45ade3
SC
469 (match_operand:SI 2 "arith_operand" "rI")))]
470 ""
471 "add %2,%0"
22e1ebf1 472 [(set_attr "type" "arith")])
bc45ade3
SC
473\f
474;; -------------------------------------------------------------------------
475;; Subtraction instructions
476;; -------------------------------------------------------------------------
477
ffae286a 478;; ??? This should be a define expand.
8e87e161 479
4fdd1f85 480(define_insn "subdi3"
07a45e5c
JW
481 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
482 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
483 (match_operand:DI 2 "arith_reg_operand" "r")))
bc45ade3
SC
484 (clobber (reg:SI 18))]
485 ""
1245df60 486 "#"
4fdd1f85 487 [(set_attr "length" "6")])
bc45ade3 488
1245df60
R
489(define_split
490 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
491 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
492 (match_operand:DI 2 "arith_reg_operand" "r")))
493 (clobber (reg:SI 18))]
494 "reload_completed"
495 [(const_int 0)]
496 "
497{
498 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
499 high0 = gen_rtx (REG, SImode,
500 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
501 high2 = gen_rtx (REG, SImode,
502 true_regnum (operands[2]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
503 emit_insn (gen_clrt ());
504 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
505 emit_insn (gen_subc1 (high0, high0, high2));
506 DONE;
507}")
508
509(define_insn "subc"
510 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
511 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
512 (match_operand:SI 2 "arith_reg_operand" "r"))
513 (reg:SI 18)))
514 (set (reg:SI 18)
515 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
516 ""
517 "subc %2,%0"
518 [(set_attr "type" "arith")])
519
520(define_insn "subc1"
521 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
522 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
523 (match_operand:SI 2 "arith_reg_operand" "r"))
524 (reg:SI 18)))
525 (clobber (reg:SI 18))]
526 ""
527 "subc %2,%0"
528 [(set_attr "type" "arith")])
529
caca3c8a 530(define_insn "*subsi3_internal"
0d7e008e
SC
531 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
532 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 533 (match_operand:SI 2 "arith_reg_operand" "r")))]
bc45ade3 534 ""
0d7e008e 535 "sub %2,%0"
bc45ade3 536 [(set_attr "type" "arith")])
caca3c8a
JW
537
538;; Convert `constant - reg' to `neg rX; add rX, #const' since this
539;; will sometimes save one instruction. Otherwise we might get
540;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
541;; are the same.
542
543(define_expand "subsi3"
544 [(set (match_operand:SI 0 "arith_reg_operand" "")
545 (minus:SI (match_operand:SI 1 "arith_operand" "")
546 (match_operand:SI 2 "arith_reg_operand" "")))]
547 ""
548 "
549{
550 if (GET_CODE (operands[1]) == CONST_INT)
551 {
552 emit_insn (gen_negsi2 (operands[0], operands[2]));
553 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
554 DONE;
555 }
556}")
bc45ade3
SC
557\f
558;; -------------------------------------------------------------------------
0d7e008e 559;; Division instructions
bc45ade3
SC
560;; -------------------------------------------------------------------------
561
ffae286a 562;; We take advantage of the library routines which don't clobber as many
0d7e008e
SC
563;; registers as a normal function call would.
564
1245df60 565;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
956d6950 566;; also has an effect on the register that holds the address of the sfunc.
1245df60
R
567;; To make this work, we have an extra dummy insns that shows the use
568;; of this register for reorg.
569
570(define_insn "use_sfunc_addr"
571 [(set (reg:SI 17) (unspec [(match_operand:SI 0 "register_operand" "r")] 5))]
572 ""
573 ""
574 [(set_attr "length" "0")])
575
ddd5a7c1 576;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
e96a50cc
JW
577;; hard register 0. If we used hard register 0, then the next instruction
578;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
579;; gets allocated to a stack slot that needs its address reloaded, then
580;; there is nothing to prevent reload from using r0 to reload the address.
581;; This reload would clobber the value in r0 we are trying to store.
582;; If we let reload allocate r0, then this problem can never happen.
0d7e008e
SC
583
584(define_insn ""
1245df60 585 [(set (match_operand:SI 0 "register_operand" "=z")
0d7e008e
SC
586 (udiv:SI (reg:SI 4) (reg:SI 5)))
587 (clobber (reg:SI 18))
588 (clobber (reg:SI 17))
0d7e008e 589 (clobber (reg:SI 4))
1245df60 590 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
0d7e008e 591 ""
1245df60 592 "jsr @%1%#"
0d7e008e 593 [(set_attr "type" "sfunc")
0d7e008e
SC
594 (set_attr "needs_delay_slot" "yes")])
595
596(define_expand "udivsi3"
51aea58d
JW
597 [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
598 (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
0d7e008e 599 (set (match_dup 3) (symbol_ref:SI "__udivsi3"))
ffae286a
JW
600 (parallel [(set (match_operand:SI 0 "register_operand" "")
601 (udiv:SI (reg:SI 4)
602 (reg:SI 5)))
603 (clobber (reg:SI 18))
604 (clobber (reg:SI 17))
605 (clobber (reg:SI 4))
606 (use (match_dup 3))])]
0d7e008e
SC
607 ""
608 "operands[3] = gen_reg_rtx(SImode);")
609
0d7e008e 610(define_insn ""
1245df60 611 [(set (match_operand:SI 0 "register_operand" "=z")
0d7e008e
SC
612 (div:SI (reg:SI 4) (reg:SI 5)))
613 (clobber (reg:SI 18))
614 (clobber (reg:SI 17))
4fdd1f85
SC
615 (clobber (reg:SI 1))
616 (clobber (reg:SI 2))
0d7e008e 617 (clobber (reg:SI 3))
1245df60 618 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
0d7e008e 619 ""
1245df60 620 "jsr @%1%#"
0d7e008e 621 [(set_attr "type" "sfunc")
0d7e008e
SC
622 (set_attr "needs_delay_slot" "yes")])
623
624(define_expand "divsi3"
51aea58d
JW
625 [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
626 (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
0d7e008e 627 (set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
ffae286a
JW
628 (parallel [(set (match_operand:SI 0 "register_operand" "")
629 (div:SI (reg:SI 4)
0d7e008e 630 (reg:SI 5)))
ffae286a
JW
631 (clobber (reg:SI 18))
632 (clobber (reg:SI 17))
633 (clobber (reg:SI 1))
634 (clobber (reg:SI 2))
635 (clobber (reg:SI 3))
636 (use (match_dup 3))])]
0d7e008e
SC
637 ""
638 "operands[3] = gen_reg_rtx(SImode);")
0d7e008e
SC
639\f
640;; -------------------------------------------------------------------------
641;; Multiplication instructions
642;; -------------------------------------------------------------------------
643
bc45ade3
SC
644(define_insn ""
645 [(set (reg:SI 21)
af55dae3
JW
646 (mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r"))
647 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))]
bc45ade3 648 ""
af55dae3 649 "mulu %1,%0"
b9654711 650 [(set_attr "type" "smpy")])
bc45ade3
SC
651
652(define_insn ""
653 [(set (reg:SI 21)
654 (mult:SI (sign_extend:SI
af55dae3 655 (match_operand:HI 0 "arith_reg_operand" "r"))
bc45ade3 656 (sign_extend:SI
af55dae3 657 (match_operand:HI 1 "arith_reg_operand" "r"))))]
bc45ade3 658 ""
af55dae3 659 "muls %1,%0"
b9654711 660 [(set_attr "type" "smpy")])
bc45ade3
SC
661
662(define_expand "mulhisi3"
663 [(set (reg:SI 21)
664 (mult:SI (sign_extend:SI
51aea58d 665 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 666 (sign_extend:SI
51aea58d
JW
667 (match_operand:HI 2 "arith_reg_operand" ""))))
668 (set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
669 (reg:SI 21))]
670 ""
671 "")
672
673(define_expand "umulhisi3"
674 [(set (reg:SI 21)
675 (mult:SI (zero_extend:SI
51aea58d 676 (match_operand:HI 1 "arith_reg_operand" ""))
bc45ade3 677 (zero_extend:SI
51aea58d
JW
678 (match_operand:HI 2 "arith_reg_operand" ""))))
679 (set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
680 (reg:SI 21))]
681 ""
682 "")
683
0d7e008e
SC
684;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
685;; a call to a routine which clobbers known registers.
686
687(define_insn ""
e96a50cc 688 [(set (match_operand:SI 1 "register_operand" "=z")
0d7e008e
SC
689 (mult:SI (reg:SI 4) (reg:SI 5)))
690 (clobber (reg:SI 21))
691 (clobber (reg:SI 18))
692 (clobber (reg:SI 17))
693 (clobber (reg:SI 3))
694 (clobber (reg:SI 2))
695 (clobber (reg:SI 1))
07a45e5c 696 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
0d7e008e
SC
697 ""
698 "jsr @%0%#"
699 [(set_attr "type" "sfunc")
0d7e008e
SC
700 (set_attr "needs_delay_slot" "yes")])
701
702(define_expand "mulsi3_call"
51aea58d
JW
703 [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
704 (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
0d7e008e 705 (set (match_dup 3) (symbol_ref:SI "__mulsi3"))
51aea58d 706 (parallel[(set (match_operand:SI 0 "register_operand" "")
0d7e008e
SC
707 (mult:SI (reg:SI 4)
708 (reg:SI 5)))
709 (clobber (reg:SI 21))
710 (clobber (reg:SI 18))
711 (clobber (reg:SI 17))
712 (clobber (reg:SI 3))
713 (clobber (reg:SI 2))
714 (clobber (reg:SI 1))
e96a50cc 715 (use (match_dup 3))])]
0d7e008e
SC
716 ""
717 "operands[3] = gen_reg_rtx(SImode);")
07a45e5c 718
0d7e008e
SC
719(define_insn "mul_l"
720 [(set (reg:SI 21)
721 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
722 (match_operand:SI 1 "arith_reg_operand" "r")))]
723 "TARGET_SH2"
724 "mul.l %1,%0"
51bd623f 725 [(set_attr "type" "dmpy")])
0d7e008e
SC
726
727(define_expand "mulsi3"
728 [(set (reg:SI 21)
51aea58d
JW
729 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
730 (match_operand:SI 2 "arith_reg_operand" "")))
731 (set (match_operand:SI 0 "arith_reg_operand" "")
0d7e008e 732 (reg:SI 21))]
51bd623f
JW
733 ""
734 "
735{
736 if (!TARGET_SH2)
737 {
738 FAIL;
739 /* ??? Does this give worse or better code? */
740 emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
741 DONE;
742 }
743}")
00f8ff66 744
af55dae3 745(define_insn "mulsidi3_i"
0d7e008e 746 [(set (reg:DI 20)
af55dae3
JW
747 (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
748 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
06e1bace 749 "TARGET_SH2"
af55dae3 750 "dmuls.l %1,%0"
0d7e008e
SC
751 [(set_attr "type" "dmpy")])
752
753(define_expand "mulsidi3"
754 [(set (reg:DI 20)
51aea58d
JW
755 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
756 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
757 (set (match_operand:DI 0 "arith_reg_operand" "")
0d7e008e 758 (reg:DI 20))]
06e1bace 759 "TARGET_SH2"
af55dae3
JW
760 "
761{
762 /* We must swap the two words when copying them from MACH/MACL to the
763 output register. */
764 if (TARGET_LITTLE_ENDIAN)
765 {
766 rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
767 rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
0d7e008e 768
af55dae3
JW
769 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
770
771 emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
772 emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
773 emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
774 DONE;
775 }
776}")
777
778(define_insn "umulsidi3_i"
0d7e008e 779 [(set (reg:DI 20)
af55dae3
JW
780 (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
781 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
06e1bace 782 "TARGET_SH2"
af55dae3 783 "dmulu.l %1,%0"
0d7e008e
SC
784 [(set_attr "type" "dmpy")])
785
786(define_expand "umulsidi3"
787 [(set (reg:DI 20)
51aea58d
JW
788 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
789 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
790 (set (match_operand:DI 0 "arith_reg_operand" "")
0d7e008e 791 (reg:DI 20))]
06e1bace 792 "TARGET_SH2"
af55dae3
JW
793 "
794{
795 /* We must swap the two words when copying them from MACH/MACL to the
796 output register. */
797 if (TARGET_LITTLE_ENDIAN)
798 {
799 rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
800 rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
801
802 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
803
804 emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
805 emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
806 emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
807 DONE;
808 }
809}")
06e1bace
RK
810
811(define_insn ""
812 [(set (reg:SI 20)
813 (truncate:SI
af55dae3
JW
814 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
815 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
06e1bace
RK
816 (const_int 32))))
817 (clobber (reg:SI 21))]
818 "TARGET_SH2"
af55dae3 819 "dmuls.l %1,%0"
06e1bace
RK
820 [(set_attr "type" "dmpy")])
821
822(define_expand "smulsi3_highpart"
823 [(parallel [(set (reg:SI 20)
824 (truncate:SI
825 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
826 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
827 (const_int 32))))
828 (clobber (reg:SI 21))])
829 (set (match_operand:SI 0 "arith_reg_operand" "")
830 (reg:SI 20))]
831 "TARGET_SH2"
832 "")
833
834(define_insn ""
835 [(set (reg:SI 20)
836 (truncate:SI
af55dae3
JW
837 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
838 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
06e1bace
RK
839 (const_int 32))))
840 (clobber (reg:SI 21))]
841 "TARGET_SH2"
af55dae3 842 "dmulu.l %1,%0"
06e1bace
RK
843 [(set_attr "type" "dmpy")])
844
845(define_expand "umulsi3_highpart"
846 [(parallel [(set (reg:SI 20)
847 (truncate:SI
848 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
849 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
850 (const_int 32))))
851 (clobber (reg:SI 21))])
852 (set (match_operand:SI 0 "arith_reg_operand" "")
853 (reg:SI 20))]
854 "TARGET_SH2"
0d7e008e 855 "")
bc45ade3
SC
856\f
857;; -------------------------------------------------------------------------
858;; Logical operations
859;; -------------------------------------------------------------------------
860
0d7e008e 861(define_insn ""
aa684c94
SC
862 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
863 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
bc45ade3
SC
864 (match_operand:SI 2 "logical_operand" "r,L")))]
865 ""
866 "and %2,%0"
867 [(set_attr "type" "arith")])
868
51bd623f
JW
869;; If the constant is 255, then emit a extu.b instruction instead of an
870;; and, since that will give better code.
871
0d7e008e
SC
872(define_expand "andsi3"
873 [(set (match_operand:SI 0 "arith_reg_operand" "")
874 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
875 (match_operand:SI 2 "logical_operand" "")))]
876 ""
51bd623f
JW
877 "
878{
879 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
880 {
881 emit_insn (gen_zero_extendqisi2 (operands[0],
882 gen_lowpart (QImode, operands[1])));
883 DONE;
884 }
885}")
0d7e008e 886
bc45ade3 887(define_insn "iorsi3"
aa684c94
SC
888 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
889 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
bc45ade3
SC
890 (match_operand:SI 2 "logical_operand" "r,L")))]
891 ""
1245df60
R
892 "or %2,%0"
893 [(set_attr "type" "arith")])
bc45ade3
SC
894
895(define_insn "xorsi3"
0d7e008e 896 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
aa684c94 897 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
0d7e008e 898 (match_operand:SI 2 "logical_operand" "L,r")))]
bc45ade3
SC
899 ""
900 "xor %2,%0"
901 [(set_attr "type" "arith")])
bc45ade3
SC
902\f
903;; -------------------------------------------------------------------------
904;; Shifts and rotates
905;; -------------------------------------------------------------------------
906
51bd623f 907(define_insn "rotlsi3_1"
b9654711
SC
908 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
909 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
910 (const_int 1)))
51aea58d
JW
911 (set (reg:SI 18)
912 (lshiftrt:SI (match_dup 1) (const_int 31)))]
b9654711 913 ""
1245df60
R
914 "rotl %0"
915 [(set_attr "type" "arith")])
b9654711 916
51bd623f 917(define_insn "rotlsi3_31"
b9654711 918 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f
JW
919 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
920 (const_int 31)))
b9654711
SC
921 (clobber (reg:SI 18))]
922 ""
1245df60
R
923 "rotr %0"
924 [(set_attr "type" "arith")])
b9654711 925
1245df60 926(define_insn "rotlsi3_16"
51bd623f
JW
927 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
928 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
929 (const_int 16)))]
b9654711 930 ""
1245df60
R
931 "swap.w %1,%0"
932 [(set_attr "type" "arith")])
b9654711 933
51bd623f
JW
934(define_expand "rotlsi3"
935 [(set (match_operand:SI 0 "arith_reg_operand" "")
936 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
937 (match_operand:SI 2 "immediate_operand" "")))]
938 ""
939 "
940{
1245df60
R
941 static char rot_tab[] = {
942 000, 000, 000, 000, 000, 000, 010, 001,
943 001, 001, 011, 013, 003, 003, 003, 003,
944 003, 003, 003, 003, 003, 013, 012, 002,
945 002, 002, 010, 000, 000, 000, 000, 000,
946 };
947
948 int count, choice;
949
51bd623f
JW
950 if (GET_CODE (operands[2]) != CONST_INT)
951 FAIL;
1245df60
R
952 count = INTVAL (operands[2]);
953 choice = rot_tab[count];
954 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
955 FAIL;
956 choice &= 7;
957 switch (choice)
51bd623f 958 {
1245df60
R
959 case 0:
960 emit_move_insn (operands[0], operands[1]);
961 count -= (count & 16) * 2;
962 break;
963 case 3:
964 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
965 count -= 16;
966 break;
967 case 1:
968 case 2:
969 {
970 rtx parts[2];
971 parts[0] = gen_reg_rtx (SImode);
972 parts[1] = gen_reg_rtx (SImode);
973 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
974 parts[choice-1] = operands[1];
975 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
976 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
977 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
978 count = (count & ~16) - 8;
979 }
51bd623f 980 }
1245df60
R
981
982 for (; count > 0; count--)
983 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
984 for (; count < 0; count++)
985 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
986
987 DONE;
51bd623f
JW
988}")
989
1245df60 990(define_insn "*rotlhi3_8"
51bd623f
JW
991 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
992 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
993 (const_int 8)))]
994 ""
1245df60
R
995 "swap.b %1,%0"
996 [(set_attr "type" "arith")])
51bd623f
JW
997
998(define_expand "rotlhi3"
999 [(set (match_operand:HI 0 "arith_reg_operand" "")
1000 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
1001 (match_operand:HI 2 "immediate_operand" "")))]
1002 ""
1003 "
1004{
1005 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1006 FAIL;
1007}")
0d7e008e
SC
1008
1009;;
1010;; shift left
1011
6b005b88
JW
1012(define_insn "ashlsi3_d"
1013 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1014 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
1015 (match_operand:SI 2 "arith_reg_operand" "r")))]
1016 "TARGET_SH3"
1245df60
R
1017 "shld %2,%0"
1018 [(set_attr "type" "dyn_shift")])
51aea58d 1019
bc45ade3 1020(define_insn "ashlsi3_k"
aa684c94
SC
1021 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1022 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
ffae286a 1023 (match_operand:SI 2 "const_int_operand" "M,K")))]
0d7e008e
SC
1024 "CONST_OK_FOR_K (INTVAL (operands[2]))"
1025 "@
51bd623f 1026 add %0,%0
1245df60
R
1027 shll%O2 %0"
1028 [(set_attr "type" "arith")])
0d7e008e 1029
98e819b9
JW
1030(define_insn "ashlhi3_k"
1031 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
1032 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
1033 (match_operand:HI 2 "const_int_operand" "M,K")))]
1034 "CONST_OK_FOR_K (INTVAL (operands[2]))"
1035 "@
1036 add %0,%0
1245df60
R
1037 shll%O2 %0"
1038 [(set_attr "type" "arith")])
98e819b9 1039
0d7e008e
SC
1040(define_insn "ashlsi3_n"
1041 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1042 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1043 (match_operand:SI 2 "const_int_operand" "n")))
0d7e008e 1044 (clobber (reg:SI 18))]
1245df60 1045 "! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
1046 "#"
1047 [(set (attr "length")
1048 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1049 (const_string "2")
1050 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1051 (const_string "4")
1052 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
1053 (const_string "6")]
1054 (const_string "8")))
bc45ade3
SC
1055 (set_attr "type" "arith")])
1056
07a45e5c
JW
1057(define_split
1058 [(set (match_operand:SI 0 "arith_reg_operand" "")
1059 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
ffae286a 1060 (match_operand:SI 2 "const_int_operand" "n")))
07a45e5c
JW
1061 (clobber (reg:SI 18))]
1062 ""
1063 [(use (reg:SI 0))]
1064 "
1065{
1066 gen_shifty_op (ASHIFT, operands);
1067 DONE;
1068}")
1069
bc45ade3 1070(define_expand "ashlsi3"
ffae286a
JW
1071 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1072 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
1073 (match_operand:SI 2 "nonmemory_operand" "")))
1074 (clobber (reg:SI 18))])]
bc45ade3 1075 ""
d2f09a2f
JW
1076 "
1077{
1245df60
R
1078 if (GET_CODE (operands[2]) == CONST_INT
1079 && sh_dynamicalize_shift_p (operands[2]))
1080 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
1081 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
1082 {
1083 emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
1084 DONE;
1085 }
d2f09a2f
JW
1086 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1087 FAIL;
1088}")
0d7e008e 1089
98e819b9
JW
1090(define_insn "ashlhi3"
1091 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1092 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
1093 (match_operand:HI 2 "const_int_operand" "n")))
1094 (clobber (reg:SI 18))]
1095 ""
1096 "#"
1097 [(set (attr "length")
1098 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1099 (const_string "2")
1100 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1101 (const_string "4")]
1102 (const_string "6")))
1103 (set_attr "type" "arith")])
1104
1105(define_split
1106 [(set (match_operand:HI 0 "arith_reg_operand" "")
1107 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
1108 (match_operand:HI 2 "const_int_operand" "n")))
1109 (clobber (reg:SI 18))]
1110 ""
1111 [(use (reg:SI 0))]
1112 "
1113{
1114 gen_shifty_hi_op (ASHIFT, operands);
1115 DONE;
1116}")
1117
0d7e008e
SC
1118;
1119; arithmetic shift right
1120;
bc45ade3
SC
1121
1122(define_insn "ashrsi3_k"
aa684c94
SC
1123 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1124 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1125 (match_operand:SI 2 "const_int_operand" "M")))
b9654711 1126 (clobber (reg:SI 18))]
ffae286a 1127 "INTVAL (operands[2]) == 1"
bc45ade3
SC
1128 "shar %0"
1129 [(set_attr "type" "arith")])
1130
98e819b9
JW
1131(define_insn "ashrhi3_k"
1132 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1133 (ashiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
1134 (match_operand:HI 2 "const_int_operand" "M")))
1135 (clobber (reg:SI 18))]
1136 "INTVAL (operands[2]) == 1"
1137 "shar %0"
1138 [(set_attr "type" "arith")])
1139
ffae286a
JW
1140;; ??? This should be a define expand.
1141
00f8ff66 1142(define_insn "ashrsi2_16"
07a45e5c
JW
1143 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1144 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3e8bd1ce 1145 (const_int 16)))]
00f8ff66 1146 ""
1245df60 1147 "#"
00f8ff66
SC
1148 [(set_attr "length" "4")])
1149
1245df60
R
1150(define_split
1151 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1152 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
1153 (const_int 16)))]
1154 ""
1155 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
1156 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
1157 "operands[2] = gen_lowpart (HImode, operands[0]);")
1158
ffae286a
JW
1159;; ??? This should be a define expand.
1160
00f8ff66 1161(define_insn "ashrsi2_31"
6b005b88 1162 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1245df60
R
1163 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1164 (const_int 31)))
3e8bd1ce 1165 (clobber (reg:SI 18))]
00f8ff66 1166 ""
1245df60 1167 "#"
6b005b88 1168 [(set_attr "length" "4")])
3e8bd1ce 1169
1245df60
R
1170(define_split
1171 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1172 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1173 (const_int 31)))
1174 (clobber (reg:SI 18))]
1175 ""
1176 [(const_int 0)]
1177 "
1178{
1179 emit_insn (gen_ashlsi_c (operands[0], operands[1], operands[1]));
1180 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
1181 DONE;
1182}")
1183
1184(define_insn "ashlsi_c"
1185 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1186 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
1187 (set (reg:SI 18) (lt:SI (match_operand:SI 2 "arith_reg_operand" "0")
1188 (const_int 0)))]
1189 ""
1190 "shll %0"
1191 [(set_attr "type" "arith")])
1192
6b005b88
JW
1193(define_insn "ashrsi3_d"
1194 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1195 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1196 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1197 "TARGET_SH3"
1245df60
R
1198 "shad %2,%0"
1199 [(set_attr "type" "dyn_shift")])
51aea58d 1200
0d7e008e
SC
1201(define_insn "ashrsi3_n"
1202 [(set (reg:SI 4)
1203 (ashiftrt:SI (reg:SI 4)
ffae286a 1204 (match_operand:SI 0 "const_int_operand" "i")))
0d7e008e
SC
1205 (clobber (reg:SI 18))
1206 (clobber (reg:SI 17))
1207 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1208 ""
1209 "jsr @%1%#"
1210 [(set_attr "type" "sfunc")
0d7e008e
SC
1211 (set_attr "needs_delay_slot" "yes")])
1212
bc45ade3 1213(define_expand "ashrsi3"
ffae286a
JW
1214 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1215 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1216 (match_operand:SI 2 "nonmemory_operand" "")))
1217 (clobber (reg:SI 18))])]
bc45ade3 1218 ""
51aea58d 1219 "if (expand_ashiftrt (operands)) DONE; else FAIL;")
0d7e008e 1220
07a45e5c 1221;; logical shift right
bc45ade3 1222
6b005b88
JW
1223(define_insn "lshrsi3_d"
1224 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1225 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1226 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1227 "TARGET_SH3"
1245df60
R
1228 "shld %2,%0"
1229 [(set_attr "type" "dyn_shift")])
00f8ff66 1230
ffae286a 1231;; Only the single bit shift clobbers the T bit.
07a45e5c
JW
1232
1233(define_insn "lshrsi3_m"
1234 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1235 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1236 (match_operand:SI 2 "const_int_operand" "M")))
b9654711 1237 (clobber (reg:SI 18))]
07a45e5c 1238 "CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60
R
1239 "shlr %0"
1240 [(set_attr "type" "arith")])
0d7e008e 1241
07a45e5c
JW
1242(define_insn "lshrsi3_k"
1243 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1244 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1245 (match_operand:SI 2 "const_int_operand" "K")))]
07a45e5c
JW
1246 "CONST_OK_FOR_K (INTVAL (operands[2]))
1247 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60
R
1248 "shlr%O2 %0"
1249 [(set_attr "type" "arith")])
0d7e008e 1250
98e819b9
JW
1251(define_insn "lshrhi3_m"
1252 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1253 (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
1254 (match_operand:HI 2 "const_int_operand" "M")))
1255 (clobber (reg:SI 18))]
1256 "CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60
R
1257 "shlr %0"
1258 [(set_attr "type" "arith")])
98e819b9
JW
1259
1260(define_insn "lshrhi3_k"
1261 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1262 (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
1263 (match_operand:HI 2 "const_int_operand" "K")))]
1264 "CONST_OK_FOR_K (INTVAL (operands[2]))
1265 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1245df60
R
1266 "shlr%O2 %0"
1267 [(set_attr "type" "arith")])
98e819b9 1268
0d7e008e
SC
1269(define_insn "lshrsi3_n"
1270 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1271 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
ffae286a 1272 (match_operand:SI 2 "const_int_operand" "n")))
0d7e008e 1273 (clobber (reg:SI 18))]
1245df60 1274 "! sh_dynamicalize_shift_p (operands[2])"
07a45e5c
JW
1275 "#"
1276 [(set (attr "length")
1277 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1278 (const_string "2")
1279 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1280 (const_string "4")
1281 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
1282 (const_string "6")]
1283 (const_string "8")))
bc45ade3
SC
1284 (set_attr "type" "arith")])
1285
07a45e5c
JW
1286(define_split
1287 [(set (match_operand:SI 0 "arith_reg_operand" "")
1288 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
ffae286a 1289 (match_operand:SI 2 "const_int_operand" "n")))
07a45e5c
JW
1290 (clobber (reg:SI 18))]
1291 ""
1292 [(use (reg:SI 0))]
1293 "
1294{
1295 gen_shifty_op (LSHIFTRT, operands);
1296 DONE;
1297}")
1298
bc45ade3 1299(define_expand "lshrsi3"
ffae286a
JW
1300 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1301 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1302 (match_operand:SI 2 "nonmemory_operand" "")))
1303 (clobber (reg:SI 18))])]
bc45ade3 1304 ""
d2f09a2f
JW
1305 "
1306{
1245df60
R
1307 if (GET_CODE (operands[2]) == CONST_INT
1308 && sh_dynamicalize_shift_p (operands[2]))
1309 operands[2] = force_reg (SImode, operands[2]);
6b005b88
JW
1310 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
1311 {
1312 rtx count = copy_to_mode_reg (SImode, operands[2]);
1313 emit_insn (gen_negsi2 (count, count));
7b7499bf 1314 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
6b005b88
JW
1315 DONE;
1316 }
d2f09a2f
JW
1317 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1318 FAIL;
1319}")
bc45ade3 1320
98e819b9
JW
1321(define_insn "lshrhi3"
1322 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1323 (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
1324 (match_operand:HI 2 "const_int_operand" "n")))
1325 (clobber (reg:SI 18))]
1326 ""
1327 "#"
1328;; ??? length attribute is sometimes six instead of four.
1329 [(set (attr "length")
1330 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1331 (const_string "2")
1332 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1333 (const_string "4")]
1334 (const_string "6")))
1335 (set_attr "type" "arith")])
1336
1337(define_split
1338 [(set (match_operand:HI 0 "arith_reg_operand" "")
1339 (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "")
1340 (match_operand:HI 2 "const_int_operand" "n")))
1341 (clobber (reg:SI 18))]
1342 ""
1343 [(use (reg:SI 0))]
1344 "
1345{
1346 gen_shifty_hi_op (LSHIFTRT, operands);
1347 DONE;
1348}")
1349
ffae286a
JW
1350;; ??? This should be a define expand.
1351
bc45ade3 1352(define_insn "ashldi3_k"
aa684c94
SC
1353 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1354 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 1355 (const_int 1)))
bc45ade3
SC
1356 (clobber (reg:SI 18))]
1357 ""
00f8ff66 1358 "shll %R0\;rotcl %S0"
1245df60
R
1359 [(set_attr "length" "4")
1360 (set_attr "type" "arith")])
bc45ade3
SC
1361
1362(define_expand "ashldi3"
ffae286a
JW
1363 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1364 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
1365 (match_operand:DI 2 "immediate_operand" "")))
1366 (clobber (reg:SI 18))])]
bc45ade3 1367 ""
07a45e5c 1368 "{ if (GET_CODE (operands[2]) != CONST_INT
ffae286a
JW
1369 || INTVAL (operands[2]) != 1) FAIL;} ")
1370
1371;; ??? This should be a define expand.
bc45ade3
SC
1372
1373(define_insn "lshrdi3_k"
aa684c94 1374 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
b9654711 1375 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 1376 (const_int 1)))
b9654711 1377 (clobber (reg:SI 18))]
bc45ade3 1378 ""
00f8ff66 1379 "shlr %S0\;rotcr %R0"
1245df60
R
1380 [(set_attr "length" "4")
1381 (set_attr "type" "arith")])
bc45ade3
SC
1382
1383(define_expand "lshrdi3"
ffae286a
JW
1384 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1385 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
bc45ade3
SC
1386 (match_operand:DI 2 "immediate_operand" "")))
1387 (clobber (reg:SI 18))])]
1388 ""
07a45e5c 1389 "{ if (GET_CODE (operands[2]) != CONST_INT
ffae286a
JW
1390 || INTVAL (operands[2]) != 1) FAIL;} ")
1391
1392;; ??? This should be a define expand.
bc45ade3
SC
1393
1394(define_insn "ashrdi3_k"
aa684c94
SC
1395 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1396 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
8e87e161 1397 (const_int 1)))
bc45ade3
SC
1398 (clobber (reg:SI 18))]
1399 ""
00f8ff66 1400 "shar %S0\;rotcr %R0"
1245df60
R
1401 [(set_attr "length" "4")
1402 (set_attr "type" "arith")])
bc45ade3
SC
1403
1404(define_expand "ashrdi3"
ffae286a
JW
1405 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1406 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1407 (match_operand:DI 2 "immediate_operand" "")))
1408 (clobber (reg:SI 18))])]
bc45ade3 1409 ""
07a45e5c 1410 "{ if (GET_CODE (operands[2]) != CONST_INT
ffae286a 1411 || INTVAL (operands[2]) != 1) FAIL; } ")
98e819b9
JW
1412
1413;; combined left/right shift
1414
1415(define_split
1416 [(set (match_operand:SI 0 "register_operand" "")
1417 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
1418 (match_operand:SI 2 "const_int_operand" "n"))
1419 (match_operand:SI 3 "const_int_operand" "n")))]
1420 "(unsigned)INTVAL (operands[2]) < 32"
1421 [(use (reg:SI 0))]
1422 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
1423 DONE;")
1424
1425(define_split
1426 [(set (match_operand:SI 0 "register_operand" "")
1427 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
1428 (match_operand:SI 2 "const_int_operand" "n"))
1429 (match_operand:SI 3 "const_int_operand" "n")))
1430 (clobber (reg:SI 18))]
1431 "(unsigned)INTVAL (operands[2]) < 32"
1432 [(use (reg:SI 0))]
1433 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
1434 DONE;")
1435
1436(define_insn ""
1437 [(set (match_operand:SI 0 "register_operand" "=r")
1438 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1439 (match_operand:SI 2 "const_int_operand" "n"))
1440 (match_operand:SI 3 "const_int_operand" "n")))
1441 (clobber (reg:SI 18))]
1442 "shl_and_kind (operands[2], operands[3], 0) == 1"
1443 "#"
1444 [(set (attr "length")
1445 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
1446 (const_string "4")
1447 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
1448 (const_string "6")
1449 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
1450 (const_string "8")
1451 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
1452 (const_string "10")
1453 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
1454 (const_string "12")
1455 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
1456 (const_string "14")
1457 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
1458 (const_string "16")]
1459 (const_string "18")))
1460 (set_attr "type" "arith")])
1461
1462(define_insn ""
1463 [(set (match_operand:SI 0 "register_operand" "=z")
1464 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1465 (match_operand:SI 2 "const_int_operand" "n"))
1466 (match_operand:SI 3 "const_int_operand" "n")))
1467 (clobber (reg:SI 18))]
1468 "shl_and_kind (operands[2], operands[3], 0) == 2"
1469 "#"
1470 [(set (attr "length")
1471 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
1472 (const_string "4")
1473 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
1474 (const_string "6")
1475 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
1476 (const_string "8")]
1477 (const_string "10")))
1478 (set_attr "type" "arith")])
1479
1480;; shift left / and combination with a scratch register: The combine pass
1481;; does not accept the individual instructions, even though they are
1482;; cheap. But it needs a precise description so that it is usable after
1483;; reload.
1484(define_insn "and_shl_scratch"
1485 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1486 (lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
1487 (match_operand:SI 2 "const_int_operand" "N,n"))
1488 (match_operand:SI 3 "" "0,r"))
1489 (match_operand:SI 4 "const_int_operand" "n,n"))
1490 (match_operand:SI 5 "const_int_operand" "n,n")))
1491 (clobber (reg:SI 18))]
1492 ""
1493 "#"
1494 [(set (attr "length")
1495 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
1496 (const_string "4")
1497 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
1498 (const_string "6")
1499 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
9788ff4d 1500 (const_string "8")
98e819b9
JW
1501 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
1502 (const_string "10")]
1503 (const_string "12")))
1504 (set_attr "type" "arith")])
1505
1506(define_split
1507 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1508 (lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
1509 (match_operand:SI 2 "const_int_operand" "N,n"))
1510 (match_operand:SI 3 "register_operand" "0,r"))
1511 (match_operand:SI 4 "const_int_operand" "n,n"))
1512 (match_operand:SI 5 "const_int_operand" "n,n")))
1513 (clobber (reg:SI 18))]
1514 ""
1515 [(use (reg:SI 0))]
1516 "
1517{
fc2380b9 1518 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
98e819b9
JW
1519
1520 if (INTVAL (operands[2]))
1521 {
1522 gen_shifty_op (LSHIFTRT, operands);
98e819b9
JW
1523 }
1524 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
1525 operands[2] = operands[4];
1526 gen_shifty_op (ASHIFT, operands);
1527 if (INTVAL (operands[5]))
1528 {
1529 operands[2] = operands[5];
1530 gen_shifty_op (LSHIFTRT, operands);
1531 }
1532 DONE;
1533}")
1534
1535;; signed left/right shift combination.
1536(define_split
1537 [(set (match_operand:SI 0 "register_operand" "=r")
1538 (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1539 (match_operand:SI 2 "const_int_operand" "n"))
1540 (match_operand:SI 3 "const_int_operand" "n")
1541 (const_int 0)))
1542 (clobber (reg:SI 18))]
1543 ""
1544 [(use (reg:SI 0))]
1545 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
1546 DONE;")
1547
1548(define_insn "shl_sext_ext"
1549 [(set (match_operand:SI 0 "register_operand" "=r")
1550 (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1551 (match_operand:SI 2 "const_int_operand" "n"))
1552 (match_operand:SI 3 "const_int_operand" "n")
1553 (const_int 0)))
1554 (clobber (reg:SI 18))]
3c377a2a 1555 "(unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
98e819b9
JW
1556 "#"
1557 [(set (attr "length")
1558 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
1559 (const_string "2")
1560 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
1561 (const_string "4")
1562 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
1563 (const_string "6")
1564 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
1565 (const_string "8")
1566 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
1567 (const_string "10")
1568 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
1569 (const_string "12")
1570 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
1571 (const_string "14")
1572 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
1573 (const_string "16")]
1574 (const_string "18")))
1575 (set_attr "type" "arith")])
1576
1577(define_insn "shl_sext_sub"
1578 [(set (match_operand:SI 0 "register_operand" "=z")
1579 (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1580 (match_operand:SI 2 "const_int_operand" "n"))
1581 (match_operand:SI 3 "const_int_operand" "n")
1582 (const_int 0)))
1583 (clobber (reg:SI 18))]
1584 "(shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
1585 "#"
1586 [(set (attr "length")
1587 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
1588 (const_string "6")
1589 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
1590 (const_string "8")
1591 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
1592 (const_string "10")
1593 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
1594 (const_string "12")]
1595 (const_string "14")))
1596 (set_attr "type" "arith")])
1597
977eef43
JW
1598;; These patterns are found in expansions of DImode shifts by 16, and
1599;; allow the xtrct instruction to be generated from C source.
1600
1601(define_insn "xtrct_left"
1602 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1603 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
1604 (const_int 16))
1605 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
1606 (const_int 16))))]
1607 ""
1245df60
R
1608 "xtrct %1,%0"
1609 [(set_attr "type" "arith")])
977eef43
JW
1610
1611(define_insn "xtrct_right"
1612 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1613 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1614 (const_int 16))
1615 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
1616 (const_int 16))))]
1617 ""
1245df60
R
1618 "xtrct %2,%0"
1619 [(set_attr "type" "arith")])
bc45ade3
SC
1620\f
1621;; -------------------------------------------------------------------------
1622;; Unary arithmetic
1623;; -------------------------------------------------------------------------
1624
8e87e161
SC
1625(define_insn "negc"
1626 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
51bd623f
JW
1627 (neg:SI (plus:SI (reg:SI 18)
1628 (match_operand:SI 1 "arith_reg_operand" "r"))))
1629 (set (reg:SI 18)
07a45e5c 1630 (ne:SI (ior:SI (reg:SI 18) (match_dup 1))
51bd623f 1631 (const_int 0)))]
bc45ade3 1632 ""
8e87e161 1633 "negc %1,%0"
22e1ebf1 1634 [(set_attr "type" "arith")])
bc45ade3 1635
8e87e161 1636(define_expand "negdi2"
51aea58d
JW
1637 [(set (match_operand:DI 0 "arith_reg_operand" "")
1638 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
8e87e161
SC
1639 (clobber (reg:SI 18))]
1640 ""
ffae286a
JW
1641 "
1642{
0a0b733a
RK
1643 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
1644 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
8e87e161 1645
0a0b733a
RK
1646 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
1647 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
1648
1649 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
1650 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
8e87e161 1651
ffae286a
JW
1652 emit_insn (gen_clrt ());
1653 emit_insn (gen_negc (low_dst, low_src));
1654 emit_insn (gen_negc (high_dst, high_src));
1655 DONE;
1656}")
8e87e161 1657
bc45ade3 1658(define_insn "negsi2"
aa684c94
SC
1659 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1660 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
bc45ade3
SC
1661 ""
1662 "neg %1,%0"
1663 [(set_attr "type" "arith")])
1664
1665(define_insn "one_cmplsi2"
aa684c94
SC
1666 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1667 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
bc45ade3
SC
1668 ""
1669 "not %1,%0"
0d7e008e 1670 [(set_attr "type" "arith")])
bc45ade3
SC
1671\f
1672;; -------------------------------------------------------------------------
1673;; Zero extension instructions
1674;; -------------------------------------------------------------------------
1675
1676(define_insn "zero_extendhisi2"
aa684c94
SC
1677 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1678 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
bc45ade3
SC
1679 ""
1680 "extu.w %1,%0"
1681 [(set_attr "type" "arith")])
1682
1683(define_insn "zero_extendqisi2"
aa684c94
SC
1684 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1685 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
bc45ade3
SC
1686 ""
1687 "extu.b %1,%0"
07a45e5c 1688 [(set_attr "type" "arith")])
bc45ade3
SC
1689
1690(define_insn "zero_extendqihi2"
aa684c94
SC
1691 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1692 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
bc45ade3
SC
1693 ""
1694 "extu.b %1,%0"
07a45e5c 1695 [(set_attr "type" "arith")])
bc45ade3
SC
1696\f
1697;; -------------------------------------------------------------------------
1698;; Sign extension instructions
1699;; -------------------------------------------------------------------------
1700
ffae286a
JW
1701;; ??? This should be a define expand.
1702;; ??? Or perhaps it should be dropped?
1703
1245df60
R
1704/* There is no point in defining extendsidi2; convert_move generates good
1705 code for that. */
bc45ade3
SC
1706
1707(define_insn "extendhisi2"
51bd623f
JW
1708 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1709 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
bc45ade3 1710 ""
0d7e008e
SC
1711 "@
1712 exts.w %1,%0
0d7e008e 1713 mov.w %1,%0"
51bd623f 1714 [(set_attr "type" "arith,load")])
bc45ade3
SC
1715
1716(define_insn "extendqisi2"
51bd623f
JW
1717 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1718 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
bc45ade3 1719 ""
0d7e008e
SC
1720 "@
1721 exts.b %1,%0
51bd623f
JW
1722 mov.b %1,%0"
1723 [(set_attr "type" "arith,load")])
bc45ade3
SC
1724
1725(define_insn "extendqihi2"
51bd623f
JW
1726 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
1727 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
bc45ade3 1728 ""
0d7e008e
SC
1729 "@
1730 exts.b %1,%0
51bd623f
JW
1731 mov.b %1,%0"
1732 [(set_attr "type" "arith,load")])
bc45ade3
SC
1733\f
1734;; -------------------------------------------------------------------------
1735;; Move instructions
1736;; -------------------------------------------------------------------------
1737
0d7e008e 1738;; define push and pop so it is easy for sh.c
b9654711
SC
1739
1740(define_insn "push"
1741 [(set (mem:SI (pre_dec:SI (reg:SI 15)))
ffae286a 1742 (match_operand:SI 0 "register_operand" "r,l,x"))]
b9654711
SC
1743 ""
1744 "@
1745 mov.l %0,@-r15
ffae286a 1746 sts.l %0,@-r15
51bd623f 1747 sts.l %0,@-r15"
ffae286a 1748 [(set_attr "type" "store,pstore,store")
0d7e008e 1749 (set_attr "hit_stack" "yes")])
b9654711
SC
1750
1751(define_insn "pop"
51bd623f 1752 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
b9654711
SC
1753 (mem:SI (post_inc:SI (reg:SI 15))))]
1754 ""
1755 "@
1756 mov.l @r15+,%0
51bd623f 1757 lds.l @r15+,%0
0d7e008e 1758 lds.l @r15+,%0"
51bd623f 1759 [(set_attr "type" "load,pload,load")
0d7e008e 1760 (set_attr "hit_stack" "yes")])
b9654711 1761
45348d9e
JW
1762(define_insn "push_e"
1763 [(set (mem:SF (pre_dec:SI (reg:SI 15)))
1764 (match_operand:SF 0 "register_operand" "r,f,y"))]
8255ed68 1765 "TARGET_SH3E"
45348d9e
JW
1766 "@
1767 mov.l %0,@-r15
1768 fmov.s %0,@-r15
1769 sts.l %0,@-r15"
1770 [(set_attr "type" "store")
1771 (set_attr "hit_stack" "yes")])
1772
1773(define_insn "pop_e"
1774 [(set (match_operand:SF 0 "register_operand" "=r,f,y")
1775 (mem:SF (post_inc:SI (reg:SI 15))))]
8255ed68 1776 "TARGET_SH3E"
45348d9e
JW
1777 "@
1778 mov.l @r15+,%0
1779 fmov.s @r15+,%0
1780 lds.l @r15+,%0"
1781 [(set_attr "type" "load")
1782 (set_attr "hit_stack" "yes")])
1783
e3391510
JW
1784;; These two patterns can happen as the result of optimization, when
1785;; comparisons get simplified to a move of zero or 1 into the T reg.
1786;; They don't disappear completely, because the T reg is a fixed hard reg.
ffae286a 1787
0d7e008e
SC
1788(define_insn "clrt"
1789 [(set (reg:SI 18) (const_int 0))]
b9654711 1790 ""
0d7e008e 1791 "clrt")
bc45ade3 1792
e3391510
JW
1793(define_insn "sett"
1794 [(set (reg:SI 18) (const_int 1))]
1795 ""
1796 "sett")
1797
1245df60 1798;; t/r is first, so that it will be preferred over r/r when reloading a move
ffae286a 1799;; of a pseudo-reg into the T reg
0d7e008e 1800(define_insn "movsi_i"
1245df60
R
1801 [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,<,xl,x,l,r")
1802 (match_operand:SI 1 "general_movsrc_operand" "r,Q,rI,m,xl,t,r,x,l,r,>,>,i"))]
45348d9e 1803 "
1245df60
R
1804 ! TARGET_SH3E
1805 && (register_operand (operands[0], SImode)
1806 || register_operand (operands[1], SImode))"
8e87e161 1807 "@
1245df60 1808 cmp/pl %1
8e87e161
SC
1809 mov.l %1,%0
1810 mov %1,%0
1811 mov.l %1,%0
1812 sts %1,%0
1813 movt %0
1814 mov.l %1,%0
1815 sts.l %1,%0
1245df60 1816 sts.l %1,%0
8e87e161
SC
1817 lds %1,%0
1818 lds.l %1,%0
1245df60 1819 lds.l %1,%0
51bd623f 1820 fake %1,%0"
1245df60
R
1821 [(set_attr "type" "*,pcload_si,move,load_si,move,move,store,store,pstore,move,load,pload,pcload_si")
1822 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*")])
07a45e5c 1823
1245df60
R
1824;; t/r must come after r/r, lest reload will try to reload stuff like
1825;; (subreg:SI (reg:SF 38 fr14) 0) into T (compiling stdlib/strtod.c -m3e -O2)
45348d9e
JW
1826;; ??? This allows moves from macl to fpul to be recognized, but these moves
1827;; will require a reload.
1828(define_insn "movsi_ie"
1245df60
R
1829 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,r,y,r,y")
1830 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,m,xl,t,r,x,l,r,>,>,i,r,y,y"))]
45348d9e
JW
1831 "TARGET_SH3E
1832 && (register_operand (operands[0], SImode)
1833 || register_operand (operands[1], SImode))"
1834 "@
45348d9e
JW
1835 mov.l %1,%0
1836 mov %1,%0
1245df60 1837 cmp/pl %1
45348d9e
JW
1838 mov.l %1,%0
1839 sts %1,%0
1840 movt %0
1841 mov.l %1,%0
1842 sts.l %1,%0
1245df60 1843 sts.l %1,%0
45348d9e
JW
1844 lds %1,%0
1845 lds.l %1,%0
1245df60 1846 lds.l %1,%0
45348d9e
JW
1847 fake %1,%0
1848 lds %1,%0
1245df60
R
1849 sts %1,%0
1850 ! move optimized away"
4dff12bf 1851 [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,pcload_si,gp_fpul,gp_fpul,nil")
1245df60
R
1852 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
1853
1854(define_insn "movsi_i_lowpart"
1855 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,m,r"))
1856 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,m,xl,t,r,i"))]
1857 "register_operand (operands[0], SImode)
1858 || register_operand (operands[1], SImode)"
1859 "@
1860 mov.l %1,%0
1861 mov %1,%0
1862 mov.l %1,%0
1863 sts %1,%0
1864 movt %0
1865 mov.l %1,%0
1866 fake %1,%0"
1867 [(set_attr "type" "pcload,move,load,move,move,store,pcload")])
bc45ade3 1868(define_expand "movsi"
0d7e008e
SC
1869 [(set (match_operand:SI 0 "general_movdst_operand" "")
1870 (match_operand:SI 1 "general_movsrc_operand" ""))]
bc45ade3 1871 ""
ffae286a 1872 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
961c4780 1873
bc45ade3 1874(define_insn "movqi_i"
07a45e5c
JW
1875 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
1876 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
1877 "arith_reg_operand (operands[0], QImode)
0d7e008e 1878 || arith_reg_operand (operands[1], QImode)"
bc45ade3
SC
1879 "@
1880 mov %1,%0
0d7e008e
SC
1881 mov.b %1,%0
1882 mov.b %1,%0
1883 movt %0
bc45ade3 1884 sts %1,%0
0d7e008e 1885 lds %1,%0"
22e1ebf1 1886 [(set_attr "type" "move,load,store,move,move,move")])
bc45ade3
SC
1887
1888(define_expand "movqi"
1889 [(set (match_operand:QI 0 "general_operand" "")
1890 (match_operand:QI 1 "general_operand" ""))]
1891 ""
ffae286a 1892 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
bc45ade3
SC
1893
1894(define_insn "movhi_i"
07a45e5c
JW
1895 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
1896 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
51aea58d
JW
1897 "arith_reg_operand (operands[0], HImode)
1898 || arith_reg_operand (operands[1], HImode)"
8e87e161
SC
1899 "@
1900 mov.w %1,%0
1901 mov %1,%0
1902 mov.w %1,%0
1903 movt %0
1904 mov.w %1,%0
8e87e161 1905 sts %1,%0
51bd623f
JW
1906 lds %1,%0
1907 fake %1,%0"
27232d28 1908 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
bc45ade3
SC
1909
1910(define_expand "movhi"
0d7e008e
SC
1911 [(set (match_operand:HI 0 "general_movdst_operand" "")
1912 (match_operand:HI 1 "general_movsrc_operand" ""))]
bc45ade3 1913 ""
ffae286a
JW
1914 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
1915
1916;; ??? This should be a define expand.
0d7e008e 1917
1245df60
R
1918;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
1919;; compiled with -m2 -ml -O3 -funroll-loops
0d7e008e 1920(define_insn ""
1245df60
R
1921 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
1922 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
51aea58d
JW
1923 "arith_reg_operand (operands[0], DImode)
1924 || arith_reg_operand (operands[1], DImode)"
0d7e008e 1925 "* return output_movedouble (insn, operands, DImode);"
22e1ebf1 1926 [(set_attr "length" "4")
1245df60 1927 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
bc45ade3 1928
d0aae509
RK
1929;; If the output is a register and the input is memory or a register, we have
1930;; to be careful and see which word needs to be loaded first.
b9b7c1c9 1931
8e87e161
SC
1932(define_split
1933 [(set (match_operand:DI 0 "general_movdst_operand" "")
1934 (match_operand:DI 1 "general_movsrc_operand" ""))]
d0aae509 1935 "reload_completed"
8e87e161
SC
1936 [(set (match_dup 2) (match_dup 3))
1937 (set (match_dup 4) (match_dup 5))]
1938 "
d0aae509
RK
1939{
1940 int regno;
1941
1942 if ((GET_CODE (operands[0]) == MEM
1943 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1944 || (GET_CODE (operands[1]) == MEM
1945 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
1946 FAIL;
1947
1948 if (GET_CODE (operands[0]) == REG)
1949 regno = REGNO (operands[0]);
1950 else if (GET_CODE (operands[0]) == SUBREG)
1951 regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]);
1952 else if (GET_CODE (operands[0]) == MEM)
1953 regno = -1;
1954
1955 if (regno == -1
1956 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
1957 {
1958 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1959 operands[3] = operand_subword (operands[1], 0, 0, DImode);
1960 operands[4] = operand_subword (operands[0], 1, 0, DImode);
1961 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1962 }
1963 else
1964 {
1965 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1966 operands[3] = operand_subword (operands[1], 1, 0, DImode);
1967 operands[4] = operand_subword (operands[0], 0, 0, DImode);
1968 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1969 }
1970
1971 if (operands[2] == 0 || operands[3] == 0
1972 || operands[4] == 0 || operands[5] == 0)
1973 FAIL;
1974}")
961c4780 1975
bc45ade3 1976(define_expand "movdi"
961c4780
SC
1977 [(set (match_operand:DI 0 "general_movdst_operand" "")
1978 (match_operand:DI 1 "general_movsrc_operand" ""))]
bc45ade3 1979 ""
ffae286a
JW
1980 "{ if ( prepare_move_operands (operands, DImode)) DONE; }")
1981
1982;; ??? This should be a define expand.
bc45ade3 1983
bc45ade3 1984(define_insn "movdf_k"
3e943b59
JR
1985 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
1986 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
51aea58d
JW
1987 "arith_reg_operand (operands[0], DFmode)
1988 || arith_reg_operand (operands[1], DFmode)"
0d7e008e 1989 "* return output_movedouble (insn, operands, DFmode);"
b9654711 1990 [(set_attr "length" "4")
3e943b59 1991 (set_attr "type" "move,pcload,load,store")])
bc45ade3 1992
d0aae509
RK
1993;; If the output is a register and the input is memory or a register, we have
1994;; to be careful and see which word needs to be loaded first.
07a45e5c 1995
8e87e161
SC
1996(define_split
1997 [(set (match_operand:DF 0 "general_movdst_operand" "")
1998 (match_operand:DF 1 "general_movsrc_operand" ""))]
d0aae509 1999 "reload_completed"
8e87e161
SC
2000 [(set (match_dup 2) (match_dup 3))
2001 (set (match_dup 4) (match_dup 5))]
2002 "
d0aae509
RK
2003{
2004 int regno;
2005
2006 if ((GET_CODE (operands[0]) == MEM
2007 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2008 || (GET_CODE (operands[1]) == MEM
2009 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
2010 FAIL;
2011
2012 if (GET_CODE (operands[0]) == REG)
2013 regno = REGNO (operands[0]);
2014 else if (GET_CODE (operands[0]) == SUBREG)
2015 regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]);
2016 else if (GET_CODE (operands[0]) == MEM)
2017 regno = -1;
2018
2019 if (regno == -1
2020 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
8e87e161
SC
2021 {
2022 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2023 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2024 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2025 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
2026 }
2027 else
2028 {
2029 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2030 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
2031 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
2032 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2033 }
2034
2035 if (operands[2] == 0 || operands[3] == 0
2036 || operands[4] == 0 || operands[5] == 0)
2037 FAIL;
2038}")
2039
653bd7a6
JW
2040;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
2041;; used only once, let combine add in the index again.
2042
2043(define_split
2044 [(set (match_operand:SI 0 "register_operand" "")
2045 (match_operand:SI 1 "" ""))
2046 (clobber (match_operand 2 "register_operand" ""))]
2047 "! reload_in_progress && ! reload_completed"
2048 [(use (reg:SI 0))]
2049 "
2050{
2051 rtx addr, reg, const_int;
2052
2053 if (GET_CODE (operands[1]) != MEM)
2054 FAIL;
2055 addr = XEXP (operands[1], 0);
2056 if (GET_CODE (addr) != PLUS)
2057 FAIL;
2058 reg = XEXP (addr, 0);
2059 const_int = XEXP (addr, 1);
2060 if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT)
2061 FAIL;
2062 emit_move_insn (operands[2], const_int);
2063 emit_move_insn (operands[0],
2064 change_address (operands[1], VOIDmode,
2065 gen_rtx (PLUS, SImode, reg, operands[2])));
2066 DONE;
2067}")
2068
2069(define_split
2070 [(set (match_operand:SI 1 "" "")
2071 (match_operand:SI 0 "register_operand" ""))
2072 (clobber (match_operand 2 "register_operand" ""))]
2073 "! reload_in_progress && ! reload_completed"
2074 [(use (reg:SI 0))]
2075 "
2076{
2077 rtx addr, reg, const_int;
2078
2079 if (GET_CODE (operands[1]) != MEM)
2080 FAIL;
2081 addr = XEXP (operands[1], 0);
2082 if (GET_CODE (addr) != PLUS)
2083 FAIL;
2084 reg = XEXP (addr, 0);
2085 const_int = XEXP (addr, 1);
2086 if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT)
2087 FAIL;
2088 emit_move_insn (operands[2], const_int);
2089 emit_move_insn (change_address (operands[1], VOIDmode,
2090 gen_rtx (PLUS, SImode, reg, operands[2])),
2091 operands[0]);
2092 DONE;
2093}")
2094
bc45ade3 2095(define_expand "movdf"
0d7e008e
SC
2096 [(set (match_operand:DF 0 "general_movdst_operand" "")
2097 (match_operand:DF 1 "general_movsrc_operand" ""))]
bc45ade3 2098 ""
1245df60
R
2099 "
2100{
2101 if (prepare_move_operands (operands, DFmode)) DONE;
2102}")
2103
bc45ade3 2104
bc45ade3 2105(define_insn "movsf_i"
3e943b59
JR
2106 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
2107 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,m,r,r,l"))]
45348d9e 2108 "
1245df60
R
2109 ! TARGET_SH3E
2110 && (arith_reg_operand (operands[0], SFmode)
2111 || arith_reg_operand (operands[1], SFmode))"
bc45ade3
SC
2112 "@
2113 mov %1,%0
2114 mov %1,%0
2115 mov.l %1,%0
2116 mov.l %1,%0
3e943b59 2117 mov.l %1,%0
b9654711 2118 lds %1,%0
0d7e008e 2119 sts %1,%0"
3e943b59 2120 [(set_attr "type" "move,move,pcload,load,store,move,move")])
bc45ade3 2121
4dff12bf
R
2122;; We may not split the ry/yr/XX alternatives to movsi_ie, since
2123;; update_flow_info would not know where to put REG_EQUAL notes
2124;; when the destination changes mode.
45348d9e 2125(define_insn "movsf_ie"
7f74cc8d 2126 [(set (match_operand:SF 0 "general_movdst_operand"
4dff12bf 2127 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,y")
7f74cc8d 2128 (match_operand:SF 1 "general_movsrc_operand"
4dff12bf
R
2129 "f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y"))
2130 (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X"))]
7f74cc8d 2131
45348d9e
JW
2132 "TARGET_SH3E
2133 && (arith_reg_operand (operands[0], SFmode)
2134 || arith_reg_operand (operands[1], SFmode))"
2135 "@
2136 fmov %1,%0
2137 mov %1,%0
2138 fldi0 %0
2139 fldi1 %0
7f74cc8d 2140 #
45348d9e
JW
2141 fmov.s %1,%0
2142 fmov.s %1,%0
2143 mov.l %1,%0
2144 mov.l %1,%0
3e943b59 2145 mov.l %1,%0
1245df60
R
2146 fsts fpul,%0
2147 flds %1,fpul
2148 lds.l %1,%0
2149 #
4dff12bf
R
2150 sts %1,%0
2151 lds %1,%0
2152 ! move optimized away"
2153 [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,nil")
2154 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,*,2,2,0")])
45348d9e 2155
1245df60
R
2156(define_split
2157 [(set (match_operand:SF 0 "register_operand" "")
2158 (match_operand:SF 1 "register_operand" ""))
2159 (clobber (reg:SI 22))]
2160 ""
2161 [(parallel [(set (reg:SF 22) (match_dup 1))
2162 (clobber (scratch:SI))])
2163 (parallel [(set (match_dup 0) (reg:SF 22))
2164 (clobber (scratch:SI))])]
2165 "")
2166
bc45ade3 2167(define_expand "movsf"
0d7e008e 2168 [(set (match_operand:SF 0 "general_movdst_operand" "")
3e943b59 2169 (match_operand:SF 1 "general_movsrc_operand" ""))]
bc45ade3 2170 ""
3e943b59
JR
2171 "
2172{
2173 if (prepare_move_operands (operands, SFmode))
2174 DONE;
7f74cc8d 2175 if (TARGET_SH3E)
3e943b59 2176 {
7f74cc8d 2177 emit_insn (gen_movsf_ie (operands[0], operands[1]));
3e943b59
JR
2178 DONE;
2179 }
2180}")
7f74cc8d
JR
2181
2182(define_expand "reload_insf"
2183 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
2184 (match_operand:SF 1 "immediate_operand" "FQ"))
2185 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
2186 ""
2187 "")
bc45ade3
SC
2188\f
2189;; ------------------------------------------------------------------------
2190;; Define the real conditional branch instructions.
2191;; ------------------------------------------------------------------------
2192
2193(define_insn "branch_true"
7c225e88 2194 [(set (pc) (if_then_else (ne (reg:SI 18) (const_int 0))
bc45ade3
SC
2195 (label_ref (match_operand 0 "" ""))
2196 (pc)))]
2197 ""
51aea58d 2198 "* return output_branch (1, insn, operands);"
bc45ade3
SC
2199 [(set_attr "type" "cbranch")])
2200
2201(define_insn "branch_false"
7c225e88 2202 [(set (pc) (if_then_else (eq (reg:SI 18) (const_int 0))
bc45ade3
SC
2203 (label_ref (match_operand 0 "" ""))
2204 (pc)))]
2205 ""
51aea58d 2206 "* return output_branch (0, insn, operands);"
bc45ade3
SC
2207 [(set_attr "type" "cbranch")])
2208
1245df60
R
2209;; Patterns to prevent reorg from re-combining a condbranch with a branch
2210;; which destination is too far away.
2211;; The const_int_operand is distinct for each branch target; it avoids
2212;; unwanted matches with redundant_insn.
2213(define_insn "block_branch_redirect"
2214 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] 4))]
bc45ade3 2215 ""
1245df60
R
2216 ""
2217 [(set_attr "length" "0")])
bc45ade3 2218
1245df60
R
2219;; This one has the additional purpose to record a possible scratch register
2220;; for the following branch.
2221(define_insn "indirect_jump_scratch"
2222 [(set (match_operand 0 "register_operand" "r")
2223 (unspec [(match_operand 1 "const_int_operand" "")] 4))]
bc45ade3 2224 ""
1245df60
R
2225 ""
2226 [(set_attr "length" "0")])
bc45ade3
SC
2227\f
2228;; Conditional branch insns
2229
2230(define_expand "beq"
1245df60 2231 [(set (pc)
7c225e88 2232 (if_then_else (ne (reg:SI 18) (const_int 0))
bc45ade3
SC
2233 (label_ref (match_operand 0 "" ""))
2234 (pc)))]
2235 ""
0d7e008e 2236 "from_compare (operands, EQ);")
bc45ade3 2237
bc45ade3 2238(define_expand "bne"
1245df60
R
2239 [(set (pc)
2240 (if_then_else (eq (reg:SI 18) (const_int 0))
2241 (label_ref (match_operand 0 "" ""))
2242 (pc)))]
bc45ade3 2243 ""
1245df60 2244 "from_compare (operands, EQ);")
bc45ade3
SC
2245
2246(define_expand "bgt"
1245df60 2247 [(set (pc)
7c225e88 2248 (if_then_else (ne (reg:SI 18) (const_int 0))
bc45ade3 2249 (label_ref (match_operand 0 "" ""))
ffae286a 2250 (pc)))]
bc45ade3 2251 ""
0d7e008e 2252 "from_compare (operands, GT);")
bc45ade3
SC
2253
2254(define_expand "blt"
1245df60
R
2255 [(set (pc)
2256 (if_then_else (eq (reg:SI 18) (const_int 0))
2257 (label_ref (match_operand 0 "" ""))
2258 (pc)))]
bc45ade3 2259 ""
45348d9e
JW
2260 "
2261{
2262 if (GET_MODE (sh_compare_op0) == SFmode)
2263 {
2264 rtx tmp = sh_compare_op0;
2265 sh_compare_op0 = sh_compare_op1;
2266 sh_compare_op1 = tmp;
2267 emit_insn (gen_bgt (operands[0]));
2268 DONE;
2269 }
1245df60 2270 from_compare (operands, GE);
45348d9e 2271}")
bc45ade3
SC
2272
2273(define_expand "ble"
1245df60
R
2274 [(set (pc)
2275 (if_then_else (eq (reg:SI 18) (const_int 0))
2276 (label_ref (match_operand 0 "" ""))
2277 (pc)))]
bc45ade3 2278 ""
1245df60
R
2279 "
2280{
2281 if (TARGET_SH3E
2282 && TARGET_IEEE
2283 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
2284 {
2285 rtx tmp = sh_compare_op0;
2286 sh_compare_op0 = sh_compare_op1;
2287 sh_compare_op1 = tmp;
2288 emit_insn (gen_bge (operands[0]));
2289 DONE;
2290 }
2291 from_compare (operands, GT);
2292}")
bc45ade3
SC
2293
2294(define_expand "bge"
1245df60 2295 [(set (pc)
7c225e88 2296 (if_then_else (ne (reg:SI 18) (const_int 0))
bc45ade3 2297 (label_ref (match_operand 0 "" ""))
ffae286a 2298 (pc)))]
bc45ade3 2299 ""
45348d9e
JW
2300 "
2301{
1245df60
R
2302 if (TARGET_SH3E
2303 && ! TARGET_IEEE
2304 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
45348d9e
JW
2305 {
2306 rtx tmp = sh_compare_op0;
2307 sh_compare_op0 = sh_compare_op1;
2308 sh_compare_op1 = tmp;
2309 emit_insn (gen_ble (operands[0]));
2310 DONE;
2311 }
2312 from_compare (operands, GE);
2313}")
bc45ade3
SC
2314
2315(define_expand "bgtu"
1245df60 2316 [(set (pc)
7c225e88 2317 (if_then_else (ne (reg:SI 18) (const_int 0))
bc45ade3
SC
2318 (label_ref (match_operand 0 "" ""))
2319 (pc)))]
2320 ""
0d7e008e 2321 "from_compare (operands, GTU); ")
bc45ade3
SC
2322
2323(define_expand "bltu"
1245df60
R
2324 [(set (pc)
2325 (if_then_else (eq (reg:SI 18) (const_int 0))
2326 (label_ref (match_operand 0 "" ""))
2327 (pc)))]
bc45ade3 2328 ""
1245df60 2329 "from_compare (operands, GEU);")
bc45ade3
SC
2330
2331(define_expand "bgeu"
1245df60 2332 [(set (pc)
7c225e88 2333 (if_then_else (ne (reg:SI 18) (const_int 0))
bc45ade3 2334 (label_ref (match_operand 0 "" ""))
ffae286a 2335 (pc)))]
bc45ade3 2336 ""
0d7e008e 2337 "from_compare (operands, GEU);")
bc45ade3
SC
2338
2339(define_expand "bleu"
1245df60
R
2340 [(set (pc)
2341 (if_then_else (eq (reg:SI 18) (const_int 0))
2342 (label_ref (match_operand 0 "" ""))
2343 (pc)))]
bc45ade3 2344 ""
1245df60 2345 "from_compare (operands, GTU);")
bc45ade3
SC
2346\f
2347;; ------------------------------------------------------------------------
2348;; Jump and linkage insns
2349;; ------------------------------------------------------------------------
2350
0d7e008e 2351(define_insn "jump"
bc45ade3
SC
2352 [(set (pc)
2353 (label_ref (match_operand 0 "" "")))]
2354 ""
2355 "*
2356{
22e1ebf1 2357 /* The length is 16 if the delay slot is unfilled. */
1245df60 2358 if (get_attr_length(insn) > 4)
51aea58d 2359 return output_far_jump(insn, operands[0]);
bc45ade3 2360 else
51aea58d 2361 return \"bra %l0%#\";
bc45ade3
SC
2362}"
2363 [(set_attr "type" "jump")
2364 (set_attr "needs_delay_slot" "yes")])
2365
bc45ade3 2366(define_insn "calli"
aa684c94 2367 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
bc45ade3
SC
2368 (match_operand 1 "" ""))
2369 (clobber (reg:SI 17))]
2370 ""
2371 "jsr @%0%#"
ffae286a
JW
2372 [(set_attr "type" "call")
2373 (set_attr "needs_delay_slot" "yes")])
961c4780 2374
bc45ade3
SC
2375(define_insn "call_valuei"
2376 [(set (match_operand 0 "" "=rf")
aa684c94 2377 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
bc45ade3
SC
2378 (match_operand 2 "" "")))
2379 (clobber (reg:SI 17))]
2380 ""
2381 "jsr @%1%#"
ffae286a
JW
2382 [(set_attr "type" "call")
2383 (set_attr "needs_delay_slot" "yes")])
bc45ade3
SC
2384
2385(define_expand "call"
51aea58d
JW
2386 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
2387 (match_operand 1 "" ""))
2388 (clobber (reg:SI 17))])]
bc45ade3 2389 ""
51aea58d 2390 "operands[0] = force_reg (SImode, XEXP (operands[0], 0));")
bc45ade3
SC
2391
2392(define_expand "call_value"
51aea58d
JW
2393 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
2394 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
2395 (match_operand 2 "" "")))
2396 (clobber (reg:SI 17))])]
bc45ade3 2397 ""
51aea58d 2398 "operands[1] = force_reg (SImode, XEXP (operands[1], 0));")
bc45ade3
SC
2399
2400(define_insn "indirect_jump"
2401 [(set (pc)
aa684c94 2402 (match_operand:SI 0 "arith_reg_operand" "r"))]
bc45ade3 2403 ""
b9654711 2404 "jmp @%0%#"
1245df60
R
2405 [(set_attr "needs_delay_slot" "yes")
2406 (set_attr "type" "jump_ind")])
a1a0806a 2407
1245df60 2408;; The use of operand 1 / 2 helps us distinguish case table jumps
f1ffca1c
JW
2409;; which can be present in structured code from indirect jumps which can not
2410;; be present in structured code. This allows -fprofile-arcs to work.
2411
1245df60
R
2412;; For SH1 processors.
2413(define_insn "casesi_jump_1"
f1ffca1c 2414 [(set (pc)
1245df60 2415 (match_operand:SI 0 "register_operand" "r"))
f1ffca1c
JW
2416 (use (label_ref (match_operand 1 "" "")))]
2417 ""
1245df60
R
2418 "jmp @%0%#"
2419 [(set_attr "needs_delay_slot" "yes")
2420 (set_attr "type" "jump_ind")])
2421
2422;; For all later processors.
2423(define_insn "casesi_jump_2"
2424 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
2425 (match_operand 1 "braf_label_ref_operand" "")))
2426 (use (label_ref (match_operand 2 "" "")))]
2427 ""
2428 "braf %0%#"
2429 [(set_attr "needs_delay_slot" "yes")
2430 (set_attr "type" "jump_ind")])
2431
2432(define_insn "dummy_jump"
2433 [(set (pc) (const_int 0))]
2434 ""
2435 ""
2436 [(set_attr "length" "0")])
f1ffca1c 2437
a1a0806a
JW
2438;; Call subroutine returning any type.
2439;; ??? This probably doesn't work.
2440
2441(define_expand "untyped_call"
2442 [(parallel [(call (match_operand 0 "" "")
2443 (const_int 0))
2444 (match_operand 1 "" "")
2445 (match_operand 2 "" "")])]
2446 "TARGET_SH3E"
2447 "
2448{
2449 int i;
2450
2451 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
2452
2453 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2454 {
2455 rtx set = XVECEXP (operands[2], 0, i);
2456 emit_move_insn (SET_DEST (set), SET_SRC (set));
2457 }
2458
2459 /* The optimizer does not know that the call sets the function value
2460 registers we stored in the result block. We avoid problems by
2461 claiming that all hard registers are used and clobbered at this
2462 point. */
2463 emit_insn (gen_blockage ());
2464
2465 DONE;
2466}")
bc45ade3
SC
2467\f
2468;; ------------------------------------------------------------------------
2469;; Misc insns
2470;; ------------------------------------------------------------------------
2471
51bd623f 2472(define_insn "dect"
aff48e32
JR
2473 [(set (reg:SI 18)
2474 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
2475 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
51bd623f 2476 "TARGET_SH2"
1245df60
R
2477 "dt %0"
2478 [(set_attr "type" "arith")])
bc45ade3
SC
2479
2480(define_insn "nop"
2481 [(const_int 0)]
2482 ""
51bd623f 2483 "nop")
0d7e008e 2484
1245df60
R
2485;; Load address of a label. This is only generated by the casesi expand,
2486;; and by machine_dependent_reorg (fixing up fp moves).
2487;; This must use unspec, because this only works for labels that are
2488;; within range,
0d7e008e
SC
2489
2490(define_insn "mova"
07a45e5c 2491 [(set (reg:SI 0)
51bd623f 2492 (unspec [(label_ref (match_operand 0 "" ""))] 1))]
0d7e008e
SC
2493 ""
2494 "mova %O0,r0"
1245df60
R
2495 [(set_attr "in_delay_slot" "no")
2496 (set_attr "type" "arith")])
0d7e008e
SC
2497
2498;; case instruction for switch statements.
2499
2500;; Operand 0 is index
2501;; operand 1 is the minimum bound
2502;; operand 2 is the maximum bound - minimum bound + 1
2503;; operand 3 is CODE_LABEL for the table;
2504;; operand 4 is the CODE_LABEL to go to if index out of range.
2505
2506(define_expand "casesi"
1245df60
R
2507 [(match_operand:SI 0 "arith_reg_operand" "")
2508 (match_operand:SI 1 "arith_reg_operand" "")
2509 (match_operand:SI 2 "arith_reg_operand" "")
2510 (match_operand 3 "" "") (match_operand 4 "" "")]
2511 ""
2512 "
2513{
2514 rtx reg = gen_reg_rtx (SImode);
2515 rtx reg2 = gen_reg_rtx (SImode);
2516 operands[1] = copy_to_mode_reg (SImode, operands[1]);
2517 operands[2] = copy_to_mode_reg (SImode, operands[2]);
2518 /* If optimizing, casesi_worker depends on the mode of the instruction
2519 before label it 'uses' - operands[3]. */
2520 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
2521 reg));
2522 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
2523 if (TARGET_SH2)
2524 {
2525 rtx lab = gen_label_rtx ();
2526 emit_jump_insn (gen_casesi_jump_2 (reg2,
2527 gen_rtx (LABEL_REF, VOIDmode, lab),
2528 operands[3]));
2529 emit_label (lab);
2530 /* Put a fake jump after the label, lest some optimization might
2531 delete the barrier and LAB. */
2532 emit_jump_insn (gen_dummy_jump ());
2533 }
2534 else
2535 {
2536 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
2537 }
2538 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
2539 operands[3], but to lab. We will fix this up in
2540 machine_dependent_reorg. */
2541 emit_barrier ();
2542 DONE;
2543}")
2544
2545(define_expand "casesi_0"
2546 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
2547 (set (match_dup 4) (minus:SI (match_dup 4)
0d7e008e
SC
2548 (match_operand:SI 1 "arith_operand" "")))
2549 (set (reg:SI 18)
1245df60 2550 (gtu:SI (match_dup 4)
22e1ebf1 2551 (match_operand:SI 2 "arith_reg_operand" "")))
0d7e008e 2552 (set (pc)
7c225e88
JW
2553 (if_then_else (ne (reg:SI 18)
2554 (const_int 0))
1245df60
R
2555 (label_ref (match_operand 3 "" ""))
2556 (pc)))]
0d7e008e 2557 ""
1245df60 2558 "")
0d7e008e 2559
1245df60
R
2560;; ??? reload might clobber r0 if we use it explicitly in the RTL before
2561;; reload; using a R0_REGS pseudo reg is likely to give poor code.
2562;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
2563
2564(define_insn "casesi_worker_0"
2565 [(set (match_operand:SI 0 "register_operand" "=r,r")
2566 (unspec [(match_operand 1 "register_operand" "0,r")
2567 (label_ref (match_operand 2 "" ""))] 2))
2568 (clobber (match_scratch:SI 3 "=X,1"))
2569 (clobber (match_scratch:SI 4 "=&z,z"))]
2570 ""
2571 "#")
2572
2573(define_split
2574 [(set (match_operand:SI 0 "register_operand" "")
2575 (unspec [(match_operand 1 "register_operand" "")
2576 (label_ref (match_operand 2 "" ""))] 2))
2577 (clobber (match_scratch:SI 3 ""))
2578 (clobber (match_scratch:SI 4 ""))]
2579 "! TARGET_SH2 && reload_completed"
2580 [(set (reg:SI 0) (unspec [(label_ref (match_dup 2))] 1))
2581 (parallel [(set (match_dup 0)
2582 (unspec [(reg:SI 0) (match_dup 1) (label_ref (match_dup 2))] 2))
2583 (clobber (match_dup 3))])
2584 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI 0)))]
2585 "LABEL_NUSES (operands[2])++;")
2586
2587(define_split
2588 [(set (match_operand:SI 0 "register_operand" "")
2589 (unspec [(match_operand 1 "register_operand" "")
2590 (label_ref (match_operand 2 "" ""))] 2))
2591 (clobber (match_scratch:SI 3 ""))
2592 (clobber (match_scratch:SI 4 ""))]
2593 "TARGET_SH2 && reload_completed"
2594 [(set (reg:SI 0) (unspec [(label_ref (match_dup 2))] 1))
2595 (parallel [(set (match_dup 0)
2596 (unspec [(reg:SI 0) (match_dup 1) (label_ref (match_dup 2))] 2))
2597 (clobber (match_dup 3))])]
2598 "LABEL_NUSES (operands[2])++;")
2599
2600(define_insn "*casesi_worker"
2601 [(set (match_operand:SI 0 "register_operand" "=r,r")
2602 (unspec [(reg:SI 0) (match_operand 1 "register_operand" "0,r")
2603 (label_ref (match_operand 2 "" ""))] 2))
2604 (clobber (match_scratch:SI 3 "=X,1"))]
0d7e008e 2605 ""
4fdd1f85 2606 "*
ffae286a 2607{
1245df60
R
2608 enum machine_mode mode
2609 = optimize
2610 ? GET_MODE (PATTERN (prev_real_insn (operands[2])))
2611 : sh_addr_diff_vec_mode;
2612 switch (mode)
2613 {
2614 case SImode:
2615 return \"shll2 %1\;mov.l @(r0,%1),%0\";
2616 case HImode:
2617 return \"add %1,%1\;mov.w @(r0,%1),%0\";
2618 case QImode:
2619 {
2620 rtx adj = PATTERN (prev_real_insn (operands[2]));
2621 if ((insn_addresses[INSN_UID (XEXP ( XVECEXP (adj, 0, 1), 0))]
2622 - insn_addresses[INSN_UID (XEXP (XVECEXP (adj, 0, 2), 0))])
2623 <= 126)
2624 return \"mov.b @(r0,%1),%0\";
2625 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
2626 }
2627 default:
2628 abort ();
2629 }
ffae286a 2630}"
51bd623f 2631 [(set_attr "length" "4")])
0d7e008e 2632
1245df60
R
2633;; Include ADDR_DIFF_VECS in the shorten_branches pass; we have to
2634;; use a negative-length instruction to actually accomplish this.
2635(define_insn "addr_diff_vec_adjust"
2636 [(unspec_volatile [(label_ref (match_operand 0 "" ""))
2637 (label_ref (match_operand 1 "" ""))
2638 (label_ref (match_operand 2 "" ""))
2639 (match_operand 3 "const_int_operand" "")] 7)]
2640 ""
2641 "*
2642{
2643 /* ??? ASM_OUTPUT_ADDR_DIFF_ELT gets passed no context information, so
2644 we must use a kludge with a global variable. */
2645 sh_addr_diff_vec_mode = GET_MODE (PATTERN (insn));
2646 return \"\";
2647}"
2648;; Need a variable length for this to be processed in each shorten_branch pass.
956d6950 2649;; The actual work is done in ADJUST_INSN_LENGTH, because length attributes
1245df60
R
2650;; need to be (a choice of) constants.
2651;; We use the calculated length before ADJUST_INSN_LENGTH to
2652;; determine if the insn_addresses array contents are valid.
2653 [(set (attr "length")
2654 (if_then_else (eq (pc) (const_int -1))
2655 (const_int 2) (const_int 0)))])
2656
961c4780 2657(define_insn "return"
0d7e008e 2658 [(return)]
961c4780
SC
2659 "reload_completed"
2660 "%@ %#"
51bd623f
JW
2661 [(set_attr "type" "return")
2662 (set_attr "needs_delay_slot" "yes")])
b9654711
SC
2663
2664(define_expand "prologue"
2665 [(const_int 0)]
2666 ""
2667 "sh_expand_prologue (); DONE;")
2668
2669(define_expand "epilogue"
2670 [(return)]
2671 ""
2672 "sh_expand_epilogue ();")
2673
2674(define_insn "blockage"
2675 [(unspec_volatile [(const_int 0)] 0)]
2676 ""
2677 ""
2678 [(set_attr "length" "0")])
bc45ade3
SC
2679\f
2680;; ------------------------------------------------------------------------
2681;; Scc instructions
2682;; ------------------------------------------------------------------------
2683
0d7e008e 2684(define_insn "movt"
aa684c94 2685 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
961c4780 2686 (eq:SI (reg:SI 18) (const_int 1)))]
bc45ade3 2687 ""
1245df60
R
2688 "movt %0"
2689 [(set_attr "type" "arith")])
bc45ade3
SC
2690
2691(define_expand "seq"
aa684c94 2692 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2693 (match_dup 1))]
2694 ""
2695 "operands[1] = prepare_scc_operands (EQ);")
2696
2697(define_expand "slt"
aa684c94 2698 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2699 (match_dup 1))]
2700 ""
2701 "operands[1] = prepare_scc_operands (LT);")
2702
2703(define_expand "sle"
1245df60 2704 [(match_operand:SI 0 "arith_reg_operand" "")]
bc45ade3 2705 ""
45348d9e
JW
2706 "
2707{
1245df60
R
2708 rtx tmp = sh_compare_op0;
2709 sh_compare_op0 = sh_compare_op1;
2710 sh_compare_op1 = tmp;
2711 emit_insn (gen_sge (operands[0]));
2712 DONE;
45348d9e 2713}")
bc45ade3
SC
2714
2715(define_expand "sgt"
aa684c94 2716 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2717 (match_dup 1))]
2718 ""
2719 "operands[1] = prepare_scc_operands (GT);")
2720
2721(define_expand "sge"
aa684c94 2722 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2723 (match_dup 1))]
2724 ""
45348d9e
JW
2725 "
2726{
2727 if (GET_MODE (sh_compare_op0) == SFmode)
2728 {
1245df60
R
2729 if (TARGET_IEEE)
2730 {
2731 rtx t_reg = gen_rtx (REG, SImode, T_REG);
2732 rtx lab = gen_label_rtx ();
2733 emit_insn (gen_rtx (SET, VOIDmode, t_reg,
2734 gen_rtx (EQ, SImode, sh_compare_op0,
2735 sh_compare_op1)));
2736 emit_jump_insn (gen_branch_true (lab));
2737 emit_insn (gen_rtx (SET, VOIDmode, t_reg,
2738 gen_rtx (GT, SImode, sh_compare_op0,
2739 sh_compare_op1)));
2740 emit_label (lab);
2741 emit_insn (gen_movt (operands[0]));
2742 }
2743 else
2744 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
45348d9e
JW
2745 DONE;
2746 }
2747 operands[1] = prepare_scc_operands (GE);
2748}")
bc45ade3
SC
2749
2750(define_expand "sgtu"
aa684c94 2751 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2752 (match_dup 1))]
2753 ""
2754 "operands[1] = prepare_scc_operands (GTU);")
2755
2756(define_expand "sltu"
aa684c94 2757 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2758 (match_dup 1))]
2759 ""
2760 "operands[1] = prepare_scc_operands (LTU);")
2761
2762(define_expand "sleu"
aa684c94 2763 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2764 (match_dup 1))]
2765 ""
2766 "operands[1] = prepare_scc_operands (LEU);")
2767
2768(define_expand "sgeu"
aa684c94 2769 [(set (match_operand:SI 0 "arith_reg_operand" "")
bc45ade3
SC
2770 (match_dup 1))]
2771 ""
2772 "operands[1] = prepare_scc_operands (GEU);")
2773
8bca10f4
JW
2774;; sne moves the complement of the T reg to DEST like this:
2775;; cmp/eq ...
2776;; mov #-1,temp
2777;; negc temp,dest
2778;; This is better than xoring compare result with 1 because it does
2779;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
2780;; loop.
2781
bc45ade3 2782(define_expand "sne"
8bca10f4
JW
2783 [(set (match_dup 2) (const_int -1))
2784 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2785 (neg:SI (plus:SI (match_dup 1)
2786 (match_dup 2))))
2787 (set (reg:SI 18)
2788 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
2789 (const_int 0)))])]
2790 ""
2791 "
2792{
2793 operands[1] = prepare_scc_operands (EQ);
2794 operands[2] = gen_reg_rtx (SImode);
2795}")
2796
1245df60
R
2797;; Use the same trick for FP sle / sge
2798(define_expand "movnegt"
2799 [(set (match_dup 2) (const_int -1))
2800 (parallel [(set (match_operand 0 "" "")
2801 (neg:SI (plus:SI (match_dup 1)
2802 (match_dup 2))))
2803 (set (reg:SI 18)
2804 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
2805 (const_int 0)))])]
2806 ""
2807 "operands[2] = gen_reg_rtx (SImode);")
2808
8bca10f4 2809;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
956d6950 2810;; This prevents a regression that occurred when we switched from xor to
8bca10f4
JW
2811;; mov/neg for sne.
2812
2813(define_split
aa684c94 2814 [(set (match_operand:SI 0 "arith_reg_operand" "")
8bca10f4
JW
2815 (plus:SI (reg:SI 18)
2816 (const_int -1)))]
bc45ade3 2817 ""
8bca10f4
JW
2818 [(set (match_dup 0) (eq:SI (reg:SI 18) (const_int 1)))
2819 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
2820 "")
bc45ade3 2821
0d7e008e
SC
2822;; -------------------------------------------------------------------------
2823;; Instructions to cope with inline literal tables
2824;; -------------------------------------------------------------------------
2825
2826; 2 byte integer in line
b9654711 2827
0d7e008e
SC
2828(define_insn "consttable_2"
2829 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 2)]
2830 ""
2831 "*
2832{
2833 assemble_integer (operands[0], 2, 1);
2834 return \"\";
2835}"
2836 [(set_attr "length" "2")
2837 (set_attr "in_delay_slot" "no")])
2838
2839; 4 byte integer in line
2840
2841(define_insn "consttable_4"
2842 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 4)]
2843 ""
2844 "*
2845{
2846 assemble_integer (operands[0], 4, 1);
2847 return \"\";
2848}"
2849 [(set_attr "length" "4")
2850 (set_attr "in_delay_slot" "no")])
2851
2852; 8 byte integer in line
2853
2854(define_insn "consttable_8"
2855 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 6)]
2856 ""
2857 "*
2858{
2859 assemble_integer (operands[0], 8, 1);
2860 return \"\";
2861}"
2862 [(set_attr "length" "8")
2863 (set_attr "in_delay_slot" "no")])
2864
3e943b59
JR
2865; 4 byte floating point
2866
2867(define_insn "consttable_sf"
2868 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")] 4)]
2869 ""
2870 "*
2871{
2872 union real_extract u;
2873 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
2874 assemble_real (u.d, SFmode);
2875 return \"\";
2876}"
2877 [(set_attr "length" "4")
2878 (set_attr "in_delay_slot" "no")])
2879
2880; 8 byte floating point
2881
2882(define_insn "consttable_df"
2883 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")] 6)]
2884 ""
2885 "*
2886{
2887 union real_extract u;
2888 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
2889 assemble_real (u.d, DFmode);
2890 return \"\";
2891}"
2892 [(set_attr "length" "8")
2893 (set_attr "in_delay_slot" "no")])
2894
1245df60
R
2895;; Alignment is needed for some constant tables; it may also be added for
2896;; Instructions at the start of loops, or after unconditional branches.
2897;; ??? We would get more accurate lengths if we did instruction
2898;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
2899;; here is too conservative.
2900
0d7e008e
SC
2901; align to a two byte boundary
2902
2903(define_insn "align_2"
1245df60 2904 [(unspec_volatile [(const_int 1)] 1)]
0d7e008e
SC
2905 ""
2906 ".align 1"
2907 [(set_attr "length" "0")
2908 (set_attr "in_delay_slot" "no")])
2909
2910; align to a four byte boundary
1245df60
R
2911;; align_4 and align_log are instructions for the starts of loops, or
2912;; after unconditional branches, which may take up extra room.
2913
2914(define_expand "align_4"
2915 [(unspec_volatile [(const_int 2)] 1)]
2916 ""
2917 "")
2918
2919; align to a cache line boundary
0d7e008e 2920
1245df60
R
2921(define_insn "align_log"
2922 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 1)]
0d7e008e 2923 ""
1245df60
R
2924 ".align %O0"
2925;; Need a variable length for this to be processed in each shorten_branch pass.
956d6950 2926;; The actual work is done in ADJUST_INSN_LENGTH, because length attributes
1245df60
R
2927;; need to be (a choice of) constants.
2928 [(set (attr "length")
2929 (if_then_else (ne (pc) (pc)) (const_int 2) (const_int 0)))
2930 (set_attr "in_delay_slot" "no")])
0d7e008e
SC
2931
2932; emitted at the end of the literal table, used to emit the
2933; 32bit branch labels if needed.
2934
2935(define_insn "consttable_end"
2936 [(unspec_volatile [(const_int 0)] 11)]
2937 ""
2938 "* return output_jump_label_table ();"
2939 [(set_attr "in_delay_slot" "no")])
2940
0d7e008e
SC
2941;; -------------------------------------------------------------------------
2942;; Misc
2943;; -------------------------------------------------------------------------
2944
07a45e5c 2945;; String/block move insn.
0d7e008e
SC
2946
2947(define_expand "movstrsi"
2948 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2949 (mem:BLK (match_operand:BLK 1 "" "")))
2950 (use (match_operand:SI 2 "nonmemory_operand" ""))
2951 (use (match_operand:SI 3 "immediate_operand" ""))
2952 (clobber (reg:SI 17))
2953 (clobber (reg:SI 4))
2954 (clobber (reg:SI 5))
2955 (clobber (reg:SI 0))])]
2956 ""
2957 "
2958{
2959 if(expand_block_move (operands))
2960 DONE;
2961 else FAIL;
2962}")
2963
2964(define_insn "block_move_real"
2965 [(parallel [(set (mem:BLK (reg:SI 4))
2966 (mem:BLK (reg:SI 5)))
2967 (use (match_operand:SI 0 "arith_reg_operand" "r"))
2968 (clobber (reg:SI 17))
0d7e008e
SC
2969 (clobber (reg:SI 0))])]
2970 ""
2971 "jsr @%0%#"
22e1ebf1 2972 [(set_attr "type" "sfunc")
0d7e008e
SC
2973 (set_attr "needs_delay_slot" "yes")])
2974
2975(define_insn "block_lump_real"
2976 [(parallel [(set (mem:BLK (reg:SI 4))
2977 (mem:BLK (reg:SI 5)))
2978 (use (match_operand:SI 0 "arith_reg_operand" "r"))
2979 (use (reg:SI 6))
2980 (clobber (reg:SI 17))
2981 (clobber (reg:SI 4))
2982 (clobber (reg:SI 5))
2983 (clobber (reg:SI 6))
2984 (clobber (reg:SI 0))])]
2985 ""
2986 "jsr @%0%#"
22e1ebf1 2987 [(set_attr "type" "sfunc")
0d7e008e 2988 (set_attr "needs_delay_slot" "yes")])
45348d9e
JW
2989\f
2990;; -------------------------------------------------------------------------
2991;; Floating point instructions.
2992;; -------------------------------------------------------------------------
2993
2994;; ??? All patterns should have a type attribute.
2995
2996(define_insn "addsf3"
2997 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2998 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
2999 (match_operand:SF 2 "arith_reg_operand" "f")))]
3000 "TARGET_SH3E"
c1aef54d
ILT
3001 "fadd %2,%0"
3002 [(set_attr "type" "fp")])
45348d9e
JW
3003
3004(define_insn "subsf3"
3005 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3006 (minus:SF (match_operand:SF 1 "arith_reg_operand" "0")
1245df60 3007 (match_operand:SF 2 "arith_reg_operand" "f")))]
45348d9e 3008 "TARGET_SH3E"
c1aef54d
ILT
3009 "fsub %2,%0"
3010 [(set_attr "type" "fp")])
45348d9e
JW
3011
3012(define_insn "mulsf3"
3013 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3014 (mult:SF (match_operand:SF 1 "arith_reg_operand" "%0")
3015 (match_operand:SF 2 "arith_reg_operand" "f")))]
3016 "TARGET_SH3E"
c1aef54d
ILT
3017 "fmul %2,%0"
3018 [(set_attr "type" "fp")])
45348d9e
JW
3019
3020(define_insn "*macsf3"
3021 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3022 (plus:SF (mult:SF (match_operand:SF 1 "arith_reg_operand" "%w")
3023 (match_operand:SF 2 "arith_reg_operand" "f"))
3024 (match_operand:SF 3 "arith_reg_operand" "0")))]
3025 "TARGET_SH3E"
c1aef54d
ILT
3026 "fmac fr0,%2,%0"
3027 [(set_attr "type" "fp")])
45348d9e
JW
3028
3029(define_insn "divsf3"
3030 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3031 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
1245df60 3032 (match_operand:SF 2 "arith_reg_operand" "f")))]
45348d9e 3033 "TARGET_SH3E"
c1aef54d
ILT
3034 "fdiv %2,%0"
3035 [(set_attr "type" "fdiv")])
45348d9e 3036
1245df60
R
3037(define_expand "floatsisf2"
3038 [(set (reg:SI 22)
3039 (match_operand:SI 1 "arith_reg_operand" ""))
3040 (set (match_operand:SF 0 "arith_reg_operand" "")
3041 (float:SF (reg:SI 22)))]
3042 "TARGET_SH3E"
3043 "")
45348d9e 3044
1245df60 3045(define_insn "*floatsisf2_ie"
45348d9e 3046 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
1245df60 3047 (float:SF (reg:SI 22)))]
45348d9e 3048 "TARGET_SH3E"
1245df60
R
3049 "float fpul,%0"
3050 [(set_attr "type" "fp")])
45348d9e 3051
1245df60
R
3052(define_expand "fix_truncsfsi2"
3053 [(set (reg:SI 22)
3054 (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
3055 (set (match_operand:SI 0 "arith_reg_operand" "=r")
3056 (reg:SI 22))]
3057 "TARGET_SH3E"
3058 "")
45348d9e 3059
1245df60
R
3060(define_insn "*fixsfsi"
3061 [(set (reg:SI 22)
3062 (fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))]
45348d9e 3063 "TARGET_SH3E"
1245df60
R
3064 "ftrc %0,fpul"
3065 [(set_attr "type" "fp")])
45348d9e 3066
1245df60 3067(define_insn "cmpgtsf_t"
45348d9e
JW
3068 [(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f")
3069 (match_operand:SF 1 "arith_reg_operand" "f")))]
3070 "TARGET_SH3E"
c1aef54d
ILT
3071 "fcmp/gt %1,%0"
3072 [(set_attr "type" "fp")])
45348d9e 3073
1245df60 3074(define_insn "cmpeqsf_t"
45348d9e
JW
3075 [(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
3076 (match_operand:SF 1 "arith_reg_operand" "f")))]
3077 "TARGET_SH3E"
c1aef54d
ILT
3078 "fcmp/eq %1,%0"
3079 [(set_attr "type" "fp")])
45348d9e 3080
1245df60
R
3081(define_insn "ieee_ccmpeqsf_t"
3082 [(set (reg:SI 18) (ior:SI (reg:SI 18)
3083 (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
3084 (match_operand:SF 1 "arith_reg_operand" "f"))))]
3085 "TARGET_SH3E && TARGET_IEEE"
3086 "* return output_ieee_ccmpeq (insn, operands);"
3087 [(set_attr "length" "4")])
3088
3089
45348d9e
JW
3090(define_expand "cmpsf"
3091 [(set (reg:SI 18) (compare (match_operand:SF 0 "arith_operand" "")
3092 (match_operand:SF 1 "arith_operand" "")))]
3093 "TARGET_SH3E"
3094 "
3095{
3096 sh_compare_op0 = operands[0];
3097 sh_compare_op1 = operands[1];
3098 DONE;
3099}")
b9654711 3100
45348d9e
JW
3101(define_insn "negsf2"
3102 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3103 (neg:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
3104 "TARGET_SH3E"
c1aef54d
ILT
3105 "fneg %0"
3106 [(set_attr "type" "fp")])
45348d9e
JW
3107
3108(define_insn "sqrtsf2"
3109 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3110 (sqrt:DF (match_operand:SF 1 "arith_reg_operand" "0")))]
3111 "TARGET_SH3E"
c1aef54d
ILT
3112 "fsqrt %0"
3113 [(set_attr "type" "fdiv")])
45348d9e
JW
3114
3115(define_insn "abssf2"
3116 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3117 (abs:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
3118 "TARGET_SH3E"
c1aef54d
ILT
3119 "fabs %0"
3120 [(set_attr "type" "fp")])
45348d9e 3121\f
725de644
JW
3122;; Bit field extract patterns. These give better code for packed bitfields,
3123;; because they allow auto-increment addresses to be generated.
3124
3125(define_expand "insv"
3126 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
3127 (match_operand:SI 1 "immediate_operand" "")
3128 (match_operand:SI 2 "immediate_operand" ""))
3129 (match_operand:SI 3 "general_operand" ""))]
3130 "! TARGET_LITTLE_ENDIAN"
3131 "
3132{
3133 rtx addr_target, orig_address, shift_reg;
3134 HOST_WIDE_INT size;
3135
3136 /* ??? expmed doesn't care for non-register predicates. */
3137 if (! memory_operand (operands[0], VOIDmode)
3138 || ! immediate_operand (operands[1], VOIDmode)
3139 || ! immediate_operand (operands[2], VOIDmode)
3140 || ! general_operand (operands[3], VOIDmode))
3141 FAIL;
3142 /* If this isn't a 16 / 24 / 32 bit field, or if
3143 it doesn't start on a byte boundary, then fail. */
3144 size = INTVAL (operands[1]);
3145 if (size < 16 || size > 32 || size % 8 != 0
3146 || (INTVAL (operands[2]) % 8) != 0)
3147 FAIL;
3148
3149 size /= 8;
3150 orig_address = XEXP (operands[0], 0);
3151 addr_target = gen_reg_rtx (SImode);
3152 shift_reg = gen_reg_rtx (SImode);
3153 emit_insn (gen_movsi (shift_reg, operands[3]));
3154 emit_insn (gen_addsi3 (addr_target, orig_address, GEN_INT (size - 1)));
3155
3156 operands[0] = change_address (operands[0], QImode, addr_target);
3157 emit_insn (gen_movqi (operands[0], gen_rtx (SUBREG, QImode, shift_reg, 0)));
3158
3159 while (size -= 1)
3160 {
3161 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
3162 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
3163 emit_insn (gen_movqi (operands[0],
3164 gen_rtx (SUBREG, QImode, shift_reg, 0)));
3165 }
3166
3167 DONE;
3168}")
3169\f
51bd623f
JW
3170;; -------------------------------------------------------------------------
3171;; Peepholes
3172;; -------------------------------------------------------------------------
961c4780 3173
51bd623f
JW
3174;; This matches cases where a stack pointer increment at the start of the
3175;; epilogue combines with a stack slot read loading the return value.
aa684c94 3176
07a45e5c 3177(define_peephole
51bd623f
JW
3178 [(set (match_operand:SI 0 "arith_reg_operand" "")
3179 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
3180 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
3181 "REGNO (operands[1]) != REGNO (operands[0])"
3182 "mov.l @%1+,%0")
00f8ff66 3183
51bd623f 3184;; See the comment on the dt combiner pattern above.
00f8ff66 3185
07a45e5c
JW
3186(define_peephole
3187 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
00f8ff66
SC
3188 (plus:SI (match_dup 0)
3189 (const_int -1)))
3190 (set (reg:SI 18)
3191 (eq:SI (match_dup 0)
3192 (const_int 0)))]
3193 "TARGET_SH2"
3194 "dt %0")
e4931540
RK
3195
3196;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
3197;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
3198;; reload when the constant is too large for a reg+offset address.
3199
3200;; ??? We would get much better code if this was done in reload. This would
3201;; require modifying find_reloads_address to recognize that if the constant
3202;; is out-of-range for an immediate add, then we get better code by reloading
3203;; the constant into a register than by reloading the sum into a register,
3204;; since the former is one instruction shorter if the address does not need
3205;; to be offsettable. Unfortunately this does not work, because there is
3206;; only one register, r0, that can be used as an index register. This register
3207;; is also the function return value register. So, if we try to force reload
3208;; to use double-reg addresses, then we end up with some instructions that
3209;; need to use r0 twice. The only way to fix this is to change the calling
3210;; convention so that r0 is not used to return values.
3211
3212(define_peephole
3213 [(set (match_operand:SI 0 "register_operand" "=r")
3214 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3215 (set (mem:SI (match_dup 0))
3216 (match_operand:SI 2 "general_movsrc_operand" ""))]
3217 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
3218 "mov.l %2,@(%0,%1)")
3219
3220(define_peephole
3221 [(set (match_operand:SI 0 "register_operand" "=r")
3222 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3223 (set (match_operand:SI 2 "general_movdst_operand" "")
3224 (mem:SI (match_dup 0)))]
3225 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
3226 "mov.l @(%0,%1),%2")
3227
3228(define_peephole
3229 [(set (match_operand:SI 0 "register_operand" "=r")
3230 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3231 (set (mem:HI (match_dup 0))
3232 (match_operand:HI 2 "general_movsrc_operand" ""))]
3233 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
3234 "mov.w %2,@(%0,%1)")
3235
3236(define_peephole
3237 [(set (match_operand:SI 0 "register_operand" "=r")
3238 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3239 (set (match_operand:HI 2 "general_movdst_operand" "")
3240 (mem:HI (match_dup 0)))]
3241 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
3242 "mov.w @(%0,%1),%2")
3243
3244(define_peephole
3245 [(set (match_operand:SI 0 "register_operand" "=r")
3246 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3247 (set (mem:QI (match_dup 0))
3248 (match_operand:QI 2 "general_movsrc_operand" ""))]
3249 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
3250 "mov.b %2,@(%0,%1)")
3251
3252(define_peephole
3253 [(set (match_operand:SI 0 "register_operand" "=r")
3254 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3255 (set (match_operand:QI 2 "general_movdst_operand" "")
3256 (mem:QI (match_dup 0)))]
3257 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
3258 "mov.b @(%0,%1),%2")
3259
3260(define_peephole
3261 [(set (match_operand:SI 0 "register_operand" "=r")
3262 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3263 (set (mem:SF (match_dup 0))
3264 (match_operand:SF 2 "general_movsrc_operand" ""))]
45348d9e
JW
3265 "REGNO (operands[0]) == 0
3266 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
3267 || (GET_CODE (operands[2]) == SUBREG
3268 && REGNO (SUBREG_REG (operands[2])) < 16))
3269 && reg_unused_after (operands[0], insn)"
e4931540
RK
3270 "mov.l %2,@(%0,%1)")
3271
3272(define_peephole
3273 [(set (match_operand:SI 0 "register_operand" "=r")
3274 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3275 (set (match_operand:SF 2 "general_movdst_operand" "")
3276
3277 (mem:SF (match_dup 0)))]
45348d9e
JW
3278 "REGNO (operands[0]) == 0
3279 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
3280 || (GET_CODE (operands[2]) == SUBREG
3281 && REGNO (SUBREG_REG (operands[2])) < 16))
3282 && reg_unused_after (operands[0], insn)"
e4931540 3283 "mov.l @(%0,%1),%2")
45348d9e
JW
3284
3285(define_peephole
3286 [(set (match_operand:SI 0 "register_operand" "=r")
3287 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3288 (set (mem:SF (match_dup 0))
3289 (match_operand:SF 2 "general_movsrc_operand" ""))]
3290 "REGNO (operands[0]) == 0
3291 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG)
3292 || (GET_CODE (operands[2]) == SUBREG
3293 && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG))
3294 && reg_unused_after (operands[0], insn)"
1245df60 3295 "fmov{.s|} %2,@(%0,%1)")
45348d9e
JW
3296
3297(define_peephole
3298 [(set (match_operand:SI 0 "register_operand" "=r")
3299 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
3300 (set (match_operand:SF 2 "general_movdst_operand" "")
3301
3302 (mem:SF (match_dup 0)))]
3303 "REGNO (operands[0]) == 0
3304 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG)
3305 || (GET_CODE (operands[2]) == SUBREG
3306 && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG))
3307 && reg_unused_after (operands[0], insn)"
1245df60 3308 "fmov{.s|} @(%0,%1),%2")
4408efce
JL
3309
3310;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
3311(define_insn "sp_switch_1"
3312 [(const_int 1)]
3313 ""
3314 "*
3315{
3316 rtx xoperands[1];
3317
3318 xoperands[0] = sp_switch;
3319 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
3320 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
3321 return \"mov r0,r15\";
3322}"
3323 [(set_attr "length" "10")])
4408efce 3324
956d6950 3325;; Switch back to the original stack for interrupt functions with the
4408efce
JL
3326;; sp_switch attribute. */
3327(define_insn "sp_switch_2"
3328 [(const_int 2)]
3329 ""
3330 "mov.l @r15+,r15\;mov.l @r15+,r0"
3331 [(set_attr "length" "4")])
This page took 0.740121 seconds and 5 git commands to generate.