* sh.md (builtin_setjmp_receiver): New expander.
[gcc.git] / gcc / config / sh / sh.md
1 ;;- Machine description for the Hitachi SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;; t -- T
46 ;; x -- mac
47 ;; l -- pr
48 ;; z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73 (AP_REG 16)
74 (PR_REG 17)
75 (T_REG 18)
76 (GBR_REG 19)
77 (MACH_REG 20)
78 (MACL_REG 21)
79 (FPUL_REG 22)
80 (RAP_REG 23)
81
82 (FPSCR_REG 48)
83
84 (PIC_REG 12)
85 (FP_REG 14)
86 (SP_REG 15)
87
88 (R0_REG 0)
89 (R1_REG 1)
90 (R2_REG 2)
91 (R3_REG 3)
92 (R4_REG 4)
93 (R5_REG 5)
94 (R6_REG 6)
95
96 (DR0_REG 24)
97 (DR2_REG 26)
98 (DR4_REG 28)
99
100 (XD0_REG 40)
101
102 ;; These are used with unspec.
103 (UNSPEC_MOVA 1)
104 (UNSPEC_CASESI 2)
105 (UNSPEC_BBR 4)
106 (UNSPEC_SFUNC 5)
107 (UNSPEC_PIC 6)
108 (UNSPEC_GOT 7)
109 (UNSPEC_GOTOFF 8)
110 (UNSPEC_PLT 9)
111 (UNSPEC_CALLER 10)
112 (UNSPEC_ICACHE 12)
113
114 ;; These are used with unspec_volatile.
115 (UNSPECV_BLOCKAGE 0)
116 (UNSPECV_ALIGN 1)
117 (UNSPECV_CONST2 2)
118 (UNSPECV_CONST4 4)
119 (UNSPECV_CONST8 6)
120 (UNSPECV_CONST_END 11)
121 ])
122
123 ;; -------------------------------------------------------------------------
124 ;; Attributes
125 ;; -------------------------------------------------------------------------
126
127 ;; Target CPU.
128
129 (define_attr "cpu"
130 "sh1,sh2,sh3,sh3e,sh4"
131 (const (symbol_ref "sh_cpu_attr")))
132
133 (define_attr "endian" "big,little"
134 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
135 (const_string "little") (const_string "big"))))
136
137 ;; Indicate if the default fpu mode is single precision.
138 (define_attr "fpu_single" "yes,no"
139 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
140 (const_string "yes") (const_string "no"))))
141
142 (define_attr "fmovd" "yes,no"
143 (const (if_then_else (symbol_ref "TARGET_FMOVD")
144 (const_string "yes") (const_string "no"))))
145 ;; issues/clock
146 (define_attr "issues" "1,2"
147 (const (if_then_else (symbol_ref "TARGET_SUPERSCALAR") (const_string "2") (const_string "1"))))
148
149 ;; cbranch conditional branch instructions
150 ;; jump unconditional jumps
151 ;; arith ordinary arithmetic
152 ;; arith3 a compound insn that behaves similarly to a sequence of
153 ;; three insns of type arith
154 ;; arith3b like above, but might end with a redirected branch
155 ;; load from memory
156 ;; load_si Likewise, SImode variant for general register.
157 ;; store to memory
158 ;; move register to register
159 ;; fmove register to register, floating point
160 ;; smpy word precision integer multiply
161 ;; dmpy longword or doublelongword precision integer multiply
162 ;; return rts
163 ;; pload load of pr reg, which can't be put into delay slot of rts
164 ;; prset copy register to pr reg, ditto
165 ;; pstore store of pr reg, which can't be put into delay slot of jsr
166 ;; prget copy pr to register, ditto
167 ;; pcload pc relative load of constant value
168 ;; pcload_si Likewise, SImode variant for general register.
169 ;; rte return from exception
170 ;; sfunc special function call with known used registers
171 ;; call function call
172 ;; fp floating point
173 ;; fdiv floating point divide (or square root)
174 ;; gp_fpul move between general purpose register and fpul
175 ;; dfp_arith, dfp_cmp,dfp_conv
176 ;; dfdiv double precision floating point divide (or square root)
177 ;; nil no-op move, will be deleted.
178
179 (define_attr "type"
180 "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,nil"
181 (const_string "other"))
182
183 ;; Indicate what precision must be selected in fpscr for this insn, if any.
184
185 (define_attr "fp_mode" "single,double,none" (const_string "none"))
186
187 ; If a conditional branch destination is within -252..258 bytes away
188 ; from the instruction it can be 2 bytes long. Something in the
189 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
190 ; branches are initially assumed to be 16 bytes long.
191 ; In machine_dependent_reorg, we split all branches that are longer than
192 ; 2 bytes.
193
194 ;; The maximum range used for SImode constant pool entries is 1018. A final
195 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
196 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
197 ;; instruction around the pool table, 2 bytes of alignment before the table,
198 ;; and 30 bytes of alignment after the table. That gives a maximum total
199 ;; pool size of 1058 bytes.
200 ;; Worst case code/pool content size ratio is 1:2 (using asms).
201 ;; Thus, in the worst case, there is one instruction in front of a maximum
202 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
203 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
204 ;; If we have a forward branch, the initial table will be put after the
205 ;; unconditional branch.
206 ;;
207 ;; ??? We could do much better by keeping track of the actual pcloads within
208 ;; the branch range and in the pcload range in front of the branch range.
209
210 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
211 ;; inside an le.
212 (define_attr "short_cbranch_p" "no,yes"
213 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
214 (const_string "no")
215 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
216 (const_string "yes")
217 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
218 (const_string "no")
219 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
220 (const_string "yes")
221 ] (const_string "no")))
222
223 (define_attr "med_branch_p" "no,yes"
224 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
225 (const_int 1988))
226 (const_string "yes")
227 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
228 (const_string "no")
229 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
230 (const_int 8186))
231 (const_string "yes")
232 ] (const_string "no")))
233
234 (define_attr "med_cbranch_p" "no,yes"
235 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
236 (const_int 1986))
237 (const_string "yes")
238 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
239 (const_string "no")
240 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
241 (const_int 8184))
242 (const_string "yes")
243 ] (const_string "no")))
244
245 (define_attr "braf_branch_p" "no,yes"
246 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
247 (const_string "no")
248 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
249 (const_int 20660))
250 (const_string "yes")
251 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
252 (const_string "no")
253 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
254 (const_int 65530))
255 (const_string "yes")
256 ] (const_string "no")))
257
258 (define_attr "braf_cbranch_p" "no,yes"
259 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
260 (const_string "no")
261 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
262 (const_int 20658))
263 (const_string "yes")
264 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
265 (const_string "no")
266 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
267 (const_int 65528))
268 (const_string "yes")
269 ] (const_string "no")))
270
271 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
272 ; For wider ranges, we need a combination of a code and a data part.
273 ; If we can get a scratch register for a long range jump, the code
274 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
275 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
276 ; long; otherwise, it must be 6 bytes long.
277
278 ; All other instructions are two bytes long by default.
279
280 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
281 ;; but getattrtab doesn't understand this.
282 (define_attr "length" ""
283 (cond [(eq_attr "type" "cbranch")
284 (cond [(eq_attr "short_cbranch_p" "yes")
285 (const_int 2)
286 (eq_attr "med_cbranch_p" "yes")
287 (const_int 6)
288 (eq_attr "braf_cbranch_p" "yes")
289 (const_int 12)
290 ;; ??? using pc is not computed transitively.
291 (ne (match_dup 0) (match_dup 0))
292 (const_int 14)
293 (ne (symbol_ref ("flag_pic")) (const_int 0))
294 (const_int 24)
295 ] (const_int 16))
296 (eq_attr "type" "jump")
297 (cond [(eq_attr "med_branch_p" "yes")
298 (const_int 2)
299 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
300 (symbol_ref "INSN"))
301 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
302 (symbol_ref "code_for_indirect_jump_scratch")))
303 (if_then_else (eq_attr "braf_branch_p" "yes")
304 (const_int 6)
305 (const_int 10))
306 (eq_attr "braf_branch_p" "yes")
307 (const_int 10)
308 ;; ??? using pc is not computed transitively.
309 (ne (match_dup 0) (match_dup 0))
310 (const_int 12)
311 (ne (symbol_ref ("flag_pic")) (const_int 0))
312 (const_int 22)
313 ] (const_int 14))
314 ] (const_int 2)))
315
316 ;; (define_function_unit {name} {num-units} {n-users} {test}
317 ;; {ready-delay} {issue-delay} [{conflict-list}])
318
319 ;; Load and store instructions save a cycle if they are aligned on a
320 ;; four byte boundary. Using a function unit for stores encourages
321 ;; gcc to separate load and store instructions by one instruction,
322 ;; which makes it more likely that the linker will be able to word
323 ;; align them when relaxing.
324
325 ;; Loads have a latency of two.
326 ;; However, call insns can have a delay slot, so that we want one more
327 ;; insn to be scheduled between the load of the function address and the call.
328 ;; This is equivalent to a latency of three.
329 ;; We cannot use a conflict list for this, because we need to distinguish
330 ;; between the actual call address and the function arguments.
331 ;; ADJUST_COST can only properly handle reductions of the cost, so we
332 ;; use a latency of three here.
333 ;; We only do this for SImode loads of general registers, to make the work
334 ;; for ADJUST_COST easier.
335 (define_function_unit "memory" 1 0
336 (and (eq_attr "issues" "1")
337 (eq_attr "type" "load_si,pcload_si"))
338 3 2)
339 (define_function_unit "memory" 1 0
340 (and (eq_attr "issues" "1")
341 (eq_attr "type" "load,pcload,pload,store,pstore"))
342 2 2)
343
344 (define_function_unit "int" 1 0
345 (and (eq_attr "issues" "1") (eq_attr "type" "arith3,arith3b")) 3 3)
346
347 (define_function_unit "int" 1 0
348 (and (eq_attr "issues" "1") (eq_attr "type" "dyn_shift")) 2 2)
349
350 (define_function_unit "int" 1 0
351 (and (eq_attr "issues" "1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
352
353 ;; ??? These are approximations.
354 (define_function_unit "mpy" 1 0
355 (and (eq_attr "issues" "1") (eq_attr "type" "smpy")) 2 2)
356 (define_function_unit "mpy" 1 0
357 (and (eq_attr "issues" "1") (eq_attr "type" "dmpy")) 3 3)
358
359 (define_function_unit "fp" 1 0
360 (and (eq_attr "issues" "1") (eq_attr "type" "fp,fmove")) 2 1)
361 (define_function_unit "fp" 1 0
362 (and (eq_attr "issues" "1") (eq_attr "type" "fdiv")) 13 12)
363
364
365 ;; SH4 scheduling
366 ;; The SH4 is a dual-issue implementation, thus we have to multiply all
367 ;; costs by at least two.
368 ;; There will be single increments of the modeled that don't correspond
369 ;; to the actual target ;; whenever two insns to be issued depend one a
370 ;; single resource, and the scheduler picks to be the first one.
371 ;; If we multiplied the costs just by two, just two of these single
372 ;; increments would amount to an actual cycle. By picking a larger
373 ;; factor, we can ameliorate the effect; However, we then have to make sure
374 ;; that only two insns are modeled as issued per actual cycle.
375 ;; Moreover, we need a way to specify the latency of insns that don't
376 ;; use an actual function unit.
377 ;; We use an 'issue' function unit to do that, and a cost factor of 10.
378
379 (define_function_unit "issue" 2 0
380 (and (eq_attr "issues" "2") (eq_attr "type" "!nil,arith3"))
381 10 10)
382
383 (define_function_unit "issue" 2 0
384 (and (eq_attr "issues" "2") (eq_attr "type" "arith3"))
385 30 30)
386
387 ;; There is no point in providing exact scheduling information about branches,
388 ;; because they are at the starts / ends of basic blocks anyways.
389
390 ;; Some insns cannot be issued before/after another insn in the same cycle,
391 ;; irrespective of the type of the other insn.
392
393 ;; default is dual-issue, but can't be paired with an insn that
394 ;; uses multiple function units.
395 (define_function_unit "single_issue" 1 0
396 (and (eq_attr "issues" "2")
397 (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
398 1 10
399 [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
400
401 (define_function_unit "single_issue" 1 0
402 (and (eq_attr "issues" "2")
403 (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
404 10 10
405 [(const_int 1)])
406
407 ;; arith3 insns are always pairable at the start, but not inecessarily at
408 ;; the end; however, there doesn;t seem to be a way to express that.
409 (define_function_unit "single_issue" 1 0
410 (and (eq_attr "issues" "2")
411 (eq_attr "type" "arith3"))
412 30 20
413 [(const_int 1)])
414
415 ;; arith3b insn are pairable at the end and have latency that prevents pairing
416 ;; with the following branch, but we don't want this latency be respected;
417 ;; When the following branch is immediately adjacent, we can redirect the
418 ;; internal branch, which is likly to be a larger win.
419 (define_function_unit "single_issue" 1 0
420 (and (eq_attr "issues" "2")
421 (eq_attr "type" "arith3b"))
422 20 20
423 [(const_int 1)])
424
425 ;; calls introduce a longisch delay that is likely to flush the pipelines.
426 (define_function_unit "single_issue" 1 0
427 (and (eq_attr "issues" "2")
428 (eq_attr "type" "call,sfunc"))
429 160 160
430 [(eq_attr "type" "!call") (eq_attr "type" "call")])
431
432 ;; Load and store instructions have no alignment peculiarities for the SH4,
433 ;; but they use the load-store unit, which they share with the fmove type
434 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
435 ;; Loads have a latency of two.
436 ;; However, call insns can only paired with a preceding insn, and have
437 ;; a delay slot, so that we want two more insns to be scheduled between the
438 ;; load of the function address and the call. This is equivalent to a
439 ;; latency of three.
440 ;; We cannot use a conflict list for this, because we need to distinguish
441 ;; between the actual call address and the function arguments.
442 ;; ADJUST_COST can only properly handle reductions of the cost, so we
443 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
444 ;; We only do this for SImode loads of general registers, to make the work
445 ;; for ADJUST_COST easier.
446
447 ;; When specifying different latencies for different insns using the
448 ;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
449 ;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
450 ;; for an executing insn E and a candidate insn C.
451 ;; Therefore, we define three different function units for load_store:
452 ;; load_store, load and load_si.
453
454 (define_function_unit "load_si" 1 0
455 (and (eq_attr "issues" "2")
456 (eq_attr "type" "load_si,pcload_si")) 30 10)
457 (define_function_unit "load" 1 0
458 (and (eq_attr "issues" "2")
459 (eq_attr "type" "load,pcload,pload")) 20 10)
460 (define_function_unit "load_store" 1 0
461 (and (eq_attr "issues" "2")
462 (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
463 10 10)
464
465 (define_function_unit "int" 1 0
466 (and (eq_attr "issues" "2") (eq_attr "type" "arith,dyn_shift")) 10 10)
467
468 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
469 ;; spurious FIFO constraint; the multiply instructions use the "int"
470 ;; unit actually only for two cycles.
471 (define_function_unit "int" 1 0
472 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 20 20)
473
474 ;; We use a fictous "mpy" unit to express the actual latency.
475 (define_function_unit "mpy" 1 0
476 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 20)
477
478 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
479 ;; spurious FIFO constraint.
480 (define_function_unit "int" 1 0
481 (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 10 10)
482
483 ;; We use a fictous "gp_fpul" unit to express the actual latency.
484 (define_function_unit "gp_fpul" 1 0
485 (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 20 10)
486
487 ;; ??? multiply uses the floating point unit, but with a two cycle delay.
488 ;; Thus, a simple single-precision fp operation could finish if issued in
489 ;; the very next cycle, but stalls when issued two or three cycles later.
490 ;; Similarily, a divide / sqrt can work without stalls if issued in
491 ;; the very next cycle, while it would have to block if issued two or
492 ;; three cycles later.
493 ;; There is no way to model this with gcc's function units. This problem is
494 ;; actually mentioned in md.texi. Tackling this problem requires first that
495 ;; it is possible to speak about the target in an open discussion.
496 ;;
497 ;; However, simple double-precision operations always conflict.
498
499 (define_function_unit "fp" 1 0
500 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 40
501 [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
502
503 ;; The "fp" unit is for pipeline stages F1 and F2.
504
505 (define_function_unit "fp" 1 0
506 (and (eq_attr "issues" "2") (eq_attr "type" "fp")) 30 10)
507
508 ;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
509 ;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
510 ;; the F3 stage.
511 (define_function_unit "fp" 1 0
512 (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 30 10)
513
514 ;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
515 ;; pipeline stages on the pipelining of fdiv/fsqrt insns.
516 ;; We also use it to give the actual latency here.
517 ;; fsqrt is actually one cycle faster than fdiv (and the value used here),
518 ;; but that will hardly matter in practice for scheduling.
519 (define_function_unit "fdiv" 1 0
520 (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 120 100)
521
522 ;; There is again a late use of the "fp" unit by [d]fdiv type insns
523 ;; that we can't express.
524
525 (define_function_unit "fp" 1 0
526 (and (eq_attr "issues" "2") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
527
528 (define_function_unit "fp" 1 0
529 (and (eq_attr "issues" "2") (eq_attr "type" "dfp_arith")) 80 60)
530
531 (define_function_unit "fp" 1 0
532 (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 10)
533
534 (define_function_unit "fdiv" 1 0
535 (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 210)
536
537 ; Definitions for filling branch delay slots.
538
539 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
540
541 ;; ??? This should be (nil) instead of (const_int 0)
542 (define_attr "hit_stack" "yes,no"
543 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
544 (const_int 0))
545 (const_string "no")]
546 (const_string "yes")))
547
548 (define_attr "interrupt_function" "no,yes"
549 (const (symbol_ref "pragma_interrupt")))
550
551 (define_attr "in_delay_slot" "yes,no"
552 (cond [(eq_attr "type" "cbranch") (const_string "no")
553 (eq_attr "type" "pcload,pcload_si") (const_string "no")
554 (eq_attr "needs_delay_slot" "yes") (const_string "no")
555 (eq_attr "length" "2") (const_string "yes")
556 ] (const_string "no")))
557
558 (define_attr "is_sfunc" ""
559 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
560
561 (define_delay
562 (eq_attr "needs_delay_slot" "yes")
563 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
564
565 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
566 ;; and thus we can't put a pop instruction in its delay slot.
567 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
568 ;; instruction can go in the delay slot.
569
570 ;; Since a normal return (rts) implicitly uses the PR register,
571 ;; we can't allow PR register loads in an rts delay slot.
572
573 (define_delay
574 (eq_attr "type" "return")
575 [(and (eq_attr "in_delay_slot" "yes")
576 (ior (and (eq_attr "interrupt_function" "no")
577 (eq_attr "type" "!pload,prset"))
578 (and (eq_attr "interrupt_function" "yes")
579 (eq_attr "hit_stack" "no")))) (nil) (nil)])
580
581 ;; Since a call implicitly uses the PR register, we can't allow
582 ;; a PR register store in a jsr delay slot.
583
584 (define_delay
585 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
586 [(and (eq_attr "in_delay_slot" "yes")
587 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
588
589 ;; Say that we have annulled true branches, since this gives smaller and
590 ;; faster code when branches are predicted as not taken.
591
592 (define_delay
593 (and (eq_attr "type" "cbranch")
594 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
595 [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
596 \f
597 ;; -------------------------------------------------------------------------
598 ;; SImode signed integer comparisons
599 ;; -------------------------------------------------------------------------
600
601 (define_insn ""
602 [(set (reg:SI T_REG)
603 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
604 (match_operand:SI 1 "arith_operand" "L,r"))
605 (const_int 0)))]
606 ""
607 "tst %1,%0")
608
609 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
610 ;; That would still allow reload to create cmpi instructions, but would
611 ;; perhaps allow forcing the constant into a register when that is better.
612 ;; Probably should use r0 for mem/imm compares, but force constant into a
613 ;; register for pseudo/imm compares.
614
615 (define_insn "cmpeqsi_t"
616 [(set (reg:SI T_REG)
617 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
618 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
619 ""
620 "@
621 tst %0,%0
622 cmp/eq %1,%0
623 cmp/eq %1,%0")
624
625 (define_insn "cmpgtsi_t"
626 [(set (reg:SI T_REG)
627 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
628 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
629 ""
630 "@
631 cmp/gt %1,%0
632 cmp/pl %0")
633
634 (define_insn "cmpgesi_t"
635 [(set (reg:SI T_REG)
636 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
637 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
638 ""
639 "@
640 cmp/ge %1,%0
641 cmp/pz %0")
642 \f
643 ;; -------------------------------------------------------------------------
644 ;; SImode unsigned integer comparisons
645 ;; -------------------------------------------------------------------------
646
647 (define_insn "cmpgeusi_t"
648 [(set (reg:SI T_REG)
649 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
650 (match_operand:SI 1 "arith_reg_operand" "r")))]
651 ""
652 "cmp/hs %1,%0")
653
654 (define_insn "cmpgtusi_t"
655 [(set (reg:SI T_REG)
656 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
657 (match_operand:SI 1 "arith_reg_operand" "r")))]
658 ""
659 "cmp/hi %1,%0")
660
661 ;; We save the compare operands in the cmpxx patterns and use them when
662 ;; we generate the branch.
663
664 (define_expand "cmpsi"
665 [(set (reg:SI T_REG)
666 (compare (match_operand:SI 0 "arith_operand" "")
667 (match_operand:SI 1 "arith_operand" "")))]
668 ""
669 "
670 {
671 sh_compare_op0 = operands[0];
672 sh_compare_op1 = operands[1];
673 DONE;
674 }")
675 \f
676 ;; -------------------------------------------------------------------------
677 ;; DImode signed integer comparisons
678 ;; -------------------------------------------------------------------------
679
680 ;; ??? Could get better scheduling by splitting the initial test from the
681 ;; rest of the insn after reload. However, the gain would hardly justify
682 ;; the sh.md size increase necessary to do that.
683
684 (define_insn ""
685 [(set (reg:SI T_REG)
686 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
687 (match_operand:DI 1 "arith_operand" "r"))
688 (const_int 0)))]
689 ""
690 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
691 insn, operands);"
692 [(set_attr "length" "6")
693 (set_attr "type" "arith3b")])
694
695 (define_insn "cmpeqdi_t"
696 [(set (reg:SI T_REG)
697 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
698 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
699 ""
700 "@
701 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
702 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
703 [(set_attr "length" "6")
704 (set_attr "type" "arith3b")])
705
706 (define_split
707 [(set (reg:SI T_REG)
708 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
709 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
710 ;; If we applied this split when not optimizing, it would only be
711 ;; applied during the machine-dependent reorg, when no new basic blocks
712 ;; may be created.
713 "reload_completed && optimize"
714 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
715 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
716 (label_ref (match_dup 6))
717 (pc)))
718 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
719 (match_dup 6)]
720 "
721 {
722 operands[2]
723 = gen_rtx_REG (SImode,
724 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
725 operands[3]
726 = (operands[1] == const0_rtx
727 ? const0_rtx
728 : gen_rtx_REG (SImode,
729 true_regnum (operands[1])
730 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
731 operands[4] = gen_lowpart (SImode, operands[0]);
732 operands[5] = gen_lowpart (SImode, operands[1]);
733 operands[6] = gen_label_rtx ();
734 }")
735
736 (define_insn "cmpgtdi_t"
737 [(set (reg:SI T_REG)
738 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
739 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
740 "TARGET_SH2"
741 "@
742 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
743 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
744 [(set_attr "length" "8")
745 (set_attr "type" "arith3")])
746
747 (define_insn "cmpgedi_t"
748 [(set (reg:SI T_REG)
749 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
750 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
751 "TARGET_SH2"
752 "@
753 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
754 cmp/pz\\t%S0"
755 [(set_attr "length" "8,2")
756 (set_attr "type" "arith3,arith")])
757 \f
758 ;; -------------------------------------------------------------------------
759 ;; DImode unsigned integer comparisons
760 ;; -------------------------------------------------------------------------
761
762 (define_insn "cmpgeudi_t"
763 [(set (reg:SI T_REG)
764 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
765 (match_operand:DI 1 "arith_reg_operand" "r")))]
766 "TARGET_SH2"
767 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
768 [(set_attr "length" "8")
769 (set_attr "type" "arith3")])
770
771 (define_insn "cmpgtudi_t"
772 [(set (reg:SI T_REG)
773 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
774 (match_operand:DI 1 "arith_reg_operand" "r")))]
775 "TARGET_SH2"
776 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
777 [(set_attr "length" "8")
778 (set_attr "type" "arith3")])
779
780 ;; We save the compare operands in the cmpxx patterns and use them when
781 ;; we generate the branch.
782
783 (define_expand "cmpdi"
784 [(set (reg:SI T_REG)
785 (compare (match_operand:DI 0 "arith_operand" "")
786 (match_operand:DI 1 "arith_operand" "")))]
787 "TARGET_SH2"
788 "
789 {
790 sh_compare_op0 = operands[0];
791 sh_compare_op1 = operands[1];
792 DONE;
793 }")
794 \f
795 ;; -------------------------------------------------------------------------
796 ;; Addition instructions
797 ;; -------------------------------------------------------------------------
798
799 ;; ??? This should be a define expand.
800
801 (define_insn "adddi3"
802 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
803 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
804 (match_operand:DI 2 "arith_reg_operand" "r")))
805 (clobber (reg:SI T_REG))]
806 ""
807 "#"
808 [(set_attr "length" "6")])
809
810 (define_split
811 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
812 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
813 (match_operand:DI 2 "arith_reg_operand" "r")))
814 (clobber (reg:SI T_REG))]
815 "reload_completed"
816 [(const_int 0)]
817 "
818 {
819 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
820 high0 = gen_rtx_REG (SImode,
821 true_regnum (operands[0])
822 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
823 high2 = gen_rtx_REG (SImode,
824 true_regnum (operands[2])
825 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
826 emit_insn (gen_clrt ());
827 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
828 emit_insn (gen_addc1 (high0, high0, high2));
829 DONE;
830 }")
831
832 (define_insn "addc"
833 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
834 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
835 (match_operand:SI 2 "arith_reg_operand" "r"))
836 (reg:SI T_REG)))
837 (set (reg:SI T_REG)
838 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
839 ""
840 "addc %2,%0"
841 [(set_attr "type" "arith")])
842
843 (define_insn "addc1"
844 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
845 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
846 (match_operand:SI 2 "arith_reg_operand" "r"))
847 (reg:SI T_REG)))
848 (clobber (reg:SI T_REG))]
849 ""
850 "addc %2,%0"
851 [(set_attr "type" "arith")])
852
853 (define_insn "addsi3"
854 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
855 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
856 (match_operand:SI 2 "arith_operand" "rI")))]
857 ""
858 "add %2,%0"
859 [(set_attr "type" "arith")])
860 \f
861 ;; -------------------------------------------------------------------------
862 ;; Subtraction instructions
863 ;; -------------------------------------------------------------------------
864
865 ;; ??? This should be a define expand.
866
867 (define_insn "subdi3"
868 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
869 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
870 (match_operand:DI 2 "arith_reg_operand" "r")))
871 (clobber (reg:SI T_REG))]
872 ""
873 "#"
874 [(set_attr "length" "6")])
875
876 (define_split
877 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
878 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
879 (match_operand:DI 2 "arith_reg_operand" "r")))
880 (clobber (reg:SI T_REG))]
881 "reload_completed"
882 [(const_int 0)]
883 "
884 {
885 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
886 high0 = gen_rtx_REG (SImode,
887 true_regnum (operands[0])
888 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
889 high2 = gen_rtx_REG (SImode,
890 true_regnum (operands[2])
891 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
892 emit_insn (gen_clrt ());
893 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
894 emit_insn (gen_subc1 (high0, high0, high2));
895 DONE;
896 }")
897
898 (define_insn "subc"
899 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
900 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
901 (match_operand:SI 2 "arith_reg_operand" "r"))
902 (reg:SI T_REG)))
903 (set (reg:SI T_REG)
904 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
905 ""
906 "subc %2,%0"
907 [(set_attr "type" "arith")])
908
909 (define_insn "subc1"
910 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
911 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
912 (match_operand:SI 2 "arith_reg_operand" "r"))
913 (reg:SI T_REG)))
914 (clobber (reg:SI T_REG))]
915 ""
916 "subc %2,%0"
917 [(set_attr "type" "arith")])
918
919 (define_insn "*subsi3_internal"
920 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
921 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
922 (match_operand:SI 2 "arith_reg_operand" "r")))]
923 ""
924 "sub %2,%0"
925 [(set_attr "type" "arith")])
926
927 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
928 ;; will sometimes save one instruction. Otherwise we might get
929 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
930 ;; are the same.
931
932 (define_expand "subsi3"
933 [(set (match_operand:SI 0 "arith_reg_operand" "")
934 (minus:SI (match_operand:SI 1 "arith_operand" "")
935 (match_operand:SI 2 "arith_reg_operand" "")))]
936 ""
937 "
938 {
939 if (GET_CODE (operands[1]) == CONST_INT)
940 {
941 emit_insn (gen_negsi2 (operands[0], operands[2]));
942 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
943 DONE;
944 }
945 }")
946 \f
947 ;; -------------------------------------------------------------------------
948 ;; Division instructions
949 ;; -------------------------------------------------------------------------
950
951 ;; We take advantage of the library routines which don't clobber as many
952 ;; registers as a normal function call would.
953
954 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
955 ;; also has an effect on the register that holds the address of the sfunc.
956 ;; To make this work, we have an extra dummy insns that shows the use
957 ;; of this register for reorg.
958
959 (define_insn "use_sfunc_addr"
960 [(set (reg:SI PR_REG)
961 (unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
962 ""
963 ""
964 [(set_attr "length" "0")])
965
966 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
967 ;; hard register 0. If we used hard register 0, then the next instruction
968 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
969 ;; gets allocated to a stack slot that needs its address reloaded, then
970 ;; there is nothing to prevent reload from using r0 to reload the address.
971 ;; This reload would clobber the value in r0 we are trying to store.
972 ;; If we let reload allocate r0, then this problem can never happen.
973
974 (define_insn "udivsi3_i1"
975 [(set (match_operand:SI 0 "register_operand" "=z")
976 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
977 (clobber (reg:SI T_REG))
978 (clobber (reg:SI PR_REG))
979 (clobber (reg:SI R4_REG))
980 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
981 "! TARGET_SH4"
982 "jsr @%1%#"
983 [(set_attr "type" "sfunc")
984 (set_attr "needs_delay_slot" "yes")])
985
986 (define_insn "udivsi3_i4"
987 [(set (match_operand:SI 0 "register_operand" "=y")
988 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
989 (clobber (reg:SI T_REG))
990 (clobber (reg:SI PR_REG))
991 (clobber (reg:DF DR0_REG))
992 (clobber (reg:DF DR2_REG))
993 (clobber (reg:DF DR4_REG))
994 (clobber (reg:SI R0_REG))
995 (clobber (reg:SI R1_REG))
996 (clobber (reg:SI R4_REG))
997 (clobber (reg:SI R5_REG))
998 (use (reg:PSI FPSCR_REG))
999 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1000 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1001 "jsr @%1%#"
1002 [(set_attr "type" "sfunc")
1003 (set_attr "fp_mode" "double")
1004 (set_attr "needs_delay_slot" "yes")])
1005
1006 (define_insn "udivsi3_i4_single"
1007 [(set (match_operand:SI 0 "register_operand" "=y")
1008 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1009 (clobber (reg:SI T_REG))
1010 (clobber (reg:SI PR_REG))
1011 (clobber (reg:DF DR0_REG))
1012 (clobber (reg:DF DR2_REG))
1013 (clobber (reg:DF DR4_REG))
1014 (clobber (reg:SI R0_REG))
1015 (clobber (reg:SI R1_REG))
1016 (clobber (reg:SI R4_REG))
1017 (clobber (reg:SI R5_REG))
1018 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1019 "TARGET_HARD_SH4 && TARGET_FPU_SINGLE"
1020 "jsr @%1%#"
1021 [(set_attr "type" "sfunc")
1022 (set_attr "needs_delay_slot" "yes")])
1023
1024 (define_expand "udivsi3"
1025 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1026 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1027 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1028 (parallel [(set (match_operand:SI 0 "register_operand" "")
1029 (udiv:SI (reg:SI R4_REG)
1030 (reg:SI R5_REG)))
1031 (clobber (reg:SI T_REG))
1032 (clobber (reg:SI PR_REG))
1033 (clobber (reg:SI R4_REG))
1034 (use (match_dup 3))])]
1035 ""
1036 "
1037 {
1038 rtx first, last;
1039
1040 operands[3] = gen_reg_rtx(SImode);
1041 /* Emit the move of the address to a pseudo outside of the libcall. */
1042 if (TARGET_HARD_SH4 && TARGET_SH3E)
1043 {
1044 emit_move_insn (operands[3],
1045 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1046 if (TARGET_FPU_SINGLE)
1047 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1048 else
1049 last = gen_udivsi3_i4 (operands[0], operands[3]);
1050 }
1051 else
1052 {
1053 emit_move_insn (operands[3],
1054 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1055 last = gen_udivsi3_i1 (operands[0], operands[3]);
1056 }
1057 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1058 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1059 last = emit_insn (last);
1060 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1061 invariant code motion can move it. */
1062 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1063 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1064 DONE;
1065 }")
1066
1067 (define_insn "divsi3_i1"
1068 [(set (match_operand:SI 0 "register_operand" "=z")
1069 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1070 (clobber (reg:SI T_REG))
1071 (clobber (reg:SI PR_REG))
1072 (clobber (reg:SI R1_REG))
1073 (clobber (reg:SI R2_REG))
1074 (clobber (reg:SI R3_REG))
1075 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1076 "! TARGET_SH4"
1077 "jsr @%1%#"
1078 [(set_attr "type" "sfunc")
1079 (set_attr "needs_delay_slot" "yes")])
1080
1081 (define_insn "divsi3_i4"
1082 [(set (match_operand:SI 0 "register_operand" "=y")
1083 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1084 (clobber (reg:SI PR_REG))
1085 (clobber (reg:DF DR0_REG))
1086 (clobber (reg:DF DR2_REG))
1087 (use (reg:PSI FPSCR_REG))
1088 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1089 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1090 "jsr @%1%#"
1091 [(set_attr "type" "sfunc")
1092 (set_attr "fp_mode" "double")
1093 (set_attr "needs_delay_slot" "yes")])
1094
1095 (define_insn "divsi3_i4_single"
1096 [(set (match_operand:SI 0 "register_operand" "=y")
1097 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1098 (clobber (reg:SI PR_REG))
1099 (clobber (reg:DF DR0_REG))
1100 (clobber (reg:DF DR2_REG))
1101 (clobber (reg:SI R2_REG))
1102 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1103 "TARGET_HARD_SH4 && TARGET_FPU_SINGLE"
1104 "jsr @%1%#"
1105 [(set_attr "type" "sfunc")
1106 (set_attr "needs_delay_slot" "yes")])
1107
1108 (define_expand "divsi3"
1109 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1110 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1111 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1112 (parallel [(set (match_operand:SI 0 "register_operand" "")
1113 (div:SI (reg:SI R4_REG)
1114 (reg:SI R5_REG)))
1115 (clobber (reg:SI T_REG))
1116 (clobber (reg:SI PR_REG))
1117 (clobber (reg:SI R1_REG))
1118 (clobber (reg:SI R2_REG))
1119 (clobber (reg:SI R3_REG))
1120 (use (match_dup 3))])]
1121 ""
1122 "
1123 {
1124 rtx first, last;
1125
1126 operands[3] = gen_reg_rtx(SImode);
1127 /* Emit the move of the address to a pseudo outside of the libcall. */
1128 if (TARGET_HARD_SH4 && TARGET_SH3E)
1129 {
1130 emit_move_insn (operands[3],
1131 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1132 if (TARGET_FPU_SINGLE)
1133 last = gen_divsi3_i4_single (operands[0], operands[3]);
1134 else
1135 last = gen_divsi3_i4 (operands[0], operands[3]);
1136 }
1137 else
1138 {
1139 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1140 last = gen_divsi3_i1 (operands[0], operands[3]);
1141 }
1142 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1143 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1144 last = emit_insn (last);
1145 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1146 invariant code motion can move it. */
1147 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1148 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1149 DONE;
1150 }")
1151 \f
1152 ;; -------------------------------------------------------------------------
1153 ;; Multiplication instructions
1154 ;; -------------------------------------------------------------------------
1155
1156 (define_insn "umulhisi3_i"
1157 [(set (reg:SI MACL_REG)
1158 (mult:SI (zero_extend:SI
1159 (match_operand:HI 0 "arith_reg_operand" "r"))
1160 (zero_extend:SI
1161 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1162 ""
1163 "mulu.w %1,%0"
1164 [(set_attr "type" "smpy")])
1165
1166 (define_insn "mulhisi3_i"
1167 [(set (reg:SI MACL_REG)
1168 (mult:SI (sign_extend:SI
1169 (match_operand:HI 0 "arith_reg_operand" "r"))
1170 (sign_extend:SI
1171 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1172 ""
1173 "muls.w %1,%0"
1174 [(set_attr "type" "smpy")])
1175
1176 (define_expand "mulhisi3"
1177 [(set (reg:SI MACL_REG)
1178 (mult:SI (sign_extend:SI
1179 (match_operand:HI 1 "arith_reg_operand" ""))
1180 (sign_extend:SI
1181 (match_operand:HI 2 "arith_reg_operand" ""))))
1182 (set (match_operand:SI 0 "arith_reg_operand" "")
1183 (reg:SI MACL_REG))]
1184 ""
1185 "
1186 {
1187 rtx first, last;
1188
1189 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1190 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1191 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1192 invariant code motion can move it. */
1193 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1194 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1195 DONE;
1196 }")
1197
1198 (define_expand "umulhisi3"
1199 [(set (reg:SI MACL_REG)
1200 (mult:SI (zero_extend:SI
1201 (match_operand:HI 1 "arith_reg_operand" ""))
1202 (zero_extend:SI
1203 (match_operand:HI 2 "arith_reg_operand" ""))))
1204 (set (match_operand:SI 0 "arith_reg_operand" "")
1205 (reg:SI MACL_REG))]
1206 ""
1207 "
1208 {
1209 rtx first, last;
1210
1211 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1212 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1213 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1214 invariant code motion can move it. */
1215 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1216 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1217 DONE;
1218 }")
1219
1220 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1221 ;; a call to a routine which clobbers known registers.
1222
1223 (define_insn ""
1224 [(set (match_operand:SI 1 "register_operand" "=z")
1225 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1226 (clobber (reg:SI MACL_REG))
1227 (clobber (reg:SI T_REG))
1228 (clobber (reg:SI PR_REG))
1229 (clobber (reg:SI R3_REG))
1230 (clobber (reg:SI R2_REG))
1231 (clobber (reg:SI R1_REG))
1232 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1233 ""
1234 "jsr @%0%#"
1235 [(set_attr "type" "sfunc")
1236 (set_attr "needs_delay_slot" "yes")])
1237
1238 (define_expand "mulsi3_call"
1239 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1240 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1241 (parallel[(set (match_operand:SI 0 "register_operand" "")
1242 (mult:SI (reg:SI R4_REG)
1243 (reg:SI R5_REG)))
1244 (clobber (reg:SI MACL_REG))
1245 (clobber (reg:SI T_REG))
1246 (clobber (reg:SI PR_REG))
1247 (clobber (reg:SI R3_REG))
1248 (clobber (reg:SI R2_REG))
1249 (clobber (reg:SI R1_REG))
1250 (use (match_operand:SI 3 "register_operand" ""))])]
1251 ""
1252 "")
1253
1254 (define_insn "mul_l"
1255 [(set (reg:SI MACL_REG)
1256 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1257 (match_operand:SI 1 "arith_reg_operand" "r")))]
1258 "TARGET_SH2"
1259 "mul.l %1,%0"
1260 [(set_attr "type" "dmpy")])
1261
1262 (define_expand "mulsi3"
1263 [(set (reg:SI MACL_REG)
1264 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1265 (match_operand:SI 2 "arith_reg_operand" "")))
1266 (set (match_operand:SI 0 "arith_reg_operand" "")
1267 (reg:SI MACL_REG))]
1268 ""
1269 "
1270 {
1271 rtx first, last;
1272
1273 if (!TARGET_SH2)
1274 {
1275 /* The address must be set outside the libcall,
1276 since it goes into a pseudo. */
1277 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1278 rtx addr = force_reg (SImode, sym);
1279 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1280 operands[2], addr);
1281 first = XVECEXP (insns, 0, 0);
1282 last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
1283 emit_insn (insns);
1284 }
1285 else
1286 {
1287 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1288
1289 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1290 /* consec_sets_giv can only recognize the first insn that sets a
1291 giv as the giv insn. So we must tag this also with a REG_EQUAL
1292 note. */
1293 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1294 }
1295 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1296 invariant code motion can move it. */
1297 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1298 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1299 DONE;
1300 }")
1301
1302 (define_insn "mulsidi3_i"
1303 [(set (reg:SI MACH_REG)
1304 (truncate:SI
1305 (lshiftrt:DI
1306 (mult:DI
1307 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1308 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1309 (const_int 32))))
1310 (set (reg:SI MACL_REG)
1311 (mult:SI (match_dup 0)
1312 (match_dup 1)))]
1313 "TARGET_SH2"
1314 "dmuls.l %1,%0"
1315 [(set_attr "type" "dmpy")])
1316
1317 (define_insn "mulsidi3"
1318 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1319 (mult:DI
1320 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1321 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1322 (clobber (reg:SI MACH_REG))
1323 (clobber (reg:SI MACL_REG))]
1324 "TARGET_SH2"
1325 "#")
1326
1327 (define_split
1328 [(set (match_operand:DI 0 "arith_reg_operand" "")
1329 (mult:DI
1330 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1331 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1332 (clobber (reg:SI MACH_REG))
1333 (clobber (reg:SI MACL_REG))]
1334 "TARGET_SH2"
1335 [(const_int 0)]
1336 "
1337 {
1338 rtx low_dst = gen_lowpart (SImode, operands[0]);
1339 rtx high_dst = gen_highpart (SImode, operands[0]);
1340
1341 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1342
1343 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1344 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1345 /* We need something to tag the possible REG_EQUAL notes on to. */
1346 emit_move_insn (operands[0], operands[0]);
1347 DONE;
1348 }")
1349
1350 (define_insn "umulsidi3_i"
1351 [(set (reg:SI MACH_REG)
1352 (truncate:SI
1353 (lshiftrt:DI
1354 (mult:DI
1355 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1356 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1357 (const_int 32))))
1358 (set (reg:SI MACL_REG)
1359 (mult:SI (match_dup 0)
1360 (match_dup 1)))]
1361 "TARGET_SH2"
1362 "dmulu.l %1,%0"
1363 [(set_attr "type" "dmpy")])
1364
1365 (define_insn "umulsidi3"
1366 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1367 (mult:DI
1368 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1369 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1370 (clobber (reg:SI MACH_REG))
1371 (clobber (reg:SI MACL_REG))]
1372 "TARGET_SH2"
1373 "#")
1374
1375 (define_split
1376 [(set (match_operand:DI 0 "arith_reg_operand" "")
1377 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1378 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1379 (clobber (reg:SI MACH_REG))
1380 (clobber (reg:SI MACL_REG))]
1381 "TARGET_SH2"
1382 [(const_int 0)]
1383 "
1384 {
1385 rtx low_dst = gen_lowpart (SImode, operands[0]);
1386 rtx high_dst = gen_highpart (SImode, operands[0]);
1387
1388 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1389
1390 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1391 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1392 /* We need something to tag the possible REG_EQUAL notes on to. */
1393 emit_move_insn (operands[0], operands[0]);
1394 DONE;
1395 }")
1396
1397 (define_insn "smulsi3_highpart_i"
1398 [(set (reg:SI MACH_REG)
1399 (truncate:SI
1400 (lshiftrt:DI
1401 (mult:DI
1402 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1403 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1404 (const_int 32))))
1405 (clobber (reg:SI MACL_REG))]
1406 "TARGET_SH2"
1407 "dmuls.l %1,%0"
1408 [(set_attr "type" "dmpy")])
1409
1410 (define_expand "smulsi3_highpart"
1411 [(parallel
1412 [(set (reg:SI MACH_REG)
1413 (truncate:SI
1414 (lshiftrt:DI
1415 (mult:DI
1416 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1417 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1418 (const_int 32))))
1419 (clobber (reg:SI MACL_REG))])
1420 (set (match_operand:SI 0 "arith_reg_operand" "")
1421 (reg:SI MACH_REG))]
1422 "TARGET_SH2"
1423 "
1424 {
1425 rtx first, last;
1426
1427 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1428 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1429 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1430 invariant code motion can move it. */
1431 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1432 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1433 /* expand_binop can't find a suitable code in mul_highpart_optab to
1434 make a REG_EQUAL note from, so make one here.
1435 ??? Alternatively, we could put this at the calling site of expand_binop,
1436 i.e. expand_mult_highpart. */
1437 REG_NOTES (last)
1438 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1439 REG_NOTES (last));
1440 DONE;
1441 }")
1442
1443 (define_insn "umulsi3_highpart_i"
1444 [(set (reg:SI MACH_REG)
1445 (truncate:SI
1446 (lshiftrt:DI
1447 (mult:DI
1448 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1449 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1450 (const_int 32))))
1451 (clobber (reg:SI MACL_REG))]
1452 "TARGET_SH2"
1453 "dmulu.l %1,%0"
1454 [(set_attr "type" "dmpy")])
1455
1456 (define_expand "umulsi3_highpart"
1457 [(parallel
1458 [(set (reg:SI MACH_REG)
1459 (truncate:SI
1460 (lshiftrt:DI
1461 (mult:DI
1462 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1463 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1464 (const_int 32))))
1465 (clobber (reg:SI MACL_REG))])
1466 (set (match_operand:SI 0 "arith_reg_operand" "")
1467 (reg:SI MACH_REG))]
1468 "TARGET_SH2"
1469 "
1470 {
1471 rtx first, last;
1472
1473 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1474 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1475 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1476 invariant code motion can move it. */
1477 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1478 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1479 DONE;
1480 }")
1481 \f
1482 ;; -------------------------------------------------------------------------
1483 ;; Logical operations
1484 ;; -------------------------------------------------------------------------
1485
1486 (define_insn ""
1487 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1488 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1489 (match_operand:SI 2 "logical_operand" "r,L")))]
1490 ""
1491 "and %2,%0"
1492 [(set_attr "type" "arith")])
1493
1494 ;; If the constant is 255, then emit a extu.b instruction instead of an
1495 ;; and, since that will give better code.
1496
1497 (define_expand "andsi3"
1498 [(set (match_operand:SI 0 "arith_reg_operand" "")
1499 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1500 (match_operand:SI 2 "logical_operand" "")))]
1501 ""
1502 "
1503 {
1504 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1505 {
1506 emit_insn (gen_zero_extendqisi2 (operands[0],
1507 gen_lowpart (QImode, operands[1])));
1508 DONE;
1509 }
1510 }")
1511
1512 (define_insn "iorsi3"
1513 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1514 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1515 (match_operand:SI 2 "logical_operand" "r,L")))]
1516 ""
1517 "or %2,%0"
1518 [(set_attr "type" "arith")])
1519
1520 (define_insn "xorsi3"
1521 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1522 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1523 (match_operand:SI 2 "logical_operand" "L,r")))]
1524 ""
1525 "xor %2,%0"
1526 [(set_attr "type" "arith")])
1527 \f
1528 ;; -------------------------------------------------------------------------
1529 ;; Shifts and rotates
1530 ;; -------------------------------------------------------------------------
1531
1532 (define_insn "rotlsi3_1"
1533 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1534 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
1535 (const_int 1)))
1536 (set (reg:SI T_REG)
1537 (lshiftrt:SI (match_dup 1) (const_int 31)))]
1538 ""
1539 "rotl %0"
1540 [(set_attr "type" "arith")])
1541
1542 (define_insn "rotlsi3_31"
1543 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1544 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
1545 (const_int 31)))
1546 (clobber (reg:SI T_REG))]
1547 ""
1548 "rotr %0"
1549 [(set_attr "type" "arith")])
1550
1551 (define_insn "rotlsi3_16"
1552 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1553 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
1554 (const_int 16)))]
1555 ""
1556 "swap.w %1,%0"
1557 [(set_attr "type" "arith")])
1558
1559 (define_expand "rotlsi3"
1560 [(set (match_operand:SI 0 "arith_reg_operand" "")
1561 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
1562 (match_operand:SI 2 "immediate_operand" "")))]
1563 ""
1564 "
1565 {
1566 static char rot_tab[] = {
1567 000, 000, 000, 000, 000, 000, 010, 001,
1568 001, 001, 011, 013, 003, 003, 003, 003,
1569 003, 003, 003, 003, 003, 013, 012, 002,
1570 002, 002, 010, 000, 000, 000, 000, 000,
1571 };
1572
1573 int count, choice;
1574
1575 if (GET_CODE (operands[2]) != CONST_INT)
1576 FAIL;
1577 count = INTVAL (operands[2]);
1578 choice = rot_tab[count];
1579 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
1580 FAIL;
1581 choice &= 7;
1582 switch (choice)
1583 {
1584 case 0:
1585 emit_move_insn (operands[0], operands[1]);
1586 count -= (count & 16) * 2;
1587 break;
1588 case 3:
1589 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
1590 count -= 16;
1591 break;
1592 case 1:
1593 case 2:
1594 {
1595 rtx parts[2];
1596 parts[0] = gen_reg_rtx (SImode);
1597 parts[1] = gen_reg_rtx (SImode);
1598 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
1599 parts[choice-1] = operands[1];
1600 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
1601 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
1602 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
1603 count = (count & ~16) - 8;
1604 }
1605 }
1606
1607 for (; count > 0; count--)
1608 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
1609 for (; count < 0; count++)
1610 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
1611
1612 DONE;
1613 }")
1614
1615 (define_insn "*rotlhi3_8"
1616 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1617 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
1618 (const_int 8)))]
1619 ""
1620 "swap.b %1,%0"
1621 [(set_attr "type" "arith")])
1622
1623 (define_expand "rotlhi3"
1624 [(set (match_operand:HI 0 "arith_reg_operand" "")
1625 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
1626 (match_operand:HI 2 "immediate_operand" "")))]
1627 ""
1628 "
1629 {
1630 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1631 FAIL;
1632 }")
1633
1634 ;;
1635 ;; shift left
1636
1637 ;; This pattern is used by init_expmed for computing the costs of shift
1638 ;; insns.
1639
1640 (define_insn_and_split "ashlsi3_std"
1641 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
1642 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
1643 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
1644 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
1645 "TARGET_SH3
1646 || (GET_CODE (operands[2]) == CONST_INT
1647 && CONST_OK_FOR_K (INTVAL (operands[2])))"
1648 "@
1649 shld %2,%0
1650 add %0,%0
1651 shll%O2 %0
1652 #"
1653 "TARGET_SH3
1654 && GET_CODE (operands[2]) == CONST_INT
1655 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
1656 [(set (match_dup 3) (match_dup 2))
1657 (parallel
1658 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
1659 (clobber (match_dup 4))])]
1660 "operands[4] = gen_rtx_SCRATCH (SImode);"
1661 [(set_attr "length" "*,*,*,4")
1662 (set_attr "type" "dyn_shift,arith,arith,arith")])
1663
1664 (define_insn "ashlhi3_k"
1665 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
1666 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
1667 (match_operand:HI 2 "const_int_operand" "M,K")))]
1668 "CONST_OK_FOR_K (INTVAL (operands[2]))"
1669 "@
1670 add %0,%0
1671 shll%O2 %0"
1672 [(set_attr "type" "arith")])
1673
1674 (define_insn "ashlsi3_n"
1675 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1676 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
1677 (match_operand:SI 2 "const_int_operand" "n")))
1678 (clobber (reg:SI T_REG))]
1679 "! sh_dynamicalize_shift_p (operands[2])"
1680 "#"
1681 [(set (attr "length")
1682 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1683 (const_string "2")
1684 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1685 (const_string "4")
1686 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
1687 (const_string "6")]
1688 (const_string "8")))
1689 (set_attr "type" "arith")])
1690
1691 (define_split
1692 [(set (match_operand:SI 0 "arith_reg_operand" "")
1693 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
1694 (match_operand:SI 2 "const_int_operand" "n")))
1695 (clobber (reg:SI T_REG))]
1696 ""
1697 [(use (reg:SI R0_REG))]
1698 "
1699 {
1700 gen_shifty_op (ASHIFT, operands);
1701 DONE;
1702 }")
1703
1704 (define_expand "ashlsi3"
1705 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1706 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
1707 (match_operand:SI 2 "nonmemory_operand" "")))
1708 (clobber (reg:SI T_REG))])]
1709 ""
1710 "
1711 {
1712 if (GET_CODE (operands[2]) == CONST_INT
1713 && sh_dynamicalize_shift_p (operands[2]))
1714 operands[2] = force_reg (SImode, operands[2]);
1715 if (TARGET_SH3)
1716 {
1717 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
1718 DONE;
1719 }
1720 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1721 FAIL;
1722 }")
1723
1724 (define_insn "ashlhi3"
1725 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1726 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
1727 (match_operand:HI 2 "const_int_operand" "n")))
1728 (clobber (reg:SI T_REG))]
1729 ""
1730 "#"
1731 [(set (attr "length")
1732 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1733 (const_string "2")
1734 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1735 (const_string "4")]
1736 (const_string "6")))
1737 (set_attr "type" "arith")])
1738
1739 (define_split
1740 [(set (match_operand:HI 0 "arith_reg_operand" "")
1741 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
1742 (match_operand:HI 2 "const_int_operand" "n")))
1743 (clobber (reg:SI T_REG))]
1744 ""
1745 [(use (reg:SI R0_REG))]
1746 "
1747 {
1748 gen_shifty_hi_op (ASHIFT, operands);
1749 DONE;
1750 }")
1751
1752 ;
1753 ; arithmetic shift right
1754 ;
1755
1756 (define_insn "ashrsi3_k"
1757 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1758 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1759 (match_operand:SI 2 "const_int_operand" "M")))
1760 (clobber (reg:SI T_REG))]
1761 "INTVAL (operands[2]) == 1"
1762 "shar %0"
1763 [(set_attr "type" "arith")])
1764
1765 ;; We can't do HImode right shifts correctly unless we start out with an
1766 ;; explicit zero / sign extension; doing that would result in worse overall
1767 ;; code, so just let the machine independent code widen the mode.
1768 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
1769
1770
1771 ;; ??? This should be a define expand.
1772
1773 (define_insn "ashrsi2_16"
1774 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1775 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
1776 (const_int 16)))]
1777 ""
1778 "#"
1779 [(set_attr "length" "4")])
1780
1781 (define_split
1782 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1783 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
1784 (const_int 16)))]
1785 ""
1786 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
1787 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
1788 "operands[2] = gen_lowpart (HImode, operands[0]);")
1789
1790 ;; ??? This should be a define expand.
1791
1792 (define_insn "ashrsi2_31"
1793 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1794 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1795 (const_int 31)))
1796 (clobber (reg:SI T_REG))]
1797 ""
1798 "#"
1799 [(set_attr "length" "4")])
1800
1801 (define_split
1802 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1803 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1804 (const_int 31)))
1805 (clobber (reg:SI T_REG))]
1806 ""
1807 [(const_int 0)]
1808 "
1809 {
1810 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
1811 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
1812 DONE;
1813 }")
1814
1815 (define_insn "ashlsi_c"
1816 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1817 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
1818 (set (reg:SI T_REG)
1819 (lt:SI (match_dup 1) (const_int 0)))]
1820 ""
1821 "shll %0"
1822 [(set_attr "type" "arith")])
1823
1824 (define_insn "ashrsi3_d"
1825 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1826 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1827 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1828 "TARGET_SH3"
1829 "shad %2,%0"
1830 [(set_attr "type" "dyn_shift")])
1831
1832 (define_insn "ashrsi3_n"
1833 [(set (reg:SI R4_REG)
1834 (ashiftrt:SI (reg:SI R4_REG)
1835 (match_operand:SI 0 "const_int_operand" "i")))
1836 (clobber (reg:SI T_REG))
1837 (clobber (reg:SI PR_REG))
1838 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1839 ""
1840 "jsr @%1%#"
1841 [(set_attr "type" "sfunc")
1842 (set_attr "needs_delay_slot" "yes")])
1843
1844 (define_expand "ashrsi3"
1845 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1846 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1847 (match_operand:SI 2 "nonmemory_operand" "")))
1848 (clobber (reg:SI T_REG))])]
1849 ""
1850 "if (expand_ashiftrt (operands)) DONE; else FAIL;")
1851
1852 ;; logical shift right
1853
1854 (define_insn "lshrsi3_d"
1855 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1856 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1857 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1858 "TARGET_SH3"
1859 "shld %2,%0"
1860 [(set_attr "type" "dyn_shift")])
1861
1862 ;; Only the single bit shift clobbers the T bit.
1863
1864 (define_insn "lshrsi3_m"
1865 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1866 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1867 (match_operand:SI 2 "const_int_operand" "M")))
1868 (clobber (reg:SI T_REG))]
1869 "CONST_OK_FOR_M (INTVAL (operands[2]))"
1870 "shlr %0"
1871 [(set_attr "type" "arith")])
1872
1873 (define_insn "lshrsi3_k"
1874 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1875 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1876 (match_operand:SI 2 "const_int_operand" "K")))]
1877 "CONST_OK_FOR_K (INTVAL (operands[2]))
1878 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1879 "shlr%O2 %0"
1880 [(set_attr "type" "arith")])
1881
1882 (define_insn "lshrsi3_n"
1883 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1884 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1885 (match_operand:SI 2 "const_int_operand" "n")))
1886 (clobber (reg:SI T_REG))]
1887 "! sh_dynamicalize_shift_p (operands[2])"
1888 "#"
1889 [(set (attr "length")
1890 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1891 (const_string "2")
1892 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1893 (const_string "4")
1894 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
1895 (const_string "6")]
1896 (const_string "8")))
1897 (set_attr "type" "arith")])
1898
1899 (define_split
1900 [(set (match_operand:SI 0 "arith_reg_operand" "")
1901 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1902 (match_operand:SI 2 "const_int_operand" "n")))
1903 (clobber (reg:SI T_REG))]
1904 ""
1905 [(use (reg:SI R0_REG))]
1906 "
1907 {
1908 gen_shifty_op (LSHIFTRT, operands);
1909 DONE;
1910 }")
1911
1912 (define_expand "lshrsi3"
1913 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1914 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1915 (match_operand:SI 2 "nonmemory_operand" "")))
1916 (clobber (reg:SI T_REG))])]
1917 ""
1918 "
1919 {
1920 if (GET_CODE (operands[2]) == CONST_INT
1921 && sh_dynamicalize_shift_p (operands[2]))
1922 operands[2] = force_reg (SImode, operands[2]);
1923 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
1924 {
1925 rtx count = copy_to_mode_reg (SImode, operands[2]);
1926 emit_insn (gen_negsi2 (count, count));
1927 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
1928 DONE;
1929 }
1930 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1931 FAIL;
1932 }")
1933
1934 ;; ??? This should be a define expand.
1935
1936 (define_insn "ashldi3_k"
1937 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1938 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
1939 (const_int 1)))
1940 (clobber (reg:SI T_REG))]
1941 ""
1942 "shll %R0\;rotcl %S0"
1943 [(set_attr "length" "4")
1944 (set_attr "type" "arith")])
1945
1946 (define_expand "ashldi3"
1947 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1948 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
1949 (match_operand:DI 2 "immediate_operand" "")))
1950 (clobber (reg:SI T_REG))])]
1951 ""
1952 "{ if (GET_CODE (operands[2]) != CONST_INT
1953 || INTVAL (operands[2]) != 1) FAIL;} ")
1954
1955 ;; ??? This should be a define expand.
1956
1957 (define_insn "lshrdi3_k"
1958 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1959 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
1960 (const_int 1)))
1961 (clobber (reg:SI T_REG))]
1962 ""
1963 "shlr %S0\;rotcr %R0"
1964 [(set_attr "length" "4")
1965 (set_attr "type" "arith")])
1966
1967 (define_expand "lshrdi3"
1968 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1969 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1970 (match_operand:DI 2 "immediate_operand" "")))
1971 (clobber (reg:SI T_REG))])]
1972 ""
1973 "{ if (GET_CODE (operands[2]) != CONST_INT
1974 || INTVAL (operands[2]) != 1) FAIL;} ")
1975
1976 ;; ??? This should be a define expand.
1977
1978 (define_insn "ashrdi3_k"
1979 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1980 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
1981 (const_int 1)))
1982 (clobber (reg:SI T_REG))]
1983 ""
1984 "shar %S0\;rotcr %R0"
1985 [(set_attr "length" "4")
1986 (set_attr "type" "arith")])
1987
1988 (define_expand "ashrdi3"
1989 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1990 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1991 (match_operand:DI 2 "immediate_operand" "")))
1992 (clobber (reg:SI T_REG))])]
1993 ""
1994 "{ if (GET_CODE (operands[2]) != CONST_INT
1995 || INTVAL (operands[2]) != 1) FAIL; } ")
1996
1997 ;; combined left/right shift
1998
1999 (define_split
2000 [(set (match_operand:SI 0 "register_operand" "")
2001 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2002 (match_operand:SI 2 "const_int_operand" "n"))
2003 (match_operand:SI 3 "const_int_operand" "n")))]
2004 "(unsigned)INTVAL (operands[2]) < 32"
2005 [(use (reg:SI R0_REG))]
2006 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2007 DONE;")
2008
2009 (define_split
2010 [(set (match_operand:SI 0 "register_operand" "")
2011 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2012 (match_operand:SI 2 "const_int_operand" "n"))
2013 (match_operand:SI 3 "const_int_operand" "n")))
2014 (clobber (reg:SI T_REG))]
2015 "(unsigned)INTVAL (operands[2]) < 32"
2016 [(use (reg:SI R0_REG))]
2017 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2018 DONE;")
2019
2020 (define_insn ""
2021 [(set (match_operand:SI 0 "register_operand" "=r")
2022 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2023 (match_operand:SI 2 "const_int_operand" "n"))
2024 (match_operand:SI 3 "const_int_operand" "n")))
2025 (clobber (reg:SI T_REG))]
2026 "shl_and_kind (operands[2], operands[3], 0) == 1"
2027 "#"
2028 [(set (attr "length")
2029 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2030 (const_string "4")
2031 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2032 (const_string "6")
2033 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2034 (const_string "8")
2035 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2036 (const_string "10")
2037 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2038 (const_string "12")
2039 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2040 (const_string "14")
2041 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2042 (const_string "16")]
2043 (const_string "18")))
2044 (set_attr "type" "arith")])
2045
2046 (define_insn ""
2047 [(set (match_operand:SI 0 "register_operand" "=z")
2048 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2049 (match_operand:SI 2 "const_int_operand" "n"))
2050 (match_operand:SI 3 "const_int_operand" "n")))
2051 (clobber (reg:SI T_REG))]
2052 "shl_and_kind (operands[2], operands[3], 0) == 2"
2053 "#"
2054 [(set (attr "length")
2055 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2056 (const_string "4")
2057 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2058 (const_string "6")
2059 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2060 (const_string "8")]
2061 (const_string "10")))
2062 (set_attr "type" "arith")])
2063
2064 ;; shift left / and combination with a scratch register: The combine pass
2065 ;; does not accept the individual instructions, even though they are
2066 ;; cheap. But it needs a precise description so that it is usable after
2067 ;; reload.
2068 (define_insn "and_shl_scratch"
2069 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2070 (lshiftrt:SI
2071 (ashift:SI
2072 (and:SI
2073 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2074 (match_operand:SI 2 "const_int_operand" "N,n"))
2075 (match_operand:SI 3 "" "0,r"))
2076 (match_operand:SI 4 "const_int_operand" "n,n"))
2077 (match_operand:SI 5 "const_int_operand" "n,n")))
2078 (clobber (reg:SI T_REG))]
2079 ""
2080 "#"
2081 [(set (attr "length")
2082 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2083 (const_string "4")
2084 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2085 (const_string "6")
2086 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2087 (const_string "8")
2088 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2089 (const_string "10")]
2090 (const_string "12")))
2091 (set_attr "type" "arith")])
2092
2093 (define_split
2094 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2095 (lshiftrt:SI
2096 (ashift:SI
2097 (and:SI
2098 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2099 (match_operand:SI 2 "const_int_operand" "N,n"))
2100 (match_operand:SI 3 "register_operand" "0,r"))
2101 (match_operand:SI 4 "const_int_operand" "n,n"))
2102 (match_operand:SI 5 "const_int_operand" "n,n")))
2103 (clobber (reg:SI T_REG))]
2104 ""
2105 [(use (reg:SI R0_REG))]
2106 "
2107 {
2108 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2109
2110 if (INTVAL (operands[2]))
2111 {
2112 gen_shifty_op (LSHIFTRT, operands);
2113 }
2114 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2115 operands[2] = operands[4];
2116 gen_shifty_op (ASHIFT, operands);
2117 if (INTVAL (operands[5]))
2118 {
2119 operands[2] = operands[5];
2120 gen_shifty_op (LSHIFTRT, operands);
2121 }
2122 DONE;
2123 }")
2124
2125 ;; signed left/right shift combination.
2126 (define_split
2127 [(set (match_operand:SI 0 "register_operand" "=r")
2128 (sign_extract:SI
2129 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2130 (match_operand:SI 2 "const_int_operand" "n"))
2131 (match_operand:SI 3 "const_int_operand" "n")
2132 (const_int 0)))
2133 (clobber (reg:SI T_REG))]
2134 ""
2135 [(use (reg:SI R0_REG))]
2136 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2137 DONE;")
2138
2139 (define_insn "shl_sext_ext"
2140 [(set (match_operand:SI 0 "register_operand" "=r")
2141 (sign_extract:SI
2142 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2143 (match_operand:SI 2 "const_int_operand" "n"))
2144 (match_operand:SI 3 "const_int_operand" "n")
2145 (const_int 0)))
2146 (clobber (reg:SI T_REG))]
2147 "(unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2148 "#"
2149 [(set (attr "length")
2150 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2151 (const_string "2")
2152 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2153 (const_string "4")
2154 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2155 (const_string "6")
2156 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2157 (const_string "8")
2158 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2159 (const_string "10")
2160 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2161 (const_string "12")
2162 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2163 (const_string "14")
2164 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2165 (const_string "16")]
2166 (const_string "18")))
2167 (set_attr "type" "arith")])
2168
2169 (define_insn "shl_sext_sub"
2170 [(set (match_operand:SI 0 "register_operand" "=z")
2171 (sign_extract:SI
2172 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2173 (match_operand:SI 2 "const_int_operand" "n"))
2174 (match_operand:SI 3 "const_int_operand" "n")
2175 (const_int 0)))
2176 (clobber (reg:SI T_REG))]
2177 "(shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2178 "#"
2179 [(set (attr "length")
2180 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2181 (const_string "6")
2182 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2183 (const_string "8")
2184 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2185 (const_string "10")
2186 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2187 (const_string "12")]
2188 (const_string "14")))
2189 (set_attr "type" "arith")])
2190
2191 ;; These patterns are found in expansions of DImode shifts by 16, and
2192 ;; allow the xtrct instruction to be generated from C source.
2193
2194 (define_insn "xtrct_left"
2195 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2196 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2197 (const_int 16))
2198 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2199 (const_int 16))))]
2200 ""
2201 "xtrct %1,%0"
2202 [(set_attr "type" "arith")])
2203
2204 (define_insn "xtrct_right"
2205 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2206 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2207 (const_int 16))
2208 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2209 (const_int 16))))]
2210 ""
2211 "xtrct %2,%0"
2212 [(set_attr "type" "arith")])
2213 \f
2214 ;; -------------------------------------------------------------------------
2215 ;; Unary arithmetic
2216 ;; -------------------------------------------------------------------------
2217
2218 (define_insn "negc"
2219 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2220 (neg:SI (plus:SI (reg:SI T_REG)
2221 (match_operand:SI 1 "arith_reg_operand" "r"))))
2222 (set (reg:SI T_REG)
2223 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2224 (const_int 0)))]
2225 ""
2226 "negc %1,%0"
2227 [(set_attr "type" "arith")])
2228
2229 (define_expand "negdi2"
2230 [(set (match_operand:DI 0 "arith_reg_operand" "")
2231 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
2232 (clobber (reg:SI T_REG))]
2233 ""
2234 "
2235 {
2236 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2237 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2238
2239 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2240 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2241
2242 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2243 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2244
2245 emit_insn (gen_clrt ());
2246 emit_insn (gen_negc (low_dst, low_src));
2247 emit_insn (gen_negc (high_dst, high_src));
2248 DONE;
2249 }")
2250
2251 (define_insn "negsi2"
2252 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2253 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2254 ""
2255 "neg %1,%0"
2256 [(set_attr "type" "arith")])
2257
2258 (define_insn "one_cmplsi2"
2259 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2260 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2261 ""
2262 "not %1,%0"
2263 [(set_attr "type" "arith")])
2264 \f
2265 ;; -------------------------------------------------------------------------
2266 ;; Zero extension instructions
2267 ;; -------------------------------------------------------------------------
2268
2269 (define_insn "zero_extendhisi2"
2270 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2271 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2272 ""
2273 "extu.w %1,%0"
2274 [(set_attr "type" "arith")])
2275
2276 (define_insn "zero_extendqisi2"
2277 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2278 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2279 ""
2280 "extu.b %1,%0"
2281 [(set_attr "type" "arith")])
2282
2283 (define_insn "zero_extendqihi2"
2284 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2285 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
2286 ""
2287 "extu.b %1,%0"
2288 [(set_attr "type" "arith")])
2289 \f
2290 ;; -------------------------------------------------------------------------
2291 ;; Sign extension instructions
2292 ;; -------------------------------------------------------------------------
2293
2294 ;; ??? This should be a define expand.
2295 ;; ??? Or perhaps it should be dropped?
2296
2297 /* There is no point in defining extendsidi2; convert_move generates good
2298 code for that. */
2299
2300 (define_insn "extendhisi2"
2301 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2302 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
2303 ""
2304 "@
2305 exts.w %1,%0
2306 mov.w %1,%0"
2307 [(set_attr "type" "arith,load")])
2308
2309 (define_insn "extendqisi2"
2310 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2311 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
2312 ""
2313 "@
2314 exts.b %1,%0
2315 mov.b %1,%0"
2316 [(set_attr "type" "arith,load")])
2317
2318 (define_insn "extendqihi2"
2319 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2320 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
2321 ""
2322 "@
2323 exts.b %1,%0
2324 mov.b %1,%0"
2325 [(set_attr "type" "arith,load")])
2326 \f
2327 ;; -------------------------------------------------------------------------
2328 ;; Move instructions
2329 ;; -------------------------------------------------------------------------
2330
2331 ;; define push and pop so it is easy for sh.c
2332
2333 (define_expand "push"
2334 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2335 (match_operand:SI 0 "register_operand" "r,l,x"))]
2336 ""
2337 "")
2338
2339 (define_expand "pop"
2340 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
2341 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
2342 ""
2343 "")
2344
2345 (define_expand "push_e"
2346 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
2347 (match_operand:SF 0 "" ""))
2348 (use (reg:PSI FPSCR_REG))
2349 (clobber (scratch:SI))])]
2350 ""
2351 "")
2352
2353 (define_insn "push_fpul"
2354 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
2355 "TARGET_SH3E"
2356 "sts.l fpul,@-r15"
2357 [(set_attr "type" "store")
2358 (set_attr "hit_stack" "yes")])
2359
2360 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
2361 ;; so use that.
2362 (define_expand "push_4"
2363 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
2364 (match_operand:DF 0 "" ""))
2365 (use (reg:PSI FPSCR_REG))
2366 (clobber (scratch:SI))])]
2367 ""
2368 "")
2369
2370 (define_expand "pop_e"
2371 [(parallel [(set (match_operand:SF 0 "" "")
2372 (mem:SF (post_inc:SI (reg:SI SP_REG))))
2373 (use (reg:PSI FPSCR_REG))
2374 (clobber (scratch:SI))])]
2375 ""
2376 "")
2377
2378 (define_insn "pop_fpul"
2379 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
2380 "TARGET_SH3E"
2381 "lds.l @r15+,fpul"
2382 [(set_attr "type" "load")
2383 (set_attr "hit_stack" "yes")])
2384
2385 (define_expand "pop_4"
2386 [(parallel [(set (match_operand:DF 0 "" "")
2387 (mem:DF (post_inc:SI (reg:SI SP_REG))))
2388 (use (reg:PSI FPSCR_REG))
2389 (clobber (scratch:SI))])]
2390 ""
2391 "")
2392
2393 ;; These two patterns can happen as the result of optimization, when
2394 ;; comparisons get simplified to a move of zero or 1 into the T reg.
2395 ;; They don't disappear completely, because the T reg is a fixed hard reg.
2396
2397 (define_insn "clrt"
2398 [(set (reg:SI T_REG) (const_int 0))]
2399 ""
2400 "clrt")
2401
2402 (define_insn "sett"
2403 [(set (reg:SI T_REG) (const_int 1))]
2404 ""
2405 "sett")
2406
2407 ;; t/r must come after r/r, lest reload will try to reload stuff like
2408 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
2409 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
2410 (define_insn "movsi_i"
2411 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
2412 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
2413 "
2414 ! TARGET_SH3E
2415 && (register_operand (operands[0], SImode)
2416 || register_operand (operands[1], SImode))"
2417 "@
2418 mov.l %1,%0
2419 mov %1,%0
2420 cmp/pl %1
2421 mov.l %1,%0
2422 sts %1,%0
2423 sts %1,%0
2424 movt %0
2425 mov.l %1,%0
2426 sts.l %1,%0
2427 sts.l %1,%0
2428 lds %1,%0
2429 lds %1,%0
2430 lds.l %1,%0
2431 lds.l %1,%0
2432 fake %1,%0"
2433 [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
2434 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
2435
2436 ;; t/r must come after r/r, lest reload will try to reload stuff like
2437 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
2438 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
2439 ;; will require a reload.
2440 (define_insn "movsi_ie"
2441 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,y")
2442 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
2443 "TARGET_SH3E
2444 && (register_operand (operands[0], SImode)
2445 || register_operand (operands[1], SImode))"
2446 "@
2447 mov.l %1,%0
2448 mov %1,%0
2449 cmp/pl %1
2450 mov.l %1,%0
2451 sts %1,%0
2452 sts %1,%0
2453 movt %0
2454 mov.l %1,%0
2455 sts.l %1,%0
2456 sts.l %1,%0
2457 lds %1,%0
2458 lds %1,%0
2459 lds.l %1,%0
2460 lds.l %1,%0
2461 lds.l %1,%0
2462 sts.l %1,%0
2463 fake %1,%0
2464 lds %1,%0
2465 sts %1,%0
2466 ! move optimized away"
2467 [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,gp_fpul,nil")
2468 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
2469
2470 (define_insn "movsi_i_lowpart"
2471 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
2472 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
2473 "register_operand (operands[0], SImode)
2474 || register_operand (operands[1], SImode)"
2475 "@
2476 mov.l %1,%0
2477 mov %1,%0
2478 mov.l %1,%0
2479 sts %1,%0
2480 sts %1,%0
2481 movt %0
2482 mov.l %1,%0
2483 fake %1,%0"
2484 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
2485
2486 (define_expand "movsi"
2487 [(set (match_operand:SI 0 "general_movdst_operand" "")
2488 (match_operand:SI 1 "general_movsrc_operand" ""))]
2489 ""
2490 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
2491
2492 (define_expand "ic_invalidate_line"
2493 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
2494 (match_dup 1)] UNSPEC_ICACHE)
2495 (clobber (scratch:SI))])]
2496 "TARGET_HARD_SH4"
2497 "
2498 {
2499 operands[0] = force_reg (Pmode, operands[0]);
2500 operands[1] = force_reg (Pmode, GEN_INT (0xf0000008));
2501 }")
2502
2503 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
2504 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
2505 ;; the requirement *1*00 for associative address writes. The alignment of
2506 ;; %0 implies that its least significant bit is cleared,
2507 ;; thus we clear the V bit of a matching entry if there is one.
2508 (define_insn "ic_invalidate_line_i"
2509 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
2510 (match_operand:SI 1 "register_operand" "r")]
2511 UNSPEC_ICACHE)
2512 (clobber (match_scratch:SI 2 "=&r"))]
2513 "TARGET_HARD_SH4"
2514 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
2515 [(set_attr "length" "8")])
2516
2517 (define_insn "movqi_i"
2518 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
2519 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
2520 "arith_reg_operand (operands[0], QImode)
2521 || arith_reg_operand (operands[1], QImode)"
2522 "@
2523 mov %1,%0
2524 mov.b %1,%0
2525 mov.b %1,%0
2526 movt %0
2527 sts %1,%0
2528 lds %1,%0"
2529 [(set_attr "type" "move,load,store,move,move,move")])
2530
2531 (define_expand "movqi"
2532 [(set (match_operand:QI 0 "general_operand" "")
2533 (match_operand:QI 1 "general_operand" ""))]
2534 ""
2535 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
2536
2537 (define_insn "movhi_i"
2538 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
2539 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
2540 "arith_reg_operand (operands[0], HImode)
2541 || arith_reg_operand (operands[1], HImode)"
2542 "@
2543 mov.w %1,%0
2544 mov %1,%0
2545 mov.w %1,%0
2546 movt %0
2547 mov.w %1,%0
2548 sts %1,%0
2549 lds %1,%0
2550 fake %1,%0"
2551 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
2552
2553 (define_expand "movhi"
2554 [(set (match_operand:HI 0 "general_movdst_operand" "")
2555 (match_operand:HI 1 "general_movsrc_operand" ""))]
2556 ""
2557 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
2558
2559 ;; ??? This should be a define expand.
2560
2561 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
2562 ;; compiled with -m2 -ml -O3 -funroll-loops
2563 (define_insn ""
2564 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
2565 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
2566 "arith_reg_operand (operands[0], DImode)
2567 || arith_reg_operand (operands[1], DImode)"
2568 "* return output_movedouble (insn, operands, DImode);"
2569 [(set_attr "length" "4")
2570 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
2571
2572 ;; If the output is a register and the input is memory or a register, we have
2573 ;; to be careful and see which word needs to be loaded first.
2574
2575 (define_split
2576 [(set (match_operand:DI 0 "general_movdst_operand" "")
2577 (match_operand:DI 1 "general_movsrc_operand" ""))]
2578 "reload_completed"
2579 [(set (match_dup 2) (match_dup 3))
2580 (set (match_dup 4) (match_dup 5))]
2581 "
2582 {
2583 int regno;
2584
2585 if ((GET_CODE (operands[0]) == MEM
2586 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2587 || (GET_CODE (operands[1]) == MEM
2588 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
2589 FAIL;
2590
2591 if (GET_CODE (operands[0]) == REG)
2592 regno = REGNO (operands[0]);
2593 else if (GET_CODE (operands[0]) == SUBREG)
2594 regno = subreg_regno (operands[0]);
2595 else if (GET_CODE (operands[0]) == MEM)
2596 regno = -1;
2597
2598 if (regno == -1
2599 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
2600 {
2601 operands[2] = operand_subword (operands[0], 0, 0, DImode);
2602 operands[3] = operand_subword (operands[1], 0, 0, DImode);
2603 operands[4] = operand_subword (operands[0], 1, 0, DImode);
2604 operands[5] = operand_subword (operands[1], 1, 0, DImode);
2605 }
2606 else
2607 {
2608 operands[2] = operand_subword (operands[0], 1, 0, DImode);
2609 operands[3] = operand_subword (operands[1], 1, 0, DImode);
2610 operands[4] = operand_subword (operands[0], 0, 0, DImode);
2611 operands[5] = operand_subword (operands[1], 0, 0, DImode);
2612 }
2613
2614 if (operands[2] == 0 || operands[3] == 0
2615 || operands[4] == 0 || operands[5] == 0)
2616 FAIL;
2617 }")
2618
2619 (define_expand "movdi"
2620 [(set (match_operand:DI 0 "general_movdst_operand" "")
2621 (match_operand:DI 1 "general_movsrc_operand" ""))]
2622 ""
2623 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
2624
2625 ;; ??? This should be a define expand.
2626
2627 (define_insn "movdf_k"
2628 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
2629 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
2630 "(! TARGET_SH4 || reload_completed
2631 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
2632 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
2633 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
2634 && (arith_reg_operand (operands[0], DFmode)
2635 || arith_reg_operand (operands[1], DFmode))"
2636 "* return output_movedouble (insn, operands, DFmode);"
2637 [(set_attr "length" "4")
2638 (set_attr "type" "move,pcload,load,store")])
2639
2640 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
2641 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
2642 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
2643 ;; the d/m/c/X alternative, which is split later into single-precision
2644 ;; instructions. And when not optimizing, no splits are done before fixing
2645 ;; up pcloads, so we need usable length information for that.
2646 (define_insn "movdf_i4"
2647 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
2648 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
2649 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
2650 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
2651 "TARGET_SH4
2652 && (arith_reg_operand (operands[0], DFmode)
2653 || arith_reg_operand (operands[1], DFmode))"
2654 "@
2655 fmov %1,%0
2656 #
2657 #
2658 fmov.d %1,%0
2659 fmov.d %1,%0
2660 #
2661 #
2662 #
2663 #
2664 #"
2665 [(set_attr_alternative "length"
2666 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
2667 (const_int 4)
2668 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
2669 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
2670 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
2671 (const_int 4)
2672 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
2673 (const_int 8) (const_int 8)])
2674 (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
2675 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
2676 (const_string "double")
2677 (const_string "none")))])
2678
2679 ;; Moving DFmode between fp/general registers through memory
2680 ;; (the top of the stack) is faster than moving through fpul even for
2681 ;; little endian. Because the type of an instruction is important for its
2682 ;; scheduling, it is beneficial to split these operations, rather than
2683 ;; emitting them in one single chunk, even if this will expose a stack
2684 ;; use that will prevent scheduling of other stack accesses beyond this
2685 ;; instruction.
2686 (define_split
2687 [(set (match_operand:DF 0 "register_operand" "")
2688 (match_operand:DF 1 "register_operand" ""))
2689 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2690 (clobber (match_scratch:SI 3 "=X"))]
2691 "TARGET_SH4 && reload_completed
2692 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
2693 [(const_int 0)]
2694 "
2695 {
2696 rtx insn, tos;
2697
2698 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
2699 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
2700 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
2701 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
2702 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
2703 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
2704 DONE;
2705 }")
2706
2707 ;; local-alloc sometimes allocates scratch registers even when not required,
2708 ;; so we must be prepared to handle these.
2709
2710 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
2711 (define_split
2712 [(set (match_operand:DF 0 "general_movdst_operand" "")
2713 (match_operand:DF 1 "general_movsrc_operand" ""))
2714 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2715 (clobber (match_scratch:SI 3 "X"))]
2716 "TARGET_SH4
2717 && reload_completed
2718 && true_regnum (operands[0]) < 16
2719 && true_regnum (operands[1]) < 16"
2720 [(set (match_dup 0) (match_dup 1))]
2721 "
2722 {
2723 /* If this was a reg <-> mem operation with base + index reg addressing,
2724 we have to handle this in a special way. */
2725 rtx mem = operands[0];
2726 int store_p = 1;
2727 if (! memory_operand (mem, DFmode))
2728 {
2729 mem = operands[1];
2730 store_p = 0;
2731 }
2732 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
2733 mem = SUBREG_REG (mem);
2734 if (GET_CODE (mem) == MEM)
2735 {
2736 rtx addr = XEXP (mem, 0);
2737 if (GET_CODE (addr) == PLUS
2738 && GET_CODE (XEXP (addr, 0)) == REG
2739 && GET_CODE (XEXP (addr, 1)) == REG)
2740 {
2741 int offset;
2742 rtx reg0 = gen_rtx (REG, Pmode, 0);
2743 rtx regop = operands[store_p], word0 ,word1;
2744
2745 if (GET_CODE (regop) == SUBREG)
2746 regop = alter_subreg (regop);
2747 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
2748 offset = 2;
2749 else
2750 offset = 4;
2751 mem = copy_rtx (mem);
2752 PUT_MODE (mem, SImode);
2753 word0 = alter_subreg (gen_rtx (SUBREG, SImode, regop, 0));
2754 word1 = alter_subreg (gen_rtx (SUBREG, SImode, regop, 4));
2755 if (store_p || ! refers_to_regno_p (REGNO (word0),
2756 REGNO (word0) + 1, addr, 0))
2757 {
2758 emit_insn (store_p
2759 ? gen_movsi_ie (mem, word0)
2760 : gen_movsi_ie (word0, mem));
2761 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
2762 mem = copy_rtx (mem);
2763 emit_insn (store_p
2764 ? gen_movsi_ie (mem, word1)
2765 : gen_movsi_ie (word1, mem));
2766 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
2767 }
2768 else
2769 {
2770 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
2771 emit_insn (gen_movsi_ie (word1, mem));
2772 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
2773 mem = copy_rtx (mem);
2774 emit_insn (gen_movsi_ie (word0, mem));
2775 }
2776 DONE;
2777 }
2778 }
2779 }")
2780
2781 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
2782 (define_split
2783 [(set (match_operand:DF 0 "register_operand" "")
2784 (match_operand:DF 1 "memory_operand" ""))
2785 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2786 (clobber (reg:SI R0_REG))]
2787 "TARGET_SH4 && reload_completed"
2788 [(parallel [(set (match_dup 0) (match_dup 1))
2789 (use (match_dup 2))
2790 (clobber (scratch:SI))])]
2791 "")
2792
2793 (define_expand "reload_indf"
2794 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
2795 (match_operand:DF 1 "immediate_operand" "FQ"))
2796 (use (reg:PSI FPSCR_REG))
2797 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
2798 ""
2799 "")
2800
2801 (define_expand "reload_outdf"
2802 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
2803 (match_operand:DF 1 "register_operand" "af,r"))
2804 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
2805 ""
2806 "")
2807
2808 ;; Simplify no-op moves.
2809 (define_split
2810 [(set (match_operand:SF 0 "register_operand" "")
2811 (match_operand:SF 1 "register_operand" ""))
2812 (use (match_operand:PSI 2 "fpscr_operand" ""))
2813 (clobber (match_scratch:SI 3 "X"))]
2814 "TARGET_SH3E && reload_completed
2815 && true_regnum (operands[0]) == true_regnum (operands[1])"
2816 [(set (match_dup 0) (match_dup 0))]
2817 "")
2818
2819 ;; fmovd substitute post-reload splits
2820 (define_split
2821 [(set (match_operand:DF 0 "register_operand" "")
2822 (match_operand:DF 1 "register_operand" ""))
2823 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2824 (clobber (match_scratch:SI 3 "X"))]
2825 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2826 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
2827 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
2828 [(const_int 0)]
2829 "
2830 {
2831 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
2832 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
2833 gen_rtx (REG, SFmode, src), operands[2]));
2834 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
2835 gen_rtx (REG, SFmode, src + 1), operands[2]));
2836 DONE;
2837 }")
2838
2839 (define_split
2840 [(set (match_operand:DF 0 "register_operand" "")
2841 (mem:DF (match_operand:SI 1 "register_operand" "")))
2842 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2843 (clobber (match_scratch:SI 3 "X"))]
2844 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2845 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
2846 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
2847 [(const_int 0)]
2848 "
2849 {
2850 int regno = true_regnum (operands[0]);
2851 rtx insn;
2852 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
2853
2854 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
2855 regno + !! TARGET_LITTLE_ENDIAN),
2856 mem2, operands[2]));
2857 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
2858 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
2859 regno + ! TARGET_LITTLE_ENDIAN),
2860 gen_rtx (MEM, SFmode, operands[1]),
2861 operands[2]));
2862 DONE;
2863 }")
2864
2865 (define_split
2866 [(set (match_operand:DF 0 "register_operand" "")
2867 (match_operand:DF 1 "memory_operand" ""))
2868 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2869 (clobber (match_scratch:SI 3 "X"))]
2870 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2871 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
2872 [(const_int 0)]
2873 "
2874 {
2875 int regno = true_regnum (operands[0]);
2876 rtx addr, insn, adjust = NULL_RTX;
2877 rtx mem2 = copy_rtx (operands[1]);
2878 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
2879 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
2880
2881 PUT_MODE (mem2, SFmode);
2882 operands[1] = copy_rtx (mem2);
2883 addr = XEXP (mem2, 0);
2884 if (GET_CODE (addr) != POST_INC)
2885 {
2886 /* If we have to modify the stack pointer, the value that we have
2887 read with post-increment might be modified by an interrupt,
2888 so write it back. */
2889 if (REGNO (addr) == STACK_POINTER_REGNUM)
2890 adjust = gen_push_e (reg0);
2891 else
2892 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
2893 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
2894 }
2895 addr = XEXP (addr, 0);
2896 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
2897 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
2898 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
2899 if (adjust)
2900 emit_insn (adjust);
2901 else
2902 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
2903 DONE;
2904 }")
2905
2906 (define_split
2907 [(set (match_operand:DF 0 "memory_operand" "")
2908 (match_operand:DF 1 "register_operand" ""))
2909 (use (match_operand:PSI 2 "fpscr_operand" "c"))
2910 (clobber (match_scratch:SI 3 "X"))]
2911 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2912 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
2913 [(const_int 0)]
2914 "
2915 {
2916 int regno = true_regnum (operands[1]);
2917 rtx insn, addr, adjust = NULL_RTX;
2918
2919 operands[0] = copy_rtx (operands[0]);
2920 PUT_MODE (operands[0], SFmode);
2921 insn = emit_insn (gen_movsf_ie (operands[0],
2922 gen_rtx (REG, SFmode,
2923 regno + ! TARGET_LITTLE_ENDIAN),
2924 operands[2]));
2925 operands[0] = copy_rtx (operands[0]);
2926 addr = XEXP (operands[0], 0);
2927 if (GET_CODE (addr) != PRE_DEC)
2928 {
2929 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
2930 emit_insn_before (adjust, insn);
2931 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
2932 }
2933 addr = XEXP (addr, 0);
2934 if (! adjust)
2935 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
2936 insn = emit_insn (gen_movsf_ie (operands[0],
2937 gen_rtx (REG, SFmode,
2938 regno + !! TARGET_LITTLE_ENDIAN),
2939 operands[2]));
2940 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
2941 DONE;
2942 }")
2943
2944 ;; If the output is a register and the input is memory or a register, we have
2945 ;; to be careful and see which word needs to be loaded first.
2946
2947 (define_split
2948 [(set (match_operand:DF 0 "general_movdst_operand" "")
2949 (match_operand:DF 1 "general_movsrc_operand" ""))]
2950 "reload_completed"
2951 [(set (match_dup 2) (match_dup 3))
2952 (set (match_dup 4) (match_dup 5))]
2953 "
2954 {
2955 int regno;
2956
2957 if ((GET_CODE (operands[0]) == MEM
2958 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2959 || (GET_CODE (operands[1]) == MEM
2960 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
2961 FAIL;
2962
2963 if (GET_CODE (operands[0]) == REG)
2964 regno = REGNO (operands[0]);
2965 else if (GET_CODE (operands[0]) == SUBREG)
2966 regno = subreg_regno (operands[0]);
2967 else if (GET_CODE (operands[0]) == MEM)
2968 regno = -1;
2969
2970 if (regno == -1
2971 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
2972 {
2973 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2974 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2975 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2976 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
2977 }
2978 else
2979 {
2980 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2981 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
2982 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
2983 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2984 }
2985
2986 if (operands[2] == 0 || operands[3] == 0
2987 || operands[4] == 0 || operands[5] == 0)
2988 FAIL;
2989 }")
2990
2991 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
2992 ;; used only once, let combine add in the index again.
2993
2994 (define_split
2995 [(set (match_operand:SI 0 "register_operand" "")
2996 (match_operand:SI 1 "" ""))
2997 (clobber (match_operand 2 "register_operand" ""))]
2998 "! reload_in_progress && ! reload_completed"
2999 [(use (reg:SI R0_REG))]
3000 "
3001 {
3002 rtx addr, reg, const_int;
3003
3004 if (GET_CODE (operands[1]) != MEM)
3005 FAIL;
3006 addr = XEXP (operands[1], 0);
3007 if (GET_CODE (addr) != PLUS)
3008 FAIL;
3009 reg = XEXP (addr, 0);
3010 const_int = XEXP (addr, 1);
3011 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
3012 && GET_CODE (const_int) == CONST_INT))
3013 FAIL;
3014 emit_move_insn (operands[2], const_int);
3015 emit_move_insn (operands[0],
3016 change_address (operands[1], VOIDmode,
3017 gen_rtx_PLUS (SImode, reg, operands[2])));
3018 DONE;
3019 }")
3020
3021 (define_split
3022 [(set (match_operand:SI 1 "" "")
3023 (match_operand:SI 0 "register_operand" ""))
3024 (clobber (match_operand 2 "register_operand" ""))]
3025 "! reload_in_progress && ! reload_completed"
3026 [(use (reg:SI R0_REG))]
3027 "
3028 {
3029 rtx addr, reg, const_int;
3030
3031 if (GET_CODE (operands[1]) != MEM)
3032 FAIL;
3033 addr = XEXP (operands[1], 0);
3034 if (GET_CODE (addr) != PLUS)
3035 FAIL;
3036 reg = XEXP (addr, 0);
3037 const_int = XEXP (addr, 1);
3038 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
3039 && GET_CODE (const_int) == CONST_INT))
3040 FAIL;
3041 emit_move_insn (operands[2], const_int);
3042 emit_move_insn (change_address (operands[1], VOIDmode,
3043 gen_rtx_PLUS (SImode, reg, operands[2])),
3044 operands[0]);
3045 DONE;
3046 }")
3047
3048 (define_expand "movdf"
3049 [(set (match_operand:DF 0 "general_movdst_operand" "")
3050 (match_operand:DF 1 "general_movsrc_operand" ""))]
3051 ""
3052 "
3053 {
3054 if (prepare_move_operands (operands, DFmode)) DONE;
3055 if (TARGET_SH4)
3056 {
3057 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
3058 DONE;
3059 }
3060 }")
3061
3062
3063 (define_insn "movsf_i"
3064 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
3065 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
3066 "
3067 (! TARGET_SH3E
3068 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
3069 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
3070 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
3071 && (arith_reg_operand (operands[0], SFmode)
3072 || arith_reg_operand (operands[1], SFmode))"
3073 "@
3074 mov %1,%0
3075 mov %1,%0
3076 mov.l %1,%0
3077 mov.l %1,%0
3078 mov.l %1,%0
3079 lds %1,%0
3080 sts %1,%0"
3081 [(set_attr "type" "move,move,pcload,load,store,move,move")])
3082
3083 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
3084 ;; update_flow_info would not know where to put REG_EQUAL notes
3085 ;; when the destination changes mode.
3086 (define_insn "movsf_ie"
3087 [(set (match_operand:SF 0 "general_movdst_operand"
3088 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
3089 (match_operand:SF 1 "general_movsrc_operand"
3090 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
3091 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
3092 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
3093
3094 "TARGET_SH3E
3095 && (arith_reg_operand (operands[0], SFmode)
3096 || arith_reg_operand (operands[1], SFmode)
3097 || arith_reg_operand (operands[3], SImode)
3098 || (fpul_operand (operands[0], SFmode)
3099 && memory_operand (operands[1], SFmode)
3100 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
3101 || (fpul_operand (operands[1], SFmode)
3102 && memory_operand (operands[0], SFmode)
3103 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
3104 "@
3105 fmov %1,%0
3106 mov %1,%0
3107 fldi0 %0
3108 fldi1 %0
3109 #
3110 fmov.s %1,%0
3111 fmov.s %1,%0
3112 mov.l %1,%0
3113 mov.l %1,%0
3114 mov.l %1,%0
3115 fsts fpul,%0
3116 flds %1,fpul
3117 lds.l %1,%0
3118 #
3119 sts %1,%0
3120 lds %1,%0
3121 sts.l %1,%0
3122 lds.l %1,%0
3123 ! move optimized away"
3124 [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
3125 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
3126 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
3127 (const_string "single")
3128 (const_string "none")))])
3129
3130 (define_split
3131 [(set (match_operand:SF 0 "register_operand" "")
3132 (match_operand:SF 1 "register_operand" ""))
3133 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3134 (clobber (reg:SI FPUL_REG))]
3135 ""
3136 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
3137 (use (match_dup 2))
3138 (clobber (scratch:SI))])
3139 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
3140 (use (match_dup 2))
3141 (clobber (scratch:SI))])]
3142 "")
3143
3144 (define_expand "movsf"
3145 [(set (match_operand:SF 0 "general_movdst_operand" "")
3146 (match_operand:SF 1 "general_movsrc_operand" ""))]
3147 ""
3148 "
3149 {
3150 if (prepare_move_operands (operands, SFmode))
3151 DONE;
3152 if (TARGET_SH3E)
3153 {
3154 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
3155 DONE;
3156 }
3157 }")
3158
3159 (define_insn "mov_nop"
3160 [(set (match_operand 0 "register_operand" "") (match_dup 0))]
3161 "TARGET_SH3E"
3162 ""
3163 [(set_attr "length" "0")
3164 (set_attr "type" "nil")])
3165
3166 (define_expand "reload_insf"
3167 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
3168 (match_operand:SF 1 "immediate_operand" "FQ"))
3169 (use (reg:PSI FPSCR_REG))
3170 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
3171 ""
3172 "")
3173
3174 (define_expand "reload_insi"
3175 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
3176 (match_operand:SF 1 "immediate_operand" "FQ"))
3177 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
3178 ""
3179 "")
3180
3181 (define_insn "*movsi_y"
3182 [(set (match_operand:SI 0 "register_operand" "=y,y")
3183 (match_operand:SI 1 "immediate_operand" "Qi,I"))
3184 (clobber (match_scratch:SI 2 "=&z,r"))]
3185 "TARGET_SH3E
3186 && (reload_in_progress || reload_completed)"
3187 "#"
3188 [(set_attr "length" "4")
3189 (set_attr "type" "pcload,move")])
3190
3191 (define_split
3192 [(set (match_operand:SI 0 "register_operand" "")
3193 (match_operand:SI 1 "immediate_operand" ""))
3194 (clobber (match_operand:SI 2 "register_operand" ""))]
3195 ""
3196 [(set (match_dup 2) (match_dup 1))
3197 (set (match_dup 0) (match_dup 2))]
3198 "")
3199
3200 (define_split
3201 [(set (match_operand:SI 0 "register_operand" "")
3202 (match_operand:SI 1 "memory_operand" ""))
3203 (clobber (reg:SI R0_REG))]
3204 ""
3205 [(set (match_dup 0) (match_dup 1))]
3206 "")
3207 \f
3208 ;; ------------------------------------------------------------------------
3209 ;; Define the real conditional branch instructions.
3210 ;; ------------------------------------------------------------------------
3211
3212 (define_insn "branch_true"
3213 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
3214 (label_ref (match_operand 0 "" ""))
3215 (pc)))]
3216 ""
3217 "* return output_branch (1, insn, operands);"
3218 [(set_attr "type" "cbranch")])
3219
3220 (define_insn "branch_false"
3221 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
3222 (label_ref (match_operand 0 "" ""))
3223 (pc)))]
3224 ""
3225 "* return output_branch (0, insn, operands);"
3226 [(set_attr "type" "cbranch")])
3227
3228 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
3229 ;; which destination is too far away.
3230 ;; The const_int_operand is distinct for each branch target; it avoids
3231 ;; unwanted matches with redundant_insn.
3232 (define_insn "block_branch_redirect"
3233 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
3234 ""
3235 ""
3236 [(set_attr "length" "0")])
3237
3238 ;; This one has the additional purpose to record a possible scratch register
3239 ;; for the following branch.
3240 (define_insn "indirect_jump_scratch"
3241 [(set (match_operand 0 "register_operand" "=r")
3242 (unspec [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
3243 ""
3244 ""
3245 [(set_attr "length" "0")])
3246 \f
3247 ;; Conditional branch insns
3248
3249 (define_expand "beq"
3250 [(set (pc)
3251 (if_then_else (ne (reg:SI T_REG) (const_int 0))
3252 (label_ref (match_operand 0 "" ""))
3253 (pc)))]
3254 ""
3255 "from_compare (operands, EQ);")
3256
3257 (define_expand "bne"
3258 [(set (pc)
3259 (if_then_else (eq (reg:SI T_REG) (const_int 0))
3260 (label_ref (match_operand 0 "" ""))
3261 (pc)))]
3262 ""
3263 "from_compare (operands, EQ);")
3264
3265 (define_expand "bgt"
3266 [(set (pc)
3267 (if_then_else (ne (reg:SI T_REG) (const_int 0))
3268 (label_ref (match_operand 0 "" ""))
3269 (pc)))]
3270 ""
3271 "from_compare (operands, GT);")
3272
3273 (define_expand "blt"
3274 [(set (pc)
3275 (if_then_else (eq (reg:SI T_REG) (const_int 0))
3276 (label_ref (match_operand 0 "" ""))
3277 (pc)))]
3278 ""
3279 "
3280 {
3281 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3282 {
3283 rtx tmp = sh_compare_op0;
3284 sh_compare_op0 = sh_compare_op1;
3285 sh_compare_op1 = tmp;
3286 emit_insn (gen_bgt (operands[0]));
3287 DONE;
3288 }
3289 from_compare (operands, GE);
3290 }")
3291
3292 (define_expand "ble"
3293 [(set (pc)
3294 (if_then_else (eq (reg:SI T_REG) (const_int 0))
3295 (label_ref (match_operand 0 "" ""))
3296 (pc)))]
3297 ""
3298 "
3299 {
3300 if (TARGET_SH3E
3301 && TARGET_IEEE
3302 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3303 {
3304 rtx tmp = sh_compare_op0;
3305 sh_compare_op0 = sh_compare_op1;
3306 sh_compare_op1 = tmp;
3307 emit_insn (gen_bge (operands[0]));
3308 DONE;
3309 }
3310 from_compare (operands, GT);
3311 }")
3312
3313 (define_expand "bge"
3314 [(set (pc)
3315 (if_then_else (ne (reg:SI T_REG) (const_int 0))
3316 (label_ref (match_operand 0 "" ""))
3317 (pc)))]
3318 ""
3319 "
3320 {
3321 if (TARGET_SH3E
3322 && ! TARGET_IEEE
3323 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3324 {
3325 rtx tmp = sh_compare_op0;
3326 sh_compare_op0 = sh_compare_op1;
3327 sh_compare_op1 = tmp;
3328 emit_insn (gen_ble (operands[0]));
3329 DONE;
3330 }
3331 from_compare (operands, GE);
3332 }")
3333
3334 (define_expand "bgtu"
3335 [(set (pc)
3336 (if_then_else (ne (reg:SI T_REG) (const_int 0))
3337 (label_ref (match_operand 0 "" ""))
3338 (pc)))]
3339 ""
3340 "from_compare (operands, GTU); ")
3341
3342 (define_expand "bltu"
3343 [(set (pc)
3344 (if_then_else (eq (reg:SI T_REG) (const_int 0))
3345 (label_ref (match_operand 0 "" ""))
3346 (pc)))]
3347 ""
3348 "from_compare (operands, GEU);")
3349
3350 (define_expand "bgeu"
3351 [(set (pc)
3352 (if_then_else (ne (reg:SI T_REG) (const_int 0))
3353 (label_ref (match_operand 0 "" ""))
3354 (pc)))]
3355 ""
3356 "from_compare (operands, GEU);")
3357
3358 (define_expand "bleu"
3359 [(set (pc)
3360 (if_then_else (eq (reg:SI T_REG) (const_int 0))
3361 (label_ref (match_operand 0 "" ""))
3362 (pc)))]
3363 ""
3364 "from_compare (operands, GTU);")
3365 \f
3366 ;; ------------------------------------------------------------------------
3367 ;; Jump and linkage insns
3368 ;; ------------------------------------------------------------------------
3369
3370 (define_insn "jump"
3371 [(set (pc)
3372 (label_ref (match_operand 0 "" "")))]
3373 ""
3374 "*
3375 {
3376 /* The length is 16 if the delay slot is unfilled. */
3377 if (get_attr_length(insn) > 4)
3378 return output_far_jump(insn, operands[0]);
3379 else
3380 return \"bra %l0%#\";
3381 }"
3382 [(set_attr "type" "jump")
3383 (set_attr "needs_delay_slot" "yes")])
3384
3385 (define_insn "calli"
3386 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
3387 (match_operand 1 "" ""))
3388 (use (reg:PSI FPSCR_REG))
3389 (clobber (reg:SI PR_REG))]
3390 ""
3391 "jsr @%0%#"
3392 [(set_attr "type" "call")
3393 (set (attr "fp_mode")
3394 (if_then_else (eq_attr "fpu_single" "yes")
3395 (const_string "single") (const_string "double")))
3396 (set_attr "needs_delay_slot" "yes")])
3397
3398 ;; This is a pc-rel call, using bsrf, for use with PIC.
3399
3400 (define_insn "calli_pcrel"
3401 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
3402 (match_operand 1 "" ""))
3403 (use (reg:PSI FPSCR_REG))
3404 (use (reg:SI PIC_REG))
3405 (use (match_operand 2 "" ""))
3406 (clobber (reg:SI PR_REG))]
3407 "TARGET_SH2"
3408 "bsrf %0\\n%O2:%#"
3409 [(set_attr "type" "call")
3410 (set (attr "fp_mode")
3411 (if_then_else (eq_attr "fpu_single" "yes")
3412 (const_string "single") (const_string "double")))
3413 (set_attr "needs_delay_slot" "yes")])
3414
3415 (define_insn_and_split "call_pcrel"
3416 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
3417 (match_operand 1 "" ""))
3418 (use (reg:PSI FPSCR_REG))
3419 (use (reg:SI PIC_REG))
3420 (clobber (reg:SI PR_REG))
3421 (clobber (match_scratch:SI 2 "=r"))]
3422 "TARGET_SH2"
3423 "#"
3424 "reload_completed"
3425 [(const_int 0)]
3426 "
3427 {
3428 rtx lab = gen_call_site ();
3429
3430 if (SYMBOL_REF_FLAG (operands[0]))
3431 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
3432 else
3433 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
3434 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
3435 DONE;
3436 }"
3437 [(set_attr "type" "call")
3438 (set (attr "fp_mode")
3439 (if_then_else (eq_attr "fpu_single" "yes")
3440 (const_string "single") (const_string "double")))
3441 (set_attr "needs_delay_slot" "yes")])
3442
3443 (define_insn "call_valuei"
3444 [(set (match_operand 0 "" "=rf")
3445 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
3446 (match_operand 2 "" "")))
3447 (use (reg:PSI FPSCR_REG))
3448 (clobber (reg:SI PR_REG))]
3449 ""
3450 "jsr @%1%#"
3451 [(set_attr "type" "call")
3452 (set (attr "fp_mode")
3453 (if_then_else (eq_attr "fpu_single" "yes")
3454 (const_string "single") (const_string "double")))
3455 (set_attr "needs_delay_slot" "yes")])
3456
3457 (define_insn "call_valuei_pcrel"
3458 [(set (match_operand 0 "" "=rf")
3459 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
3460 (match_operand 2 "" "")))
3461 (use (reg:PSI FPSCR_REG))
3462 (use (reg:SI PIC_REG))
3463 (use (match_operand 3 "" ""))
3464 (clobber (reg:SI PR_REG))]
3465 "TARGET_SH2"
3466 "bsrf %1\\n%O3:%#"
3467 [(set_attr "type" "call")
3468 (set (attr "fp_mode")
3469 (if_then_else (eq_attr "fpu_single" "yes")
3470 (const_string "single") (const_string "double")))
3471 (set_attr "needs_delay_slot" "yes")])
3472
3473 (define_insn_and_split "call_value_pcrel"
3474 [(set (match_operand 0 "" "=rf")
3475 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
3476 (match_operand 2 "" "")))
3477 (use (reg:PSI FPSCR_REG))
3478 (use (reg:SI PIC_REG))
3479 (clobber (reg:SI PR_REG))
3480 (clobber (match_scratch:SI 3 "=r"))]
3481 "TARGET_SH2"
3482 "#"
3483 "reload_completed"
3484 [(const_int 0)]
3485 "
3486 {
3487 rtx lab = gen_call_site ();
3488
3489 if (SYMBOL_REF_FLAG (operands[1]))
3490 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
3491 else
3492 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
3493 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
3494 operands[2], lab));
3495 DONE;
3496 }"
3497 [(set_attr "type" "call")
3498 (set (attr "fp_mode")
3499 (if_then_else (eq_attr "fpu_single" "yes")
3500 (const_string "single") (const_string "double")))
3501 (set_attr "needs_delay_slot" "yes")])
3502
3503 (define_expand "call"
3504 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
3505 (match_operand 1 "" ""))
3506 (use (reg:PSI FPSCR_REG))
3507 (clobber (reg:SI PR_REG))])]
3508 ""
3509 "
3510 {
3511 if (flag_pic && TARGET_SH2
3512 && GET_CODE (operands[0]) == MEM
3513 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
3514 {
3515 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
3516 DONE;
3517 }
3518 else
3519 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
3520 }")
3521
3522 (define_expand "call_value"
3523 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
3524 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
3525 (match_operand 2 "" "")))
3526 (use (reg:PSI FPSCR_REG))
3527 (clobber (reg:SI PR_REG))])]
3528 ""
3529 "
3530 {
3531 if (flag_pic && TARGET_SH2
3532 && GET_CODE (operands[1]) == MEM
3533 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
3534 {
3535 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
3536 operands[2]));
3537 DONE;
3538 }
3539 else
3540 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
3541 }")
3542
3543 (define_insn "sibcalli"
3544 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
3545 (match_operand 1 "" ""))
3546 (use (reg:PSI FPSCR_REG))
3547 (return)]
3548 ""
3549 "jmp @%0%#"
3550 [(set_attr "needs_delay_slot" "yes")
3551 (set (attr "fp_mode")
3552 (if_then_else (eq_attr "fpu_single" "yes")
3553 (const_string "single") (const_string "double")))
3554 (set_attr "type" "jump_ind")])
3555
3556 (define_insn "sibcalli_pcrel"
3557 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
3558 (match_operand 1 "" ""))
3559 (use (match_operand 2 "" ""))
3560 (use (reg:PSI FPSCR_REG))
3561 (return)]
3562 "TARGET_SH2"
3563 "braf %0\\n%O2:%#"
3564 [(set_attr "needs_delay_slot" "yes")
3565 (set (attr "fp_mode")
3566 (if_then_else (eq_attr "fpu_single" "yes")
3567 (const_string "single") (const_string "double")))
3568 (set_attr "type" "jump_ind")])
3569
3570 (define_insn_and_split "sibcall_pcrel"
3571 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
3572 (match_operand 1 "" ""))
3573 (use (reg:PSI FPSCR_REG))
3574 (clobber (match_scratch:SI 2 "=k"))
3575 (return)]
3576 "TARGET_SH2"
3577 "#"
3578 "reload_completed"
3579 [(const_int 0)]
3580 "
3581 {
3582 rtx lab = gen_call_site ();
3583 rtx call_insn;
3584
3585 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
3586 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
3587 lab));
3588 SIBLING_CALL_P (call_insn) = 1;
3589 DONE;
3590 }"
3591 [(set_attr "needs_delay_slot" "yes")
3592 (set (attr "fp_mode")
3593 (if_then_else (eq_attr "fpu_single" "yes")
3594 (const_string "single") (const_string "double")))
3595 (set_attr "type" "jump_ind")])
3596
3597 (define_expand "sibcall"
3598 [(parallel
3599 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
3600 (match_operand 1 "" ""))
3601 (use (reg:PSI FPSCR_REG))
3602 (return)])]
3603 ""
3604 "
3605 {
3606 if (flag_pic && TARGET_SH2
3607 && GET_CODE (operands[0]) == MEM
3608 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
3609 /* The PLT needs the PIC register, but the epilogue would have
3610 to restore it, so we can only use PC-relative PIC calls for
3611 static functions. */
3612 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
3613 {
3614 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
3615 DONE;
3616 }
3617 else
3618 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
3619 }")
3620
3621 (define_expand "sibcall_value"
3622 [(set (match_operand 0 "" "")
3623 (call (match_operand 1 "" "")
3624 (match_operand 2 "" "")))]
3625 ""
3626 "
3627 {
3628 emit_call_insn (gen_sibcall (operands[1], operands[2]));
3629 DONE;
3630 }")
3631
3632 (define_expand "sibcall_epilogue"
3633 [(return)]
3634 ""
3635 "
3636 {
3637 sh_expand_epilogue ();
3638 DONE;
3639 }")
3640
3641 (define_insn "indirect_jump"
3642 [(set (pc)
3643 (match_operand:SI 0 "arith_reg_operand" "r"))]
3644 ""
3645 "jmp @%0%#"
3646 [(set_attr "needs_delay_slot" "yes")
3647 (set_attr "type" "jump_ind")])
3648
3649 ;; The use of operand 1 / 2 helps us distinguish case table jumps
3650 ;; which can be present in structured code from indirect jumps which can not
3651 ;; be present in structured code. This allows -fprofile-arcs to work.
3652
3653 ;; For SH1 processors.
3654 (define_insn "casesi_jump_1"
3655 [(set (pc)
3656 (match_operand:SI 0 "register_operand" "r"))
3657 (use (label_ref (match_operand 1 "" "")))]
3658 ""
3659 "jmp @%0%#"
3660 [(set_attr "needs_delay_slot" "yes")
3661 (set_attr "type" "jump_ind")])
3662
3663 ;; For all later processors.
3664 (define_insn "casesi_jump_2"
3665 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
3666 (label_ref (match_operand 1 "" ""))))
3667 (use (label_ref (match_operand 2 "" "")))]
3668 "TARGET_SH2
3669 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
3670 "braf %0%#"
3671 [(set_attr "needs_delay_slot" "yes")
3672 (set_attr "type" "jump_ind")])
3673
3674 ;; Call subroutine returning any type.
3675 ;; ??? This probably doesn't work.
3676
3677 (define_expand "untyped_call"
3678 [(parallel [(call (match_operand 0 "" "")
3679 (const_int 0))
3680 (match_operand 1 "" "")
3681 (match_operand 2 "" "")])]
3682 "TARGET_SH3E"
3683 "
3684 {
3685 int i;
3686
3687 emit_call_insn (gen_call (operands[0], const0_rtx));
3688
3689 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3690 {
3691 rtx set = XVECEXP (operands[2], 0, i);
3692 emit_move_insn (SET_DEST (set), SET_SRC (set));
3693 }
3694
3695 /* The optimizer does not know that the call sets the function value
3696 registers we stored in the result block. We avoid problems by
3697 claiming that all hard registers are used and clobbered at this
3698 point. */
3699 emit_insn (gen_blockage ());
3700
3701 DONE;
3702 }")
3703 \f
3704 ;; ------------------------------------------------------------------------
3705 ;; Misc insns
3706 ;; ------------------------------------------------------------------------
3707
3708 (define_insn "dect"
3709 [(set (reg:SI T_REG)
3710 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
3711 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
3712 "TARGET_SH2"
3713 "dt %0"
3714 [(set_attr "type" "arith")])
3715
3716 (define_insn "nop"
3717 [(const_int 0)]
3718 ""
3719 "nop")
3720
3721 ;; Load address of a label. This is only generated by the casesi expand,
3722 ;; and by machine_dependent_reorg (fixing up fp moves).
3723 ;; This must use unspec, because this only works for labels that are
3724 ;; within range,
3725
3726 (define_insn "mova"
3727 [(set (reg:SI R0_REG)
3728 (unspec [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
3729 ""
3730 "mova %O0,r0"
3731 [(set_attr "in_delay_slot" "no")
3732 (set_attr "type" "arith")])
3733
3734 ;; machine_dependent_reorg() will make this a `mova'.
3735 (define_insn "mova_const"
3736 [(set (reg:SI R0_REG)
3737 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
3738 ""
3739 "#"
3740 [(set_attr "in_delay_slot" "no")
3741 (set_attr "type" "arith")])
3742
3743 (define_expand "GOTaddr2picreg"
3744 [(set (reg:SI R0_REG)
3745 (unspec [(const (unspec [(match_dup 1)] UNSPEC_PIC))]
3746 UNSPEC_MOVA))
3747 (set (match_dup 0) (const (unspec [(match_dup 1)] UNSPEC_PIC)))
3748 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
3749 "" "
3750 {
3751 operands[0] = pic_offset_table_rtx;
3752 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
3753 }
3754 ")
3755
3756 (define_expand "builtin_setjmp_receiver"
3757 [(match_operand 0 "" "")]
3758 "flag_pic"
3759 "
3760 {
3761 emit_insn (gen_GOTaddr2picreg ());
3762 DONE;
3763 }")
3764
3765 (define_expand "call_site"
3766 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
3767 ""
3768 "
3769 {
3770 static HOST_WIDE_INT i = 0;
3771 operands[0] = GEN_INT (i);
3772 i++;
3773 }")
3774
3775 (define_expand "sym_label2reg"
3776 [(set (match_operand:SI 0 "" "")
3777 (const (minus:SI
3778 (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC))
3779 (const (plus:SI
3780 (match_operand:SI 2 "" "")
3781 (const_int 2))))))]
3782 "" "")
3783
3784 (define_expand "symGOT2reg"
3785 [(set (match_operand:SI 0 "" "")
3786 (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOT)))
3787 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
3788 (set (match_dup 0) (mem:SI (match_dup 0)))]
3789 ""
3790 "
3791 {
3792 operands[2] = pic_offset_table_rtx;
3793 }")
3794
3795 (define_expand "symGOTOFF2reg"
3796 [(set (match_operand:SI 0 "" "")
3797 (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
3798 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3799 ""
3800 "
3801 {
3802 operands[2] = pic_offset_table_rtx;
3803 }")
3804
3805 (define_expand "symPLT_label2reg"
3806 [(set (match_operand:SI 0 "" "")
3807 (const (minus:SI
3808 (const (plus:SI
3809 (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT)
3810 (pc)))
3811 (const (plus:SI
3812 (match_operand:SI 2 "" "")
3813 (const_int 2))))))
3814 ;; Even though the PIC register is not really used by the call
3815 ;; sequence in which this is expanded, the PLT code assumes the PIC
3816 ;; register is set, so we must not skip its initialization. Since
3817 ;; we only use this expand as part of calling sequences, and never
3818 ;; to take the address of a function, this is the best point to
3819 ;; insert the (use). Using the PLT to take the address of a
3820 ;; function would be wrong, not only because the PLT entry could
3821 ;; then be called from a function that doesn't initialize the PIC
3822 ;; register to the proper GOT, but also because pointers to the
3823 ;; same function might not compare equal, should they be set by
3824 ;; different shared libraries.
3825 (use (reg:SI PIC_REG))]
3826 ""
3827 "")
3828
3829 ;; case instruction for switch statements.
3830
3831 ;; Operand 0 is index
3832 ;; operand 1 is the minimum bound
3833 ;; operand 2 is the maximum bound - minimum bound + 1
3834 ;; operand 3 is CODE_LABEL for the table;
3835 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3836
3837 (define_expand "casesi"
3838 [(match_operand:SI 0 "arith_reg_operand" "")
3839 (match_operand:SI 1 "arith_reg_operand" "")
3840 (match_operand:SI 2 "arith_reg_operand" "")
3841 (match_operand 3 "" "") (match_operand 4 "" "")]
3842 ""
3843 "
3844 {
3845 rtx reg = gen_reg_rtx (SImode);
3846 rtx reg2 = gen_reg_rtx (SImode);
3847 operands[1] = copy_to_mode_reg (SImode, operands[1]);
3848 operands[2] = copy_to_mode_reg (SImode, operands[2]);
3849 /* If optimizing, casesi_worker depends on the mode of the instruction
3850 before label it 'uses' - operands[3]. */
3851 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
3852 reg));
3853 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
3854 if (TARGET_SH2)
3855 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
3856 else
3857 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
3858 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
3859 operands[3], but to lab. We will fix this up in
3860 machine_dependent_reorg. */
3861 emit_barrier ();
3862 DONE;
3863 }")
3864
3865 (define_expand "casesi_0"
3866 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
3867 (set (match_dup 4) (minus:SI (match_dup 4)
3868 (match_operand:SI 1 "arith_operand" "")))
3869 (set (reg:SI T_REG)
3870 (gtu:SI (match_dup 4)
3871 (match_operand:SI 2 "arith_reg_operand" "")))
3872 (set (pc)
3873 (if_then_else (ne (reg:SI T_REG)
3874 (const_int 0))
3875 (label_ref (match_operand 3 "" ""))
3876 (pc)))]
3877 ""
3878 "")
3879
3880 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
3881 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
3882 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
3883
3884 (define_insn "casesi_worker_0"
3885 [(set (match_operand:SI 0 "register_operand" "=r,r")
3886 (unspec [(match_operand 1 "register_operand" "0,r")
3887 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
3888 (clobber (match_scratch:SI 3 "=X,1"))
3889 (clobber (match_scratch:SI 4 "=&z,z"))]
3890 ""
3891 "#")
3892
3893 (define_split
3894 [(set (match_operand:SI 0 "register_operand" "")
3895 (unspec [(match_operand 1 "register_operand" "")
3896 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
3897 (clobber (match_scratch:SI 3 ""))
3898 (clobber (match_scratch:SI 4 ""))]
3899 "! TARGET_SH2 && reload_completed"
3900 [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
3901 (parallel [(set (match_dup 0)
3902 (unspec [(reg:SI R0_REG) (match_dup 1)
3903 (label_ref (match_dup 2))] UNSPEC_CASESI))
3904 (clobber (match_dup 3))])
3905 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
3906 "LABEL_NUSES (operands[2])++;")
3907
3908 (define_split
3909 [(set (match_operand:SI 0 "register_operand" "")
3910 (unspec [(match_operand 1 "register_operand" "")
3911 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
3912 (clobber (match_scratch:SI 3 ""))
3913 (clobber (match_scratch:SI 4 ""))]
3914 "TARGET_SH2 && reload_completed"
3915 [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
3916 (parallel [(set (match_dup 0)
3917 (unspec [(reg:SI R0_REG) (match_dup 1)
3918 (label_ref (match_dup 2))] UNSPEC_CASESI))
3919 (clobber (match_dup 3))])]
3920 "LABEL_NUSES (operands[2])++;")
3921
3922 (define_insn "*casesi_worker"
3923 [(set (match_operand:SI 0 "register_operand" "=r,r")
3924 (unspec [(reg:SI R0_REG) (match_operand 1 "register_operand" "0,r")
3925 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
3926 (clobber (match_scratch:SI 3 "=X,1"))]
3927 ""
3928 "*
3929 {
3930 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
3931
3932 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
3933 abort ();
3934
3935 switch (GET_MODE (diff_vec))
3936 {
3937 case SImode:
3938 return \"shll2 %1\;mov.l @(r0,%1),%0\";
3939 case HImode:
3940 return \"add %1,%1\;mov.w @(r0,%1),%0\";
3941 case QImode:
3942 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3943 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
3944 return \"mov.b @(r0,%1),%0\";
3945 default:
3946 abort ();
3947 }
3948 }"
3949 [(set_attr "length" "4")])
3950
3951 (define_expand "return"
3952 [(return)]
3953 "reload_completed && ! sh_need_epilogue ()"
3954 "")
3955
3956 (define_insn "*return_i"
3957 [(return)]
3958 "reload_completed"
3959 "%@ %#"
3960 [(set_attr "type" "return")
3961 (set_attr "needs_delay_slot" "yes")])
3962
3963 (define_expand "prologue"
3964 [(const_int 0)]
3965 ""
3966 "sh_expand_prologue (); DONE;")
3967
3968 (define_expand "epilogue"
3969 [(return)]
3970 ""
3971 "sh_expand_epilogue ();")
3972
3973 (define_insn "blockage"
3974 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
3975 ""
3976 ""
3977 [(set_attr "length" "0")])
3978 \f
3979 ;; ------------------------------------------------------------------------
3980 ;; Scc instructions
3981 ;; ------------------------------------------------------------------------
3982
3983 (define_insn "movt"
3984 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3985 (eq:SI (reg:SI T_REG) (const_int 1)))]
3986 ""
3987 "movt %0"
3988 [(set_attr "type" "arith")])
3989
3990 (define_expand "seq"
3991 [(set (match_operand:SI 0 "arith_reg_operand" "")
3992 (match_dup 1))]
3993 ""
3994 "operands[1] = prepare_scc_operands (EQ);")
3995
3996 (define_expand "slt"
3997 [(set (match_operand:SI 0 "arith_reg_operand" "")
3998 (match_dup 1))]
3999 ""
4000 "operands[1] = prepare_scc_operands (LT);")
4001
4002 (define_expand "sle"
4003 [(match_operand:SI 0 "arith_reg_operand" "")]
4004 ""
4005 "
4006 {
4007 rtx tmp = sh_compare_op0;
4008 sh_compare_op0 = sh_compare_op1;
4009 sh_compare_op1 = tmp;
4010 emit_insn (gen_sge (operands[0]));
4011 DONE;
4012 }")
4013
4014 (define_expand "sgt"
4015 [(set (match_operand:SI 0 "arith_reg_operand" "")
4016 (match_dup 1))]
4017 ""
4018 "operands[1] = prepare_scc_operands (GT);")
4019
4020 (define_expand "sge"
4021 [(set (match_operand:SI 0 "arith_reg_operand" "")
4022 (match_dup 1))]
4023 ""
4024 "
4025 {
4026 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
4027 {
4028 if (TARGET_IEEE)
4029 {
4030 rtx lab = gen_label_rtx ();
4031 prepare_scc_operands (EQ);
4032 emit_jump_insn (gen_branch_true (lab));
4033 prepare_scc_operands (GT);
4034 emit_label (lab);
4035 emit_insn (gen_movt (operands[0]));
4036 }
4037 else
4038 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
4039 DONE;
4040 }
4041 operands[1] = prepare_scc_operands (GE);
4042 }")
4043
4044 (define_expand "sgtu"
4045 [(set (match_operand:SI 0 "arith_reg_operand" "")
4046 (match_dup 1))]
4047 ""
4048 "operands[1] = prepare_scc_operands (GTU);")
4049
4050 (define_expand "sltu"
4051 [(set (match_operand:SI 0 "arith_reg_operand" "")
4052 (match_dup 1))]
4053 ""
4054 "operands[1] = prepare_scc_operands (LTU);")
4055
4056 (define_expand "sleu"
4057 [(set (match_operand:SI 0 "arith_reg_operand" "")
4058 (match_dup 1))]
4059 ""
4060 "operands[1] = prepare_scc_operands (LEU);")
4061
4062 (define_expand "sgeu"
4063 [(set (match_operand:SI 0 "arith_reg_operand" "")
4064 (match_dup 1))]
4065 ""
4066 "operands[1] = prepare_scc_operands (GEU);")
4067
4068 ;; sne moves the complement of the T reg to DEST like this:
4069 ;; cmp/eq ...
4070 ;; mov #-1,temp
4071 ;; negc temp,dest
4072 ;; This is better than xoring compare result with 1 because it does
4073 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
4074 ;; loop.
4075
4076 (define_expand "sne"
4077 [(set (match_dup 2) (const_int -1))
4078 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
4079 (neg:SI (plus:SI (match_dup 1)
4080 (match_dup 2))))
4081 (set (reg:SI T_REG)
4082 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
4083 (const_int 0)))])]
4084 ""
4085 "
4086 {
4087 operands[1] = prepare_scc_operands (EQ);
4088 operands[2] = gen_reg_rtx (SImode);
4089 }")
4090
4091 ;; Use the same trick for FP sle / sge
4092 (define_expand "movnegt"
4093 [(set (match_dup 2) (const_int -1))
4094 (parallel [(set (match_operand 0 "" "")
4095 (neg:SI (plus:SI (match_dup 1)
4096 (match_dup 2))))
4097 (set (reg:SI T_REG)
4098 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
4099 (const_int 0)))])]
4100 ""
4101 "operands[2] = gen_reg_rtx (SImode);")
4102
4103 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
4104 ;; This prevents a regression that occurred when we switched from xor to
4105 ;; mov/neg for sne.
4106
4107 (define_split
4108 [(set (match_operand:SI 0 "arith_reg_operand" "")
4109 (plus:SI (reg:SI T_REG)
4110 (const_int -1)))]
4111 ""
4112 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
4113 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
4114 "")
4115
4116 ;; -------------------------------------------------------------------------
4117 ;; Instructions to cope with inline literal tables
4118 ;; -------------------------------------------------------------------------
4119
4120 ; 2 byte integer in line
4121
4122 (define_insn "consttable_2"
4123 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
4124 UNSPECV_CONST2)]
4125 ""
4126 "*
4127 {
4128 assemble_integer (operands[0], 2, 1);
4129 return \"\";
4130 }"
4131 [(set_attr "length" "2")
4132 (set_attr "in_delay_slot" "no")])
4133
4134 ; 4 byte integer in line
4135
4136 (define_insn "consttable_4"
4137 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
4138 UNSPECV_CONST4)]
4139 ""
4140 "*
4141 {
4142 assemble_integer (operands[0], 4, 1);
4143 return \"\";
4144 }"
4145 [(set_attr "length" "4")
4146 (set_attr "in_delay_slot" "no")])
4147
4148 ; 8 byte integer in line
4149
4150 (define_insn "consttable_8"
4151 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
4152 UNSPECV_CONST8)]
4153 ""
4154 "*
4155 {
4156 assemble_integer (operands[0], 8, 1);
4157 return \"\";
4158 }"
4159 [(set_attr "length" "8")
4160 (set_attr "in_delay_slot" "no")])
4161
4162 ; 4 byte floating point
4163
4164 (define_insn "consttable_sf"
4165 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")]
4166 UNSPECV_CONST4)]
4167 ""
4168 "*
4169 {
4170 union real_extract u;
4171 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
4172 assemble_real (u.d, SFmode);
4173 return \"\";
4174 }"
4175 [(set_attr "length" "4")
4176 (set_attr "in_delay_slot" "no")])
4177
4178 ; 8 byte floating point
4179
4180 (define_insn "consttable_df"
4181 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")]
4182 UNSPECV_CONST8)]
4183 ""
4184 "*
4185 {
4186 union real_extract u;
4187 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
4188 assemble_real (u.d, DFmode);
4189 return \"\";
4190 }"
4191 [(set_attr "length" "8")
4192 (set_attr "in_delay_slot" "no")])
4193
4194 ;; Alignment is needed for some constant tables; it may also be added for
4195 ;; Instructions at the start of loops, or after unconditional branches.
4196 ;; ??? We would get more accurate lengths if we did instruction
4197 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
4198 ;; here is too conservative.
4199
4200 ; align to a two byte boundary
4201
4202 (define_expand "align_2"
4203 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
4204 ""
4205 "")
4206
4207 ; align to a four byte boundary
4208 ;; align_4 and align_log are instructions for the starts of loops, or
4209 ;; after unconditional branches, which may take up extra room.
4210
4211 (define_expand "align_4"
4212 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
4213 ""
4214 "")
4215
4216 ; align to a cache line boundary
4217
4218 (define_insn "align_log"
4219 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
4220 ""
4221 ""
4222 [(set_attr "length" "0")
4223 (set_attr "in_delay_slot" "no")])
4224
4225 ; emitted at the end of the literal table, used to emit the
4226 ; 32bit branch labels if needed.
4227
4228 (define_insn "consttable_end"
4229 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
4230 ""
4231 "* return output_jump_label_table ();"
4232 [(set_attr "in_delay_slot" "no")])
4233
4234 ;; -------------------------------------------------------------------------
4235 ;; Misc
4236 ;; -------------------------------------------------------------------------
4237
4238 ;; String/block move insn.
4239
4240 (define_expand "movstrsi"
4241 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
4242 (mem:BLK (match_operand:BLK 1 "" "")))
4243 (use (match_operand:SI 2 "nonmemory_operand" ""))
4244 (use (match_operand:SI 3 "immediate_operand" ""))
4245 (clobber (reg:SI PR_REG))
4246 (clobber (reg:SI R4_REG))
4247 (clobber (reg:SI R5_REG))
4248 (clobber (reg:SI R0_REG))])]
4249 ""
4250 "
4251 {
4252 if(expand_block_move (operands))
4253 DONE;
4254 else FAIL;
4255 }")
4256
4257 (define_insn "block_move_real"
4258 [(parallel [(set (mem:BLK (reg:SI R4_REG))
4259 (mem:BLK (reg:SI R5_REG)))
4260 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4261 (clobber (reg:SI PR_REG))
4262 (clobber (reg:SI R0_REG))])]
4263 "! TARGET_HARD_SH4"
4264 "jsr @%0%#"
4265 [(set_attr "type" "sfunc")
4266 (set_attr "needs_delay_slot" "yes")])
4267
4268 (define_insn "block_lump_real"
4269 [(parallel [(set (mem:BLK (reg:SI R4_REG))
4270 (mem:BLK (reg:SI R5_REG)))
4271 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4272 (use (reg:SI R6_REG))
4273 (clobber (reg:SI PR_REG))
4274 (clobber (reg:SI T_REG))
4275 (clobber (reg:SI R4_REG))
4276 (clobber (reg:SI R5_REG))
4277 (clobber (reg:SI R6_REG))
4278 (clobber (reg:SI R0_REG))])]
4279 "! TARGET_HARD_SH4"
4280 "jsr @%0%#"
4281 [(set_attr "type" "sfunc")
4282 (set_attr "needs_delay_slot" "yes")])
4283
4284 (define_insn "block_move_real_i4"
4285 [(parallel [(set (mem:BLK (reg:SI R4_REG))
4286 (mem:BLK (reg:SI R5_REG)))
4287 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4288 (clobber (reg:SI PR_REG))
4289 (clobber (reg:SI R0_REG))
4290 (clobber (reg:SI R1_REG))
4291 (clobber (reg:SI R2_REG))])]
4292 "TARGET_HARD_SH4"
4293 "jsr @%0%#"
4294 [(set_attr "type" "sfunc")
4295 (set_attr "needs_delay_slot" "yes")])
4296
4297 (define_insn "block_lump_real_i4"
4298 [(parallel [(set (mem:BLK (reg:SI R4_REG))
4299 (mem:BLK (reg:SI R5_REG)))
4300 (use (match_operand:SI 0 "arith_reg_operand" "r"))
4301 (use (reg:SI R6_REG))
4302 (clobber (reg:SI PR_REG))
4303 (clobber (reg:SI T_REG))
4304 (clobber (reg:SI R4_REG))
4305 (clobber (reg:SI R5_REG))
4306 (clobber (reg:SI R6_REG))
4307 (clobber (reg:SI R0_REG))
4308 (clobber (reg:SI R1_REG))
4309 (clobber (reg:SI R2_REG))
4310 (clobber (reg:SI R3_REG))])]
4311 "TARGET_HARD_SH4"
4312 "jsr @%0%#"
4313 [(set_attr "type" "sfunc")
4314 (set_attr "needs_delay_slot" "yes")])
4315 \f
4316 ;; -------------------------------------------------------------------------
4317 ;; Floating point instructions.
4318 ;; -------------------------------------------------------------------------
4319
4320 ;; ??? All patterns should have a type attribute.
4321
4322 (define_expand "fpu_switch0"
4323 [(set (match_operand:SI 0 "" "") (match_dup 2))
4324 (set (match_dup 1) (mem:PSI (match_dup 0)))]
4325 "TARGET_SH4"
4326 "
4327 {
4328 operands[1] = get_fpscr_rtx ();
4329 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
4330 if (flag_pic)
4331 operands[2] = legitimize_pic_address (operands[2], SImode,
4332 no_new_pseudos ? operands[0] : 0);
4333 }")
4334
4335 (define_expand "fpu_switch1"
4336 [(set (match_operand:SI 0 "" "") (match_dup 2))
4337 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
4338 (set (match_dup 1) (mem:PSI (match_dup 3)))]
4339 "TARGET_SH4"
4340 "
4341 {
4342 operands[1] = get_fpscr_rtx ();
4343 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
4344 if (flag_pic)
4345 operands[2] = legitimize_pic_address (operands[2], SImode,
4346 no_new_pseudos ? operands[0] : 0);
4347 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
4348 }")
4349
4350 (define_expand "movpsi"
4351 [(set (match_operand:PSI 0 "register_operand" "")
4352 (match_operand:PSI 1 "general_movsrc_operand" ""))]
4353 "TARGET_SH4"
4354 "")
4355
4356 ;; The c / m alternative is a fake to guide reload to load directly into
4357 ;; fpscr, since reload doesn't know how to use post-increment.
4358 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
4359 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
4360 ;; predicate after reload.
4361 ;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
4362 ;; like a gpr <-> fpul move.
4363 (define_insn "fpu_switch"
4364 [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
4365 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
4366 "TARGET_SH4
4367 && (! reload_completed
4368 || true_regnum (operands[0]) != FPSCR_REG
4369 || GET_CODE (operands[1]) != MEM
4370 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
4371 "@
4372 ! precision stays the same
4373 lds.l %1,fpscr
4374 mov.l %1,%0
4375 #
4376 lds %1,fpscr
4377 mov %1,%0
4378 mov.l %1,%0
4379 sts fpscr,%0"
4380 [(set_attr "length" "0,2,2,4,2,2,2,2")
4381 (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")])
4382
4383 (define_split
4384 [(set (reg:PSI FPSCR_REG)
4385 (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
4386 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
4387 [(set (match_dup 0) (match_dup 0))]
4388 "
4389 {
4390 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4391 gen_rtx (MEM, PSImode,
4392 gen_rtx (POST_INC, Pmode,
4393 operands[0]))));
4394 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
4395 }")
4396
4397 (define_split
4398 [(set (reg:PSI FPSCR_REG)
4399 (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
4400 "TARGET_SH4"
4401 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
4402 "
4403 {
4404 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4405 gen_rtx (MEM, PSImode,
4406 gen_rtx (POST_INC, Pmode,
4407 operands[0]))));
4408 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
4409 }")
4410
4411 ;; ??? This uses the fp unit, but has no type indicating that.
4412 ;; If we did that, this would either give a bogus latency or introduce
4413 ;; a bogus FIFO constraint.
4414 ;; Since this insn is currently only used for prologues/epilogues,
4415 ;; it is probably best to claim no function unit, which matches the
4416 ;; current setting.
4417 (define_insn "toggle_sz"
4418 [(set (reg:PSI FPSCR_REG)
4419 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
4420 "TARGET_SH4"
4421 "fschg")
4422
4423 (define_expand "addsf3"
4424 [(match_operand:SF 0 "arith_reg_operand" "")
4425 (match_operand:SF 1 "arith_reg_operand" "")
4426 (match_operand:SF 2 "arith_reg_operand" "")]
4427 "TARGET_SH3E"
4428 "{ expand_sf_binop (&gen_addsf3_i, operands); DONE; }")
4429
4430 (define_insn "addsf3_i"
4431 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
4432 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
4433 (match_operand:SF 2 "arith_reg_operand" "f")))
4434 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4435 "TARGET_SH3E"
4436 "fadd %2,%0"
4437 [(set_attr "type" "fp")
4438 (set_attr "fp_mode" "single")])
4439
4440 (define_expand "subsf3"
4441 [(match_operand:SF 0 "fp_arith_reg_operand" "")
4442 (match_operand:SF 1 "fp_arith_reg_operand" "")
4443 (match_operand:SF 2 "fp_arith_reg_operand" "")]
4444 "TARGET_SH3E"
4445 "{ expand_sf_binop (&gen_subsf3_i, operands); DONE; }")
4446
4447 (define_insn "subsf3_i"
4448 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4449 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
4450 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
4451 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4452 "TARGET_SH3E"
4453 "fsub %2,%0"
4454 [(set_attr "type" "fp")
4455 (set_attr "fp_mode" "single")])
4456
4457 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
4458 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
4459 ;; mixed-precision SH4 targets. To allow it to be still generated for the
4460 ;; SH3E, we use a separate insn for SH3E mulsf3.
4461
4462 (define_expand "mulsf3"
4463 [(match_operand:SF 0 "fp_arith_reg_operand" "")
4464 (match_operand:SF 1 "fp_arith_reg_operand" "")
4465 (match_operand:SF 2 "fp_arith_reg_operand" "")]
4466 "TARGET_SH3E"
4467 "
4468 {
4469 if (TARGET_SH4)
4470 expand_sf_binop (&gen_mulsf3_i4, operands);
4471 else
4472 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
4473 DONE;
4474 }")
4475
4476 (define_insn "mulsf3_i4"
4477 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4478 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
4479 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
4480 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4481 "TARGET_SH3E"
4482 "fmul %2,%0"
4483 [(set_attr "type" "fp")
4484 (set_attr "fp_mode" "single")])
4485
4486 (define_insn "mulsf3_ie"
4487 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4488 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
4489 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
4490 "TARGET_SH3E && ! TARGET_SH4"
4491 "fmul %2,%0"
4492 [(set_attr "type" "fp")])
4493
4494 (define_insn "*macsf3"
4495 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4496 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
4497 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
4498 (match_operand:SF 3 "arith_reg_operand" "0")))
4499 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
4500 "TARGET_SH3E && ! TARGET_SH4"
4501 "fmac fr0,%2,%0"
4502 [(set_attr "type" "fp")
4503 (set_attr "fp_mode" "single")])
4504
4505 (define_expand "divsf3"
4506 [(match_operand:SF 0 "arith_reg_operand" "")
4507 (match_operand:SF 1 "arith_reg_operand" "")
4508 (match_operand:SF 2 "arith_reg_operand" "")]
4509 "TARGET_SH3E"
4510 "{ expand_sf_binop (&gen_divsf3_i, operands); DONE; }")
4511
4512 (define_insn "divsf3_i"
4513 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
4514 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
4515 (match_operand:SF 2 "arith_reg_operand" "f")))
4516 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4517 "TARGET_SH3E"
4518 "fdiv %2,%0"
4519 [(set_attr "type" "fdiv")
4520 (set_attr "fp_mode" "single")])
4521
4522 (define_expand "floatsisf2"
4523 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
4524 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
4525 "TARGET_SH3E"
4526 "
4527 {
4528 if (TARGET_SH4)
4529 {
4530 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4531 DONE;
4532 }
4533 }")
4534
4535 (define_insn "floatsisf2_i4"
4536 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4537 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
4538 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4539 "TARGET_SH4"
4540 "float %1,%0"
4541 [(set_attr "type" "fp")
4542 (set_attr "fp_mode" "single")])
4543
4544 (define_insn "*floatsisf2_ie"
4545 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4546 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
4547 "TARGET_SH3E && ! TARGET_SH4"
4548 "float %1,%0"
4549 [(set_attr "type" "fp")])
4550
4551 (define_expand "fix_truncsfsi2"
4552 [(set (match_operand:SI 0 "fpul_operand" "=y")
4553 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
4554 "TARGET_SH3E"
4555 "
4556 {
4557 if (TARGET_SH4)
4558 {
4559 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4560 DONE;
4561 }
4562 }")
4563
4564 (define_insn "fix_truncsfsi2_i4"
4565 [(set (match_operand:SI 0 "fpul_operand" "=y")
4566 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
4567 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4568 "TARGET_SH4"
4569 "ftrc %1,%0"
4570 [(set_attr "type" "fp")
4571 (set_attr "fp_mode" "single")])
4572
4573 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
4574 ;; fix_truncsfsi2_i4.
4575 ;; (define_insn "fix_truncsfsi2_i4_2"
4576 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4577 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
4578 ;; (use (reg:PSI FPSCR_REG))
4579 ;; (clobber (reg:SI FPUL_REG))]
4580 ;; "TARGET_SH4"
4581 ;; "#"
4582 ;; [(set_attr "length" "4")
4583 ;; (set_attr "fp_mode" "single")])
4584
4585 ;;(define_split
4586 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4587 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
4588 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4589 ;; (clobber (reg:SI FPUL_REG))]
4590 ;; "TARGET_SH4"
4591 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
4592 ;; (use (match_dup 2))])
4593 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
4594
4595 (define_insn "*fixsfsi"
4596 [(set (match_operand:SI 0 "fpul_operand" "=y")
4597 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
4598 "TARGET_SH3E && ! TARGET_SH4"
4599 "ftrc %1,%0"
4600 [(set_attr "type" "fp")])
4601
4602 (define_insn "cmpgtsf_t"
4603 [(set (reg:SI T_REG)
4604 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
4605 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
4606 "TARGET_SH3E && ! TARGET_SH4"
4607 "fcmp/gt %1,%0"
4608 [(set_attr "type" "fp")
4609 (set_attr "fp_mode" "single")])
4610
4611 (define_insn "cmpeqsf_t"
4612 [(set (reg:SI T_REG)
4613 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
4614 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
4615 "TARGET_SH3E && ! TARGET_SH4"
4616 "fcmp/eq %1,%0"
4617 [(set_attr "type" "fp")
4618 (set_attr "fp_mode" "single")])
4619
4620 (define_insn "ieee_ccmpeqsf_t"
4621 [(set (reg:SI T_REG)
4622 (ior:SI (reg:SI T_REG)
4623 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
4624 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
4625 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
4626 "* return output_ieee_ccmpeq (insn, operands);"
4627 [(set_attr "length" "4")])
4628
4629
4630 (define_insn "cmpgtsf_t_i4"
4631 [(set (reg:SI T_REG)
4632 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
4633 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
4634 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4635 "TARGET_SH4"
4636 "fcmp/gt %1,%0"
4637 [(set_attr "type" "fp")
4638 (set_attr "fp_mode" "single")])
4639
4640 (define_insn "cmpeqsf_t_i4"
4641 [(set (reg:SI T_REG)
4642 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
4643 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
4644 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4645 "TARGET_SH4"
4646 "fcmp/eq %1,%0"
4647 [(set_attr "type" "fp")
4648 (set_attr "fp_mode" "single")])
4649
4650 (define_insn "*ieee_ccmpeqsf_t_4"
4651 [(set (reg:SI T_REG)
4652 (ior:SI (reg:SI T_REG)
4653 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
4654 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
4655 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4656 "TARGET_IEEE && TARGET_SH4"
4657 "* return output_ieee_ccmpeq (insn, operands);"
4658 [(set_attr "length" "4")
4659 (set_attr "fp_mode" "single")])
4660
4661 (define_expand "cmpsf"
4662 [(set (reg:SI T_REG)
4663 (compare (match_operand:SF 0 "arith_operand" "")
4664 (match_operand:SF 1 "arith_operand" "")))]
4665 "TARGET_SH3E"
4666 "
4667 {
4668 sh_compare_op0 = operands[0];
4669 sh_compare_op1 = operands[1];
4670 DONE;
4671 }")
4672
4673 (define_expand "negsf2"
4674 [(match_operand:SF 0 "fp_arith_reg_operand" "")
4675 (match_operand:SF 1 "fp_arith_reg_operand" "")]
4676 "TARGET_SH3E"
4677 "{ expand_sf_unop (&gen_negsf2_i, operands); DONE; }")
4678
4679 (define_insn "negsf2_i"
4680 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4681 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
4682 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4683 "TARGET_SH3E"
4684 "fneg %0"
4685 [(set_attr "type" "fmove")
4686 (set_attr "fp_mode" "single")])
4687
4688 (define_expand "sqrtsf2"
4689 [(match_operand:SF 0 "fp_arith_reg_operand" "")
4690 (match_operand:SF 1 "fp_arith_reg_operand" "")]
4691 "TARGET_SH3E"
4692 "{ expand_sf_unop (&gen_sqrtsf2_i, operands); DONE; }")
4693
4694 (define_insn "sqrtsf2_i"
4695 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4696 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
4697 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4698 "TARGET_SH3E"
4699 "fsqrt %0"
4700 [(set_attr "type" "fdiv")
4701 (set_attr "fp_mode" "single")])
4702
4703 (define_expand "abssf2"
4704 [(match_operand:SF 0 "fp_arith_reg_operand" "")
4705 (match_operand:SF 1 "fp_arith_reg_operand" "")]
4706 "TARGET_SH3E"
4707 "{ expand_sf_unop (&gen_abssf2_i, operands); DONE; }")
4708
4709 (define_insn "abssf2_i"
4710 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
4711 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
4712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4713 "TARGET_SH3E"
4714 "fabs %0"
4715 [(set_attr "type" "fmove")
4716 (set_attr "fp_mode" "single")])
4717
4718 (define_expand "adddf3"
4719 [(match_operand:DF 0 "fp_arith_reg_operand" "")
4720 (match_operand:DF 1 "fp_arith_reg_operand" "")
4721 (match_operand:DF 2 "fp_arith_reg_operand" "")]
4722 "TARGET_SH4"
4723 "{ expand_df_binop (&gen_adddf3_i, operands); DONE; }")
4724
4725 (define_insn "adddf3_i"
4726 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
4727 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
4728 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
4729 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4730 "TARGET_SH4"
4731 "fadd %2,%0"
4732 [(set_attr "type" "dfp_arith")
4733 (set_attr "fp_mode" "double")])
4734
4735 (define_expand "subdf3"
4736 [(match_operand:DF 0 "fp_arith_reg_operand" "")
4737 (match_operand:DF 1 "fp_arith_reg_operand" "")
4738 (match_operand:DF 2 "fp_arith_reg_operand" "")]
4739 "TARGET_SH4"
4740 "{ expand_df_binop (&gen_subdf3_i, operands); DONE; }")
4741
4742 (define_insn "subdf3_i"
4743 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
4744 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
4745 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
4746 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4747 "TARGET_SH4"
4748 "fsub %2,%0"
4749 [(set_attr "type" "dfp_arith")
4750 (set_attr "fp_mode" "double")])
4751
4752 (define_expand "muldf3"
4753 [(match_operand:DF 0 "fp_arith_reg_operand" "")
4754 (match_operand:DF 1 "fp_arith_reg_operand" "")
4755 (match_operand:DF 2 "fp_arith_reg_operand" "")]
4756 "TARGET_SH4"
4757 "{ expand_df_binop (&gen_muldf3_i, operands); DONE; }")
4758
4759 (define_insn "muldf3_i"
4760 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
4761 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
4762 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
4763 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4764 "TARGET_SH4"
4765 "fmul %2,%0"
4766 [(set_attr "type" "dfp_arith")
4767 (set_attr "fp_mode" "double")])
4768
4769 (define_expand "divdf3"
4770 [(match_operand:DF 0 "fp_arith_reg_operand" "")
4771 (match_operand:DF 1 "fp_arith_reg_operand" "")
4772 (match_operand:DF 2 "fp_arith_reg_operand" "")]
4773 "TARGET_SH4"
4774 "{ expand_df_binop (&gen_divdf3_i, operands); DONE; }")
4775
4776 (define_insn "divdf3_i"
4777 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
4778 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
4779 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
4780 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4781 "TARGET_SH4"
4782 "fdiv %2,%0"
4783 [(set_attr "type" "dfdiv")
4784 (set_attr "fp_mode" "double")])
4785
4786 (define_expand "floatsidf2"
4787 [(match_operand:DF 0 "fp_arith_reg_operand" "")
4788 (match_operand:SI 1 "fpul_operand" "")]
4789 "TARGET_SH4"
4790 "
4791 {
4792 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1], get_fpscr_rtx ()));
4793 DONE;
4794 }")
4795
4796 (define_insn "floatsidf2_i"
4797 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
4798 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
4799 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4800 "TARGET_SH4"
4801 "float %1,%0"
4802 [(set_attr "type" "dfp_conv")
4803 (set_attr "fp_mode" "double")])
4804
4805 (define_expand "fix_truncdfsi2"
4806 [(match_operand:SI 0 "fpul_operand" "")
4807 (match_operand:DF 1 "fp_arith_reg_operand" "")]
4808 "TARGET_SH4"
4809 "
4810 {
4811 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1], get_fpscr_rtx ()));
4812 DONE;
4813 }")
4814
4815 (define_insn "fix_truncdfsi2_i"
4816 [(set (match_operand:SI 0 "fpul_operand" "=y")
4817 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
4818 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4819 "TARGET_SH4"
4820 "ftrc %1,%0"
4821 [(set_attr "type" "dfp_conv")
4822 (set_attr "fp_mode" "double")])
4823
4824 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
4825 ;; fix_truncdfsi2_i.
4826 ;; (define_insn "fix_truncdfsi2_i4"
4827 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4828 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
4829 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4830 ;; (clobber (reg:SI FPUL_REG))]
4831 ;; "TARGET_SH4"
4832 ;; "#"
4833 ;; [(set_attr "length" "4")
4834 ;; (set_attr "fp_mode" "double")])
4835 ;;
4836 ;; (define_split
4837 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4838 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
4839 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
4840 ;; (clobber (reg:SI FPUL_REG))]
4841 ;; "TARGET_SH4"
4842 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
4843 ;; (use (match_dup 2))])
4844 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
4845
4846 (define_insn "cmpgtdf_t"
4847 [(set (reg:SI T_REG)
4848 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
4849 (match_operand:DF 1 "arith_reg_operand" "f")))
4850 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4851 "TARGET_SH4"
4852 "fcmp/gt %1,%0"
4853 [(set_attr "type" "dfp_cmp")
4854 (set_attr "fp_mode" "double")])
4855
4856 (define_insn "cmpeqdf_t"
4857 [(set (reg:SI T_REG)
4858 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
4859 (match_operand:DF 1 "arith_reg_operand" "f")))
4860 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4861 "TARGET_SH4"
4862 "fcmp/eq %1,%0"
4863 [(set_attr "type" "dfp_cmp")
4864 (set_attr "fp_mode" "double")])
4865
4866 (define_insn "*ieee_ccmpeqdf_t"
4867 [(set (reg:SI T_REG)
4868 (ior:SI (reg:SI T_REG)
4869 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
4870 (match_operand:DF 1 "arith_reg_operand" "f"))))
4871 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4872 "TARGET_IEEE && TARGET_SH4"
4873 "* return output_ieee_ccmpeq (insn, operands);"
4874 [(set_attr "length" "4")
4875 (set_attr "fp_mode" "double")])
4876
4877 (define_expand "cmpdf"
4878 [(set (reg:SI T_REG)
4879 (compare (match_operand:DF 0 "arith_operand" "")
4880 (match_operand:DF 1 "arith_operand" "")))]
4881 "TARGET_SH4"
4882 "
4883 {
4884 sh_compare_op0 = operands[0];
4885 sh_compare_op1 = operands[1];
4886 DONE;
4887 }")
4888
4889 (define_expand "negdf2"
4890 [(match_operand:DF 0 "arith_reg_operand" "")
4891 (match_operand:DF 1 "arith_reg_operand" "")]
4892 "TARGET_SH4"
4893 "{ expand_df_unop (&gen_negdf2_i, operands); DONE; }")
4894
4895 (define_insn "negdf2_i"
4896 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4897 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
4898 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4899 "TARGET_SH4"
4900 "fneg %0"
4901 [(set_attr "type" "fmove")
4902 (set_attr "fp_mode" "double")])
4903
4904 (define_expand "sqrtdf2"
4905 [(match_operand:DF 0 "arith_reg_operand" "")
4906 (match_operand:DF 1 "arith_reg_operand" "")]
4907 "TARGET_SH4"
4908 "{ expand_df_unop (&gen_sqrtdf2_i, operands); DONE; }")
4909
4910 (define_insn "sqrtdf2_i"
4911 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4912 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
4913 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4914 "TARGET_SH4"
4915 "fsqrt %0"
4916 [(set_attr "type" "dfdiv")
4917 (set_attr "fp_mode" "double")])
4918
4919 (define_expand "absdf2"
4920 [(match_operand:DF 0 "arith_reg_operand" "")
4921 (match_operand:DF 1 "arith_reg_operand" "")]
4922 "TARGET_SH4"
4923 "{ expand_df_unop (&gen_absdf2_i, operands); DONE; }")
4924
4925 (define_insn "absdf2_i"
4926 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4927 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
4928 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4929 "TARGET_SH4"
4930 "fabs %0"
4931 [(set_attr "type" "fmove")
4932 (set_attr "fp_mode" "double")])
4933
4934 (define_expand "extendsfdf2"
4935 [(match_operand:DF 0 "fp_arith_reg_operand" "")
4936 (match_operand:SF 1 "fpul_operand" "")]
4937 "TARGET_SH4"
4938 "
4939 {
4940 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4941 DONE;
4942 }")
4943
4944 (define_insn "extendsfdf2_i4"
4945 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
4946 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
4947 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4948 "TARGET_SH4"
4949 "fcnvsd %1,%0"
4950 [(set_attr "type" "fp")
4951 (set_attr "fp_mode" "double")])
4952
4953 (define_expand "truncdfsf2"
4954 [(match_operand:SF 0 "fpul_operand" "")
4955 (match_operand:DF 1 "fp_arith_reg_operand" "")]
4956 "TARGET_SH4"
4957 "
4958 {
4959 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4960 DONE;
4961 }")
4962
4963 (define_insn "truncdfsf2_i4"
4964 [(set (match_operand:SF 0 "fpul_operand" "=y")
4965 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
4966 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4967 "TARGET_SH4"
4968 "fcnvds %1,%0"
4969 [(set_attr "type" "fp")
4970 (set_attr "fp_mode" "double")])
4971 \f
4972 ;; Bit field extract patterns. These give better code for packed bitfields,
4973 ;; because they allow auto-increment addresses to be generated.
4974
4975 (define_expand "insv"
4976 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
4977 (match_operand:SI 1 "immediate_operand" "")
4978 (match_operand:SI 2 "immediate_operand" ""))
4979 (match_operand:SI 3 "general_operand" ""))]
4980 "! TARGET_LITTLE_ENDIAN"
4981 "
4982 {
4983 rtx addr_target, orig_address, shift_reg;
4984 HOST_WIDE_INT size;
4985
4986 /* ??? expmed doesn't care for non-register predicates. */
4987 if (! memory_operand (operands[0], VOIDmode)
4988 || ! immediate_operand (operands[1], VOIDmode)
4989 || ! immediate_operand (operands[2], VOIDmode)
4990 || ! general_operand (operands[3], VOIDmode))
4991 FAIL;
4992 /* If this isn't a 16 / 24 / 32 bit field, or if
4993 it doesn't start on a byte boundary, then fail. */
4994 size = INTVAL (operands[1]);
4995 if (size < 16 || size > 32 || size % 8 != 0
4996 || (INTVAL (operands[2]) % 8) != 0)
4997 FAIL;
4998
4999 size /= 8;
5000 orig_address = XEXP (operands[0], 0);
5001 shift_reg = gen_reg_rtx (SImode);
5002 emit_insn (gen_movsi (shift_reg, operands[3]));
5003 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
5004
5005 operands[0] = change_address (operands[0], QImode, addr_target);
5006 emit_insn (gen_movqi (operands[0], gen_rtx_SUBREG (QImode, shift_reg, 0)));
5007
5008 while (size -= 1)
5009 {
5010 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
5011 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
5012 emit_insn (gen_movqi (operands[0],
5013 gen_rtx_SUBREG (QImode, shift_reg, 0)));
5014 }
5015
5016 DONE;
5017 }")
5018 \f
5019 ;; -------------------------------------------------------------------------
5020 ;; Peepholes
5021 ;; -------------------------------------------------------------------------
5022
5023 ;; This matches cases where a stack pointer increment at the start of the
5024 ;; epilogue combines with a stack slot read loading the return value.
5025
5026 (define_peephole
5027 [(set (match_operand:SI 0 "arith_reg_operand" "")
5028 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
5029 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
5030 "REGNO (operands[1]) != REGNO (operands[0])"
5031 "mov.l @%1+,%0")
5032
5033 ;; See the comment on the dt combiner pattern above.
5034
5035 (define_peephole
5036 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5037 (plus:SI (match_dup 0)
5038 (const_int -1)))
5039 (set (reg:SI T_REG)
5040 (eq:SI (match_dup 0)
5041 (const_int 0)))]
5042 "TARGET_SH2"
5043 "dt %0")
5044
5045 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
5046 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
5047 ;; reload when the constant is too large for a reg+offset address.
5048
5049 ;; ??? We would get much better code if this was done in reload. This would
5050 ;; require modifying find_reloads_address to recognize that if the constant
5051 ;; is out-of-range for an immediate add, then we get better code by reloading
5052 ;; the constant into a register than by reloading the sum into a register,
5053 ;; since the former is one instruction shorter if the address does not need
5054 ;; to be offsettable. Unfortunately this does not work, because there is
5055 ;; only one register, r0, that can be used as an index register. This register
5056 ;; is also the function return value register. So, if we try to force reload
5057 ;; to use double-reg addresses, then we end up with some instructions that
5058 ;; need to use r0 twice. The only way to fix this is to change the calling
5059 ;; convention so that r0 is not used to return values.
5060
5061 (define_peephole
5062 [(set (match_operand:SI 0 "register_operand" "=r")
5063 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5064 (set (mem:SI (match_dup 0))
5065 (match_operand:SI 2 "general_movsrc_operand" ""))]
5066 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
5067 "mov.l %2,@(%0,%1)")
5068
5069 (define_peephole
5070 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5072 (set (match_operand:SI 2 "general_movdst_operand" "")
5073 (mem:SI (match_dup 0)))]
5074 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
5075 "mov.l @(%0,%1),%2")
5076
5077 (define_peephole
5078 [(set (match_operand:SI 0 "register_operand" "=r")
5079 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5080 (set (mem:HI (match_dup 0))
5081 (match_operand:HI 2 "general_movsrc_operand" ""))]
5082 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
5083 "mov.w %2,@(%0,%1)")
5084
5085 (define_peephole
5086 [(set (match_operand:SI 0 "register_operand" "=r")
5087 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5088 (set (match_operand:HI 2 "general_movdst_operand" "")
5089 (mem:HI (match_dup 0)))]
5090 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
5091 "mov.w @(%0,%1),%2")
5092
5093 (define_peephole
5094 [(set (match_operand:SI 0 "register_operand" "=r")
5095 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5096 (set (mem:QI (match_dup 0))
5097 (match_operand:QI 2 "general_movsrc_operand" ""))]
5098 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
5099 "mov.b %2,@(%0,%1)")
5100
5101 (define_peephole
5102 [(set (match_operand:SI 0 "register_operand" "=r")
5103 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5104 (set (match_operand:QI 2 "general_movdst_operand" "")
5105 (mem:QI (match_dup 0)))]
5106 "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
5107 "mov.b @(%0,%1),%2")
5108
5109 (define_peephole
5110 [(set (match_operand:SI 0 "register_operand" "=r")
5111 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5112 (set (mem:SF (match_dup 0))
5113 (match_operand:SF 2 "general_movsrc_operand" ""))]
5114 "REGNO (operands[0]) == 0
5115 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
5116 || (GET_CODE (operands[2]) == SUBREG
5117 && REGNO (SUBREG_REG (operands[2])) < 16))
5118 && reg_unused_after (operands[0], insn)"
5119 "mov.l %2,@(%0,%1)")
5120
5121 (define_peephole
5122 [(set (match_operand:SI 0 "register_operand" "=r")
5123 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5124 (set (match_operand:SF 2 "general_movdst_operand" "")
5125
5126 (mem:SF (match_dup 0)))]
5127 "REGNO (operands[0]) == 0
5128 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
5129 || (GET_CODE (operands[2]) == SUBREG
5130 && REGNO (SUBREG_REG (operands[2])) < 16))
5131 && reg_unused_after (operands[0], insn)"
5132 "mov.l @(%0,%1),%2")
5133
5134 (define_peephole
5135 [(set (match_operand:SI 0 "register_operand" "=r")
5136 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5137 (set (mem:SF (match_dup 0))
5138 (match_operand:SF 2 "general_movsrc_operand" ""))]
5139 "REGNO (operands[0]) == 0
5140 && ((GET_CODE (operands[2]) == REG
5141 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
5142 || (GET_CODE (operands[2]) == SUBREG
5143 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
5144 && reg_unused_after (operands[0], insn)"
5145 "fmov{.s|} %2,@(%0,%1)")
5146
5147 (define_peephole
5148 [(set (match_operand:SI 0 "register_operand" "=r")
5149 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
5150 (set (match_operand:SF 2 "general_movdst_operand" "")
5151
5152 (mem:SF (match_dup 0)))]
5153 "REGNO (operands[0]) == 0
5154 && ((GET_CODE (operands[2]) == REG
5155 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
5156 || (GET_CODE (operands[2]) == SUBREG
5157 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
5158 && reg_unused_after (operands[0], insn)"
5159 "fmov{.s|} @(%0,%1),%2")
5160
5161 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
5162 (define_insn "sp_switch_1"
5163 [(const_int 1)]
5164 ""
5165 "*
5166 {
5167 rtx xoperands[1];
5168
5169 xoperands[0] = sp_switch;
5170 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
5171 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
5172 return \"mov r0,r15\";
5173 }"
5174 [(set_attr "length" "10")])
5175
5176 ;; Switch back to the original stack for interrupt functions with the
5177 ;; sp_switch attribute. */
5178 (define_insn "sp_switch_2"
5179 [(const_int 2)]
5180 ""
5181 "mov.l @r15+,r15\;mov.l @r15+,r0"
5182 [(set_attr "length" "4")])