* sh.c (trap_exit, sp_switch): New variables.
[official-gcc.git] / gcc / config / sh / sh.md
blobd0f79ff37184b580bbb6a3be3c86f0c4c8d78fbf
1 ;;- Machine description for the Hitachi SH.
2 ;;  Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
3 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
4 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences.  Especially the sequences for arithmetic right shifts.
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
32 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33 ;; way to generate them.
35 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36 ;; for a str* inline function.
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42 ;; Special constraints for SH machine description:
44 ;;    t -- T
45 ;;    x -- mac
46 ;;    l -- pr
47 ;;    z -- r0
49 ;; Special formats used for outputting SH instructions:
51 ;;   %.  --  print a .s if insn needs delay slot
52 ;;   %@  --  print rte/rts if is/isn't an interrupt function
53 ;;   %#  --  output a nop if there is nothing to put in the delay slot
54 ;;   %O  --  print a constant without the #
55 ;;   %R  --  print the lsw reg of a double
56 ;;   %S  --  print the msw reg of a double
57 ;;   %T  --  print next word of a double REG or MEM
59 ;; Special predicates:
61 ;;  arith_operand          -- operand is valid source for arithmetic op
62 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
63 ;;  general_movdst_operand -- operand is valid move destination
64 ;;  general_movsrc_operand -- operand is valid move source
65 ;;  logical_operand        -- operand is valid source for logical op
66 ;; -------------------------------------------------------------------------
67 ;; Attributes
68 ;; -------------------------------------------------------------------------
70 ;; Target CPU.
72 (define_attr "cpu" "sh0,sh1,sh2,sh3,sh3e"
73   (const (symbol_ref "sh_cpu_attr")))
75 ;; cbranch      conditional branch instructions
76 ;; jump         unconditional jumps
77 ;; arith        ordinary arithmetic
78 ;; load         from memory
79 ;; store        to memory
80 ;; move         register to register
81 ;; smpy         word precision integer multiply
82 ;; dmpy         longword or doublelongword precision integer multiply
83 ;; return       rts
84 ;; pload        load of pr reg, which can't be put into delay slot of rts
85 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
86 ;; pcload       pc relative load of constant value
87 ;; rte          return from exception
88 ;; sfunc        special function call with known used registers
89 ;; call         function call
90 ;; fp           floating point
91 ;; fdiv         floating point divide (or square root)
93 (define_attr "type"
94  "cbranch,jump,arith,other,load,store,move,smpy,dmpy,return,pload,pstore,pcload,rte,sfunc,call,fp,fdiv"
95   (const_string "other"))
97 ; If a conditional branch destination is within -252..258 bytes away
98 ; from the instruction it can be 2 bytes long.  Something in the
99 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
100 ; branches are 16 bytes long.
102 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
103 ; Otherwise, it must be 14 bytes long.
105 ; All other instructions are two bytes long by default.
107 ; All positive offsets have an adjustment added, which is the number of bytes
108 ; difference between this instruction length and the next larger instruction
109 ; length.  This is because shorten_branches starts with the largest
110 ; instruction size and then tries to reduce them.
112 (define_attr "length" ""
113   (cond [(eq_attr "type" "cbranch")
114          (if_then_else (and (ge (minus (match_dup 0) (pc))
115                                 (const_int -252))
116                             (le (minus (match_dup 0) (pc))
117                                 (const_int 262)))
118                        (const_int 2)
119                        (if_then_else (and (ge (minus (match_dup 0) (pc))
120                                               (const_int -4090))
121                                           (le (minus (match_dup 0) (pc))
122                                               (const_int 4110)))
123                                      (const_int 6)
124                                      (const_int 16)))
126          (eq_attr "type" "jump")
127          (if_then_else (and (ge (minus (match_dup 0) (pc))
128                                 (const_int -4092))
129                             (le (minus (match_dup 0) (pc))
130                                 (const_int 4110)))
131                        (const_int 2)
132                        (const_int 14))
133          ] (const_int 2)))
135 ;; (define_function_unit {name} {num-units} {n-users} {test}
136 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
138 ;; Load and store instructions save a cycle if they are aligned on a
139 ;; four byte boundary.  Using a function unit for stores encourages
140 ;; gcc to separate load and store instructions by one instruction,
141 ;; which makes it more likely that the linker will be able to word
142 ;; align them when relaxing.
143 (define_function_unit "memory" 1 0
144   (eq_attr "type" "load,pcload,pload,store,pstore") 2 2)
146 ;; ??? These are approximations.
147 (define_function_unit "mpy"    1 0 (eq_attr "type" "smpy") 2 2)
148 (define_function_unit "mpy"    1 0 (eq_attr "type" "dmpy") 3 3)
150 (define_function_unit "fp"     1 0 (eq_attr "type" "fp") 2 1)
151 (define_function_unit "fp"     1 0 (eq_attr "type" "fdiv") 13 12)
153 ; Definitions for filling branch delay slots.
155 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
157 (define_attr "hit_stack" "yes,no" (const_string "no"))
159 (define_attr "interrupt_function" "no,yes"
160   (const (symbol_ref "pragma_interrupt")))
162 (define_attr "in_delay_slot" "yes,no"
163   (cond [(eq_attr "type" "cbranch") (const_string "no")
164          (eq_attr "type" "pcload") (const_string "no")
165          (eq_attr "needs_delay_slot" "yes") (const_string "no")
166          (eq_attr "length" "2") (const_string "yes")
167          ] (const_string "no")))
169 (define_delay
170   (eq_attr "needs_delay_slot" "yes")
171   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
173 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
174 ;; and thus we can't put a pop instruction in its delay slot.
175 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
176 ;; instruction can go in the delay slot.
178 ;; Since a normal return (rts) implicitly uses the PR register,
179 ;; we can't allow PR register loads in an rts delay slot.
181 (define_delay
182   (eq_attr "type" "return")
183   [(and (eq_attr "in_delay_slot" "yes")
184         (ior (and (eq_attr "interrupt_function" "no")
185                   (eq_attr "type" "!pload"))
186              (and (eq_attr "interrupt_function" "yes")
187                   (eq_attr "hit_stack" "no")))) (nil) (nil)])
189 ;; Since a call implicitly uses the PR register, we can't allow
190 ;; a PR register store in a jsr delay slot.
192 (define_delay
193   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
194   [(and (eq_attr "in_delay_slot" "yes")
195         (eq_attr "type" "!pstore")) (nil) (nil)])
197 ;; Say that we have annulled true branches, since this gives smaller and
198 ;; faster code when branches are predicted as not taken.
200 ;; ??? Branches which are out-of-range actually have two delay slots,
201 ;; the first is either always executed or else annulled false, and the
202 ;; second is always annulled false.  Handling these differently from
203 ;; in range branches would give better code.
205 (define_delay
206   (and (eq_attr "type" "cbranch")
207        (eq_attr "cpu" "sh2,sh3"))
208   [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
210 ;; -------------------------------------------------------------------------
211 ;; SImode signed integer comparisons
212 ;; -------------------------------------------------------------------------
214 (define_insn ""
215   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
216         (eq:SI (reg:SI 18)
217                (const_int 1)))]
218   ""
219   "movt %0")
221 (define_insn ""
222   [(set (reg:SI 18)
223         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
224                        (match_operand:SI 1 "arith_operand" "L,r"))
225                (const_int 0)))]
226   ""
227   "tst  %1,%0")
229 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
230 ;; That would still allow reload to create cmpi instructions, but would
231 ;; perhaps allow forcing the constant into a register when that is better.
232 ;; Probably should use r0 for mem/imm compares, but force constant into a
233 ;; register for pseudo/imm compares.
235 (define_insn "cmpeqsi_t"
236   [(set (reg:SI 18) (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
237                            (match_operand:SI 1 "arith_operand" "N,rI,r")))]
238   ""
239   "@
240         tst     %0,%0
241         cmp/eq  %1,%0
242         cmp/eq  %1,%0")
244 (define_insn "cmpgtsi_t"
245   [(set (reg:SI 18) (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
246                            (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
247   ""
248   "@
249         cmp/gt  %1,%0
250         cmp/pl  %0")
252 (define_insn "cmpgesi_t"
253   [(set (reg:SI 18) (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
254                            (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
255   ""
256   "@
257         cmp/ge  %1,%0
258         cmp/pz  %0")
260 ;; -------------------------------------------------------------------------
261 ;; SImode unsigned integer comparisons
262 ;; -------------------------------------------------------------------------
264 (define_insn "cmpgeusi_t"
265   [(set (reg:SI 18) (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
266                             (match_operand:SI 1 "arith_reg_operand" "r")))]
267   ""
268   "cmp/hs       %1,%0")
270 (define_insn "cmpgtusi_t"
271   [(set (reg:SI 18) (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
272                             (match_operand:SI 1 "arith_reg_operand" "r")))]
273   ""
274   "cmp/hi       %1,%0")
276 ;; We save the compare operands in the cmpxx patterns and use them when
277 ;; we generate the branch.
279 (define_expand "cmpsi"
280   [(set (reg:SI 18) (compare (match_operand:SI 0 "arith_operand" "")
281                              (match_operand:SI 1 "arith_operand" "")))]
282   ""
283   "
285   sh_compare_op0 = operands[0];
286   sh_compare_op1 = operands[1];
287   DONE;
290 ;; -------------------------------------------------------------------------
291 ;; Addition instructions
292 ;; -------------------------------------------------------------------------
294 ;; ??? This should be a define expand.
296 (define_insn "adddi3"
297   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
298         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
299                  (match_operand:DI 2 "arith_reg_operand" "r")))
300    (clobber (reg:SI 18))]
301   ""
302   "clrt\;addc   %R2,%R0\;addc   %S2,%S0"
303   [(set_attr "length" "6")])
305 (define_insn "addsi3"
306   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
307         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
308                  (match_operand:SI 2 "arith_operand" "rI")))]
309   ""
310   "add  %2,%0"
311   [(set_attr "type" "arith")])
313 ;; -------------------------------------------------------------------------
314 ;; Subtraction instructions
315 ;; -------------------------------------------------------------------------
317 ;; ??? This should be a define expand.
319 (define_insn "subdi3"
320   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
321         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
322                  (match_operand:DI 2 "arith_reg_operand" "r")))
323    (clobber (reg:SI 18))]
324   ""
325   "clrt\;subc   %R2,%R0\;subc   %S2,%S0"
326   [(set_attr "length" "6")])
328 (define_insn "*subsi3_internal"
329   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
330         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
331                   (match_operand:SI 2 "arith_reg_operand" "r")))]
332   ""
333   "sub  %2,%0"
334   [(set_attr "type" "arith")])
336 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
337 ;; will sometimes save one instruction.  Otherwise we might get
338 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
339 ;; are the same.
341 (define_expand "subsi3"
342   [(set (match_operand:SI 0 "arith_reg_operand" "")
343         (minus:SI (match_operand:SI 1 "arith_operand" "")
344                   (match_operand:SI 2 "arith_reg_operand" "")))]
345   ""
346   "
348   if (GET_CODE (operands[1]) == CONST_INT)
349     {
350       emit_insn (gen_negsi2 (operands[0], operands[2]));
351       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
352       DONE;
353     }
356 ;; -------------------------------------------------------------------------
357 ;; Division instructions
358 ;; -------------------------------------------------------------------------
360 ;; We take advantage of the library routines which don't clobber as many
361 ;; registers as a normal function call would.
363 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
364 ;; hard register 0.  If we used hard register 0, then the next instruction
365 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
366 ;; gets allocated to a stack slot that needs its address reloaded, then
367 ;; there is nothing to prevent reload from using r0 to reload the address.
368 ;; This reload would clobber the value in r0 we are trying to store.
369 ;; If we let reload allocate r0, then this problem can never happen.
371 (define_insn ""
372   [(set (match_operand:SI 1 "register_operand" "=z")
373         (udiv:SI (reg:SI 4) (reg:SI 5)))
374    (clobber (reg:SI 18))
375    (clobber (reg:SI 17))
376    (clobber (reg:SI 4))
377    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
378   ""
379   "jsr  @%0%#"
380   [(set_attr "type" "sfunc")
381    (set_attr "needs_delay_slot" "yes")])
383 (define_expand "udivsi3"
384   [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
385    (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
386    (set (match_dup 3) (symbol_ref:SI "__udivsi3"))
387    (parallel [(set (match_operand:SI 0 "register_operand" "")
388                    (udiv:SI (reg:SI 4)
389                             (reg:SI 5)))
390               (clobber (reg:SI 18))
391               (clobber (reg:SI 17))
392               (clobber (reg:SI 4))
393               (use (match_dup 3))])]
394   ""
395   "operands[3] = gen_reg_rtx(SImode);")
397 (define_insn ""
398   [(set (match_operand:SI 1 "register_operand" "=z")
399         (div:SI (reg:SI 4) (reg:SI 5)))
400    (clobber (reg:SI 18))
401    (clobber (reg:SI 17))
402    (clobber (reg:SI 1))
403    (clobber (reg:SI 2))
404    (clobber (reg:SI 3))
405    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
406   ""
407   "jsr  @%0%#"
408   [(set_attr "type" "sfunc")
409    (set_attr "needs_delay_slot" "yes")])
411 (define_expand "divsi3"
412   [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
413    (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
414    (set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
415    (parallel [(set (match_operand:SI 0 "register_operand" "")
416                    (div:SI (reg:SI 4)
417                            (reg:SI 5)))
418               (clobber (reg:SI 18))
419               (clobber (reg:SI 17))
420               (clobber (reg:SI 1))
421               (clobber (reg:SI 2))
422               (clobber (reg:SI 3))
423               (use (match_dup 3))])]
424   ""
425   "operands[3] = gen_reg_rtx(SImode);")
427 ;; -------------------------------------------------------------------------
428 ;; Multiplication instructions
429 ;; -------------------------------------------------------------------------
431 (define_insn ""
432   [(set (reg:SI 21)
433         (mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r"))
434                  (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))]
435   ""
436   "mulu %1,%0"
437   [(set_attr "type" "smpy")])
439 (define_insn ""
440   [(set (reg:SI 21)
441         (mult:SI (sign_extend:SI
442                   (match_operand:HI 0 "arith_reg_operand" "r"))
443                  (sign_extend:SI
444                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
445   ""
446   "muls %1,%0"
447   [(set_attr "type" "smpy")])
449 (define_expand "mulhisi3"
450   [(set (reg:SI 21)
451         (mult:SI (sign_extend:SI
452                   (match_operand:HI 1 "arith_reg_operand" ""))
453                  (sign_extend:SI
454                   (match_operand:HI 2 "arith_reg_operand" ""))))
455    (set (match_operand:SI 0 "arith_reg_operand" "")
456         (reg:SI 21))]
457   ""
458   "")
460 (define_expand "umulhisi3"
461   [(set (reg:SI 21)
462         (mult:SI (zero_extend:SI
463                   (match_operand:HI 1 "arith_reg_operand" ""))
464                  (zero_extend:SI
465                   (match_operand:HI 2 "arith_reg_operand" ""))))
466    (set (match_operand:SI 0 "arith_reg_operand" "")
467         (reg:SI 21))]
468   ""
469   "")
471 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
472 ;; a call to a routine which clobbers known registers.
474 (define_insn ""
475   [(set (match_operand:SI 1 "register_operand" "=z")
476         (mult:SI (reg:SI 4) (reg:SI 5)))
477    (clobber (reg:SI 21))
478    (clobber (reg:SI 18))
479    (clobber (reg:SI 17))
480    (clobber (reg:SI 3))
481    (clobber (reg:SI 2))
482    (clobber (reg:SI 1))
483    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
484   ""
485   "jsr  @%0%#"
486   [(set_attr "type" "sfunc")
487    (set_attr "needs_delay_slot" "yes")])
489 (define_expand "mulsi3_call"
490   [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
491    (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
492    (set (match_dup 3) (symbol_ref:SI "__mulsi3"))
493    (parallel[(set (match_operand:SI 0 "register_operand" "")
494                   (mult:SI (reg:SI 4)
495                            (reg:SI 5)))
496              (clobber (reg:SI 21))
497              (clobber (reg:SI 18))
498              (clobber (reg:SI 17))
499              (clobber (reg:SI 3))
500              (clobber (reg:SI 2))
501              (clobber (reg:SI 1))
502              (use (match_dup 3))])]
503   ""
504   "operands[3] = gen_reg_rtx(SImode);")
506 (define_insn "mul_l"
507   [(set (reg:SI 21)
508         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
509                  (match_operand:SI 1 "arith_reg_operand" "r")))]
510   "TARGET_SH2"
511   "mul.l        %1,%0"
512   [(set_attr "type" "dmpy")])
514 (define_expand "mulsi3"
515   [(set (reg:SI 21)
516         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
517                   (match_operand:SI 2 "arith_reg_operand" "")))
518    (set (match_operand:SI 0 "arith_reg_operand" "")
519         (reg:SI 21))]
520   ""
521   "
523   if (!TARGET_SH2)
524     {
525       FAIL;
526       /* ??? Does this give worse or better code?  */
527       emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
528       DONE;
529     }
532 (define_insn "mulsidi3_i"
533   [(set (reg:DI 20)
534         (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
535                  (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
536   "TARGET_SH2"
537   "dmuls.l      %1,%0"
538   [(set_attr "type" "dmpy")])
540 (define_expand "mulsidi3"
541   [(set (reg:DI 20)
542         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
543                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
544    (set (match_operand:DI 0 "arith_reg_operand" "")
545         (reg:DI 20))]
546   "TARGET_SH2"
547   "
549   /* We must swap the two words when copying them from MACH/MACL to the
550      output register.  */
551   if (TARGET_LITTLE_ENDIAN)
552     {
553       rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
554       rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
556       emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
558       emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
559       emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
560       emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
561       DONE;
562     }
565 (define_insn "umulsidi3_i"
566   [(set (reg:DI 20)
567         (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
568                  (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
569   "TARGET_SH2"
570   "dmulu.l      %1,%0"
571   [(set_attr "type" "dmpy")])
573 (define_expand "umulsidi3"
574   [(set (reg:DI 20)
575         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
576                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
577    (set (match_operand:DI 0 "arith_reg_operand" "")
578         (reg:DI 20))]
579   "TARGET_SH2"
580   "
582   /* We must swap the two words when copying them from MACH/MACL to the
583      output register.  */
584   if (TARGET_LITTLE_ENDIAN)
585     {
586       rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
587       rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
589       emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
591       emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
592       emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
593       emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
594       DONE;
595     }
598 (define_insn ""
599   [(set (reg:SI 20)
600         (truncate:SI
601          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
602                                (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
603                       (const_int 32))))
604    (clobber (reg:SI 21))]
605   "TARGET_SH2"
606   "dmuls.l      %1,%0"
607   [(set_attr "type" "dmpy")])
609 (define_expand "smulsi3_highpart"
610   [(parallel [(set (reg:SI 20)
611                    (truncate:SI
612                     (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
613                                           (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
614                                  (const_int 32))))
615               (clobber (reg:SI 21))])
616    (set (match_operand:SI 0 "arith_reg_operand" "")
617         (reg:SI 20))]
618   "TARGET_SH2"
619   "")
621 (define_insn ""
622   [(set (reg:SI 20)
623         (truncate:SI
624          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
625                                (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
626                       (const_int 32))))
627    (clobber (reg:SI 21))]
628   "TARGET_SH2"
629   "dmulu.l      %1,%0"
630   [(set_attr "type" "dmpy")])
632 (define_expand "umulsi3_highpart"
633   [(parallel [(set (reg:SI 20)
634                    (truncate:SI
635                     (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
636                                           (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
637                                  (const_int 32))))
638               (clobber (reg:SI 21))])
639    (set (match_operand:SI 0 "arith_reg_operand" "")
640         (reg:SI 20))]
641   "TARGET_SH2"
642   "")
644 ;; -------------------------------------------------------------------------
645 ;; Logical operations
646 ;; -------------------------------------------------------------------------
648 (define_insn ""
649   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
650         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
651                 (match_operand:SI 2 "logical_operand" "r,L")))]
652   ""
653   "and  %2,%0"
654   [(set_attr "type" "arith")])
656 ;; If the constant is 255, then emit a extu.b instruction instead of an
657 ;; and, since that will give better code.
659 (define_expand "andsi3"
660   [(set (match_operand:SI 0 "arith_reg_operand" "")
661         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
662                 (match_operand:SI 2 "logical_operand" "")))]
663   ""
664   "
666   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
667     {
668       emit_insn (gen_zero_extendqisi2 (operands[0],
669                                        gen_lowpart (QImode, operands[1])));
670       DONE;
671     }
674 (define_insn "iorsi3"
675   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
676         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
677                 (match_operand:SI 2 "logical_operand" "r,L")))]
678   ""
679   "or   %2,%0")
681 (define_insn "xorsi3"
682   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
683         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
684                 (match_operand:SI 2 "logical_operand" "L,r")))]
685   ""
686   "xor  %2,%0"
687   [(set_attr "type" "arith")])
689 ;; -------------------------------------------------------------------------
690 ;; Shifts and rotates
691 ;; -------------------------------------------------------------------------
693 (define_insn "rotlsi3_1"
694   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
695         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
696                    (const_int 1)))
697    (set (reg:SI 18)
698         (lshiftrt:SI (match_dup 1) (const_int 31)))]
699   ""
700   "rotl %0")
702 (define_insn "rotlsi3_31"
703   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
704         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
705                    (const_int 31)))
706    (clobber (reg:SI 18))]
707   ""
708   "rotr %0")
710 (define_insn ""
711   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
712         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
713                    (const_int 16)))]
714   ""
715   "swap.w       %1,%0")
717 (define_expand "rotlsi3"
718   [(set (match_operand:SI 0 "arith_reg_operand" "")
719         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
720                    (match_operand:SI 2 "immediate_operand" "")))]
721   ""
722   "
724   if (GET_CODE (operands[2]) != CONST_INT)
725     FAIL;
727   if (INTVAL (operands[2]) == 1)
728     {
729       emit_insn (gen_rotlsi3_1 (operands[0], operands[1]));
730       DONE;
731     }
732   else if (INTVAL (operands[2]) == 31)
733     {
734       emit_insn (gen_rotlsi3_31 (operands[0], operands[1]));
735       DONE;
736     }
737   else if (INTVAL (operands[2]) != 16)
738     FAIL;
741 (define_insn ""
742   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
743         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
744                    (const_int 8)))]
745   ""
746   "swap.b       %1,%0")
748 (define_expand "rotlhi3"
749   [(set (match_operand:HI 0 "arith_reg_operand" "")
750         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
751                    (match_operand:HI 2 "immediate_operand" "")))]
752   ""
753   "
755   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
756     FAIL;
760 ;; shift left
762 (define_insn "ashlsi3_d"
763   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
764         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
765                    (match_operand:SI 2 "arith_reg_operand" "r")))]
766   "TARGET_SH3"
767   "shld %2,%0")
769 (define_insn "ashlsi3_k"
770   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
771         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
772                    (match_operand:SI 2 "const_int_operand" "M,K")))]
773   "CONST_OK_FOR_K (INTVAL (operands[2]))"
774   "@
775         add     %0,%0
776         shll%O2 %0")
778 (define_insn "ashlhi3_k"
779   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
780         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
781                    (match_operand:HI 2 "const_int_operand" "M,K")))]
782   "CONST_OK_FOR_K (INTVAL (operands[2]))"
783   "@
784         add     %0,%0
785         shll%O2 %0")
787 (define_insn "ashlsi3_n"
788   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
789         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
790                    (match_operand:SI 2 "const_int_operand" "n")))
791    (clobber (reg:SI 18))]
792   ""
793   "#"
794   [(set (attr "length")
795         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
796                (const_string "2")
797                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
798                (const_string "4")
799                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
800                (const_string "6")]
801               (const_string "8")))
802    (set_attr "type" "arith")])
804 (define_split
805   [(set (match_operand:SI 0 "arith_reg_operand" "")
806         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
807                    (match_operand:SI 2 "const_int_operand" "n")))
808    (clobber (reg:SI 18))]
809   ""
810   [(use (reg:SI 0))]
811   "
813   gen_shifty_op (ASHIFT, operands);
814   DONE;
817 (define_expand "ashlsi3"
818   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
819                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
820                               (match_operand:SI 2 "nonmemory_operand" "")))
821               (clobber (reg:SI 18))])]
822   ""
823   "
825   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
826     {
827       emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
828       DONE;
829     }
830   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
831     FAIL;
834 (define_insn "ashlhi3"
835   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
836         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
837                    (match_operand:HI 2 "const_int_operand" "n")))
838    (clobber (reg:SI 18))]
839   ""
840   "#"
841   [(set (attr "length")
842         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
843                (const_string "2")
844                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
845                (const_string "4")]
846               (const_string "6")))
847    (set_attr "type" "arith")])
849 (define_split
850   [(set (match_operand:HI 0 "arith_reg_operand" "")
851         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
852                    (match_operand:HI 2 "const_int_operand" "n")))
853    (clobber (reg:SI 18))]
854   ""
855   [(use (reg:SI 0))]
856   "
858   gen_shifty_hi_op (ASHIFT, operands);
859   DONE;
863 ; arithmetic shift right
866 (define_insn "ashrsi3_k"
867   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
868         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
869                      (match_operand:SI 2 "const_int_operand" "M")))
870    (clobber (reg:SI 18))]
871   "INTVAL (operands[2]) == 1"
872   "shar %0"
873   [(set_attr "type" "arith")])
875 (define_insn "ashrhi3_k"
876   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
877         (ashiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
878                      (match_operand:HI 2 "const_int_operand" "M")))
879    (clobber (reg:SI 18))]
880   "INTVAL (operands[2]) == 1"
881   "shar %0"
882   [(set_attr "type" "arith")])
884 ;; ??? This should be a define expand.
886 (define_insn "ashrsi2_16"
887   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
888         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
889                      (const_int 16)))]
890   ""
891   "swap.w       %1,%0\;exts.w   %0,%0"
892   [(set_attr "length" "4")])
894 ;; ??? This should be a define expand.
896 (define_insn "ashrsi2_31"
897   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
898         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
899                      (const_int 31)))
900    (clobber (reg:SI 18))]
901   ""
902   "@
903    shll %0\;subc        %0,%0"
904   [(set_attr "length" "4")])
906 (define_insn "ashrsi3_d"
907   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
908         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
909                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
910   "TARGET_SH3"
911   "shad %2,%0")
913 (define_insn "ashrsi3_n"
914   [(set (reg:SI 4)
915         (ashiftrt:SI (reg:SI 4)
916                      (match_operand:SI 0 "const_int_operand" "i")))
917    (clobber (reg:SI 18))
918    (clobber (reg:SI 17))
919    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
920   ""
921   "jsr  @%1%#"
922   [(set_attr "type" "sfunc")
923    (set_attr "needs_delay_slot" "yes")])
925 (define_expand "ashrsi3"
926   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
927                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
928                                 (match_operand:SI 2 "nonmemory_operand" "")))
929               (clobber (reg:SI 18))])]
930   ""
931   "if (expand_ashiftrt (operands)) DONE; else FAIL;")
933 ;; logical shift right
935 (define_insn "lshrsi3_d"
936   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
937         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
938                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
939   "TARGET_SH3"
940   "shld %2,%0")
942 ;;  Only the single bit shift clobbers the T bit.
944 (define_insn "lshrsi3_m"
945   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
946         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
947                      (match_operand:SI 2 "const_int_operand" "M")))
948    (clobber (reg:SI 18))]
949   "CONST_OK_FOR_M (INTVAL (operands[2]))"
950   "shlr %0")
952 (define_insn "lshrsi3_k"
953   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
954         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
955                      (match_operand:SI 2 "const_int_operand" "K")))]
956   "CONST_OK_FOR_K (INTVAL (operands[2]))
957    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
958   "shlr%O2      %0")
960 (define_insn "lshrhi3_m"
961   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
962         (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
963                      (match_operand:HI 2 "const_int_operand" "M")))
964    (clobber (reg:SI 18))]
965   "CONST_OK_FOR_M (INTVAL (operands[2]))"
966   "shlr %0")
968 (define_insn "lshrhi3_k"
969   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
970         (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
971                      (match_operand:HI 2 "const_int_operand" "K")))]
972   "CONST_OK_FOR_K (INTVAL (operands[2]))
973    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
974   "shlr%O2      %0")
976 (define_insn "lshrsi3_n"
977   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
978         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
979                      (match_operand:SI 2 "const_int_operand" "n")))
980    (clobber (reg:SI 18))]
981   ""
982   "#"
983   [(set (attr "length")
984         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
985                (const_string "2")
986                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
987                (const_string "4")
988                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
989                (const_string "6")]
990               (const_string "8")))
991    (set_attr "type" "arith")])
993 (define_split
994   [(set (match_operand:SI 0 "arith_reg_operand" "")
995         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
996                      (match_operand:SI 2 "const_int_operand" "n")))
997    (clobber (reg:SI 18))]
998   ""
999   [(use (reg:SI 0))]
1000   "
1002   gen_shifty_op (LSHIFTRT, operands);
1003   DONE;
1006 (define_expand "lshrsi3"
1007   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1008                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1009                                 (match_operand:SI 2 "nonmemory_operand" "")))
1010               (clobber (reg:SI 18))])]
1011   ""
1012   "
1014   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
1015     {
1016       rtx count = copy_to_mode_reg (SImode, operands[2]);
1017       emit_insn (gen_negsi2 (count, count));
1018       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
1019       DONE;
1020     }
1021   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1022     FAIL;
1025 (define_insn "lshrhi3"
1026   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1027         (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0")
1028                      (match_operand:HI 2 "const_int_operand" "n")))
1029    (clobber (reg:SI 18))]
1030   ""
1031   "#"
1032 ;; ??? length attribute is sometimes six instead of four.
1033   [(set (attr "length")
1034         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1035                (const_string "2")
1036                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1037                (const_string "4")]
1038               (const_string "6")))
1039    (set_attr "type" "arith")])
1041 (define_split
1042   [(set (match_operand:HI 0 "arith_reg_operand" "")
1043         (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "")
1044                      (match_operand:HI 2 "const_int_operand" "n")))
1045    (clobber (reg:SI 18))]
1046   ""
1047   [(use (reg:SI 0))]
1048   "
1050   gen_shifty_hi_op (LSHIFTRT, operands);
1051   DONE;
1054 ;; ??? This should be a define expand.
1056 (define_insn "ashldi3_k"
1057   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1058         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
1059                    (const_int 1)))
1060    (clobber (reg:SI 18))]
1061   ""
1062   "shll %R0\;rotcl      %S0"
1063   [(set_attr "length" "4")])
1065 (define_expand "ashldi3"
1066   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1067                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
1068                               (match_operand:DI 2 "immediate_operand" "")))
1069               (clobber (reg:SI 18))])]
1070   ""
1071   "{ if (GET_CODE (operands[2]) != CONST_INT
1072          || INTVAL (operands[2]) != 1) FAIL;} ")
1074 ;; ??? This should be a define expand.
1076 (define_insn "lshrdi3_k"
1077   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1078         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
1079                      (const_int 1)))
1080    (clobber (reg:SI 18))]
1081   ""
1082   "shlr %S0\;rotcr      %R0"
1083   [(set_attr "length" "4")])
1085 (define_expand "lshrdi3"
1086   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1087                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1088                                (match_operand:DI 2 "immediate_operand" "")))
1089              (clobber (reg:SI 18))])]
1090   ""
1091   "{ if (GET_CODE (operands[2]) != CONST_INT
1092          || INTVAL (operands[2]) != 1) FAIL;} ")
1094 ;; ??? This should be a define expand.
1096 (define_insn "ashrdi3_k"
1097   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1098         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
1099                      (const_int 1)))
1100    (clobber (reg:SI 18))]
1101   ""
1102   "shar %S0\;rotcr      %R0"
1103   [(set_attr "length" "4")])
1105 (define_expand "ashrdi3"
1106   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1107                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1108                                 (match_operand:DI 2 "immediate_operand" "")))
1109               (clobber (reg:SI 18))])]
1110   ""
1111   "{ if (GET_CODE (operands[2]) != CONST_INT
1112          || INTVAL (operands[2]) != 1) FAIL; } ")
1114 ;; combined left/right shift
1116 (define_split
1117   [(set (match_operand:SI 0 "register_operand" "")
1118         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
1119                            (match_operand:SI 2 "const_int_operand" "n"))
1120                 (match_operand:SI 3 "const_int_operand" "n")))]
1121   "(unsigned)INTVAL (operands[2]) < 32"
1122   [(use (reg:SI 0))]
1123   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
1124    DONE;")
1126 (define_split
1127   [(set (match_operand:SI 0 "register_operand" "")
1128         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
1129                            (match_operand:SI 2 "const_int_operand" "n"))
1130                 (match_operand:SI 3 "const_int_operand" "n")))
1131    (clobber (reg:SI 18))]
1132   "(unsigned)INTVAL (operands[2]) < 32"
1133   [(use (reg:SI 0))]
1134   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
1135    DONE;")
1137 (define_insn ""
1138   [(set (match_operand:SI 0 "register_operand" "=r")
1139         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1140                            (match_operand:SI 2 "const_int_operand" "n"))
1141                 (match_operand:SI 3 "const_int_operand" "n")))
1142    (clobber (reg:SI 18))]
1143   "shl_and_kind (operands[2], operands[3], 0) == 1"
1144  "#"
1145   [(set (attr "length")
1146         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
1147                (const_string "4")
1148                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
1149                (const_string "6")
1150                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
1151                (const_string "8")
1152                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
1153                (const_string "10")
1154                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
1155                (const_string "12")
1156                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
1157                (const_string "14")
1158                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
1159                (const_string "16")]
1160               (const_string "18")))
1161    (set_attr "type" "arith")])
1163 (define_insn ""
1164   [(set (match_operand:SI 0 "register_operand" "=z")
1165         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1166                            (match_operand:SI 2 "const_int_operand" "n"))
1167                 (match_operand:SI 3 "const_int_operand" "n")))
1168    (clobber (reg:SI 18))]
1169   "shl_and_kind (operands[2], operands[3], 0) == 2"
1170  "#"
1171   [(set (attr "length")
1172         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
1173                (const_string "4")
1174                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
1175                (const_string "6")
1176                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
1177                (const_string "8")]
1178               (const_string "10")))
1179    (set_attr "type" "arith")])
1181 ;; shift left / and combination with a scratch register: The combine pass
1182 ;; does not accept the individual instructions, even though they are
1183 ;; cheap.  But it needs a precise description so that it is usable after
1184 ;; reload.
1185 (define_insn "and_shl_scratch"
1186   [(set (match_operand:SI 0 "register_operand" "=r,&r")
1187         (lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
1188                                                      (match_operand:SI 2 "const_int_operand" "N,n"))
1189                                         (match_operand:SI 3 "" "0,r"))
1190                                 (match_operand:SI 4 "const_int_operand" "n,n"))
1191                      (match_operand:SI 5 "const_int_operand" "n,n")))
1192    (clobber (reg:SI 18))]
1193   ""
1194   "#"
1195   [(set (attr "length")
1196         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
1197                (const_string "4")
1198                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
1199                (const_string "6")
1200                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
1201                (const_string "8")
1202                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
1203                (const_string "10")]
1204               (const_string "12")))
1205    (set_attr "type" "arith")])
1207 (define_split
1208   [(set (match_operand:SI 0 "register_operand" "=r,&r")
1209         (lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
1210                                                      (match_operand:SI 2 "const_int_operand" "N,n"))
1211                                         (match_operand:SI 3 "register_operand" "0,r"))
1212                                 (match_operand:SI 4 "const_int_operand" "n,n"))
1213                      (match_operand:SI 5 "const_int_operand" "n,n")))
1214    (clobber (reg:SI 18))]
1215   ""
1216   [(use (reg:SI 0))]
1217   "
1219   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
1221   if (INTVAL (operands[2]))
1222     {
1223       gen_shifty_op (LSHIFTRT, operands);
1224     }
1225   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
1226   operands[2] = operands[4];
1227   gen_shifty_op (ASHIFT, operands);
1228   if (INTVAL (operands[5]))
1229     {
1230       operands[2] = operands[5];
1231       gen_shifty_op (LSHIFTRT, operands);
1232     }
1233   DONE;
1236 ;; signed left/right shift combination.
1237 (define_split
1238   [(set (match_operand:SI 0 "register_operand" "=r")
1239         (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1240                                     (match_operand:SI 2 "const_int_operand" "n"))
1241                          (match_operand:SI 3 "const_int_operand" "n")
1242                          (const_int 0)))
1243    (clobber (reg:SI 18))]
1244   ""
1245   [(use (reg:SI 0))]
1246   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
1247    DONE;")
1249 (define_insn "shl_sext_ext"
1250   [(set (match_operand:SI 0 "register_operand" "=r")
1251         (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1252                                     (match_operand:SI 2 "const_int_operand" "n"))
1253                          (match_operand:SI 3 "const_int_operand" "n")
1254                          (const_int 0)))
1255    (clobber (reg:SI 18))]
1256   "(unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
1257   "#"
1258   [(set (attr "length")
1259         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
1260                (const_string "2")
1261                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
1262                (const_string "4")
1263                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
1264                (const_string "6")
1265                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
1266                (const_string "8")
1267                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
1268                (const_string "10")
1269                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
1270                (const_string "12")
1271                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
1272                (const_string "14")
1273                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
1274                (const_string "16")]
1275               (const_string "18")))
1276     (set_attr "type" "arith")])
1278 (define_insn "shl_sext_sub"
1279   [(set (match_operand:SI 0 "register_operand" "=z")
1280         (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1281                                     (match_operand:SI 2 "const_int_operand" "n"))
1282                          (match_operand:SI 3 "const_int_operand" "n")
1283                          (const_int 0)))
1284    (clobber (reg:SI 18))]
1285   "(shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
1286   "#"
1287   [(set (attr "length")
1288         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
1289                (const_string "6")
1290                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
1291                (const_string "8")
1292                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
1293                (const_string "10")
1294                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
1295                (const_string "12")]
1296               (const_string "14")))
1297     (set_attr "type" "arith")])
1299 ;; These patterns are found in expansions of DImode shifts by 16, and
1300 ;; allow the xtrct instruction to be generated from C source.
1302 (define_insn "xtrct_left"
1303   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1304         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
1305                            (const_int 16))
1306                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
1307                              (const_int 16))))]
1308   ""
1309   "xtrct        %1,%0")
1311 (define_insn "xtrct_right"
1312   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1313         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1314                              (const_int 16))
1315                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
1316                            (const_int 16))))]
1317   ""
1318   "xtrct        %2,%0")
1320 ;; -------------------------------------------------------------------------
1321 ;; Unary arithmetic
1322 ;; -------------------------------------------------------------------------
1324 (define_insn "negc"
1325   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1326         (neg:SI (plus:SI (reg:SI 18)
1327                          (match_operand:SI 1 "arith_reg_operand" "r"))))
1328    (set (reg:SI 18)
1329         (ne:SI (ior:SI (reg:SI 18) (match_dup 1))
1330                (const_int 0)))]
1331   ""
1332   "negc %1,%0"
1333   [(set_attr "type" "arith")])
1335 (define_expand "negdi2"
1336   [(set (match_operand:DI 0 "arith_reg_operand" "")
1337         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
1338    (clobber (reg:SI 18))]
1339   ""
1340   "
1342   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
1343   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
1345   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
1346   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
1348   rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
1349   rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
1351   emit_insn (gen_clrt ());
1352   emit_insn (gen_negc (low_dst, low_src));
1353   emit_insn (gen_negc (high_dst, high_src));
1354   DONE;
1357 (define_insn "negsi2"
1358   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1359         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
1360   ""
1361   "neg  %1,%0"
1362   [(set_attr "type" "arith")])
1364 (define_insn "one_cmplsi2"
1365   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1366         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
1367   ""
1368   "not  %1,%0"
1369   [(set_attr "type" "arith")])
1371 ;; -------------------------------------------------------------------------
1372 ;; Zero extension instructions
1373 ;; -------------------------------------------------------------------------
1375 (define_insn "zero_extendhisi2"
1376   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1377         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
1378   ""
1379   "extu.w       %1,%0"
1380   [(set_attr "type" "arith")])
1382 (define_insn "zero_extendqisi2"
1383   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1384         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
1385   ""
1386   "extu.b       %1,%0"
1387   [(set_attr "type" "arith")])
1389 (define_insn "zero_extendqihi2"
1390   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1391         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
1392   ""
1393   "extu.b       %1,%0"
1394   [(set_attr "type" "arith")])
1396 ;; -------------------------------------------------------------------------
1397 ;; Sign extension instructions
1398 ;; -------------------------------------------------------------------------
1400 ;; ??? This should be a define expand.
1401 ;; ??? Or perhaps it should be dropped?
1403 (define_insn "extendsidi2"
1404   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1405         (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1406    (clobber (reg:SI 18))]
1407   ""
1408   "mov  %1,%S0\;mov     %1,%R0\;shll    %S0\;subc       %S0,%S0"
1409   [(set_attr "length" "8")])
1411 (define_insn "extendhisi2"
1412   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1413         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
1414   ""
1415   "@
1416         exts.w  %1,%0
1417         mov.w   %1,%0"
1418   [(set_attr "type" "arith,load")])
1420 (define_insn "extendqisi2"
1421   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1422         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
1423   ""
1424   "@
1425         exts.b  %1,%0
1426         mov.b   %1,%0"
1427   [(set_attr "type" "arith,load")])
1429 (define_insn "extendqihi2"
1430   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
1431         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
1432   ""
1433   "@
1434         exts.b  %1,%0
1435         mov.b   %1,%0"
1436   [(set_attr "type" "arith,load")])
1438 ;; -------------------------------------------------------------------------
1439 ;; Move instructions
1440 ;; -------------------------------------------------------------------------
1442 ;; define push and pop so it is easy for sh.c
1444 (define_insn "push"
1445   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
1446         (match_operand:SI 0 "register_operand" "r,l,x"))]
1447   ""
1448   "@
1449         mov.l   %0,@-r15
1450         sts.l   %0,@-r15
1451         sts.l   %0,@-r15"
1452   [(set_attr "type" "store,pstore,store")
1453    (set_attr "hit_stack" "yes")])
1455 (define_insn "pop"
1456   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
1457         (mem:SI (post_inc:SI (reg:SI 15))))]
1458   ""
1459   "@
1460         mov.l   @r15+,%0
1461         lds.l   @r15+,%0
1462         lds.l   @r15+,%0"
1463   [(set_attr "type" "load,pload,load")
1464    (set_attr "hit_stack" "yes")])
1466 (define_insn "push_e"
1467   [(set (mem:SF (pre_dec:SI (reg:SI 15)))
1468         (match_operand:SF 0 "register_operand" "r,f,y"))]
1469   "TARGET_SH3E"
1470   "@
1471         mov.l   %0,@-r15
1472         fmov.s  %0,@-r15
1473         sts.l   %0,@-r15"
1474   [(set_attr "type" "store")
1475    (set_attr "hit_stack" "yes")])
1477 (define_insn "pop_e"
1478   [(set (match_operand:SF 0 "register_operand" "=r,f,y")
1479         (mem:SF (post_inc:SI (reg:SI 15))))]
1480   "TARGET_SH3E"
1481   "@
1482         mov.l   @r15+,%0
1483         fmov.s  @r15+,%0
1484         lds.l   @r15+,%0"
1485   [(set_attr "type" "load")
1486    (set_attr "hit_stack" "yes")])
1488 ;; These two patterns can happen as the result of optimization, when
1489 ;; comparisons get simplified to a move of zero or 1 into the T reg.
1490 ;; They don't disappear completely, because the T reg is a fixed hard reg.
1492 (define_insn "clrt"
1493   [(set (reg:SI 18) (const_int 0))]
1494   ""
1495   "clrt")
1497 (define_insn "sett"
1498   [(set (reg:SI 18) (const_int 1))]
1499   ""
1500   "sett")
1502 ;; t/z is first, so that it will be preferred over r/r when reloading a move
1503 ;; of a pseudo-reg into the T reg
1504 (define_insn "movsi_i"
1505   [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,xl,xl,r")
1506         (match_operand:SI 1 "general_movsrc_operand" "z,Q,rI,m,xl,t,r,xl,r,>,i"))]
1507   "
1508    ! TARGET_SH3E &&
1509    (register_operand (operands[0], SImode)
1510     || register_operand (operands[1], SImode))"
1511   "@
1512         tst     %1,%1\;rotcl    %1\;xor #1,%1\;rotcr    %1
1513         mov.l   %1,%0
1514         mov     %1,%0
1515         mov.l   %1,%0
1516         sts     %1,%0
1517         movt    %0
1518         mov.l   %1,%0
1519         sts.l   %1,%0
1520         lds     %1,%0
1521         lds.l   %1,%0
1522         fake    %1,%0"
1523   [(set_attr "type" "move,pcload,move,load,move,store,store,move,load,move,pcload")
1524    (set_attr "length" "8,*,*,*,*,*,*,*,*,*,*")])
1526 ;; t/z is first, so that it will be preferred over r/r when reloading a move
1527 ;; of a pseudo-reg into the T reg
1528 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
1529 ;; will require a reload.
1530 (define_insn "movsi_ie"
1531   [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,xl,xl,r,y,r")
1532         (match_operand:SI 1 "general_movsrc_operand" "z,Q,rI,m,xl,t,r,xl,r,>,i,r,y"))]
1533   "TARGET_SH3E
1534    && (register_operand (operands[0], SImode)
1535        || register_operand (operands[1], SImode))"
1536   "@
1537         tst     %1,%1\;rotcl    %1\;xor #1,%1\;rotcr    %1
1538         mov.l   %1,%0
1539         mov     %1,%0
1540         mov.l   %1,%0
1541         sts     %1,%0
1542         movt    %0
1543         mov.l   %1,%0
1544         sts.l   %1,%0
1545         lds     %1,%0
1546         lds.l   %1,%0
1547         fake    %1,%0
1548         lds     %1,%0
1549         sts     %1,%0"
1550   [(set_attr "type" "move,pcload,move,load,move,store,store,move,load,move,pcload,move,move")
1551    (set_attr "length" "8,*,*,*,*,*,*,*,*,*,*,*,*")])
1553 (define_expand "movsi"
1554   [(set (match_operand:SI 0 "general_movdst_operand" "")
1555         (match_operand:SI 1 "general_movsrc_operand" ""))]
1556   ""
1557   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
1559 (define_insn "movqi_i"
1560   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
1561         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
1562   "arith_reg_operand (operands[0], QImode)
1563    || arith_reg_operand (operands[1], QImode)"
1564   "@
1565         mov     %1,%0
1566         mov.b   %1,%0
1567         mov.b   %1,%0
1568         movt    %0
1569         sts     %1,%0
1570         lds     %1,%0"
1571  [(set_attr "type" "move,load,store,move,move,move")])
1573 (define_expand "movqi"
1574   [(set (match_operand:QI 0 "general_operand" "")
1575         (match_operand:QI 1 "general_operand"  ""))]
1576   ""
1577   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
1579 (define_insn "movhi_i"
1580   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
1581         (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
1582   "arith_reg_operand (operands[0], HImode)
1583    || arith_reg_operand (operands[1], HImode)"
1584   "@
1585         mov.w   %1,%0
1586         mov     %1,%0
1587         mov.w   %1,%0
1588         movt    %0
1589         mov.w   %1,%0
1590         sts     %1,%0
1591         lds     %1,%0
1592         fake    %1,%0"
1593   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
1595 (define_expand "movhi"
1596   [(set (match_operand:HI 0 "general_movdst_operand" "")
1597         (match_operand:HI 1 "general_movsrc_operand"  ""))]
1598   ""
1599   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
1601 ;; ??? This should be a define expand.
1603 (define_insn ""
1604   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r")
1605         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x"))]
1606   "arith_reg_operand (operands[0], DImode)
1607    || arith_reg_operand (operands[1], DImode)"
1608   "* return output_movedouble (insn, operands, DImode);"
1609   [(set_attr "length" "4")
1610    (set_attr "type" "pcload,move,load,store,move,pcload,move")])
1612 ;; If the output is a register and the input is memory or a register, we have
1613 ;; to be careful and see which word needs to be loaded first.  
1615 (define_split
1616   [(set (match_operand:DI 0 "general_movdst_operand" "")
1617         (match_operand:DI 1 "general_movsrc_operand" ""))]
1618   "reload_completed"
1619   [(set (match_dup 2) (match_dup 3))
1620    (set (match_dup 4) (match_dup 5))]
1621   "
1623   int regno;
1625   if ((GET_CODE (operands[0]) == MEM
1626        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1627       || (GET_CODE (operands[1]) == MEM
1628           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
1629     FAIL;
1631   if (GET_CODE (operands[0]) == REG)
1632     regno = REGNO (operands[0]);
1633   else if (GET_CODE (operands[0]) == SUBREG)
1634     regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]);
1635   else if (GET_CODE (operands[0]) == MEM)
1636     regno = -1;
1638   if (regno == -1
1639       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
1640     {
1641       operands[2] = operand_subword (operands[0], 0, 0, DImode);
1642       operands[3] = operand_subword (operands[1], 0, 0, DImode);
1643       operands[4] = operand_subword (operands[0], 1, 0, DImode);
1644       operands[5] = operand_subword (operands[1], 1, 0, DImode);
1645     }
1646   else
1647     {
1648       operands[2] = operand_subword (operands[0], 1, 0, DImode);
1649       operands[3] = operand_subword (operands[1], 1, 0, DImode);
1650       operands[4] = operand_subword (operands[0], 0, 0, DImode);
1651       operands[5] = operand_subword (operands[1], 0, 0, DImode);
1652     }
1654   if (operands[2] == 0 || operands[3] == 0
1655       || operands[4] == 0 || operands[5] == 0)
1656     FAIL;
1659 (define_expand "movdi"
1660   [(set (match_operand:DI 0 "general_movdst_operand" "")
1661         (match_operand:DI 1 "general_movsrc_operand" ""))]
1662   ""
1663   "{ if ( prepare_move_operands (operands, DImode)) DONE; }")
1665 ;; ??? This should be a define expand.
1667 (define_insn "movdf_k"
1668   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
1669         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
1670   "arith_reg_operand (operands[0], DFmode)
1671    || arith_reg_operand (operands[1], DFmode)"
1672   "* return output_movedouble (insn, operands, DFmode);"
1673   [(set_attr "length" "4")
1674    (set_attr "type" "move,pcload,load,store")])
1676 ;; If the output is a register and the input is memory or a register, we have
1677 ;; to be careful and see which word needs to be loaded first.  
1679 (define_split
1680   [(set (match_operand:DF 0 "general_movdst_operand" "")
1681         (match_operand:DF 1 "general_movsrc_operand" ""))]
1682   "reload_completed"
1683   [(set (match_dup 2) (match_dup 3))
1684    (set (match_dup 4) (match_dup 5))]
1685   "
1687   int regno;
1689   if ((GET_CODE (operands[0]) == MEM
1690        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1691       || (GET_CODE (operands[1]) == MEM
1692           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
1693     FAIL;
1695   if (GET_CODE (operands[0]) == REG)
1696     regno = REGNO (operands[0]);
1697   else if (GET_CODE (operands[0]) == SUBREG)
1698     regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]);
1699   else if (GET_CODE (operands[0]) == MEM)
1700     regno = -1;
1702   if (regno == -1
1703       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
1704     {
1705       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1706       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1707       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1708       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
1709     }
1710   else
1711     {
1712       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
1713       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
1714       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
1715       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
1716     }
1718   if (operands[2] == 0 || operands[3] == 0
1719       || operands[4] == 0 || operands[5] == 0)
1720     FAIL;
1723 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
1724 ;; used only once, let combine add in the index again.
1726 (define_split
1727   [(set (match_operand:SI 0 "register_operand" "")
1728         (match_operand:SI 1 "" ""))
1729    (clobber (match_operand 2 "register_operand" ""))]
1730   "! reload_in_progress && ! reload_completed"
1731   [(use (reg:SI 0))]
1732   "
1734   rtx addr, reg, const_int;
1736   if (GET_CODE (operands[1]) != MEM)
1737     FAIL;
1738   addr = XEXP (operands[1], 0);
1739   if (GET_CODE (addr) != PLUS)
1740     FAIL;
1741   reg = XEXP (addr, 0);
1742   const_int = XEXP (addr, 1);
1743   if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT)
1744     FAIL;
1745   emit_move_insn (operands[2], const_int);
1746   emit_move_insn (operands[0],
1747                   change_address (operands[1], VOIDmode,
1748                                   gen_rtx (PLUS, SImode, reg, operands[2])));
1749   DONE;
1752 (define_split
1753   [(set (match_operand:SI 1 "" "")
1754         (match_operand:SI 0 "register_operand" ""))
1755    (clobber (match_operand 2 "register_operand" ""))]
1756   "! reload_in_progress && ! reload_completed"
1757   [(use (reg:SI 0))]
1758   "
1760   rtx addr, reg, const_int;
1762   if (GET_CODE (operands[1]) != MEM)
1763     FAIL;
1764   addr = XEXP (operands[1], 0);
1765   if (GET_CODE (addr) != PLUS)
1766     FAIL;
1767   reg = XEXP (addr, 0);
1768   const_int = XEXP (addr, 1);
1769   if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT)
1770     FAIL;
1771   emit_move_insn (operands[2], const_int);
1772   emit_move_insn (change_address (operands[1], VOIDmode,
1773                                   gen_rtx (PLUS, SImode, reg, operands[2])),
1774                   operands[0]);
1775   DONE;
1778 (define_expand "movdf"
1779   [(set (match_operand:DF 0 "general_movdst_operand" "")
1780         (match_operand:DF 1 "general_movsrc_operand" ""))]
1781   ""
1782   "{ if (prepare_move_operands (operands, DFmode)) DONE; }")
1784 (define_insn "movsf_i"
1785   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
1786         (match_operand:SF 1 "general_movsrc_operand"  "r,I,FQ,m,r,r,l"))]
1787   "
1788    ! TARGET_SH3E &&
1789    (arith_reg_operand (operands[0], SFmode)
1790     || arith_reg_operand (operands[1], SFmode))"
1791   "@
1792         mov     %1,%0
1793         mov     %1,%0
1794         mov.l   %1,%0
1795         mov.l   %1,%0
1796         mov.l   %1,%0
1797         lds     %1,%0
1798         sts     %1,%0"
1799   [(set_attr "type" "move,move,pcload,load,store,move,move")])
1801 (define_insn "movsf_ie"
1802   [(set (match_operand:SF 0 "general_movdst_operand"
1803          "=f,r,f,f,?f,f,m,r,r,m,!??r,!??f")
1804         (match_operand:SF 1 "general_movsrc_operand"
1805           "f,r,G,H,FQ,m,f,FQ,m,r,f,r"))
1806    (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X"))]
1808   "TARGET_SH3E
1809    && (arith_reg_operand (operands[0], SFmode)
1810        || arith_reg_operand (operands[1], SFmode))"
1811   "@
1812         fmov    %1,%0
1813         mov     %1,%0
1814         fldi0   %0
1815         fldi1   %0
1816         #
1817         fmov.s  %1,%0
1818         fmov.s  %1,%0
1819         mov.l   %1,%0
1820         mov.l   %1,%0
1821         mov.l   %1,%0
1822         flds    %1,fpul\;sts    fpul,%0
1823         lds     %1,fpul\;fsts   fpul,%0"
1824   [(set_attr "type" "move,move,fp,fp,pcload,load,store,pcload,load,store,move,fp")
1825    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,4,4")])
1827 (define_split
1828   [(set (match_operand:SF 0 "general_movdst_operand" "")
1829         (match_operand:SF 1 "general_movsrc_operand"  ""))
1830    (clobber (reg:SI 0))]
1831   "GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER"
1832   [(parallel [(set (match_dup 0) (match_dup 1))
1833               (clobber (scratch:SI))])]
1834   "
1836   if (REGNO (operands[0]) >= FIRST_FP_REG && REGNO (operands[0]) <= LAST_FP_REG)
1837     {
1838       if (GET_CODE (operands[1]) != MEM)
1839         FAIL;
1840       emit_insn (gen_mova (XEXP (operands[1], 0)));
1841       XEXP (operands[1], 0) = gen_rtx (REG, Pmode, 0);
1842     }
1845 (define_expand "movsf"
1846   [(set (match_operand:SF 0 "general_movdst_operand" "")
1847         (match_operand:SF 1 "general_movsrc_operand" ""))]
1848   ""
1849   "
1851   if (prepare_move_operands (operands, SFmode))
1852     DONE;
1853   if (TARGET_SH3E)
1854     {
1855       emit_insn (gen_movsf_ie (operands[0], operands[1]));
1856       DONE;
1857     }
1860 (define_expand "reload_insf"
1861   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
1862                    (match_operand:SF 1 "immediate_operand" "FQ"))
1863               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
1864   ""
1865   "")
1867 ;; ------------------------------------------------------------------------
1868 ;; Define the real conditional branch instructions.
1869 ;; ------------------------------------------------------------------------
1871 (define_insn "branch_true"
1872   [(set (pc) (if_then_else (ne (reg:SI 18) (const_int 0))
1873                            (label_ref (match_operand 0 "" ""))
1874                            (pc)))]
1875   ""
1876   "* return output_branch (1, insn, operands);"
1877   [(set_attr "type" "cbranch")])
1879 (define_insn "branch_false"
1880   [(set (pc) (if_then_else (eq (reg:SI 18) (const_int 0))
1881                            (label_ref (match_operand 0 "" ""))
1882                            (pc)))]
1883   ""
1884   "* return output_branch (0, insn, operands);"
1885   [(set_attr "type" "cbranch")])
1887 (define_insn "inverse_branch_true"
1888   [(set (pc) (if_then_else (ne (reg:SI 18) (const_int 0))
1889                            (pc)
1890                            (label_ref (match_operand 0 "" ""))))]
1891   ""
1892   "* return output_branch (0, insn, operands);"
1893   [(set_attr "type" "cbranch")])
1895 (define_insn "inverse_branch_false"
1896   [(set (pc) (if_then_else (eq (reg:SI 18) (const_int 0))
1897                            (pc)
1898                            (label_ref (match_operand 0 "" ""))))]
1899   ""
1900   "* return output_branch (1, insn, operands);"
1901   [(set_attr "type" "cbranch")])
1903 ;; Conditional branch insns
1905 (define_expand "beq"
1906   [(set (reg:SI 18) (eq:SI (match_dup 1) (match_dup 2)))
1907    (set (pc)
1908         (if_then_else (ne (reg:SI 18) (const_int 0))
1909                       (label_ref (match_operand 0 "" ""))
1910                       (pc)))]
1911   ""
1912   "from_compare (operands, EQ);")
1914 ; There is no bne compare, so we reverse the branch arms.
1916 (define_expand "bne"
1917   [(set (reg:SI 18) (eq:SI (match_dup 1) (match_dup 2)))
1918    (set (pc)
1919         (if_then_else (ne (reg:SI 18) (const_int 0))
1920                       (pc)
1921                       (label_ref (match_operand 0 "" ""))))]
1922   ""
1923   "from_compare (operands, NE);")
1925 (define_expand "bgt"
1926   [(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 2)))
1927    (set (pc)
1928         (if_then_else (ne (reg:SI 18) (const_int 0))
1929                       (label_ref (match_operand 0 "" ""))
1930                       (pc)))]
1931   ""
1932   "from_compare (operands, GT);")
1934 (define_expand "blt"
1935   [(set (reg:SI 18) (ge:SI (match_dup 1) (match_dup 2)))
1936    (set (pc)
1937         (if_then_else (ne (reg:SI 18) (const_int 0))
1938                       (pc)
1939                       (label_ref (match_operand 0 "" ""))))]
1940   ""
1941   "
1943   if (GET_MODE (sh_compare_op0) == SFmode)
1944     {
1945       rtx tmp = sh_compare_op0;
1946       sh_compare_op0 = sh_compare_op1;
1947       sh_compare_op1 = tmp;
1948       emit_insn (gen_bgt (operands[0]));
1949       DONE;
1950     }
1951   from_compare (operands, LT);
1954 (define_expand "ble"
1955   [(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 2)))
1956    (set (pc)
1957         (if_then_else (ne (reg:SI 18) (const_int 0))
1958                       (pc)
1959                       (label_ref (match_operand 0 "" ""))))]
1960   ""
1961   "from_compare (operands, LE);")
1963 (define_expand "bge"
1964   [(set (reg:SI 18) (ge:SI (match_dup 1) (match_dup 2)))
1965    (set (pc)
1966         (if_then_else (ne (reg:SI 18) (const_int 0))
1967                       (label_ref (match_operand 0 "" ""))
1968                       (pc)))]
1969   ""
1970   "
1972   if (GET_MODE (sh_compare_op0) == SFmode)
1973     {
1974       rtx tmp = sh_compare_op0;
1975       sh_compare_op0 = sh_compare_op1;
1976       sh_compare_op1 = tmp;
1977       emit_insn (gen_ble (operands[0]));
1978       DONE;
1979     }
1980   from_compare (operands, GE);
1983 (define_expand "bgtu"
1984   [(set (reg:SI 18) (gtu:SI (match_dup 1) (match_dup 2)))
1985    (set (pc)
1986         (if_then_else (ne (reg:SI 18) (const_int 0))
1987                       (label_ref (match_operand 0 "" ""))
1988                       (pc)))]
1989   ""
1990   "from_compare (operands, GTU); ")
1992 (define_expand "bltu"
1993   [(set (reg:SI 18) (geu:SI (match_dup 1) (match_dup 2)))
1994    (set (pc)
1995                   (if_then_else (ne (reg:SI 18) (const_int 0))
1996                                 (pc)
1997                                 (label_ref (match_operand 0 "" ""))))]
1998   ""
1999   "from_compare (operands, LTU);")
2001 (define_expand "bgeu"
2002   [(set (reg:SI 18) (geu:SI (match_dup 1) (match_dup 2)))
2003    (set (pc)
2004         (if_then_else (ne (reg:SI 18) (const_int 0))
2005                       (label_ref (match_operand 0 "" ""))
2006                       (pc)))]
2007   ""
2008   "from_compare (operands, GEU);")
2010 (define_expand "bleu"
2011   [(set (reg:SI 18) (gtu:SI (match_dup 1) (match_dup 2)))
2012    (set (pc)
2013         (if_then_else (ne (reg:SI 18) (const_int 0))
2014                       (pc)
2015                       (label_ref (match_operand 0 "" ""))))]
2016   ""
2017   "from_compare (operands, LEU);")
2019 ;; ------------------------------------------------------------------------
2020 ;; Jump and linkage insns
2021 ;; ------------------------------------------------------------------------
2023 (define_insn "jump"
2024   [(set (pc)
2025         (label_ref (match_operand 0 "" "")))]
2026   ""
2027   "*
2029   /* The length is 16 if the delay slot is unfilled.  */
2030   if (get_attr_length(insn) >= 14)
2031     return output_far_jump(insn, operands[0]);
2032   else
2033     return   \"bra      %l0%#\";
2035   [(set_attr "type" "jump")
2036    (set_attr "needs_delay_slot" "yes")])
2038 (define_insn "calli"
2039   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
2040          (match_operand 1 "" ""))
2041    (clobber (reg:SI 17))]
2042   ""
2043   "jsr  @%0%#"
2044   [(set_attr "type" "call")
2045    (set_attr "needs_delay_slot" "yes")])
2047 (define_insn "call_valuei"
2048   [(set (match_operand 0 "" "=rf")
2049         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
2050               (match_operand 2 "" "")))
2051    (clobber (reg:SI 17))]
2052   ""
2053   "jsr  @%1%#"
2054   [(set_attr "type" "call")
2055    (set_attr "needs_delay_slot" "yes")])
2057 (define_expand "call"
2058   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
2059                             (match_operand 1 "" ""))
2060               (clobber (reg:SI 17))])]
2061   ""
2062   "operands[0] = force_reg (SImode, XEXP (operands[0], 0));")
2064 (define_expand "call_value"
2065   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
2066                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
2067                                  (match_operand 2 "" "")))
2068               (clobber (reg:SI 17))])]
2069   ""
2070   "operands[1] = force_reg (SImode, XEXP (operands[1], 0));")
2072 (define_insn "indirect_jump"
2073   [(set (pc)
2074         (match_operand:SI 0 "arith_reg_operand" "r"))]
2075   ""
2076   "jmp  @%0%#"
2077   [(set_attr "needs_delay_slot" "yes")])
2079 ;; This might seem redundant, but it helps us distinguish case table jumps
2080 ;; which can be present in structured code from indirect jumps which can not
2081 ;; be present in structured code.  This allows -fprofile-arcs to work.
2083 (define_insn "*casesi_jump"
2084   [(set (pc)
2085         (match_operand:SI 0 "arith_reg_operand" "r"))
2086    (use (label_ref (match_operand 1 "" "")))]
2087   ""
2088   "jmp  @%0%#"
2089   [(set_attr "needs_delay_slot" "yes")])
2091 ;; Call subroutine returning any type.
2092 ;; ??? This probably doesn't work.
2094 (define_expand "untyped_call"
2095   [(parallel [(call (match_operand 0 "" "")
2096                     (const_int 0))
2097               (match_operand 1 "" "")
2098               (match_operand 2 "" "")])]
2099   "TARGET_SH3E"
2100   "
2102   int i;
2104   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
2106   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2107     {
2108       rtx set = XVECEXP (operands[2], 0, i);
2109       emit_move_insn (SET_DEST (set), SET_SRC (set));
2110     }
2112   /* The optimizer does not know that the call sets the function value
2113      registers we stored in the result block.  We avoid problems by
2114      claiming that all hard registers are used and clobbered at this
2115      point.  */
2116   emit_insn (gen_blockage ());
2118   DONE;
2121 ;; ------------------------------------------------------------------------
2122 ;; Misc insns
2123 ;; ------------------------------------------------------------------------
2125 (define_insn "dect"
2126   [(set (reg:SI 18)
2127         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
2128    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
2129   "TARGET_SH2"
2130   "dt   %0")
2132 (define_insn "nop"
2133   [(const_int 0)]
2134   ""
2135   "nop")
2137 ;; Load address of a label. This is only generated by the casesi expand.
2138 ;; This must use unspec, because this only works immediately before a casesi.
2140 (define_insn "mova"
2141   [(set (reg:SI 0)
2142         (unspec [(label_ref (match_operand 0 "" ""))] 1))]
2143   ""
2144   "mova %O0,r0"
2145   [(set_attr "in_delay_slot" "no")])
2147 ;; case instruction for switch statements.
2149 ;; Operand 0 is index
2150 ;; operand 1 is the minimum bound
2151 ;; operand 2 is the maximum bound - minimum bound + 1
2152 ;; operand 3 is CODE_LABEL for the table;
2153 ;; operand 4 is the CODE_LABEL to go to if index out of range.
2155 ;; ??? There should be a barrier after the jump at the end.
2157 (define_expand "casesi"
2158   [(set (match_dup 5) (match_operand:SI 0 "arith_reg_operand" ""))
2159    (set (match_dup 5) (minus:SI (match_dup 5)
2160                                 (match_operand:SI 1 "arith_operand" "")))
2161    (set (reg:SI 18)
2162         (gtu:SI (match_dup 5)
2163                 (match_operand:SI 2 "arith_reg_operand" "")))
2164    (set (pc)
2165         (if_then_else (ne (reg:SI 18)
2166                           (const_int 0))
2167                       (label_ref (match_operand 4 "" ""))
2168                       (pc)))
2169    (set (match_dup 6) (match_dup 5))
2170    (set (match_dup 6) (ashift:SI (match_dup 6) (match_dup 7)))
2171    (set (reg:SI 0) (unspec [(label_ref (match_operand 3 "" ""))] 1))
2172    (parallel [(set (reg:SI 0) (plus:SI (reg:SI 0)
2173                                        (mem:HI (plus:SI (reg:SI 0)
2174                                                         (match_dup 6)))))
2175               (set (match_dup 6) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))])
2176    (parallel [(set (pc) (reg:SI 0))
2177               (use (label_ref (match_dup 3)))])]
2178   ""
2179   "
2181   operands[1] = copy_to_mode_reg (SImode, operands[1]);
2182   operands[2] = copy_to_mode_reg (SImode, operands[2]);
2183   operands[5] = gen_reg_rtx (SImode);
2184   operands[6] = gen_reg_rtx (SImode);
2185   operands[7] = GEN_INT (TARGET_BIGTABLE  ? 2 : 1);
2188 (define_insn "casesi_worker"
2189   [(set (reg:SI 0)
2190         (plus:SI (reg:SI 0)
2191                  (mem:HI (plus:SI (reg:SI 0)
2192                                   (match_operand:SI 0 "arith_reg_operand" "+r")))))
2193    (set (match_dup 0) (mem:HI (plus:SI (reg:SI 0)
2194                                        (match_dup 0))))]
2195   ""
2196   "*
2198   if (TARGET_BIGTABLE)
2199     return \"mov.l      @(r0,%0),%0\;add        %0,r0\";
2200   else
2201     return \"mov.w      @(r0,%0),%0\;add        %0,r0\";
2203   [(set_attr "length" "4")])
2205 (define_insn "return"
2206   [(return)]
2207   "reload_completed"
2208   "%@   %#"
2209   [(set_attr "type" "return")
2210    (set_attr "needs_delay_slot" "yes")])
2212 (define_expand "prologue"
2213   [(const_int 0)]
2214   ""
2215   "sh_expand_prologue (); DONE;")
2217 (define_expand "epilogue"
2218   [(return)]
2219   ""
2220   "sh_expand_epilogue ();")
2222 (define_insn "blockage"
2223   [(unspec_volatile [(const_int 0)] 0)]
2224   ""
2225   ""
2226   [(set_attr "length" "0")])
2228 ;; ------------------------------------------------------------------------
2229 ;; Scc instructions
2230 ;; ------------------------------------------------------------------------
2232 (define_insn "movt"
2233   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2234         (eq:SI (reg:SI 18) (const_int 1)))]
2235   ""
2236   "movt %0")
2238 (define_expand "seq"
2239   [(set (match_operand:SI 0 "arith_reg_operand" "")
2240         (match_dup 1))]
2241   ""
2242   "operands[1] = prepare_scc_operands (EQ);")
2244 (define_expand "slt"
2245   [(set (match_operand:SI 0 "arith_reg_operand" "")
2246         (match_dup 1))]
2247   ""
2248   "operands[1] = prepare_scc_operands (LT);")
2250 (define_expand "sle"
2251   [(set (match_operand:SI 0 "arith_reg_operand" "")
2252         (match_dup 1))]
2253   ""
2254   "
2256   if (GET_MODE (sh_compare_op0) == SFmode)
2257     {
2258       emit_insn (gen_sgt (operands[0]));
2259       emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
2260       DONE;
2261     }
2262   operands[1] = prepare_scc_operands (LE);
2265 (define_expand "sgt"
2266   [(set (match_operand:SI 0 "arith_reg_operand" "")
2267         (match_dup 1))]
2268   ""
2269   "operands[1] = prepare_scc_operands (GT);")
2271 (define_expand "sge"
2272   [(set (match_operand:SI 0 "arith_reg_operand" "")
2273         (match_dup 1))]
2274   ""
2275   "
2277   if (GET_MODE (sh_compare_op0) == SFmode)
2278     {
2279       emit_insn (gen_slt (operands[0]));
2280       emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
2281       DONE;
2282     }
2283   operands[1] = prepare_scc_operands (GE);
2286 (define_expand "sgtu"
2287   [(set (match_operand:SI 0 "arith_reg_operand" "")
2288         (match_dup 1))]
2289   ""
2290   "operands[1] = prepare_scc_operands (GTU);")
2292 (define_expand "sltu"
2293   [(set (match_operand:SI 0 "arith_reg_operand" "")
2294         (match_dup 1))]
2295   ""
2296   "operands[1] = prepare_scc_operands (LTU);")
2298 (define_expand "sleu"
2299   [(set (match_operand:SI 0 "arith_reg_operand" "")
2300         (match_dup 1))]
2301   ""
2302   "operands[1] = prepare_scc_operands (LEU);")
2304 (define_expand "sgeu"
2305   [(set (match_operand:SI 0 "arith_reg_operand" "")
2306         (match_dup 1))]
2307   ""
2308   "operands[1] = prepare_scc_operands (GEU);")
2310 ;; sne moves the complement of the T reg to DEST like this:
2311 ;;      cmp/eq ...
2312 ;;      mov    #-1,temp
2313 ;;      negc   temp,dest
2314 ;;   This is better than xoring compare result with 1 because it does
2315 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
2316 ;;   loop.
2318 (define_expand "sne"
2319   [(set (match_dup 2) (const_int -1))
2320    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2321                    (neg:SI (plus:SI (match_dup 1)
2322                                     (match_dup 2))))
2323               (set (reg:SI 18)
2324                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
2325                           (const_int 0)))])]  
2326   ""
2327   "
2329    operands[1] = prepare_scc_operands (EQ);
2330    operands[2] = gen_reg_rtx (SImode);
2333 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
2334 ;; This prevents a regression that occured when we switched from xor to
2335 ;; mov/neg for sne.
2337 (define_split
2338   [(set (match_operand:SI 0 "arith_reg_operand" "")
2339         (plus:SI (reg:SI 18)
2340                  (const_int -1)))]
2341   ""
2342   [(set (match_dup 0) (eq:SI (reg:SI 18) (const_int 1)))
2343    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
2344   "")
2346 ;; -------------------------------------------------------------------------
2347 ;; Instructions to cope with inline literal tables
2348 ;; -------------------------------------------------------------------------
2350 ; 2 byte integer in line
2352 (define_insn "consttable_2"
2353  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 2)]
2354  ""
2355  "*
2357   assemble_integer (operands[0], 2, 1);
2358   return \"\";
2360  [(set_attr "length" "2")
2361  (set_attr "in_delay_slot" "no")])
2363 ; 4 byte integer in line
2365 (define_insn "consttable_4"
2366  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 4)]
2367  ""
2368  "*
2370   assemble_integer (operands[0], 4, 1);
2371   return \"\";
2373  [(set_attr "length" "4")
2374   (set_attr "in_delay_slot" "no")])
2376 ; 8 byte integer in line
2378 (define_insn "consttable_8"
2379  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 6)]
2380  ""
2381  "*
2383   assemble_integer (operands[0], 8, 1);
2384   return \"\";
2386  [(set_attr "length" "8")
2387   (set_attr "in_delay_slot" "no")])
2389 ; 4 byte floating point
2391 (define_insn "consttable_sf"
2392  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")] 4)]
2393  ""
2394  "*
2396   union real_extract u;
2397   bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
2398   assemble_real (u.d, SFmode);
2399   return \"\";
2401  [(set_attr "length" "4")
2402   (set_attr "in_delay_slot" "no")])
2404 ; 8 byte floating point
2406 (define_insn "consttable_df"
2407  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")] 6)]
2408  ""
2409  "*
2411   union real_extract u;
2412   bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
2413   assemble_real (u.d, DFmode);
2414   return \"\";
2416  [(set_attr "length" "8")
2417   (set_attr "in_delay_slot" "no")])
2419 ; align to a two byte boundary
2421 (define_insn "align_2"
2422  [(unspec_volatile [(const_int 0)] 10)]
2423  ""
2424  ".align 1"
2425  [(set_attr "length" "0")
2426   (set_attr "in_delay_slot" "no")])
2428 ; align to a four byte boundary
2430 (define_insn "align_4"
2431  [(unspec_volatile [(const_int 0)] 5)]
2432  ""
2433  ".align 2"
2434  [(set_attr "in_delay_slot" "no")])
2436 ; emitted at the end of the literal table, used to emit the
2437 ; 32bit branch labels if needed.
2439 (define_insn "consttable_end"
2440   [(unspec_volatile [(const_int 0)] 11)]
2441   ""
2442   "* return output_jump_label_table ();"
2443   [(set_attr "in_delay_slot" "no")])
2445 ;; -------------------------------------------------------------------------
2446 ;; Misc
2447 ;; -------------------------------------------------------------------------
2449 ;; String/block move insn.
2451 (define_expand "movstrsi"
2452   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2453                    (mem:BLK (match_operand:BLK 1 "" "")))
2454               (use (match_operand:SI 2 "nonmemory_operand" ""))
2455               (use (match_operand:SI 3 "immediate_operand" ""))
2456               (clobber (reg:SI 17))
2457               (clobber (reg:SI 4))
2458               (clobber (reg:SI 5))
2459               (clobber (reg:SI 0))])]
2460   ""
2461   "
2463   if(expand_block_move (operands))
2464      DONE;
2465   else FAIL;
2468 (define_insn "block_move_real"
2469   [(parallel [(set (mem:BLK (reg:SI 4))
2470                    (mem:BLK (reg:SI 5)))
2471               (use (match_operand:SI 0 "arith_reg_operand" "r"))
2472               (clobber (reg:SI 17))
2473               (clobber (reg:SI 0))])]
2474   ""
2475   "jsr  @%0%#"
2476   [(set_attr "type" "sfunc")
2477    (set_attr "needs_delay_slot" "yes")])
2479 (define_insn "block_lump_real"
2480   [(parallel [(set (mem:BLK (reg:SI 4))
2481                    (mem:BLK (reg:SI 5)))
2482               (use (match_operand:SI 0 "arith_reg_operand" "r"))
2483               (use (reg:SI 6))
2484               (clobber (reg:SI 17))
2485               (clobber (reg:SI 4))
2486               (clobber (reg:SI 5))
2487               (clobber (reg:SI 6))
2488               (clobber (reg:SI 0))])]
2489   ""
2490   "jsr  @%0%#"
2491   [(set_attr "type" "sfunc")
2492    (set_attr "needs_delay_slot" "yes")])
2494 ;; -------------------------------------------------------------------------
2495 ;; Floating point instructions.
2496 ;; -------------------------------------------------------------------------
2498 ;; ??? All patterns should have a type attribute.
2500 (define_insn "addsf3"
2501   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2502         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
2503                  (match_operand:SF 2 "arith_reg_operand" "f")))]
2504   "TARGET_SH3E"
2505   "fadd %2,%0"
2506   [(set_attr "type" "fp")])
2508 (define_insn "subsf3"
2509   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2510         (minus:SF (match_operand:SF 1 "arith_reg_operand" "0")
2511                   (match_operand:SF 2 "arith_reg_operand" "f")))]
2512   "TARGET_SH3E"
2513   "fsub %2,%0"
2514   [(set_attr "type" "fp")])
2516 (define_insn "mulsf3"
2517   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2518         (mult:SF (match_operand:SF 1 "arith_reg_operand" "%0")
2519                  (match_operand:SF 2 "arith_reg_operand" "f")))]
2520   "TARGET_SH3E"
2521   "fmul %2,%0"
2522   [(set_attr "type" "fp")])
2524 (define_insn "*macsf3"
2525   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2526         (plus:SF (mult:SF (match_operand:SF 1 "arith_reg_operand" "%w")
2527                           (match_operand:SF 2 "arith_reg_operand" "f"))
2528                  (match_operand:SF 3 "arith_reg_operand" "0")))]
2529   "TARGET_SH3E"
2530   "fmac fr0,%2,%0"
2531   [(set_attr "type" "fp")])
2533 (define_insn "divsf3"
2534   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2535         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
2536                 (match_operand:SF 2 "arith_reg_operand" "f")))]
2537   "TARGET_SH3E"
2538   "fdiv %2,%0"
2539   [(set_attr "type" "fdiv")])
2541 ;; ??? This is the right solution, but it fails because the movs[if] patterns
2542 ;; silently clobber FPUL (r22) for int<->fp moves.  Thus we can not explicitly
2543 ;; use FPUL here.
2545 ;;(define_expand "floatsisf2"
2546 ;;  [(set (reg:SI 22)
2547 ;;      (match_operand:SI 1 "arith_reg_operand" ""))
2548 ;;   (set (match_operand:SF 0 "arith_reg_operand" "")
2549 ;;        (float:SF (reg:SI 22)))]
2550 ;;  "TARGET_SH3E"
2551 ;;  "")
2553 ;;(define_insn "*floatsisf"
2554 ;;  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2555 ;;      (float:SF (reg:SI 22)))]
2556 ;;  "TARGET_SH3E"
2557 ;;  "float      fpul,%0")
2559 (define_insn "floatsisf2"
2560   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2561         (float:SF (match_operand:SI 1 "arith_reg_operand" "r")))]
2562   "TARGET_SH3E"
2563   "lds  %1,fpul\;float  fpul,%0"
2564   [(set_attr "length" "4")
2565    (set_attr "type" "fp")])
2567 ;; ??? This is the right solution, but it fails because the movs[if] patterns
2568 ;; silently clobber FPUL (r22) for int<->fp moves.  Thus we can not explicitly
2569 ;; use FPUL here.
2571 ;;(define_expand "fix_truncsfsi2"
2572 ;;  [(set (reg:SI 22)
2573 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
2574 ;;   (set (match_operand:SI 0 "arith_reg_operand" "=r")
2575 ;;      (reg:SI 22))]
2576 ;;  "TARGET_SH3E"
2577 ;;  "")
2579 ;;(define_insn "*fixsfsi"
2580 ;;  [(set (reg:SI 22)
2581 ;;      (fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))]
2582 ;;  "TARGET_SH3E"
2583 ;;  "ftrc       %0,fpul")
2585 (define_insn "fix_truncsfsi2"
2586   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2587         (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))]
2588   "TARGET_SH3E"
2589   "ftrc %1,fpul\;sts    fpul,%0"
2590   [(set_attr "length" "4")
2591    (set_attr "type" "move")])
2593 ;; ??? This should be SFmode not SImode in the compare, but that would
2594 ;; require fixing the branch patterns too.
2595 (define_insn "*cmpgtsf_t"
2596   [(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f")
2597                            (match_operand:SF 1 "arith_reg_operand" "f")))]
2598   "TARGET_SH3E"
2599   "fcmp/gt      %1,%0"
2600   [(set_attr "type" "fp")])
2602 ;; ??? This should be SFmode not SImode in the compare, but that would
2603 ;; require fixing the branch patterns too.
2604 (define_insn "*cmpeqsf_t"
2605   [(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
2606                            (match_operand:SF 1 "arith_reg_operand" "f")))]
2607   "TARGET_SH3E"
2608   "fcmp/eq      %1,%0"
2609   [(set_attr "type" "fp")])
2611 (define_expand "cmpsf"
2612   [(set (reg:SI 18) (compare (match_operand:SF 0 "arith_operand" "")
2613                              (match_operand:SF 1 "arith_operand" "")))]
2614   "TARGET_SH3E"
2615   "
2617   sh_compare_op0 = operands[0];
2618   sh_compare_op1 = operands[1];
2619   DONE;
2622 (define_insn "negsf2"
2623   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2624         (neg:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
2625   "TARGET_SH3E"
2626   "fneg %0"
2627   [(set_attr "type" "fp")])
2629 (define_insn "sqrtsf2"
2630   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2631         (sqrt:DF (match_operand:SF 1 "arith_reg_operand" "0")))]
2632   "TARGET_SH3E"
2633   "fsqrt        %0"
2634   [(set_attr "type" "fdiv")])
2636 (define_insn "abssf2"
2637   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
2638         (abs:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
2639   "TARGET_SH3E"
2640   "fabs %0"
2641   [(set_attr "type" "fp")])
2643 ;; Bit field extract patterns.  These give better code for packed bitfields,
2644 ;; because they allow auto-increment addresses to be generated.
2646 (define_expand "insv"
2647   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
2648                          (match_operand:SI 1 "immediate_operand" "")
2649                          (match_operand:SI 2 "immediate_operand" ""))
2650         (match_operand:SI 3 "general_operand" ""))]
2651   "! TARGET_LITTLE_ENDIAN"
2652   "
2654   rtx addr_target, orig_address, shift_reg;
2655   HOST_WIDE_INT size;
2657   /* ??? expmed doesn't care for non-register predicates.  */
2658   if (! memory_operand (operands[0], VOIDmode)
2659       || ! immediate_operand (operands[1], VOIDmode)
2660       || ! immediate_operand (operands[2], VOIDmode)
2661       || ! general_operand (operands[3], VOIDmode))
2662     FAIL;
2663   /* If this isn't a 16 / 24 / 32 bit field, or if
2664      it doesn't start on a byte boundary, then fail.  */
2665   size = INTVAL (operands[1]);
2666   if (size < 16 || size > 32 || size % 8 != 0
2667       || (INTVAL (operands[2]) % 8) != 0)
2668     FAIL;
2670   size /= 8;
2671   orig_address = XEXP (operands[0], 0);
2672   addr_target = gen_reg_rtx (SImode);
2673   shift_reg = gen_reg_rtx (SImode);
2674   emit_insn (gen_movsi (shift_reg, operands[3]));
2675   emit_insn (gen_addsi3 (addr_target, orig_address, GEN_INT (size - 1)));
2677   operands[0] = change_address (operands[0], QImode, addr_target);
2678   emit_insn (gen_movqi (operands[0], gen_rtx (SUBREG, QImode, shift_reg, 0)));
2680   while (size -= 1)
2681     {
2682       emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
2683       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
2684       emit_insn (gen_movqi (operands[0],
2685                             gen_rtx (SUBREG, QImode, shift_reg, 0)));
2686     }
2688   DONE;
2691 ;; -------------------------------------------------------------------------
2692 ;; Peepholes
2693 ;; -------------------------------------------------------------------------
2695 ;; This matches cases where a stack pointer increment at the start of the
2696 ;; epilogue combines with a stack slot read loading the return value.
2698 (define_peephole
2699   [(set (match_operand:SI 0 "arith_reg_operand" "")
2700         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
2701    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
2702   "REGNO (operands[1]) != REGNO (operands[0])"
2703   "mov.l        @%1+,%0")
2705 ;; See the comment on the dt combiner pattern above.
2707 (define_peephole
2708   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2709         (plus:SI (match_dup 0)
2710                  (const_int -1)))
2711    (set (reg:SI 18)
2712         (eq:SI (match_dup 0)
2713                (const_int 0)))]
2714   "TARGET_SH2"
2715   "dt   %0")
2717 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
2718 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
2719 ;; reload when the constant is too large for a reg+offset address.
2721 ;; ??? We would get much better code if this was done in reload.  This would
2722 ;; require modifying find_reloads_address to recognize that if the constant
2723 ;; is out-of-range for an immediate add, then we get better code by reloading
2724 ;; the constant into a register than by reloading the sum into a register,
2725 ;; since the former is one instruction shorter if the address does not need
2726 ;; to be offsettable.  Unfortunately this does not work, because there is
2727 ;; only one register, r0, that can be used as an index register.  This register
2728 ;; is also the function return value register.  So, if we try to force reload
2729 ;; to use double-reg addresses, then we end up with some instructions that
2730 ;; need to use r0 twice.  The only way to fix this is to change the calling
2731 ;; convention so that r0 is not used to return values.
2733 (define_peephole
2734   [(set (match_operand:SI 0 "register_operand" "=r")
2735         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2736    (set (mem:SI (match_dup 0))
2737         (match_operand:SI 2 "general_movsrc_operand" ""))]
2738   "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
2739   "mov.l        %2,@(%0,%1)")
2741 (define_peephole
2742   [(set (match_operand:SI 0 "register_operand" "=r")
2743         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2744    (set (match_operand:SI 2 "general_movdst_operand" "")
2745         (mem:SI (match_dup 0)))]
2746   "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
2747   "mov.l        @(%0,%1),%2")
2749 (define_peephole
2750   [(set (match_operand:SI 0 "register_operand" "=r")
2751         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2752    (set (mem:HI (match_dup 0))
2753         (match_operand:HI 2 "general_movsrc_operand" ""))]
2754   "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
2755   "mov.w        %2,@(%0,%1)")
2757 (define_peephole
2758   [(set (match_operand:SI 0 "register_operand" "=r")
2759         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2760    (set (match_operand:HI 2 "general_movdst_operand" "")
2761         (mem:HI (match_dup 0)))]
2762   "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
2763   "mov.w        @(%0,%1),%2")
2765 (define_peephole
2766   [(set (match_operand:SI 0 "register_operand" "=r")
2767         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2768    (set (mem:QI (match_dup 0))
2769         (match_operand:QI 2 "general_movsrc_operand" ""))]
2770   "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
2771   "mov.b        %2,@(%0,%1)")
2773 (define_peephole
2774   [(set (match_operand:SI 0 "register_operand" "=r")
2775         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2776    (set (match_operand:QI 2 "general_movdst_operand" "")
2777         (mem:QI (match_dup 0)))]
2778   "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
2779   "mov.b        @(%0,%1),%2")
2781 (define_peephole
2782   [(set (match_operand:SI 0 "register_operand" "=r")
2783         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2784    (set (mem:SF (match_dup 0))
2785         (match_operand:SF 2 "general_movsrc_operand" ""))]
2786   "REGNO (operands[0]) == 0
2787    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
2788        || (GET_CODE (operands[2]) == SUBREG
2789            && REGNO (SUBREG_REG (operands[2])) < 16))
2790    && reg_unused_after (operands[0], insn)"
2791   "mov.l        %2,@(%0,%1)")
2793 (define_peephole
2794   [(set (match_operand:SI 0 "register_operand" "=r")
2795         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2796    (set (match_operand:SF 2 "general_movdst_operand" "")
2798         (mem:SF (match_dup 0)))]
2799   "REGNO (operands[0]) == 0
2800    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
2801        || (GET_CODE (operands[2]) == SUBREG
2802            && REGNO (SUBREG_REG (operands[2])) < 16))
2803    && reg_unused_after (operands[0], insn)"
2804   "mov.l        @(%0,%1),%2")
2806 (define_peephole
2807   [(set (match_operand:SI 0 "register_operand" "=r")
2808         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2809    (set (mem:SF (match_dup 0))
2810         (match_operand:SF 2 "general_movsrc_operand" ""))]
2811   "REGNO (operands[0]) == 0
2812    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG)
2813        || (GET_CODE (operands[2]) == SUBREG
2814            && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG))
2815    && reg_unused_after (operands[0], insn)"
2816   "fmov.s       %2,@(%0,%1)")
2818 (define_peephole
2819   [(set (match_operand:SI 0 "register_operand" "=r")
2820         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
2821    (set (match_operand:SF 2 "general_movdst_operand" "")
2823         (mem:SF (match_dup 0)))]
2824   "REGNO (operands[0]) == 0
2825    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG)
2826        || (GET_CODE (operands[2]) == SUBREG
2827            && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG))
2828    && reg_unused_after (operands[0], insn)"
2829   "fmov.s       @(%0,%1),%2")
2831 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
2832 (define_insn "sp_switch_1"
2833   [(const_int 1)]
2834   ""
2835   "*
2837   rtx xoperands[1];
2839   xoperands[0] = sp_switch;
2840   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
2841   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
2842   return \"mov r0,r15\";
2844   [(set_attr "length" "10")])
2845    (set_attr "type" "move")])
2847 ;; Switch back to the original stack for interrupt funtions with the
2848 ;; sp_switch attribute.  */
2849 (define_insn "sp_switch_2"
2850   [(const_int 2)]
2851   ""
2852   "mov.l @r15+,r15\;mov.l @r15+,r0"
2853   [(set_attr "length" "4")])