Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS hook.
[official-gcc.git] / gcc / config / visium / visium.md
blob969cb887a6c1da274ed5c9d26a472ac92c3855ba
1 ;; Machine description for Visium.
2 ;; Copyright (C) 2002-2015 Free Software Foundation, Inc.
3 ;; Contributed by C.Nettleton, J.P.Parkes and P.Garbett.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24 ;; Extra register constraints are:
25 ;;   'b'   EAM register mdb
26 ;;   'c'   EAM register mdc
27 ;;   'f'   Floating-point register
28 ;;   'k'   Register that can be used as the target of a sibcall, i.e. call-used
29 ;;         general register not clobbered in the epilogue: r1-r8 and r10
30 ;;   'l'   Low general register, i.e. general register accessible in user mode
31 ;;         on the GR6 and, consequently, that can be used as the target of a
32 ;;         branch with prediction: r1-r28
33 ;;   't'   Register r1
34 ;;   'u'   Register r2
35 ;;   'v'   Register r3
37 ;; Immediate integer operand constraints are:
38 ;;   'J'  0 .. 65535     (16-bit immediate)
39 ;;   'K'  1 .. 31        (5-bit immediate)
40 ;;   'L'  -1 .. -65535   (16-bit negative immediate)
41 ;;   'M'  -1             (minus one)
42 ;;   'O'  0              (integer zero)
43 ;;   'P'  32             (thirty two)
45 ;; Immediate FP operand constraints are:
46 ;;   'G'  0.0            (floating-point zero)
48 ;; Operand substitution characters are:
49 ;;   %#   delay slot follows, if empty, fill with NOP
50 ;;   %b   LS 8 bits of immediate operand
51 ;;   %w   LS 16 bits of immediate operand
52 ;;   %u   MS 16 bits of immediate operand
53 ;;   %r   register or zero (r0)
54 ;;   %f   FP register or zero (f0)
55 ;;   %d   second register in a pair
57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
60 ;; Registers by name.
61 (define_constants [
62   (R_R1          1)
63   (R_R2          2)
64   (R_R3          3)
65   (R_R4          4)
66   (R_R5          5)
67   (R_R6          6)
68   (R_LINK       21)
69   (R_FP         22)
70   (R_SP         23)
71   (R_MDB        32)
72   (R_MDC        33)
73   (R_FLAGS      50)
76 ;; UNSPEC usage.
77 (define_c_enum "unspec" [
78   UNSPEC_MDBHI
79   UNSPEC_FLOAD
80   UNSPEC_FSTORE
81   UNSPEC_ITOF
82   UNSPEC_FTOI
83   UNSPEC_NOP
86 ;; UNSPEC_VOLATILE usage.
87 (define_c_enum "unspecv" [
88   UNSPECV_BLOCKAGE
89   UNSPECV_DSI
92 (include "predicates.md")
93 (include "constraints.md")
96 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
98 ;; Attributes.
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
103 ; Instruction type.
105 ;imm_reg       Move of immediate value to register.
106 ;mem_reg       Move from memory to register.
107 ;eam_reg       Move from EAM to register.
108 ;fp_reg        Move from FPU to register.
109 ;reg_mem       Move from register to memory.
110 ;reg_eam       Move from register to EAM.
111 ;reg_fp        Move from register to FPU.
112 ;arith         Arithmetic operation, result in register, sets overflow.
113 ;arith2        Two successive arithmetic operations.
114 ;logic         Logical operation, result in register, does not set overflow.
115 ;abs_branch    Absolute branch.
116 ;branch        Branch.
117 ;bmi           Block move.
118 ;call          Call to subprogram.
119 ;ret           Return from subprogram.
120 ;rfi           Return from interrupt.
121 ;dsi           Disable interrupts.
122 ;cmp           Compare or test.
123 ;div           EAM 32/32 division.
124 ;divd          EAM 64/32 division.
125 ;mul           EAM 32 * 32 -> 64 multiplication.
126 ;shiftdi       EAM 64 bit shift.
127 ;fdiv          Floating point divide.
128 ;fsqrt         Floating point square root.
129 ;ftoi          Fix float to integer.
130 ;itof          Float integer.
131 ;fmove         Floating point move w/ or w/o change of sign: fmove, fabs, fneg.
132 ;fcmp          Floating point compare or test.
133 ;fp            Other floating point operations.
134 ;nop           No operation.
135 ;multi         Multiple instructions which split.
136 ;asm           User asm instructions.
138 (define_attr "type"
139 "imm_reg,mem_reg,eam_reg,fp_reg,reg_mem,reg_eam,reg_fp,arith,arith2,logic,abs_branch,branch,bmi,call,ret,rfi,dsi,cmp,div,divd,mul,shiftdi,fdiv,fsqrt,ftoi,itof,fmove,fcmp,fp,nop,multi,asm" (const_string "logic"))
141 ; Those insns that occupy 4 bytes.
142 (define_attr "single_insn" "no,yes"
143   (if_then_else (eq_attr "type" "arith2,rfi,multi")
144                 (const_string "no")
145                 (const_string "yes")))
147 ; True if branch or call will be emitting a nop into its delay slot.
148 (define_attr "empty_delay_slot" "false,true"
149   (symbol_ref "(empty_delay_slot (insn)
150                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
152 ; Length in bytes.
153 ; The allowed range for the offset of short branches is [-131072;131068]
154 ; and it is counted from the address of the insn so we need to subtract
155 ; 8 for forward branches because (pc) points to the next insn for them.
156 (define_attr "length" ""
157   (cond [(eq_attr "type" "abs_branch,call,ret")
158            (if_then_else (eq_attr "empty_delay_slot" "true")
159                          (const_int 8)
160                          (const_int 4))
161          (eq_attr "type" "branch")
162            (if_then_else (leu (plus (minus (match_dup 0) (pc))
163                                     (const_int 131060))
164                               (const_int 262120))
165                          (if_then_else (eq_attr "empty_delay_slot" "true")
166                                        (const_int 8)
167                                        (const_int 4))
168                          (const_int 20))
169          (eq_attr "single_insn" "no")
170            (const_int 8)] (const_int 4)))
172 (define_asm_attributes [(set_attr "type" "asm")])
174 ; Delay slots.
175 (define_delay (eq_attr "type" "abs_branch,branch,call,ret")
176   [(and (eq_attr "type" "!abs_branch,branch,call,ret,rfi,bmi,mul,div,divd,fdiv,fsqrt,asm")
177         (eq_attr "single_insn" "yes"))
178     (nil) (nil)])
181 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
183 ;; Processor pipeline description.
185 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
188 ; Attribute for cpu type.
189 ; These must match the values for enum processor_type in visium-opts.h.
190 (define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr")))
192 (include "gr5.md")
193 (include "gr6.md")
196 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198 ;; Iterators.
200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
203 (define_mode_iterator QHI [QI HI])
204 (define_mode_iterator I [QI HI SI])
205 (define_mode_attr s [(QI ".b") (HI ".w") (SI ".l")])
207 ; This code iterator allows signed and unsigned widening multiplications
208 ; to use the same template.
209 (define_code_iterator any_extend [sign_extend zero_extend])
211 ; <u> expands to an empty string when doing a signed operation and
212 ; "u" when doing an unsigned operation.
213 (define_code_attr u [(sign_extend "") (zero_extend "u")])
215 ; <su> is like <u>, but the signed form expands to "s" rather than "".
216 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
218 ; This code iterator allows returns and simple returns to use the same template.
219 (define_code_iterator any_return [return simple_return])
220 (define_code_attr return_pred [(return "visium_can_use_return_insn_p ()")
221                                (simple_return "!visium_interrupt_function_p ()")])
222 (define_code_attr return_str [(return "") (simple_return "simple_")])
224 ; This code iterator allows integer and FP cstores to use the same template.
225 (define_code_iterator any_scc [ltu lt])
226 (define_code_attr scc_str [(ltu "sltu") (lt "slt")])
228 ;This code iterator allows cstore splitters to use the same template.
229 (define_code_iterator any_add [plus minus])
230 (define_code_attr add_op  [(plus "PLUS") (minus "MINUS")])
231 (define_code_attr add_str [(plus "plus") (minus "minus")])
234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
236 ;; Substitutions.
238 ;; They are used to define the second instruction of the pairs required by
239 ;; the postreload compare elimination pass, with a first variant for the
240 ;; logical insns and a second variant for the arithmetic insns.
242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245 (define_subst "flags_subst_logic"
246   [(set (match_operand 0 "") (match_operand 1 ""))
247    (clobber (reg:CC R_FLAGS))]
248   ""
249   [(set (match_dup 0) (match_dup 1))
250    (set (reg:CC R_FLAGS)
251         (compare:CC (match_dup 1) (const_int 0)))])
253 (define_subst_attr "subst_logic" "flags_subst_logic" "_flags" "_set_flags")
255 (define_subst "flags_subst_arith"
256   [(set (match_operand 0 "") (match_operand 1 ""))
257    (clobber (reg:CC R_FLAGS))]
258   ""
259   [(set (match_dup 0) (match_dup 1))
260    (set (reg:CC_NOOV R_FLAGS)
261         (compare:CC_NOOV (match_dup 1) (const_int 0)))])
263 (define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags")
266 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268 ;; QImode moves
270 ;; For moving among registers we use the move.b instruction.  This is
271 ;; actually an OR instruction using an alias.  For moving between register
272 ;; and memory we need the address of the memory location in a register.
273 ;; However, we can accept an expression (reg + offset) where offset is in
274 ;; the range 0 .. 31.
276 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
279 (define_expand "movqi"
280   [(set (match_operand:QI 0 "nonimmediate_operand" "")
281         (match_operand:QI 1 "general_operand" ""))]
282   ""
284   prepare_move_operands (operands, QImode);
287 (define_insn "*movqi_insn"
288   [(set (match_operand:QI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
289         (match_operand:QI 1 "general_operand"      " r,rO, r, r,?b,?c,i,m"))]
290   "ok_for_simple_move_operands (operands, QImode)"
291   "@
292     #
293     write.b %0,%r1
294     writemd %1,r0               ;movqi ?b r
295     writemdc %1         ;movqi ?c r
296     readmda %0          ;movqi r ?b
297     readmdc %0          ;movqi r ?c
298     moviq   %0,%b1              ;movqi  r  i
299     read.b  %0,%1"
300   [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
302 (define_insn "*movqi_insn<subst_logic>"
303   [(set (match_operand:QI 0 "gpc_reg_operand" "=r")
304         (match_operand:QI 1 "gpc_reg_operand" "r"))
305    (clobber (reg:CC R_FLAGS))]
306   "reload_completed"
307   "move.b  %0,%1"
308   [(set_attr "type" "logic")])
310 (define_split
311   [(set (match_operand:QI 0 "gpc_reg_operand" "")
312         (match_operand:QI 1 "gpc_reg_operand" ""))]
313   "reload_completed"
314   [(parallel [(set (match_dup 0) (match_dup 1))
315               (clobber (reg:CC R_FLAGS))])]
316   "")
318 (define_expand "movstrictqi"
319   [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
320         (match_operand:QI 1 "general_operand"                   ""))]
321   "")
323 (define_insn "*movstrictqi_insn"
324   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r,r"))
325         (match_operand:QI 1 "general_operand"                   "rO,m"))]
326   "ok_for_simple_move_strict_operands (operands, QImode)"
327   "@
328     #
329     read.b  %0,%1"
330   [(set_attr "type" "logic,mem_reg")])
332 (define_insn "*movstrictqi_insn<subst_logic>"
333   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
334         (match_operand:QI 1 "reg_or_0_operand"                  "rO"))
335    (clobber (reg:CC R_FLAGS))]
336   "reload_completed"
337   "move.b  %0,%r1"
338   [(set_attr "type" "logic")])
340 (define_split
341   [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
342         (match_operand:QI 1 "reg_or_0_operand" ""))]
343   "reload_completed"
344   [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
345               (clobber (reg:CC R_FLAGS))])]
346   "")
349 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
351 ;; HImode moves
353 ;; For moving among registers we use the move.w instruction.  This is
354 ;; actually an OR instruction using an alias.  For moving between register
355 ;; and memory we need the address of the memory location in a register.
356 ;; However, we can accept an expression (reg + offset) where offset is in
357 ;; the range 0 .. 62 and is shifted right one place in the assembled 
358 ;; instruction.
360 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
363 (define_expand "movhi"
364   [(set (match_operand:HI 0 "nonimmediate_operand" "")
365         (match_operand:HI 1 "general_operand" ""))]
366   ""
368   prepare_move_operands (operands, HImode);
371 (define_insn "*movhi_insn"
372   [(set (match_operand:HI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
373         (match_operand:HI 1 "general_operand"      " r,rO, r, r,?b,?c,i,m"))]
374   "ok_for_simple_move_operands (operands, HImode)"
375   "@
376     #
377     write.w %0,%r1
378     writemd %1,r0               ;movhi ?b r
379     writemdc %1         ;movhi ?c r
380     readmda %0          ;movhi r ?b
381     readmdc %0          ;movhi r ?c
382     moviq   %0,%w1              ;movhi  r  i
383     read.w  %0,%1"
384   [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
386 (define_insn "*movhi_insn<subst_logic>"
387   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
388         (match_operand:HI 1 "gpc_reg_operand" "r"))
389    (clobber (reg:CC R_FLAGS))]
390   "reload_completed"
391   "move.w  %0,%1"
392   [(set_attr "type" "logic")])
394 (define_split
395   [(set (match_operand:HI 0 "gpc_reg_operand" "")
396         (match_operand:HI 1 "gpc_reg_operand" ""))]
397   "reload_completed"
398   [(parallel [(set (match_dup 0) (match_dup 1))
399               (clobber (reg:CC R_FLAGS))])]
400   "")
402 (define_expand "movstricthi"
403   [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
404         (match_operand:HI 1 "general_operand"                   ""))]
405   "")
407 (define_insn "*movstricthi_insn"
408   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r,r,r"))
409         (match_operand:HI 1 "general_operand"                   " r,i,m"))]
410   "ok_for_simple_move_strict_operands (operands, HImode)"
411   "@
412     #
413     movil   %0,%w1
414     read.w  %0,%1"
415   [(set_attr "type" "logic,imm_reg,mem_reg")])
417 (define_insn "*movstricthi_insn<subst_logic>"
418   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
419         (match_operand:HI 1 "register_operand"                  "r"))
420    (clobber (reg:CC R_FLAGS))]
421   "reload_completed"
422   "move.w  %0,%1"
423   [(set_attr "type" "logic")])
425 (define_split
426   [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
427         (match_operand:HI 1 "register_operand" ""))]
428   "reload_completed"
429   [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
430               (clobber (reg:CC R_FLAGS))])]
431   "")
434 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
436 ;; SImode moves
438 ;; For moving among registers we use the move.l instruction.  This is
439 ;; actually an OR instruction using an alias.  For moving between register
440 ;; and memory we need the address of the memory location in a register.
441 ;; However, we can accept an expression (reg + offset) where offset is in
442 ;; the range 0 .. 124 and is shifted right two places in the assembled 
443 ;; instruction.
445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448 (define_expand "movsi"
449   [(set (match_operand:SI 0 "nonimmediate_operand" "")
450         (match_operand:SI 1 "general_operand" ""))]
451   ""
453   prepare_move_operands (operands, SImode);
456 (define_insn "*movsi_high"
457   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 
458         (high:SI (match_operand:SI 1 "immediate_operand" "n,i")) )]
459   ""
460   "@
461     moviu   %0,%u1
462     moviu   %0,%%u %a1"
463   [(set_attr "type" "imm_reg")])
465 ; We only care about the lower 16 bits of the constant 
466 ; being inserted into the upper 16 bits of the register.
467 (define_insn "*moviu"
468   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
469                          (const_int 16)
470                          (const_int 0))
471         (match_operand:SI 1 "const_int_operand" "n"))]
472   ""
473   "moviu   %0,%w1"
474   [(set_attr "type" "imm_reg")])
476 (define_insn "*movsi_losum"
477   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
478         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
479                    (match_operand:SI 2 "immediate_operand" "n,i")))]
480   ""
481   "@
482     movil   %0,%w2
483     movil   %0,%%l %a2"
484   [(set_attr "type" "imm_reg")])
486 (define_insn "*movil"
487   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
488                          (const_int 16)
489                          (const_int 16))
490         (match_operand:SI 1 "const_int_operand" "n"))]
491   ""
492   "movil   %0,%w1"
493   [(set_attr "type" "imm_reg")])
495 (define_insn "*movsi_insn_no_ieee"
496   [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,!f")
497         (match_operand:SI 1 "general_operand"      " r,rO, r, r,?b,?c,J,M,i,m,!f, r"))]
498   "!TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
499   "@
500     #
501     write.l %0,%r1
502     writemd %1,r0               ;movsi  ?b  r
503     writemdc %1         ;movsi  ?c  r
504     readmda %0          ;movsi  r  ?b
505     readmdc %0          ;movsi  r  ?c
506     moviq   %0,%1               ;movsi  r  J
507     #
508     #                   ;movsi  r  i
509     read.l  %0,%1
510     fstore  %0,%1
511     fload   %0,%1"
512   [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp")])
514 (define_insn "*movsi_insn"
515   [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,?f,f")
516         (match_operand:SI 1 "general_operand"      " r,rO, r, r,?b,?c,J,M,i,m,?f, r,f"))]
517   "TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
518   "@
519     #
520     write.l %0,%r1
521     writemd %1,r0               ;movsi  ?b  r
522     writemdc %1         ;movsi  ?c  r
523     readmda %0          ;movsi  r  ?b
524     readmdc %0          ;movsi  r  ?c
525     moviq   %0,%1               ;movsi  r  J
526     #
527     #                   ;movsi  r  i
528     read.l  %0,%1
529     fstore  %0,%1
530     fload   %0,%1
531     fmove   %0,%1"
532   [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp,fmove")])
534 (define_insn "*movsi_insn<subst_logic>"
535   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
536         (match_operand:SI 1 "gpc_reg_operand" "r"))
537    (clobber (reg:CC R_FLAGS))]
538   "reload_completed"
539   "move.l  %0,%1"
540   [(set_attr "type" "logic")])
542 (define_insn "*movsi_insn_m1<subst_logic>"
543   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
544         (const_int -1))
545    (clobber (reg:CC R_FLAGS))]
546   "reload_completed"
547   "not.l   %0,r0"
548   [(set_attr "type" "logic")])
550 (define_split
551   [(set (match_operand:SI 0 "gpc_reg_operand" "")
552         (match_operand:SI 1 "gpc_reg_operand" ""))]
553   "reload_completed"
554   [(parallel [(set (match_dup 0) (match_dup 1))
555               (clobber (reg:CC R_FLAGS))])]
556   "")
558 (define_split
559   [(set (match_operand:SI 0 "gpc_reg_operand" "")
560         (const_int -1))]
561   "reload_completed"
562   [(parallel [(set (match_dup 0) (const_int -1))
563               (clobber (reg:CC R_FLAGS))])]
564   "")
566 (define_insn "*movsi_mdbhi"
567   [(set (match_operand:SI 0 "register_operand" "=r")
568         (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
569   ""
570   "readmdb %0"
571   [(set_attr "type" "eam_reg")])
573 (define_split
574   [(set (match_operand:SI 0 "gpc_reg_operand" "")
575         (match_operand:SI 1 "large_immediate_operand" ""))]
576   "reload_completed"
577   [(set (match_dup 0)
578         (high:SI (match_dup 1)) )
579    (set (match_dup 0)
580         (lo_sum:SI (match_dup 0) (match_dup 1)))]
581   "")
584 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
586 ;; DImode moves
588 ;; When the destination is the EAM register MDB, then we use the writemd
589 ;; instruction.  In all other cases we split the move into two 32-bit moves.
591 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
594 (define_expand "movdi"
595   [(set (match_operand:DI 0 "nonimmediate_operand" "")
596         (match_operand:DI 1 "general_operand" ""))]
597   ""
599   prepare_move_operands (operands, DImode);
602 (define_insn "*movdi_insn"
603   [(set (match_operand:DI 0 "nonimmediate_operand" "= r, m, r,??b")
604         (match_operand:DI 1 "general_operand"      "rim,rO,?b,  r"))]
605   "ok_for_simple_move_operands (operands, DImode)"
606   "@
607     #
608     #
609     #
610     writemd %d1,%1              ;movdi  ?b r"
611   [(set_attr "type" "multi,multi,multi,reg_eam")])
613 (define_split
614   [(set (match_operand:DI 0 "gpc_reg_operand" "") (reg:DI R_MDB))]
615   "reload_completed"
616   [(set (match_dup 1) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))
617    (set (match_dup 2) (reg:SI R_MDB))]
619   operands[1] = operand_subword (operands[0], 0, 1, DImode);
620   operands[2] = operand_subword (operands[0], 1, 1, DImode);
623 (define_split
624   [(set (match_operand:DI 0 "non_eam_dst_operand" "")
625         (match_operand:DI 1 "non_eam_src_operand" ""))]
626   "reload_completed"
627   [(set (match_dup 2) (match_dup 3))
628    (set (match_dup 4) (match_dup 5))]
630   split_double_move (operands, DImode);
634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
636 ;; SFmode moves
638 ;; Constants are constructed in a GP register and moved to the FP register.
640 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
643 (define_expand "movsf"
644   [(set (match_operand:SF 0 "nonimmediate_operand" "")
645         (match_operand:SF 1 "general_operand" ""))]
646   ""
648   prepare_move_operands (operands, SFmode);
651 (define_insn "*movsf_insn"
652   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,r,r, m,r,r,r")
653         (match_operand:SF 1 "general_operand"      " f,G,r,f,r,rG,G,F,m"))]
654   "ok_for_simple_move_operands (operands, SFmode)"
655   "@
656     fmove   %0,%1
657     fmove   %0,f0
658     fload   %0,%1
659     fstore  %0,%1
660     #
661     write.l %0,%r1
662     moviq   %0,0
663     #
664     read.l  %0,%1"
665   [(set_attr "type" "fmove,fmove,reg_fp,fp_reg,logic,reg_mem,imm_reg,multi,mem_reg")])
667 (define_insn "*movsf_insn"
668   [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
669         (match_operand:SF 1 "gpc_reg_operand" "r"))
670    (clobber (reg:CC R_FLAGS))]
671   "reload_completed"
672   "move.l  %0,%1"
673   [(set_attr "type" "logic")])
675 (define_split
676   [(set (match_operand:SF 0 "gpc_reg_operand" "")
677         (match_operand:SF 1 "gpc_reg_operand" ""))]
678   "reload_completed"
679   [(parallel [(set (match_dup 0) (match_dup 1))
680               (clobber (reg:CC R_FLAGS))])]
681   "")
683 (define_split
684   [(set (match_operand:SF 0 "gpc_reg_operand" "")
685         (match_operand:SF 1 "const_double_operand" ""))]
686   "reload_completed"
687   [(set (match_dup 2) (match_dup 3))]
689   long l;
690   REAL_VALUE_TYPE rv;
692   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
693   REAL_VALUE_TO_TARGET_SINGLE (rv, l);
695   operands[2] = operand_subword (operands[0], 0, 0, SFmode);
696   operands[3] = GEN_INT (trunc_int_for_mode (l, SImode));
700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
702 ;; DFmode moves
704 ;; We always split a DFmode move into two SImode moves.
706 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
709 (define_expand "movdf"
710   [(set (match_operand:DF 0 "nonimmediate_operand" "")
711         (match_operand:DF 1 "general_operand" ""))]
712   ""
714   prepare_move_operands (operands, DFmode);
717 (define_insn "*movdf_insn"
718   [(set (match_operand:DF 0 "nonimmediate_operand" "= r, m")
719         (match_operand:DF 1 "general_operand"      "rFm,rG"))]
720   "ok_for_simple_move_operands (operands, DFmode)"
721   "#"
722   [(set_attr "type" "multi")])
724 (define_split
725   [(set (match_operand:DF 0 "nonimmediate_operand" "")
726         (match_operand:DF 1 "general_operand" ""))]
727   "reload_completed"
728   [(set (match_dup 2) (match_dup 3))
729    (set (match_dup 4) (match_dup 5))]
731   split_double_move (operands, DFmode);
735 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
737 ;; Integer Add
739 ;; Modes QI, HI, SI and DI are supported directly.
741 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
744 (define_expand "add<mode>3"
745   [(set (match_operand:QHI 0 "register_operand" "")
746         (plus:QHI (match_operand:QHI 1 "register_operand" "")
747                   (match_operand:QHI 2 "register_operand" "")))]
748   "")
750 (define_insn_and_split "*add<mode>3_insn"
751   [(set (match_operand:QHI 0 "register_operand" "=r")
752         (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
753                   (match_operand:QHI 2 "register_operand" "r")))]
754   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
755   "#"
756   "reload_completed"
757   [(parallel [(set (match_dup 0)
758                    (plus:QHI (match_dup 1) (match_dup 2)))
759               (clobber (reg:CC R_FLAGS))])]
760   ""
761   [(set_attr "type" "arith")])
763 (define_insn "*add<mode>3_insn<subst_arith>"
764   [(set (match_operand:QHI 0 "register_operand" "=r")
765         (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
766                   (match_operand:QHI 2 "register_operand" "r")))
767    (clobber (reg:CC R_FLAGS))]
768   "reload_completed"
769   "add<s>   %0,%1,%2"
770   [(set_attr "type" "arith")])
772 (define_expand "addsi3"
773   [(set (match_operand:SI 0 "register_operand" "")
774         (plus:SI (match_operand:SI 1 "register_operand" "")
775                  (match_operand:SI 2 "add_operand" "")))]
776   "")
778 (define_expand "addsi3_flags"
779   [(parallel [(set (match_operand:SI 0 "register_operand" "")
780                    (plus:SI (match_operand:SI 1 "register_operand" "")
781                             (match_operand:SI 2 "add_operand" "")))
782               (clobber (reg:CC R_FLAGS))])]
783   "reload_completed"
784   "")
786 (define_insn_and_split "*addsi3_insn"
787   [(set (match_operand:SI 0 "register_operand"          "=r,r,r")
788         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
789                  (match_operand:SI 2 "add_operand"      " L,r,J")))]
790   "ok_for_simple_arith_logic_operands (operands, SImode)"
791   "#"
792   "reload_completed"
793   [(parallel [(set (match_dup 0)
794                    (plus:SI (match_dup 1) (match_dup 2)))
795               (clobber (reg:CC R_FLAGS))])]
796   ""
797   [(set_attr "type" "arith")])
799 ; Favour the addition of small negative constants, since they are
800 ; expensive to load into a register.
802 (define_insn "*addsi3_insn<subst_arith>"
803   [(set (match_operand:SI 0 "register_operand"          "=r,r,r")
804         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
805                  (match_operand:SI 2 "add_operand"      " L,r,J")))
806    (clobber (reg:CC R_FLAGS))]
807   "reload_completed"
808   "@
809     subi    %0,%n2
810     add.l   %0,%1,%2
811     addi    %0,%2"
812   [(set_attr "type" "arith")])
814 (define_expand "adddi3"
815   [(set (match_operand:DI 0 "register_operand" "")
816         (plus:DI (match_operand:DI 1 "register_operand" "")
817                  (match_operand:DI 2 "add_operand" "")))]
818   "")
820 (define_insn_and_split "*addi3_insn"
821   [(set (match_operand:DI 0 "register_operand"          "=r,r,&r")
822         (plus:DI (match_operand:DI 1 "register_operand" "%0,0, r")
823                  (match_operand:DI 2 "add_operand"      " J,L, r")))]
824   "ok_for_simple_arith_logic_operands (operands, DImode)"
825   "#"
826   "reload_completed"
827   [(parallel [(set (match_dup 0)
828                    (plus:DI (match_dup 1) (match_dup 2)))
829               (clobber (reg:CC R_FLAGS))])]
830   ""
831   [(set_attr "type" "arith2")])
833 ; Disfavour the use of add.l because of the early clobber.
835 (define_insn "*adddi3_insn_flags"
836   [(set (match_operand:DI 0 "register_operand"          "=r,r,&r")
837         (plus:DI (match_operand:DI 1 "register_operand" "%0,0, r")
838                  (match_operand:DI 2 "add_operand"      " J,L, r")))
839    (clobber (reg:CC R_FLAGS))]
840   "reload_completed"
841   "@
842     addi    %d0,%2\n\tadc.l   %0,%0,r0
843     subi    %d0,%n2\n\tsubc.l  %0,%0,r0
844     add.l   %d0,%d1,%d2\n\tadc.l   %0,%1,%2"
845   [(set_attr "type" "arith2")])
848 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
850 ;; Integer Add with Carry
852 ;; Only SI mode is supported as slt[u] for the sake of cstore.
854 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
857 (define_insn "*<scc_str><subst_arith>"
858   [(set (match_operand:SI 0 "register_operand" "=r")
859         (any_scc:SI (reg R_FLAGS) (const_int 0)))
860    (clobber (reg:CC R_FLAGS))]
861   "reload_completed"
862   "adc.l   %0,r0,r0"
863   [(set_attr "type" "arith")])
865 (define_insn "*plus_<scc_str><subst_arith>"
866   [(set (match_operand:SI 0 "register_operand" "=r")
867         (plus:SI (match_operand:SI 1 "register_operand" "r")
868                  (any_scc:SI (reg R_FLAGS) (const_int 0))))
869    (clobber (reg:CC R_FLAGS))]
870   "reload_completed"
871   "adc.l   %0,%1,r0"
872   [(set_attr "type" "arith")])
875 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
877 ;; Integer Subtract
879 ;; Modes QI, HI, SI and DI are supported directly.
881 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
884 (define_expand "sub<mode>3"
885   [(set (match_operand:QHI 0 "register_operand" "")
886         (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "")
887                    (match_operand:QHI 2 "register_operand" "")))]
888   "")
890 (define_insn_and_split "*sub<mode>3_insn"
891   [(set (match_operand:QHI 0 "register_operand" "=r")
892         (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
893                    (match_operand:QHI 2 "register_operand" "r")))]
894   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
895   "#"
896   "reload_completed"
897   [(parallel [(set (match_dup 0)
898                    (minus:QHI (match_dup 1) (match_dup 2)))
899               (clobber (reg:CC R_FLAGS))])]
900  ""
901   [(set_attr "type" "arith")])
903 (define_insn "*sub<mode>3_insn<subst_arith>"
904   [(set (match_operand:QHI 0 "register_operand" "=r")
905         (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
906                    (match_operand:QHI 2 "register_operand" "r")))
907    (clobber (reg:CC R_FLAGS))]
908   "reload_completed"
909   "sub<s>   %0,%r1,%2"
910   [(set_attr "type" "arith")])
912 (define_expand "subsi3"
913   [(set (match_operand:SI 0 "register_operand" "")
914         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
915                   (match_operand:SI 2 "add_operand" "")))]
916   "")
918 (define_expand "subsi3_flags"
919   [(parallel [(set (match_operand:SI 0 "register_operand" "")
920                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
921                              (match_operand:SI 2 "add_operand" "")))
922               (clobber (reg:CC R_FLAGS))])]
923   "reload_completed"
924   "")
926 (define_insn_and_split "*subsi3_insn"
927   [(set (match_operand:SI 0 "register_operand"           "=r,r, r")
928         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
929                   (match_operand:SI 2 "add_operand"      " L,r, J")))]
930   "ok_for_simple_arith_logic_operands (operands, SImode)"
931   "#"
932   "reload_completed"
933   [(parallel [(set (match_dup 0)
934                    (minus:SI (match_dup 1) (match_dup 2)))
935               (clobber (reg:CC R_FLAGS))])]
936  ""
937   [(set_attr "type" "arith")])
939 ; Favour the subtraction of small negative constants, since they are
940 ; expensive to load into a register.
942 (define_insn "*subsi3_insn<subst_arith>"
943   [(set (match_operand:SI 0 "register_operand"           "=r,r, r")
944         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
945                   (match_operand:SI 2 "add_operand"      " L,r, J")))
946    (clobber (reg:CC R_FLAGS))]
947   "reload_completed"
948   "@
949     addi    %0,%n2
950     sub.l   %0,%r1,%2
951     subi    %0,%2"
952   [(set_attr "type" "arith")])
954 (define_expand "subdi3"
955   [(set (match_operand:DI 0 "register_operand" "")
956         (minus:DI (match_operand:DI 1 "register_operand" "")
957                   (match_operand:DI 2 "add_operand" "")))]
958   "")
960 (define_insn_and_split "*subdi3_insn"
961   [(set (match_operand:DI 0 "register_operand"           "=r,r,&r")
962         (minus:DI (match_operand:DI 1 "register_operand" " 0,0, r")
963                   (match_operand:DI 2 "add_operand"      " J,L, r")))]
964   "ok_for_simple_arith_logic_operands (operands, DImode)"
965   "#"
966   "reload_completed"
967   [(parallel [(set (match_dup 0)
968                    (minus:DI (match_dup 1) (match_dup 2)))
969               (clobber (reg:CC R_FLAGS))])]
970  ""
971   [(set_attr "type" "arith2")])
973 ; Disfavour the use of the sub.l because of the early clobber.
975 (define_insn "*subdi3_insn_flags"
976   [(set (match_operand:DI 0 "register_operand"           "=r,r,&r")
977         (minus:DI (match_operand:DI 1 "register_operand" " 0,0, r")
978                   (match_operand:DI 2 "add_operand"      " J,L, r")))
979    (clobber (reg:CC R_FLAGS))]
980   "reload_completed"
981   "@
982     subi    %d0,%2\n\tsubc.l  %0,%0,r0
983     addi    %d0,%n2\n\tadc.l   %0,%0,r0
984     sub.l   %d0,%d1,%d2\n\tsubc.l  %0,%1,%2"
985   [(set_attr "type" "arith2")])
988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
990 ;; Integer Subtract with Carry
992 ;; Only SI mode is supported as neg<slt[u]> for the sake of cstore.
994 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
997 (define_insn "*neg_<scc_str><subst_arith>"
998   [(set (match_operand:SI 0 "register_operand" "=r")
999         (neg:SI (any_scc:SI (reg R_FLAGS) (const_int 0))))
1000    (clobber (reg:CC R_FLAGS))]
1001   "reload_completed"
1002   "subc.l  %0,r0,r0"
1003   [(set_attr "type" "arith")])
1005 (define_insn "*minus_<scc_str><subst_arith>"
1006   [(set (match_operand:SI 0 "register_operand" "=r")
1007         (minus:SI (match_operand:SI 1 "register_operand" "r")
1008                   (any_scc:SI (reg R_FLAGS) (const_int 0))))
1009    (clobber (reg:CC R_FLAGS))]
1010   "reload_completed"
1011   "subc.l  %0,%1,r0"
1012   [(set_attr "type" "arith")])
1015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1017 ;; Integer Negate
1019 ;; Modes QI, HI, SI and DI are supported directly.
1021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1024 (define_expand "neg<mode>2"
1025   [(set (match_operand:I 0 "register_operand" "")
1026         (neg:I (match_operand:I 1 "register_operand" "")))]
1027   "")
1029 (define_insn_and_split "*neg<mode>2_insn"
1030   [(set (match_operand:I 0 "register_operand" "=r")
1031         (neg:I (match_operand:I 1 "register_operand" "r")))]
1032   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1033   "#"
1034   "reload_completed"
1035   [(parallel [(set (match_dup 0) (neg:I (match_dup 1)))
1036               (clobber (reg:CC R_FLAGS))])]
1037   ""
1038   [(set_attr "type" "arith")])
1040 (define_insn "*neg<mode>2_insn<subst_arith>"
1041   [(set (match_operand:I 0 "register_operand" "=r")
1042         (neg:I (match_operand:I 1 "register_operand" "r")))
1043    (clobber (reg:CC R_FLAGS))]
1044   "reload_completed"
1045   "sub<s>   %0,r0,%1"
1046   [(set_attr "type" "arith")])
1048 (define_expand "negdi2"
1049   [(set (match_operand:DI 0 "register_operand" "")
1050         (neg:DI (match_operand:DI 1 "register_operand" "")))]
1051   "")
1053 (define_insn_and_split "*negdi2_insn"
1054   [(set (match_operand:DI 0 "register_operand" "=&r")
1055         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
1056   "ok_for_simple_arith_logic_operands (operands, DImode)"
1057   "#"
1058   "reload_completed"
1059   [(parallel [(set (match_dup 0) (neg:DI (match_dup 1)))
1060               (clobber (reg:CC R_FLAGS))])]
1061   ""
1062   [(set_attr "type" "arith2")])
1064 (define_insn "*negdi2_insn_flags"
1065   [(set (match_operand:DI 0 "register_operand" "=&r")
1066         (neg:DI (match_operand:DI 1 "register_operand" "r")))
1067    (clobber (reg:CC R_FLAGS))]
1068   "reload_completed"
1069   "sub.l   %d0,r0,%d1\n\tsubc.l  %0,r0,%1"
1070   [(set_attr "type" "arith2")])
1073 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1075 ;; Integer Multiply (non-widening and widening, signed and unsigned)
1077 ;; Only SI mode is supported.
1079 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1082 ; The mults and multu instructions clear MDC but we only pretend that they
1083 ; clobber it to keep things relatively simple.
1085 (define_insn "mulsi3"
1086   [(set (match_operand:SI 0 "register_operand" "=b")
1087          (mult:SI (match_operand:SI 1 "register_operand" "%r")
1088                   (match_operand:SI 2 "register_operand" "r")))
1089    (clobber (reg:SI R_MDC))]
1090   ""
1091   "mults   %1,%2"
1092   [(set_attr "type" "mul")])
1094 ; The names are mulsidi3 and umulsidi3 here.
1096 (define_insn "<u>mulsidi3"
1097   [(set (match_operand:DI 0 "register_operand" "=b")
1098         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1099                  (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))
1100    (clobber (reg:SI R_MDC))]
1101   ""
1102   "mult<su>   %1,%2"
1103   [(set_attr "type" "mul")])
1105 ; But they are smulsi3_highpart and umulsi3_highpart here.
1107 (define_insn_and_split "<su>mulsi3_highpart"
1108   [(set (match_operand:SI 0 "register_operand" "=r")
1109         (truncate:SI
1110           (ashiftrt:DI
1111             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1112                      (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
1113             (const_int 32))))
1114    (clobber (reg:DI R_MDB))
1115    (clobber (reg:SI R_MDC))]
1116   ""
1117   "#"
1118   "reload_completed"
1119   [(parallel [(set (reg:DI R_MDB)
1120                    (mult:DI (any_extend:DI (match_dup 1))
1121                             (any_extend:DI (match_dup 2))))
1122               (clobber (reg:SI R_MDC))])
1123    (set (match_dup 0) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
1124   ""
1125   [(set_attr "type" "multi")])
1128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1130 ;; Integer divide and modulus (signed and unsigned)
1132 ;; Only SI mode is supported.
1134 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1137 (define_insn "*divmodsi4_insn"
1138   [(set (match_operand:SI 0 "register_operand" "=b")
1139         (div:SI (match_operand:SI 1 "register_operand" "0")
1140                 (match_operand:SI 2 "register_operand" "r")))
1141    (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))]
1142   ""
1143   "divs    %2"
1144   [(set_attr "type" "div")])
1146 (define_insn_and_split "divmodsi4"
1147   [(set (match_operand:SI 0 "register_operand" "=b")
1148         (div:SI (match_operand:SI 1 "register_operand" "0")
1149                 (match_operand:SI 2 "register_operand" "r")))
1150    (set (match_operand:SI 3 "register_operand" "=r")
1151         (mod:SI (match_dup 1) (match_dup 2)))
1152    (clobber (reg:SI R_MDC))]
1153   ""
1154   "#"
1155   "reload_completed"
1156   [(parallel [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2)))
1157               (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))])
1158    (set (match_dup 3) (reg:SI R_MDC))]
1159   ""
1160   [(set_attr "type" "multi")])
1162 (define_insn "*udivmodsi4_insn"
1163   [(set (match_operand:SI 0 "register_operand" "=b")
1164         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1165                  (match_operand:SI 2 "register_operand" "r")))
1166    (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))]
1167   ""
1168   "divu    %2"
1169   [(set_attr "type" "div")])
1171 (define_insn_and_split "udivmodsi4"
1172   [(set (match_operand:SI 0 "register_operand" "=b")
1173         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1174                  (match_operand:SI 2 "register_operand" "r")))
1175    (set (match_operand:SI 3 "register_operand" "=r")
1176         (umod:SI (match_dup 1) (match_dup 2)))
1177    (clobber (reg:SI R_MDC))]
1178   ""
1179   "#"
1180   "reload_completed"
1181   [(parallel [(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2)))
1182               (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))])
1183    (set (match_dup 3) (reg:SI R_MDC))]
1184   ""
1185   [(set_attr "type" "multi")])
1187 ; FIXME. How do we persuade the compiler to use 64/32 bit divides directly ?
1189 (define_insn "*divds"
1190   [(set (reg:DI R_MDB)
1191         (div:DI (reg:DI R_MDB) (sign_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1192    (set (reg:SI R_MDC) (truncate:SI (mod:DI (reg:DI R_MDB) (sign_extend:DI (match_dup 0)))))]
1193   ""
1194   "divds   %0"
1195   [(set_attr "type" "divd")])
1197 (define_insn "*divdu"
1198   [(set (reg:DI R_MDB)
1199         (udiv:DI (reg:DI R_MDB) (zero_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1200    (set (reg:SI R_MDC) (truncate:SI (umod:DI (reg:DI R_MDB) (zero_extend:DI (match_dup 0)))))]
1201   ""
1202   "divdu   %0"
1203   [(set_attr "type" "divd")])
1205 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1207 ;; Bitwise Logical AND
1209 ;; Modes QI, HI and SI are supported directly.
1211 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1214 (define_expand "and<mode>3"
1215   [(set (match_operand:I 0 "register_operand" "")
1216         (and:I (match_operand:I 1 "register_operand" "")
1217                (match_operand:I 2 "register_operand" "")))]
1218   "")
1220 (define_insn_and_split "*and<mode>3_insn"
1221   [(set (match_operand:I 0 "register_operand" "=r")
1222         (and:I (match_operand:I 1 "register_operand" "%r")
1223                (match_operand:I 2 "register_operand" "r")))]
1224   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1225   "#"
1226   "reload_completed"
1227   [(parallel [(set (match_dup 0)
1228                    (and:I (match_dup 1) (match_dup 2)))
1229               (clobber (reg:CC R_FLAGS))])]
1230   ""
1231   [(set_attr "type" "logic")])
1233 (define_insn "*and<mode>3_insn<subst_logic>"
1234   [(set (match_operand:I 0 "register_operand" "=r")
1235         (and:I (match_operand:I 1 "register_operand" "%r")
1236                (match_operand:I 2 "register_operand" "r")))
1237    (clobber (reg:CC R_FLAGS))]
1238   "reload_completed"
1239   "and<s>   %0,%1,%2"
1240   [(set_attr "type" "logic")])
1243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1245 ;; Bitwise Inclusive Logical OR
1247 ;; Modes QI, HI and SI are supported directly.
1249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1252 (define_expand "ior<mode>3"
1253   [(set (match_operand:I 0 "register_operand" "")
1254         (ior:I (match_operand:I 1 "register_operand" "")
1255                (match_operand:I 2 "register_operand" "")))]
1256   "")
1258 (define_insn_and_split "*ior<mode>3_insn"
1259   [(set (match_operand:I 0 "register_operand" "=r")
1260         (ior:I (match_operand:I 1 "register_operand" "%r")
1261                (match_operand:I 2 "register_operand" "r")))]
1262   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1263   "#"
1264   "reload_completed"
1265   [(parallel [(set (match_dup 0)
1266                    (ior:I (match_dup 1) (match_dup 2)))
1267               (clobber (reg:CC R_FLAGS))])]
1268   ""
1269   [(set_attr "type" "logic")])
1271 (define_insn "*ior<mode>3_insn<subst_logic>"
1272   [(set (match_operand:I 0 "register_operand" "=r")
1273         (ior:I (match_operand:I 1 "register_operand" "%r")
1274                (match_operand:I 2 "register_operand" "r")))
1275    (clobber (reg:CC R_FLAGS))]
1276   "reload_completed"
1277   "or<s>    %0,%1,%2"
1278   [(set_attr "type" "logic")])
1281 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1283 ;; Bitwise Exclusive Logical OR
1285 ;; Modes QI, HI and SI are supported directly.
1287 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1290 (define_expand "xor<mode>3"
1291   [(set (match_operand:I 0 "register_operand" "")
1292         (xor:I (match_operand:I 1 "register_operand" "")
1293                 (match_operand:I 2 "register_operand" "")))]
1294   "")
1296 (define_insn_and_split "*xor<mode>3_insn"
1297   [(set (match_operand:I 0 "register_operand" "=r")
1298         (xor:I (match_operand:I 1 "register_operand" "%r")
1299                (match_operand:I 2 "register_operand" "r")))]
1300   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1301   "#"
1302   "reload_completed"
1303   [(parallel [(set (match_dup 0)
1304                    (xor:I (match_dup 1) (match_dup 2)))
1305               (clobber (reg:CC R_FLAGS))])]
1306   ""
1307   [(set_attr "type" "logic")])
1309 (define_insn "*xor<mode>3_insn<subst_logic>"
1310   [(set (match_operand:I 0 "register_operand" "=r")
1311         (xor:I (match_operand:I 1 "register_operand" "%r")
1312                (match_operand:I 2 "register_operand" "r")))
1313    (clobber (reg:CC R_FLAGS))]
1314   "reload_completed"
1315   "xor<s>   %0,%1,%2"
1316   [(set_attr "type" "logic")])
1319 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1321 ;; Bitwise Logical NOT
1323 ;; Modes QI, HI and SI are supported directly.
1325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1328 (define_expand "one_cmpl<mode>2"
1329   [(set (match_operand:I 0 "register_operand" "")
1330         (not:I (match_operand:I 1 "reg_or_0_operand" "")))]
1331   "")
1333 (define_insn_and_split "*one_cmpl<mode>2_insn"
1334   [(set (match_operand:I 0 "register_operand" "=r")
1335         (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))]
1336   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1337   "#"
1338   "reload_completed"
1339   [(parallel [(set (match_dup 0) (not:I (match_dup 1)))
1340               (clobber (reg:CC R_FLAGS))])]
1341   ""
1342   [(set_attr "type" "logic")])
1344 (define_insn "*one_cmpl<mode>2_insn<subst_logic>"
1345   [(set (match_operand:I 0 "register_operand" "=r")
1346         (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))
1347    (clobber (reg:CC R_FLAGS))]
1348   "reload_completed"
1349   "not<s>   %0,%r1"
1350   [(set_attr "type" "logic")])
1353 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1355 ;; Arithmetic Shift Left
1357 ;; Modes QI, HI, SI and DI are supported directly.
1359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1362 (define_expand "ashl<mode>3"
1363   [(set (match_operand:I 0 "register_operand" "")
1364         (ashift:I (match_operand:I  1 "register_operand"     "")
1365                   (match_operand:QI 2 "reg_or_shift_operand" "")))]
1366   "")
1368 (define_insn_and_split "*ashl<mode>3_insn"
1369   [(set (match_operand:I 0 "register_operand" "=r,r")
1370         (ashift:I (match_operand:I  1 "register_operand"     "r,r")
1371                   (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1372   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1373   "#"
1374   "reload_completed"
1375   [(parallel [(set (match_dup 0)
1376                    (ashift:I (match_dup 1) (match_dup 2)))
1377               (clobber (reg:CC R_FLAGS))])]
1378   ""
1379   [(set_attr "type" "arith")])
1381 (define_insn "*ashl<mode>3_insn<subst_arith>"
1382   [(set (match_operand:I 0 "register_operand" "=r,r")
1383         (ashift:I (match_operand:I  1 "register_operand"     "r,r")
1384                   (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1385    (clobber (reg:CC R_FLAGS))]
1386   "reload_completed"
1387   "asl<s>   %0,%1,%2"
1388   [(set_attr "type" "arith")])
1390 (define_insn "ashldi3"
1391   [(set (match_operand:DI 0 "register_operand" "=b,r")
1392         (ashift:DI (match_operand:DI 1 "register_operand" "0,r")
1393                    (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1394    (clobber (reg:SI R_MDC))]
1395   ""
1396   "@
1397     asld    %2
1398     #"
1399   [(set_attr "type" "shiftdi,multi")])
1401 (define_split
1402   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1403         (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
1404                    (const_int 32)))
1405    (clobber (reg:SI R_MDC))]
1406   "reload_completed"
1407   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 4))
1408    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
1409   "")
1412 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1414 ;; Arithmetic Shift Right
1416 ;; Modes QI, HI, SI and DI are supported directly.
1418 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1421 (define_expand "ashr<mode>3"
1422   [(set (match_operand:I 0 "register_operand" "")
1423         (ashiftrt:I (match_operand:I  1 "register_operand"     "")
1424                     (match_operand:QI 2 "reg_or_shift_operand" "")))]
1425   "")
1427 (define_insn_and_split "*ashr<mode>3_insn"
1428   [(set (match_operand:I 0 "register_operand" "=r,r")
1429         (ashiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1430                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1431   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1432   "#"
1433   "reload_completed"
1434   [(parallel [(set (match_dup 0)
1435                    (ashiftrt:I (match_dup 1) (match_dup 2)))
1436               (clobber (reg:CC R_FLAGS))])]
1437   ""
1438   [(set_attr "type" "logic")])
1440 (define_insn "*ashr<mode>3_insn<subst_logic>"
1441   [(set (match_operand:I 0 "register_operand" "=r,r")
1442         (ashiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1443                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1444    (clobber (reg:CC R_FLAGS))]
1445   "reload_completed"
1446   "asr<s>   %0,%1,%2"
1447   [(set_attr "type" "logic")])
1449 (define_insn "ashrdi3"
1450   [(set (match_operand:DI 0 "register_operand" "=b,r")
1451         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1452                      (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1453    (clobber (reg:SI R_MDC))]
1454   ""
1455   "@
1456     asrd    %2
1457     #"
1458   [(set_attr "type" "shiftdi,multi")])
1460 (define_split
1461   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1462         (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1463                      (const_int 32)))
1464    (clobber (reg:SI R_MDC))]
1465   "reload_completed"
1466   [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1467    (parallel [(set (subreg:SI (match_dup 0) 0)
1468                    (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))
1469               (clobber (reg:CC R_FLAGS))])]
1470   "")
1473 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1475 ;; Logical Shift Right
1477 ;; Modes QI, HI, SI and DI are supported directly.
1479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1482 (define_expand "lshr<mode>3"
1483   [(set (match_operand:I 0 "register_operand" "")
1484         (lshiftrt:I (match_operand:I  1 "register_operand"     "")
1485                     (match_operand:QI 2 "reg_or_shift_operand" "")))]
1486   "")
1488 (define_insn_and_split "*lshr<mode>3_insn"
1489   [(set (match_operand:I 0 "register_operand" "=r,r")
1490         (lshiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1491                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1492   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1493   "#"
1494   "reload_completed"
1495   [(parallel [(set (match_dup 0)
1496                    (lshiftrt:I (match_dup 1) (match_dup 2)))
1497               (clobber (reg:CC R_FLAGS))])]
1498   ""
1499   [(set_attr "type" "logic")])
1501 (define_insn "*lshr<mode>3_insn<subst_logic>"
1502   [(set (match_operand:I 0 "register_operand" "=r,r")
1503         (lshiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1504                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1505    (clobber (reg:CC R_FLAGS))]
1506   "reload_completed"
1507   "lsr<s>   %0,%1,%2"
1508   [(set_attr "type" "logic")])
1510 (define_insn "lshrdi3"
1511   [(set (match_operand:DI 0 "register_operand" "=b,r")
1512         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1513                      (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1514    (clobber (reg:SI R_MDC))]
1515   ""
1516   "@
1517     lsrd    %2
1518     #"
1519   [(set_attr "type" "shiftdi,multi")])
1521 (define_split
1522   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1523         (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1524                      (const_int 32)))
1525    (clobber (reg:SI R_MDC))]
1526   "reload_completed"
1527   [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1528    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
1529   "")
1532 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1534 ;; Truncate
1536 ;; Truncations among modes QI, HI, SI and DI are supported directly.
1538 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1541 (define_expand "trunchiqi2"
1542   [(set (match_operand:QI 0 "register_operand" "")
1543          (truncate:QI (match_operand:HI 1 "register_operand" "")))]
1544   "")
1546 (define_insn_and_split "*trunchiqi2_insn"
1547   [(set (match_operand:QI 0 "register_operand" "=r")
1548         (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
1549   "ok_for_simple_arith_logic_operands (operands, QImode)"
1550   "#"
1551   "reload_completed"
1552   [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1)))
1553               (clobber (reg:CC R_FLAGS))])]
1554   ""
1555   [(set_attr "type" "logic")])
1557 (define_insn "*trunchiqi2_insn<subst_logic>"
1558   [(set (match_operand:QI 0 "register_operand" "=r")
1559         (truncate:QI (match_operand:HI 1 "register_operand" "r")))
1560    (clobber (reg:CC R_FLAGS))]
1561   "reload_completed"
1562   "move.b  %0,%1"
1563   [(set_attr "type" "logic")])
1565 (define_expand "truncsihi2"
1566   [(set (match_operand:HI 0 "register_operand" "")
1567         (truncate:HI (match_operand:SI 1 "register_operand" "")))]
1568   "")
1570 (define_insn_and_split "*truncsihi2_insn"
1571   [(set (match_operand:HI 0 "register_operand" "=r")
1572         (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
1573   "ok_for_simple_arith_logic_operands (operands, HImode)"
1574   "#"
1575   "reload_completed"
1576   [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1)))
1577               (clobber (reg:CC R_FLAGS))])]
1578   ""
1579   [(set_attr "type" "logic")])
1581 (define_insn "*truncsihi2_insn<subst_logic>"
1582   [(set (match_operand:HI 0 "register_operand" "=r")
1583         (truncate:HI (match_operand:SI 1 "register_operand" "r")))
1584    (clobber (reg:CC R_FLAGS))]
1585   "reload_completed"
1586   "move.w  %0,%1"
1587   [(set_attr "type" "logic")])
1589 (define_expand "truncdisi2"
1590   [(set (match_operand:SI 0 "register_operand" "")
1591         (truncate:SI (match_operand:DI 1 "register_operand" "")))]
1592   "")
1594 (define_insn_and_split "*truncdisi2_insn"
1595   [(set (match_operand:SI 0 "register_operand" "=r")
1596         (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
1597   "ok_for_simple_arith_logic_operands (operands, SImode)"
1598   "#"
1599   "reload_completed"
1600   [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1)))
1601               (clobber (reg:CC R_FLAGS))])]
1602   ""
1603   [(set_attr "type" "logic")])
1605 (define_insn "*truncdisi2_insn<subst_logic>"
1606   [(set (match_operand:SI 0 "register_operand" "=r")
1607         (truncate:SI (match_operand:DI 1 "register_operand" "r")))
1608    (clobber (reg:CC R_FLAGS))]
1609   "reload_completed"
1610   "move.l  %0,%d1"
1611   [(set_attr "type" "logic")])
1614 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1616 ;; Sign-extend
1618 ;; Sign-extensions among modes QI, HI, SI and DI are supported directly.
1620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1623 (define_expand "extendqihi2"
1624   [(set (match_operand:HI 0 "register_operand" "")
1625         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1626   "")
1628 (define_insn_and_split "*extendqihi2_insn"
1629   [(set (match_operand:HI 0 "register_operand" "=r")
1630         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1631   "ok_for_simple_arith_logic_operands (operands, HImode)"
1632   "#"
1633   "reload_completed"
1634   [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
1635               (clobber (reg:CC R_FLAGS))])]
1636   ""
1637   [(set_attr "type" "logic")])
1639 (define_insn "*extendqihi2_insn<subst_logic>"
1640   [(set (match_operand:HI 0 "register_operand" "=r")
1641         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))
1642    (clobber (reg:CC R_FLAGS))]
1643   "reload_completed"
1644   "extb.w  %0,%1"
1645   [(set_attr "type" "logic")])
1647 (define_expand "extendqisi2"
1648   [(set (match_operand:SI 0 "register_operand" "")
1649         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1650   "")
1652 (define_insn_and_split "*extendqisi2_insn"
1653   [(set (match_operand:SI 0 "register_operand" "=r")
1654         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1655   "ok_for_simple_arith_logic_operands (operands, SImode)"
1656   "#"
1657   "reload_completed"
1658   [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
1659               (clobber (reg:CC R_FLAGS))])]
1660   ""
1661   [(set_attr "type" "logic")])
1663 (define_insn "*extendqisi2_insn<subst_logic>"
1664   [(set (match_operand:SI 0 "register_operand" "=r")
1665         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))
1666    (clobber (reg:CC R_FLAGS))]
1667   "reload_completed"
1668   "extb.l  %0,%1"
1669   [(set_attr "type" "logic")])
1671 (define_expand "extendhisi2"
1672   [(set (match_operand:SI 0 "register_operand" "")
1673         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1674   "")
1676 (define_insn_and_split "*extendhisi2_insn"
1677   [(set (match_operand:SI 0 "register_operand" "=r")
1678         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1679   "ok_for_simple_arith_logic_operands (operands, SImode)"
1680   "#"
1681   "reload_completed"
1682   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1683                    (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
1684               (clobber (reg:CC R_FLAGS))])]
1685   ""
1686   [(set_attr "type" "logic")])
1688 (define_insn "*extendhisi2_insn<subst_logic>"
1689   [(set (match_operand:SI 0 "register_operand" "=r")
1690         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))
1691    (clobber (reg:CC R_FLAGS))]
1692   "reload_completed"
1693   "extw.l  %0,%1"
1694   [(set_attr "type" "logic")])
1696 (define_expand "extendsidi2"
1697   [(set (match_operand:DI 0 "register_operand" "")
1698         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
1699   "")
1701 (define_insn_and_split "*extendsidi2_insn"
1702   [(set (match_operand:DI 0 "register_operand" "=r")
1703         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1704   "ok_for_simple_arith_logic_operands (operands, DImode)"
1705   "#"
1706   "reload_completed"
1707   [(parallel [(set (match_dup 3) (match_dup 1))
1708               (clobber (reg:CC R_FLAGS))])
1709    (parallel [(set (match_dup 2)
1710                    (ashiftrt:SI (match_dup 1) (const_int 31)))
1711               (clobber (reg:CC R_FLAGS))])]
1713   operands[2] = operand_subword (operands[0], 0, 0, DImode);
1714   operands[3] = operand_subword (operands[0], 1, 0, DImode);
1716   [(set_attr "type" "multi")])
1719 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1721 ;; Zero-extend
1723 ;; Zero-extensions among modes QI, HI, SI and DI are supported directly.
1725 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1728 ; QI is zero-extended to wider modes by shifting left and then performing
1729 ; a logical shift right to insert the zeroes. This avoids the need to use
1730 ; another register.
1732 (define_expand "zero_extendqihi2"
1733   [(set (match_operand:HI 0 "register_operand" "")
1734         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1735   "")
1737 (define_insn_and_split "*zero_extendqihi2_insn"
1738   [(set (match_operand:HI 0 "register_operand" "=r")
1739         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1740   "ok_for_simple_arith_logic_operands (operands, HImode)"
1741   "#"
1742   "reload_completed"
1743   [(parallel [(set (match_dup 0)
1744                    (ashift:HI (match_dup 2) (const_int 8)))
1745               (clobber (reg:CC R_FLAGS))])
1746    (parallel [(set (match_dup 0)
1747                    (lshiftrt:HI (match_dup 0) (const_int 8)))
1748               (clobber (reg:CC R_FLAGS))])]
1750   operands[2] = gen_rtx_SUBREG (HImode, operands[1], 0);
1752   [(set_attr "type" "multi")])
1754 (define_expand "zero_extendqisi2"
1755   [(set (match_operand:SI 0 "register_operand" "")
1756         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1757   "")
1759 (define_insn_and_split "*zero_extendqisi2_insn"
1760   [(set (match_operand:SI 0 "register_operand" "=r")
1761         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1762   "ok_for_simple_arith_logic_operands (operands, SImode)"
1763   "#"
1764   "reload_completed"
1765   [(parallel [(set (match_dup 0)
1766                    (ashift:SI (match_dup 2) (const_int 24)))
1767               (clobber (reg:CC R_FLAGS))])
1768    (parallel [(set (match_dup 0)
1769                    (lshiftrt:SI (match_dup 0) (const_int 24)))
1770               (clobber (reg:CC R_FLAGS))])]
1772   operands[2] = gen_rtx_SUBREG (SImode, operands[1], 0);
1774   [(set_attr "type" "multi")])
1776 (define_insn "zero_extendhisi2"
1777   [(set (match_operand:SI 0 "register_operand" "=r")
1778         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1779   ""
1780   "moviu   %0,0"
1781   [(set_attr "type" "imm_reg")])
1783 (define_expand "zero_extendsidi2"
1784   [(set (match_operand:DI 0 "register_operand" "")
1785         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
1786   "")
1788 (define_insn_and_split "*zero_extendsidi2_insn"
1789   [(set (match_operand:DI 0 "register_operand" "=r")
1790         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1791   "ok_for_simple_arith_logic_operands (operands, DImode)"
1792   "#"
1793   "reload_completed"
1794   [(parallel [(set (match_dup 3) (match_dup 1))
1795               (clobber (reg:CC R_FLAGS))])
1796    (set (match_dup 2) (const_int 0))]
1798   operands[2] = operand_subword (operands[0], 0, 0, DImode);
1799   operands[3] = operand_subword (operands[0], 1, 0, DImode);
1801   [(set_attr "type" "multi")])
1804 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1806 ;; Bit Test
1808 ;; Only SI mode is supported directly.
1810 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1813 ; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB.
1815 (define_insn "*btst"
1816   [(set (reg:CC_BTST R_FLAGS)
1817         (compare:CC_BTST (zero_extract:SI
1818                            (match_operand:SI 0 "register_operand" "r")
1819                            (const_int 1)
1820                            (match_operand:QI 1 "const_shift_operand" "K"))
1821                          (const_int 0)))]
1822   "reload_completed"
1823   "lsr.l   r0,%0,32-%1"
1824   [(set_attr "type" "logic")])
1827 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1829 ;; Integer comparisons
1831 ;; Modes QI, HI and SI are supported directly.
1833 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1836 (define_insn "*cmp<mode>"
1837   [(set (reg:CC R_FLAGS)
1838         (compare:CC (match_operand:I 0 "register_operand" "r")
1839                     (match_operand:I 1 "reg_or_0_operand" "rO")))]
1840   "reload_completed"
1841   "cmp<s>   %0,%r1"
1842   [(set_attr "type" "cmp")])
1844 (define_insn "*cmp<mode>_sne"
1845   [(set (reg:CC R_FLAGS)
1846         (compare:CC (not:I (match_operand:I 0 "register_operand" "r"))
1847                     (const_int -1)))]
1848   "reload_completed"
1849   "cmp<s>   r0,%0"
1850   [(set_attr "type" "cmp")])
1853 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1855 ;; Single float operations
1857 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1860 (define_insn "addsf3"
1861   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1862         (plus:SF (match_operand:SF 1 "fp_reg_operand" "%f")
1863                  (match_operand:SF 2 "fp_reg_operand" "f")))]
1864   "TARGET_FPU"
1865   "fadd    %0,%1,%2"
1866   [(set_attr "type" "fp")])
1868 (define_insn "subsf3"
1869   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1870         (minus:SF (match_operand:SF 1 "fp_reg_operand" "f")
1871                   (match_operand:SF 2 "fp_reg_operand" "f")))]
1872   "TARGET_FPU"
1873   "fsub    %0,%1,%2"
1874   [(set_attr "type" "fp")])
1876 (define_insn "mulsf3"
1877   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1878         (mult:SF (match_operand:SF 1 "fp_reg_operand" "%f")
1879                  (match_operand:SF 2 "fp_reg_operand" "f")))]
1880   "TARGET_FPU"
1881   "fmult   %0,%1,%2"
1882   [(set_attr "type" "fp")])
1884 (define_insn "divsf3"
1885   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1886         (div:SF (match_operand:SF 1 "fp_reg_operand" "f")
1887                 (match_operand:SF 2 "fp_reg_operand" "f")))]
1888   "TARGET_FPU"
1889   "fdiv    %0,%1,%2"
1890   [(set_attr "type" "fdiv")])
1892 (define_insn "sqrtsf2"
1893   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1894         (sqrt:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
1895   "TARGET_FPU"
1896   "fsqrt   %0,%1"
1897   [(set_attr "type" "fsqrt")])
1899 (define_insn "negsf2"
1900   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1901         (neg:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
1902   "TARGET_FPU"
1903   "fneg    %0,%1"
1904   [(set_attr "type" "fmove")])
1906 (define_insn "abssf2"
1907   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1908         (abs:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
1909   "TARGET_FPU"
1910   "fabs    %0,%1"
1911   [(set_attr "type" "fmove")])
1913 (define_expand "copysignsf3"
1914   [(match_operand:SF 0 "register_operand" "")
1915    (match_operand:SF 1 "nonmemory_operand" "")
1916    (match_operand:SF 2 "register_operand" "")]
1917   "TARGET_FPU && !TARGET_FPU_IEEE"
1919   visium_expand_copysign (operands, SFmode);
1920   DONE;
1924 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1926 ;; Single float <-> single integer conversions for !TARGET_FPU_IEEE
1928 ;; An FMOVE instruction converts a signalling NaN (zero high order bit of the
1929 ;; mantissa) to a quiet NaN (-1). This is acceptable when the data to be
1930 ;; moved is in fact a floating-point number, but to avoid nasty surprises
1931 ;; integers must in general be kept out of the floating-point registers.
1932 ;; HARD_REGNO_MODE_OK thus only allows SFmode in these registers.
1933 ;; However, since FTOI and ITOF use floating-point registers for both their
1934 ;; inputs and outputs, to use these instructions integers must transiently
1935 ;; occupy such registers. To disguise this from the compiler, UNSPECs are
1936 ;; used for floating-point operations on integers and floating from general
1937 ;; register to floating-point register and fixing in the reverse direction
1938 ;; are only split into the individual UNSPEC operations after reload.
1940 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1943 (define_insn "*fload_no_ieee"
1944   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1945         (unspec:SF [(match_operand:SI 1 "register_operand" "r")] UNSPEC_FLOAD))]
1946   "TARGET_FPU && !TARGET_FPU_IEEE"
1947   "fload   %0,%1"
1948   [(set_attr "type" "reg_fp")])
1950 (define_insn "*itof_no_ieee"
1951   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1952         (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_ITOF))]
1953   "TARGET_FPU && !TARGET_FPU_IEEE"
1954   "itof    %0,%1"
1955   [(set_attr "type" "itof")])
1957 (define_insn_and_split "*floatsisf2_no_ieee"
1958   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1959         (float:SF (match_operand:SI 1 "register_operand" "r")))]
1960   "TARGET_FPU && !TARGET_FPU_IEEE"
1961   "#"
1962   "&& reload_completed"
1963   [(set (match_dup 0)
1964         (unspec:SF [(match_dup 1)] UNSPEC_FLOAD))
1965    (set (match_dup 0)
1966         (unspec:SF [(match_dup 0)] UNSPEC_ITOF))]
1967   ""
1968   [(set_attr "type" "multi")])
1970 (define_insn "*ftoi_no_ieee"
1971   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
1972         (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FTOI))]
1973   "TARGET_FPU && !TARGET_FPU_IEEE"
1974   "ftoi    %0,%1"
1975   [(set_attr "type" "ftoi")])
1977 (define_insn "*fstore_no_ieee"
1978   [(set (match_operand:SI 0 "register_operand" "=r")
1979         (unspec:SI [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FSTORE))]
1980   "TARGET_FPU && !TARGET_FPU_IEEE"
1981   "fstore  %0,%1"
1982   [(set_attr "type" "fp_reg")])
1984 (define_insn_and_split "fix_truncsfsi2_no_ieee"
1985   [(set (match_operand:SI 0 "register_operand" "=r")
1986         (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))
1987    (clobber (match_scratch:SF 2 "=1"))]
1988   "TARGET_FPU && !TARGET_FPU_IEEE"
1989   "#"
1990   "&& reload_completed"
1991   [(set (match_dup 1)
1992         (unspec:SF [(match_dup 1)] UNSPEC_FTOI))
1993    (set (match_dup 0)
1994         (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))]
1995   ""
1996   [(set_attr "type" "multi")])
1999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2001 ;; Single float <-> single integer conversions
2003 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2006 (define_insn "*itof"
2007   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2008         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2009   "TARGET_FPU_IEEE"
2010   "itof    %0,%1"
2011   [(set_attr "type" "itof")])
2013 (define_expand "floatsisf2"
2014   [(set (match_operand:SF 0 "fp_reg_operand" "")
2015         (float:SF (match_operand:SI 1 "register_operand" "")))]
2016   "TARGET_FPU"
2017   "")
2019 (define_insn "*ftoi"
2020   [(set (match_operand:SI 0 "register_operand" "=f")
2021         (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))]
2022   "TARGET_FPU_IEEE"
2023   "ftoi    %0,%1"
2024   [(set_attr "type" "ftoi")])
2026 (define_expand "fix_truncsfsi2"
2027   [(set (match_operand:SI 0 "register_operand" "")
2028         (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" ""))))]
2029   "TARGET_FPU"
2031   if (!TARGET_FPU_IEEE)
2032     {
2033       emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1]));
2034       DONE;
2035     }
2039 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2041 ;; Single float comparisons
2043 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2046 (define_insn "*cmpsf_fp"
2047   [(set (reg:CCFP R_FLAGS)
2048         (compare:CCFP (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2049                       (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2050   "TARGET_FPU && reload_completed"
2051   "fcmp    r0,%f0,%f1"
2052   [(set_attr "type" "fcmp")])
2054 (define_insn "*cmpsf_fpe"
2055   [(set (reg:CCFPE R_FLAGS)
2056         (compare:CCFPE (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2057                        (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2058   "TARGET_FPU && reload_completed"
2059   "fcmpe   r0,%f0,%f1"
2060   [(set_attr "type" "fcmp")])
2063 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2065 ;; Conditional branch instructions
2067 ;; Note - we do not specify the two instructions necessary to perform
2068 ;; a compare-and-branch in the cbranch<mode>4 pattern because that would
2069 ;; allow the comparison to be moved away from the jump before the reload
2070 ;; pass has completed.  That would be problematical because reload can
2071 ;; generate instructions in between which would clobber the CC register.
2073 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2076 (define_expand "cbranch<mode>4"
2077   [(set (pc)
2078         (if_then_else (match_operator 0 "comparison_operator"
2079                        [(match_operand:I 1 "register_operand")
2080                         (match_operand:I 2 "reg_or_0_operand")])
2081                       (label_ref (match_operand 3 ""))
2082                       (pc)))]
2083   ""
2086 (define_insn_and_split "*cbranch<mode>4_insn"
2087   [(set (pc)
2088         (if_then_else (match_operator 0 "comparison_operator"
2089                        [(match_operand:I 1 "register_operand" "r")
2090                         (match_operand:I 2 "reg_or_0_operand" "rO")])
2091                       (label_ref (match_operand 3 ""))
2092                       (pc)))]
2093   ""
2094   "#"
2095   "reload_completed"
2096   [(const_int 0)]
2098   visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2099                         operands[3]);
2100   DONE;
2102   [(set_attr "type" "cmp")])
2104 (define_insn_and_split "*cbranchsi4_btst_insn"
2105   [(set (pc)
2106         (if_then_else (match_operator 0 "visium_btst_operator"
2107                        [(zero_extract:SI
2108                            (match_operand:SI 1 "register_operand" "r")
2109                            (const_int 1)
2110                            (match_operand:QI 2 "const_shift_operand" "K"))
2111                         (const_int 0)])
2112                       (label_ref (match_operand 3 ""))
2113                       (pc)))]
2114   ""
2115   "#"
2116   "reload_completed"
2117   [(const_int 0)]
2119   visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2120                         XEXP (operands[0], 1), operands[3]);
2121   DONE;
2123   [(set_attr "type" "cmp")])
2125 (define_expand "cbranchsf4"
2126   [(set (pc)
2127         (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2128                        [(match_operand:SF 1 "fp_reg_operand")
2129                         (match_operand:SF 2 "fp_reg_or_0_operand")])
2130                       (label_ref (match_operand 3 ""))
2131                       (pc)))]
2132   "TARGET_FPU"
2135 (define_insn_and_split "*cbranchsf4_insn"
2136   [(set (pc)
2137         (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2138                        [(match_operand:SF 1 "fp_reg_operand" "f")
2139                         (match_operand:SF 2 "fp_reg_or_0_operand" "fG")])
2140                       (label_ref (match_operand 3 ""))
2141                       (pc)))]
2142   "TARGET_FPU"
2143   "#"
2144   "&& reload_completed"
2145   [(const_int 0)]
2147   visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2148                         operands[3]);
2149   DONE;
2151   [(set_attr "type" "fcmp")])
2153 ; Now match both normal and inverted branches.
2155 (define_insn "*normal_branch"
2156   [(set (pc)
2157         (if_then_else (match_operator 1 "visium_branch_operator"
2158                        [(reg R_FLAGS) (const_int 0)])
2159                       (label_ref (match_operand 0 ""))
2160                       (pc)))]
2161   "reload_completed"
2163   return output_cbranch (operands[0], GET_CODE (operands[1]),
2164                          GET_MODE (XEXP (operands[1], 0)), 0, insn);
2166   [(set_attr "type" "branch")])
2168 (define_insn "*inverted_branch"
2169   [(set (pc)
2170         (if_then_else (match_operator 1 "visium_branch_operator"
2171                        [(reg R_FLAGS) (const_int 0)])
2172                       (pc)
2173                       (label_ref (match_operand 0 ""))))]
2174   "reload_completed"
2176   return output_cbranch (operands[0], GET_CODE (operands[1]),
2177                          GET_MODE (XEXP (operands[1], 0)), 1, insn);
2179   [(set_attr "type" "branch")])
2181 ; And then match both normal and inverted returns.
2183 (define_insn "*cond_<return_str>return"
2184   [(set (pc)
2185         (if_then_else (match_operator 0 "visium_branch_operator"
2186                        [(reg R_FLAGS) (const_int 0)])
2187                       (any_return)
2188                       (pc)))]
2189   "<return_pred> && reload_completed"
2191   return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2192                          GET_MODE (XEXP (operands[0], 0)), 0, insn);
2194   [(set_attr "type" "ret")])
2196 (define_insn "*inverted_cond_<return_str>return"
2197   [(set (pc)
2198         (if_then_else (match_operator 0 "visium_branch_operator"
2199                        [(reg R_FLAGS) (const_int 0)])
2200                       (pc)
2201                       (any_return)))]
2202   "<return_pred> && reload_completed"
2204   return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2205                          GET_MODE (XEXP (operands[0], 0)), 1, insn);
2207   [(set_attr "type" "ret")])
2210 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2212 ;; Unconditional branch instructions
2214 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2217 (define_insn "jump"
2218   [(set (pc)
2219         (label_ref (match_operand 0 "" "")))]
2220   ""
2222   return output_ubranch (operands[0], insn);
2224   [(set_attr "type" "branch")])
2226 (define_insn "indirect_jump"
2227   [(set (pc)
2228         (match_operand:SI 0 "register_operand" "r"))]
2229   ""
2230   "bra     tr,%0,r0%#           ;indirect jump"
2231   [(set_attr "type" "abs_branch")])
2233 (define_insn "tablejump"
2234   [(set (pc)
2235         (match_operand:SI 0 "register_operand" "r"))
2236    (use (label_ref (match_operand 1 "" "")))]
2237   ""
2238   "bra     tr,%0,r0%#           ;tablejump"
2239   [(set_attr "type" "abs_branch")])
2242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2244 ;; Subprogram call instructions
2246 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2249 ; Subroutine call instruction returning no value.  Operand 0 is the function
2250 ; to call; operand 1 is the number of bytes of arguments pushed (in mode
2251 ; 'SImode', except it is normally a 'const_int'); operand 2 is the number of
2252 ; registers used as operands.
2254 (define_expand "call"
2255   [(parallel [(call (match_operand 0 "" "")
2256                     (match_operand 1 "" ""))
2257               (use (match_operand 2 "" ""))
2258               (clobber (match_dup 3))])]
2259   ""
2261   if (GET_CODE (XEXP (operands[0], 0)) != REG)
2262     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2264   if (!operands[2])
2265     operands[2] =  const0_rtx;
2267   operands[3] = gen_rtx_REG (Pmode, R_LINK);
2270 (define_insn "*call_internal"
2271   [(call (mem:SI (match_operand:SI 0 "register_operand" "l,!r"))
2272          (match_operand 1 "" ""))
2273    (use (match_operand 2 "" ""))
2274    (clobber (match_operand 3 "" ""))]
2275   "!SIBLING_CALL_P (insn)"
2276   "bra     tr,%0,%3%#           ;call"
2277   [(set_attr "type" "call")])
2279 ; Subroutine call instruction returning a value.  Operand 0 is the hard
2280 ; register in which the value is returned.  There are three more operands, the
2281 ; same as the three operands of the 'call' instruction (but with numbers
2282 ; increased by one).
2284 (define_expand "call_value"
2285   [(parallel [(set (match_operand 0 "register_operand" "")
2286                    (call (match_operand 1 "" "")
2287                          (match_operand 2 "" "")))
2288               (use (match_operand 3 "" ""))
2289               (clobber (match_dup 4))])]
2290   ""
2292   if (GET_CODE (XEXP (operands[1], 0)) != REG)
2293     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2295   if (!operands[3])
2296     operands[3] = const0_rtx;
2298   operands[4] = gen_rtx_REG (Pmode, R_LINK);
2301 (define_insn "*call_value_internal"
2302   [(set (match_operand 0 "register_operand" "")
2303         (call (mem:SI (match_operand:SI 1 "register_operand" "l,!r"))
2304               (match_operand 2 "" "")))
2305         (use (match_operand 3 "" ""))
2306         (clobber (match_operand 4 "" ""))]
2307   "!SIBLING_CALL_P (insn)"
2308   "bra     tr,%1,%4%#           ;call value"
2309   [(set_attr "type" "call")])
2311 ; Tail calls are similar, except that the link register is not used.  But
2312 ; we don't use r0 as the destination register of the branch because we want
2313 ; the Branch Pre-decode Logic of the GR6 to use the Address Load Array to
2314 ; predict the branch target.
2316 (define_expand "sibcall"
2317   [(parallel [(call (match_operand 0 "" "")
2318                     (match_operand 1 "" ""))
2319               (use (match_operand 2 "" ""))
2320               (clobber (match_dup 3))])]
2321   ""
2323   if (GET_CODE (XEXP (operands[0], 0)) != REG)
2324     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2326   if (!operands[2])
2327     operands[2] = const0_rtx;
2329   operands[3] = gen_rtx_SCRATCH (SImode);
2332 (define_insn "*sibcall_internal"
2333   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
2334          (match_operand 1 "" ""))
2335    (use (match_operand 2 "" ""))
2336    (clobber (match_scratch:SI 3 "=0"))]
2337   "SIBLING_CALL_P (insn)"
2338   "bra     tr,%0,%0%#           ;sibcall"
2339   [(set_attr "type" "call")])
2341 (define_expand "sibcall_value"
2342   [(parallel [(set (match_operand 0 "register_operand" "")
2343                    (call (match_operand 1 "" "")
2344                          (match_operand 2 "" "")))
2345               (use (match_operand 3 "" ""))
2346               (clobber (match_dup 4))])]
2347   ""
2349   if (GET_CODE (XEXP (operands[1], 0)) != REG)
2350     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2352   if (!operands[3])
2353     operands[3] = const0_rtx;
2355   operands[4] = gen_rtx_SCRATCH (SImode);
2358 (define_insn "*sibcall_value_internal"
2359   [(set (match_operand 0 "register_operand" "")
2360         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
2361               (match_operand 2 "" "")))
2362    (use (match_operand 3 "" ""))
2363    (clobber (match_scratch:SI 4 "=1"))]
2364   "SIBLING_CALL_P (insn)"
2365   "bra     tr,%1,%1%#           ;sibcall value"
2366   [(set_attr "type" "call")])
2368 ; Call subroutine returning any type.
2369 (define_expand "untyped_call"
2370   [(parallel [(call (match_operand 0 "" "")
2371                     (const_int 0))
2372               (match_operand 1 "" "")
2373               (match_operand 2 "" "")])]
2374   ""
2376   int i;
2378   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2380   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2381     {
2382       rtx set = XVECEXP (operands[2], 0, i);
2383       emit_move_insn (SET_DEST (set), SET_SRC (set));
2384     }
2386   /* The optimizer does not know that the call sets the function value
2387      registers we stored in the result block.  We avoid problems by
2388      claiming that all hard registers are used and clobbered at this
2389      point.  */
2390   emit_insn (gen_blockage ());
2392   DONE;
2396 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2398 ;; Compare-and-store instructions
2400 ;; Modes QI, HI, SI and SF are supported directly.
2402 ;; Note - we do not specify the two instructions necessary to perform
2403 ;; a compare-and-store in the cstore<mode>4 pattern because that would
2404 ;; allow the comparison to be moved away from the store before the reload
2405 ;; pass has completed.  That would be problematical because reload can
2406 ;; generate instructions in between which would clobber the CC register.
2408 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2411 (define_expand "cstore<mode>4"
2412   [(set (match_operand:SI 0)
2413         (match_operator:SI 1 "visium_int_cstore_operator"
2414          [(match_operand:I 2 "register_operand")
2415           (match_operand:I 3 "reg_or_0_operand")]))]
2416   ""
2418   visium_expand_int_cstore (operands, <MODE>mode);
2419   DONE;
2422 (define_insn_and_split "*cstore<mode>4_insn"
2423   [(set (match_operand:SI 0 "register_operand" "=r")
2424         (ltu:SI (match_operand:I 1 "register_operand" "r")
2425                 (match_operand:I 2 "reg_or_0_operand" "rO")))]
2426   ""
2427   "#"
2428   "reload_completed"
2429   [(const_int 0)]
2431   visium_split_cstore (SET, operands[0], NULL_RTX,
2432                        LTU, operands[1], operands[2]);
2433   DONE;
2435   [(set_attr "type" "cmp")])
2437 (define_insn_and_split "*neg_cstore<mode>4_insn"
2438   [(set (match_operand:SI 0 "register_operand" "=r")
2439         (neg:SI (ltu:SI (match_operand:I 1 "register_operand" "r")
2440                         (match_operand:I 2 "reg_or_0_operand" "rO"))))]
2441   ""
2442   "#"
2443   "reload_completed"
2444   [(const_int 0)]
2446   visium_split_cstore (NEG, operands[0], NULL_RTX,
2447                        LTU, operands[1], operands[2]);
2448   DONE;
2450   [(set_attr "type" "cmp")])
2452 (define_insn_and_split "*<add_str>_cstore<mode>4_insn"
2453   [(set (match_operand:SI 0 "register_operand" "=r")
2454         (any_add:SI (match_operand:SI 1 "register_operand" "r")
2455                     (ltu:SI (match_operand:I 2 "register_operand" "r")
2456                             (match_operand:I 3 "reg_or_0_operand" "rO"))))]
2457   ""
2458   "#"
2459   "reload_completed"
2460   [(const_int 0)]
2462   visium_split_cstore (<add_op>, operands[0], operands[1],
2463                        LTU, operands[2], operands[3]);
2464   DONE;
2466   [(set_attr "type" "cmp")])
2468 (define_insn_and_split "*cstore<mode>4_sne_insn"
2469   [(set (match_operand:SI 0 "register_operand" "=r")
2470         (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2471                 (const_int -1)))]
2472   ""
2473   "#"
2474   "reload_completed"
2475   [(const_int 0)]
2477   visium_split_cstore (SET, operands[0], NULL_RTX,
2478                        LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2479   DONE;
2481   [(set_attr "type" "cmp")])
2483 (define_insn_and_split "*neg_cstore<mode>4_sne_insn"
2484   [(set (match_operand:SI 0 "register_operand" "=r")
2485         (neg:SI (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2486                         (const_int -1))))]
2487   ""
2488   "#"
2489   "reload_completed"
2490   [(const_int 0)]
2492   visium_split_cstore (NEG, operands[0], NULL_RTX,
2493                        LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2494   DONE;
2496   [(set_attr "type" "cmp")])
2498 (define_insn_and_split "*<add_str>_cstore<mode>4_sne_insn"
2499   [(set (match_operand:SI 0 "register_operand" "=r")
2500         (any_add:SI (match_operand:SI 1 "register_operand" "r")
2501                     (ltu:SI (not:I (match_operand:I 2 "register_operand" "r"))
2502                             (const_int -1))))]
2503   ""
2504   "#"
2505   "reload_completed"
2506   [(const_int 0)]
2508   visium_split_cstore (<add_op>, operands[0], operands[1],
2509                        LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx);
2510   DONE;
2512   [(set_attr "type" "cmp")])
2514 (define_expand "cstoresf4"
2515   [(set (match_operand:SI 0)
2516         (match_operator:SI 1 "visium_fp_cstore_operator"
2517          [(match_operand:SF 2 "fp_reg_operand")
2518           (match_operand:SF 3 "fp_reg_or_0_operand")]))]
2519   "TARGET_FPU"
2521   visium_expand_fp_cstore (operands, SFmode);
2522   DONE;
2525 (define_insn_and_split "*cstoresf4_insn"
2526   [(set (match_operand:SI 0 "register_operand" "=r")
2527         (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2528                (match_operand:SF 2 "fp_reg_or_0_operand" "fG")))]
2529   "TARGET_FPU"
2530   "#"
2531   "&& reload_completed"
2532   [(const_int 0)]
2534   visium_split_cstore (SET, operands [0], NULL_RTX,
2535                        LT, operands[1], operands[2]);
2536   DONE;
2538   [(set_attr "type" "fcmp")])
2540 (define_insn_and_split "*neg_cstoresf4_insn"
2541   [(set (match_operand:SI 0 "register_operand" "=r")
2542         (neg:SI (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2543                        (match_operand:SF 2 "fp_reg_or_0_operand" "fG"))))]
2544   "TARGET_FPU"
2545   "#"
2546   "&& reload_completed"
2547   [(const_int 0)]
2549   visium_split_cstore (NEG, operands [0], NULL_RTX,
2550                        LT, operands[1], operands[2]);
2551   DONE;
2553   [(set_attr "type" "fcmp")])
2555 (define_insn_and_split "*<add_str>_cstoresf4_insn"
2556   [(set (match_operand:SI 0 "register_operand" "=r")
2557         (any_add:SI (match_operand:SI 1 "register_operand" "r")
2558                     (lt:SI (match_operand:SF 2 "fp_reg_or_0_operand" "fG")
2559                            (match_operand:SF 3 "fp_reg_or_0_operand" "fG"))))]
2560   "TARGET_FPU"
2561   "#"
2562   "&& reload_completed"
2563   [(const_int 0)]
2565   visium_split_cstore (<add_op>, operands [0], operands[1],
2566                        LT, operands[2], operands[3]);
2567   DONE;
2569   [(set_attr "type" "fcmp")])
2572 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2574 ;; RTL pro/epilogue support
2576 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2579 ; Expand prologue in RTL
2580 (define_expand "prologue"
2581   [(const_int 0)]
2582   ""
2584   visium_expand_prologue ();
2585   DONE;
2588 ; Expand epilogue in RTL
2589 (define_expand "epilogue"
2590   [(return)]
2591   ""
2593   visium_expand_epilogue ();
2596 ; Expand epilogue without a final jump in RTL
2597 (define_expand "sibcall_epilogue"
2598   [(return)]
2599   ""
2601   visium_expand_epilogue ();
2602   DONE;
2605 ; The artificial dependency on the link register is to prevent the
2606 ; frame instruction from being put in a call delay slot, which can
2607 ; confuse the CFI machinery.
2609 (define_insn "stack_save"
2610   [(set (reg:SI R_FP) (reg:SI R_SP))
2611    (use (reg:SI R_LINK))
2612    (clobber (reg:CC R_FLAGS))]
2613   "reload_completed"
2614   "move.l  fp,sp                ;stack_save"
2615   [(set_attr "type" "logic")])
2617 ; The construct (mem:BLK (scratch)) is considered to alias all other
2618 ; memory accesses.  Thus it can be used as a memory barrier in stack
2619 ; deallocation patterns.
2621 (define_insn "stack_restore"
2622   [(set (reg:SI R_SP) (reg:SI R_FP))
2623    (clobber (mem:BLK (scratch)))
2624    (clobber (reg:CC R_FLAGS))]
2625   "reload_completed"
2626   "move.l  sp,fp                ;stack_restore"
2627   [(set_attr "type" "logic")])
2629 (define_insn "stack_pop"
2630   [(set (reg:SI R_SP)
2631         (plus:SI (reg:SI R_SP) (match_operand:SI 0 "add_operand" "J,r")))
2632    (clobber (mem:BLK (scratch)))
2633    (clobber (reg:CC R_FLAGS))]
2634   "reload_completed"
2635   "@
2636     addi    sp,%0               ;stack pop
2637     add.l   sp,sp,%0            ;stack pop"
2638   [(set_attr "type" "arith")])
2640 (define_expand "<return_str>return"
2641   [(any_return)]
2642   "<return_pred>"
2643   "")
2645 (define_insn "*<return_str>return_internal"
2646   [(any_return)]
2647   "!visium_interrupt_function_p ()"
2649   return output_ubranch (pc_rtx, insn);
2651   [(set_attr "type" "ret")])
2653 (define_insn "*return_internal_interrupt"
2654   [(return)]
2655   "visium_interrupt_function_p ()"
2656   "rfi\n\t nop                          ;return from interrupt"
2657   [(set_attr "type" "rfi")])
2659 (define_insn "dsi"
2660   [(unspec_volatile [(const_int 0)] UNSPECV_DSI)]
2661   ""
2662   "dsi"
2663   [(set_attr "type" "dsi")])
2666 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2668 ;; NOP (no-op instruction)
2670 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2673 (define_insn "nop"
2674   [(const_int 0)]
2675   ""
2676   "nop                  ;generated nop"
2677   [(set_attr "type" "nop")])
2679 (define_insn "hazard_nop"
2680   [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
2681   ""
2682   "nop                  ;hazard avoidance nop"
2683   [(set_attr "type" "nop")])
2685 (define_insn "blockage"
2686   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2687   ""
2688   ""
2689   [(set_attr "type" "nop")])
2692 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2694 ;; String/block operations
2696 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2699 ;; String/block move insn.
2700 ;; Argument 0 is the destination
2701 ;; Argument 1 is the source
2702 ;; Argument 2 is the length
2703 ;; Argument 3 is the alignment
2705 (define_expand "movmemsi"
2706   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
2707                    (match_operand:BLK 1 "memory_operand" ""))
2708               (use (match_operand:SI  2 "general_operand" ""))
2709               (use (match_operand:SI  3 "const_int_operand" ""))])]
2710   ""
2712   if (visium_expand_block_move (operands))
2713     DONE;
2714   else
2715     FAIL;
2718 (define_insn "*bmd"
2719   [(set (mem:BLK (reg:SI R_R1))
2720         (mem:BLK (reg:SI R_R2)))
2721    (use (reg:SI R_R3))
2722    (clobber (reg:SI R_R1))
2723    (clobber (reg:SI R_R2))
2724    (clobber (reg:SI R_R3))
2725    (clobber (reg:SI R_R4))
2726    (clobber (reg:SI R_R5))
2727    (clobber (reg:SI R_R6))]
2728   "TARGET_BMI"
2729   "bmd     r1,r2,r3"
2730   [(set_attr "type" "bmi")])
2732 ;; String/block set insn.
2733 ;; Argument 0 is the destination
2734 ;; Argument 1 is the length
2735 ;; Argument 2 is the value
2736 ;; Argument 3 is the alignment
2738 (define_expand "setmemsi"
2739   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
2740                    (match_operand 2 "nonmemory_operand" ""))
2741               (use (match_operand:SI  1 "general_operand" ""))
2742               (use (match_operand:SI  3 "const_int_operand" ""))])]
2743   ""
2745   if (visium_expand_block_set (operands))
2746     DONE;
2747   else
2748     FAIL;