Add assember CFI directives to millicode division and remainder routines.
[official-gcc.git] / gcc / config / visium / visium.md
blobf45ed2a701be7e3db2b5e657bde12e63595af037
1 ;; Machine description for Visium.
2 ;; Copyright (C) 2002-2023 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
84   UNSPEC_ADDV
85   UNSPEC_SUBV
86   UNSPEC_NEGV
89 ;; UNSPEC_VOLATILE usage.
90 (define_c_enum "unspecv" [
91   UNSPECV_BLOCKAGE
92   UNSPECV_DSI
95 (include "predicates.md")
96 (include "constraints.md")
99 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101 ;; Attributes.
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106 ; Attribute for cpu type.
107 ; These must match the values for enum processor_type in visium-opts.h.
108 (define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr")))
110 ; Instruction type.
112 ;imm_reg       Move of immediate value to register.
113 ;mem_reg       Move from memory to register.
114 ;eam_reg       Move from EAM to register.
115 ;fp_reg        Move from FPU to register.
116 ;reg_mem       Move from register to memory.
117 ;reg_eam       Move from register to EAM.
118 ;reg_fp        Move from register to FPU.
119 ;arith         Arithmetic operation, result in register, sets overflow.
120 ;arith2        Two successive arithmetic operations.
121 ;logic         Logical operation, result in register, does not set overflow.
122 ;abs_branch    Absolute branch.
123 ;branch        Branch.
124 ;bmi           Block move.
125 ;call          Call to subprogram.
126 ;ret           Return from subprogram.
127 ;rfi           Return from interrupt.
128 ;dsi           Disable interrupts.
129 ;cmp           Compare or test.
130 ;div           EAM 32/32 division.
131 ;divd          EAM 64/32 division.
132 ;mul           EAM 32 * 32 -> 64 multiplication.
133 ;shiftdi       EAM 64 bit shift.
134 ;fdiv          Floating point divide.
135 ;fsqrt         Floating point square root.
136 ;ftoi          Fix float to integer.
137 ;itof          Float integer.
138 ;fmove         Floating point move w/ or w/o change of sign: fmove, fabs, fneg.
139 ;fcmp          Floating point compare or test.
140 ;fp            Other floating point operations.
141 ;nop           No operation.
142 ;multi         Multiple instructions which split.
143 ;asm           User asm instructions.
144 ;trap          Trap instructions.
146 (define_attr "type"
147 "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,trap" (const_string "logic"))
149 ; Those insns that occupy 4 bytes.
150 (define_attr "single_insn" "no,yes"
151   (if_then_else (eq_attr "type" "arith2,rfi,multi")
152                 (const_string "no")
153                 (const_string "yes")))
155 ; True if branch or call will be emitting a nop into its delay slot.
156 (define_attr "empty_delay_slot" "false,true"
157   (symbol_ref "(empty_delay_slot (insn)
158                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
160 ; Length in bytes.
161 ; On the GR6, absolute branches must be aligned on a 64-bit boundary to avoid
162 ; a pipeline hazard.  This is done by the assembler, so the length of these
163 ; instructions for the compiler can effectively be 4, 8, or 12 bytes.
164 ; The allowed range for the offset of relative branches is [-131072;131068]
165 ; and it is counted from the address of the insn so we need to subtract
166 ; 8 for forward branches because (pc) points to the next insn for them.
167 (define_attr "length" ""
168   (cond [(eq_attr "type" "abs_branch,call,ret")
169            (if_then_else (eq_attr "empty_delay_slot" "true")
170                          (if_then_else (and (eq_attr "cpu" "gr6")
171                                             (eq (mod (pc) (const_int 8))
172                                                 (const_int 4)))
173                                        (const_int 12)
174                                        (const_int 8))
175                          (if_then_else (and (eq_attr "cpu" "gr6")
176                                             (eq (mod (pc) (const_int 8))
177                                                 (const_int 4)))
178                                        (const_int 8)
179                                        (const_int 4)))
180          (eq_attr "type" "branch")
181            (if_then_else (leu (plus (minus (match_dup 0) (pc))
182                                     (const_int 131060))
183                               (const_int 262120))
184                          (if_then_else (eq_attr "empty_delay_slot" "true")
185                                        (const_int 8)
186                                        (const_int 4))
187                          (if_then_else (and (eq_attr "cpu" "gr6")
188                                             (eq (mod (pc) (const_int 8))
189                                                 (const_int 0)))
190                                        (const_int 24)
191                                        (const_int 20)))
192          (eq_attr "single_insn" "no")
193            (const_int 8)] (const_int 4)))
195 (define_asm_attributes [(set_attr "type" "asm")])
197 ; Delay slots.
198 (define_delay (eq_attr "type" "abs_branch,branch,call,ret")
199   [(and (eq_attr "type" "!abs_branch,branch,call,ret,rfi,bmi,mul,div,divd,fdiv,fsqrt,asm")
200         (eq_attr "single_insn" "yes"))
201     (nil) (nil)])
204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
206 ;; Processor pipeline description.
208 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
211 (include "gr5.md")
212 (include "gr6.md")
215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
217 ;; Iterators.
219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
222 (define_mode_iterator QHI [QI HI])
223 (define_mode_iterator I [QI HI SI])
224 (define_mode_attr b [(QI "8") (HI "16") (SI "32")])
225 (define_mode_attr s [(QI ".b") (HI ".w") (SI ".l")])
227 ; This code iterator allows signed and unsigned widening multiplications
228 ; to use the same template.
229 (define_code_iterator any_extend [sign_extend zero_extend])
231 ; <u> expands to an empty string when doing a signed operation and
232 ; "u" when doing an unsigned operation.
233 (define_code_attr u [(sign_extend "") (zero_extend "u")])
235 ; <su> is like <u>, but the signed form expands to "s" rather than "".
236 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
238 ; This code iterator allows returns and simple returns to use the same template.
239 (define_code_iterator any_return [return simple_return])
240 (define_code_attr return_pred [(return "visium_can_use_return_insn_p ()")
241                                (simple_return "!visium_interrupt_function_p ()")])
242 (define_code_attr return_str [(return "") (simple_return "simple_")])
244 ; This code iterator allows integer and FP cstores to use the same template.
245 (define_code_iterator any_scc [ltu lt])
246 (define_code_attr scc_str [(ltu "sltu") (lt "slt")])
248 ;This code iterator allows cstore splitters to use the same template.
249 (define_code_iterator any_add [plus minus])
250 (define_code_attr add_op  [(plus "PLUS") (minus "MINUS")])
251 (define_code_attr add_str [(plus "plus") (minus "minus")])
254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
256 ;; Substitutions.
258 ;; They are used to define the first instruction of the pairs required by
259 ;; the postreload compare elimination pass, with a first variant for the
260 ;; logical insns and a second variant for the arithmetic insns.
262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
265 (define_subst "flags_subst_logic"
266   [(set (match_operand 0 "") (match_operand 1 ""))
267    (clobber (reg:CC R_FLAGS))]
268   ""
269   [(set (reg:CC R_FLAGS)
270         (compare:CC (match_dup 1) (const_int 0)))
271    (set (match_dup 0) (match_dup 1))])
273 (define_subst_attr "subst_logic" "flags_subst_logic" "_flags" "_set_flags")
275 (define_subst "flags_subst_arith"
276   [(set (match_operand 0 "") (match_operand 1 ""))
277    (clobber (reg:CC R_FLAGS))]
278   ""
279   [(set (reg:CCNZ R_FLAGS)
280         (compare:CCNZ (match_dup 1) (const_int 0)))
281    (set (match_dup 0) (match_dup 1))])
283 (define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags")
286 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
288 ;; QImode moves
290 ;; For moving among registers we use the move.b instruction.  This is
291 ;; actually an OR instruction using an alias.  For moving between register
292 ;; and memory we need the address of the memory location in a register.
293 ;; However, we can accept an expression (reg + offset) where offset is in
294 ;; the range 0 .. 31.
296 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
299 (define_expand "movqi"
300   [(set (match_operand:QI 0 "nonimmediate_operand" "")
301         (match_operand:QI 1 "general_operand" ""))]
302   ""
304   prepare_move_operands (operands, QImode);
307 (define_insn "*movqi_insn"
308   [(set (match_operand:QI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
309         (match_operand:QI 1 "general_operand"      " r,rO, r, r,?b,?c,i,m"))]
310   "ok_for_simple_move_operands (operands, QImode)"
311   "@
312     #
313     write.b %0,%r1
314     writemd %1,r0               ;movqi ?b r
315     writemdc %1         ;movqi ?c r
316     readmda %0          ;movqi r ?b
317     readmdc %0          ;movqi r ?c
318     moviq   %0,%b1              ;movqi  r  i
319     read.b  %0,%1"
320   [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
322 (define_insn "*movqi_insn<subst_logic>"
323   [(set (match_operand:QI 0 "gpc_reg_operand" "=r")
324         (match_operand:QI 1 "gpc_reg_operand" "r"))
325    (clobber (reg:CC R_FLAGS))]
326   "reload_completed"
327   "move.b  %0,%1"
328   [(set_attr "type" "logic")])
330 (define_split
331   [(set (match_operand:QI 0 "gpc_reg_operand" "")
332         (match_operand:QI 1 "gpc_reg_operand" ""))]
333   "reload_completed"
334   [(parallel [(set (match_dup 0) (match_dup 1))
335               (clobber (reg:CC R_FLAGS))])]
336   "")
338 (define_expand "movstrictqi"
339   [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
340         (match_operand:QI 1 "general_operand"                   ""))]
341   "")
343 (define_insn "*movstrictqi_insn"
344   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r,r"))
345         (match_operand:QI 1 "general_operand"                   "rO,m"))]
346   "ok_for_simple_move_strict_operands (operands, QImode)"
347   "@
348     #
349     read.b  %0,%1"
350   [(set_attr "type" "logic,mem_reg")])
352 (define_insn "*movstrictqi_insn<subst_logic>"
353   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
354         (match_operand:QI 1 "reg_or_0_operand"                  "rO"))
355    (clobber (reg:CC R_FLAGS))]
356   "reload_completed"
357   "move.b  %0,%r1"
358   [(set_attr "type" "logic")])
360 (define_split
361   [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
362         (match_operand:QI 1 "reg_or_0_operand" ""))]
363   "reload_completed"
364   [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
365               (clobber (reg:CC R_FLAGS))])]
366   "")
369 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371 ;; HImode moves
373 ;; For moving among registers we use the move.w instruction.  This is
374 ;; actually an OR instruction using an alias.  For moving between register
375 ;; and memory we need the address of the memory location in a register.
376 ;; However, we can accept an expression (reg + offset) where offset is in
377 ;; the range 0 .. 62 and is shifted right one place in the assembled 
378 ;; instruction.
380 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
383 (define_expand "movhi"
384   [(set (match_operand:HI 0 "nonimmediate_operand" "")
385         (match_operand:HI 1 "general_operand" ""))]
386   ""
388   prepare_move_operands (operands, HImode);
391 (define_insn "*movhi_insn"
392   [(set (match_operand:HI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
393         (match_operand:HI 1 "general_operand"      " r,rO, r, r,?b,?c,i,m"))]
394   "ok_for_simple_move_operands (operands, HImode)"
395   "@
396     #
397     write.w %0,%r1
398     writemd %1,r0               ;movhi ?b r
399     writemdc %1         ;movhi ?c r
400     readmda %0          ;movhi r ?b
401     readmdc %0          ;movhi r ?c
402     moviq   %0,%w1              ;movhi  r  i
403     read.w  %0,%1"
404   [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
406 (define_insn "*movhi_insn<subst_logic>"
407   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
408         (match_operand:HI 1 "gpc_reg_operand" "r"))
409    (clobber (reg:CC R_FLAGS))]
410   "reload_completed"
411   "move.w  %0,%1"
412   [(set_attr "type" "logic")])
414 (define_split
415   [(set (match_operand:HI 0 "gpc_reg_operand" "")
416         (match_operand:HI 1 "gpc_reg_operand" ""))]
417   "reload_completed"
418   [(parallel [(set (match_dup 0) (match_dup 1))
419               (clobber (reg:CC R_FLAGS))])]
420   "")
422 (define_expand "movstricthi"
423   [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
424         (match_operand:HI 1 "general_operand"                   ""))]
425   "")
427 (define_insn "*movstricthi_insn"
428   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r,r,r"))
429         (match_operand:HI 1 "general_operand"                   " r,i,m"))]
430   "ok_for_simple_move_strict_operands (operands, HImode)"
431   "@
432     #
433     movil   %0,%w1
434     read.w  %0,%1"
435   [(set_attr "type" "logic,imm_reg,mem_reg")])
437 (define_insn "*movstricthi_insn<subst_logic>"
438   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
439         (match_operand:HI 1 "register_operand"                  "r"))
440    (clobber (reg:CC R_FLAGS))]
441   "reload_completed"
442   "move.w  %0,%1"
443   [(set_attr "type" "logic")])
445 (define_split
446   [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
447         (match_operand:HI 1 "register_operand" ""))]
448   "reload_completed"
449   [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
450               (clobber (reg:CC R_FLAGS))])]
451   "")
454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
456 ;; SImode moves
458 ;; For moving among registers we use the move.l instruction.  This is
459 ;; actually an OR instruction using an alias.  For moving between register
460 ;; and memory we need the address of the memory location in a register.
461 ;; However, we can accept an expression (reg + offset) where offset is in
462 ;; the range 0 .. 124 and is shifted right two places in the assembled 
463 ;; instruction.
465 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
468 (define_expand "movsi"
469   [(set (match_operand:SI 0 "nonimmediate_operand" "")
470         (match_operand:SI 1 "general_operand" ""))]
471   ""
473   prepare_move_operands (operands, SImode);
476 (define_insn "*movsi_high"
477   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 
478         (high:SI (match_operand:SI 1 "immediate_operand" "n,i")) )]
479   ""
480   "@
481     moviu   %0,%u1
482     moviu   %0,%%u %a1"
483   [(set_attr "type" "imm_reg")])
485 ; We only care about the lower 16 bits of the constant 
486 ; being inserted into the upper 16 bits of the register.
487 (define_insn "*moviu"
488   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
489                          (const_int 16)
490                          (const_int 0))
491         (match_operand:SI 1 "const_int_operand" "n"))]
492   ""
493   "moviu   %0,%w1"
494   [(set_attr "type" "imm_reg")])
496 (define_insn "*movsi_losum"
497   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
498         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
499                    (match_operand:SI 2 "immediate_operand" "n,i")))]
500   ""
501   "@
502     movil   %0,%w2
503     movil   %0,%%l %a2"
504   [(set_attr "type" "imm_reg")])
506 (define_insn "*movil"
507   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
508                          (const_int 16)
509                          (const_int 16))
510         (match_operand:SI 1 "const_int_operand" "n"))]
511   ""
512   "movil   %0,%w1"
513   [(set_attr "type" "imm_reg")])
515 (define_insn "*movsi_insn_no_ieee"
516   [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,!f")
517         (match_operand:SI 1 "general_operand"      " r,rO, r, r,?b,?c,J,M,i,m,!f, r"))]
518   "!TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
519   "@
520     #
521     write.l %0,%r1
522     writemd %1,r0               ;movsi  ?b  r
523     writemdc %1         ;movsi  ?c  r
524     readmda %0          ;movsi  r  ?b
525     readmdc %0          ;movsi  r  ?c
526     moviq   %0,%1               ;movsi  r  J
527     #
528     #                   ;movsi  r  i
529     read.l  %0,%1
530     fstore  %0,%1
531     fload   %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")])
534 (define_insn "*movsi_insn"
535   [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,?f,f")
536         (match_operand:SI 1 "general_operand"      " r,rO, r, r,?b,?c,J,M,i,m,?f, r,f"))]
537   "TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
538   "@
539     #
540     write.l %0,%r1
541     writemd %1,r0               ;movsi  ?b  r
542     writemdc %1         ;movsi  ?c  r
543     readmda %0          ;movsi  r  ?b
544     readmdc %0          ;movsi  r  ?c
545     moviq   %0,%1               ;movsi  r  J
546     #
547     #                   ;movsi  r  i
548     read.l  %0,%1
549     fstore  %0,%1
550     fload   %0,%1
551     fmove   %0,%1"
552   [(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")])
554 (define_insn "*movsi_insn<subst_logic>"
555   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
556         (match_operand:SI 1 "gpc_reg_operand" "r"))
557    (clobber (reg:CC R_FLAGS))]
558   "reload_completed"
559   "move.l  %0,%1"
560   [(set_attr "type" "logic")])
562 (define_insn "*movsi_insn_m1<subst_logic>"
563   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
564         (const_int -1))
565    (clobber (reg:CC R_FLAGS))]
566   "reload_completed"
567   "not.l   %0,r0"
568   [(set_attr "type" "logic")])
570 (define_split
571   [(set (match_operand:SI 0 "gpc_reg_operand" "")
572         (match_operand:SI 1 "gpc_reg_operand" ""))]
573   "reload_completed"
574   [(parallel [(set (match_dup 0) (match_dup 1))
575               (clobber (reg:CC R_FLAGS))])]
576   "")
578 (define_split
579   [(set (match_operand:SI 0 "gpc_reg_operand" "")
580         (const_int -1))]
581   "reload_completed"
582   [(parallel [(set (match_dup 0) (const_int -1))
583               (clobber (reg:CC R_FLAGS))])]
584   "")
586 (define_insn "*movsi_mdbhi"
587   [(set (match_operand:SI 0 "register_operand" "=r")
588         (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
589   ""
590   "readmdb %0"
591   [(set_attr "type" "eam_reg")])
593 (define_split
594   [(set (match_operand:SI 0 "gpc_reg_operand" "")
595         (match_operand:SI 1 "large_immediate_operand" ""))]
596   "reload_completed"
597   [(set (match_dup 0)
598         (high:SI (match_dup 1)) )
599    (set (match_dup 0)
600         (lo_sum:SI (match_dup 0) (match_dup 1)))]
601   "")
604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
606 ;; DImode moves
608 ;; When the destination is the EAM register MDB, then we use the writemd
609 ;; instruction.  In all other cases we split the move into two 32-bit moves.
611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
614 (define_expand "movdi"
615   [(set (match_operand:DI 0 "nonimmediate_operand" "")
616         (match_operand:DI 1 "general_operand" ""))]
617   ""
619   prepare_move_operands (operands, DImode);
622 (define_insn "*movdi_insn"
623   [(set (match_operand:DI 0 "nonimmediate_operand" "= r, m, r,??b")
624         (match_operand:DI 1 "general_operand"      "rim,rO,?b,  r"))]
625   "ok_for_simple_move_operands (operands, DImode)"
626   "@
627     #
628     #
629     #
630     writemd %d1,%1              ;movdi  ?b r"
631   [(set_attr "type" "multi,multi,multi,reg_eam")])
633 (define_split
634   [(set (match_operand:DI 0 "gpc_reg_operand" "") (reg:DI R_MDB))]
635   "reload_completed"
636   [(set (match_dup 1) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))
637    (set (match_dup 2) (reg:SI R_MDB))]
639   operands[1] = operand_subword (operands[0], 0, 1, DImode);
640   operands[2] = operand_subword (operands[0], 1, 1, DImode);
643 (define_split
644   [(set (match_operand:DI 0 "non_eam_dst_operand" "")
645         (match_operand:DI 1 "non_eam_src_operand" ""))]
646   "reload_completed"
647   [(set (match_dup 2) (match_dup 3))
648    (set (match_dup 4) (match_dup 5))]
650   visium_split_double_move (operands, DImode);
654 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
656 ;; SFmode moves
658 ;; Constants are constructed in a GP register and moved to the FP register.
660 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
663 (define_expand "movsf"
664   [(set (match_operand:SF 0 "nonimmediate_operand" "")
665         (match_operand:SF 1 "general_operand" ""))]
666   ""
668   prepare_move_operands (operands, SFmode);
671 (define_insn "*movsf_insn"
672   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,r,r, m,r,r,r")
673         (match_operand:SF 1 "general_operand"      " f,G,r,f,r,rG,G,F,m"))]
674   "ok_for_simple_move_operands (operands, SFmode)"
675   "@
676     fmove   %0,%1
677     fmove   %0,f0
678     fload   %0,%1
679     fstore  %0,%1
680     #
681     write.l %0,%r1
682     moviq   %0,0
683     #
684     read.l  %0,%1"
685   [(set_attr "type" "fmove,fmove,reg_fp,fp_reg,logic,reg_mem,imm_reg,multi,mem_reg")])
687 (define_insn "*movsf_insn"
688   [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
689         (match_operand:SF 1 "gpc_reg_operand" "r"))
690    (clobber (reg:CC R_FLAGS))]
691   "reload_completed"
692   "move.l  %0,%1"
693   [(set_attr "type" "logic")])
695 (define_split
696   [(set (match_operand:SF 0 "gpc_reg_operand" "")
697         (match_operand:SF 1 "gpc_reg_operand" ""))]
698   "reload_completed"
699   [(parallel [(set (match_dup 0) (match_dup 1))
700               (clobber (reg:CC R_FLAGS))])]
701   "")
703 (define_split
704   [(set (match_operand:SF 0 "gpc_reg_operand" "")
705         (match_operand:SF 1 "const_double_operand" ""))]
706   "reload_completed"
707   [(set (match_dup 2) (match_dup 3))]
709   long l;
711   REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
713   operands[2] = operand_subword (operands[0], 0, 0, SFmode);
714   operands[3] = GEN_INT (trunc_int_for_mode (l, SImode));
718 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
720 ;; DFmode moves
722 ;; We always split a DFmode move into two SImode moves.
724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
727 (define_expand "movdf"
728   [(set (match_operand:DF 0 "nonimmediate_operand" "")
729         (match_operand:DF 1 "general_operand" ""))]
730   ""
732   prepare_move_operands (operands, DFmode);
735 (define_insn "*movdf_insn"
736   [(set (match_operand:DF 0 "nonimmediate_operand" "= r, m")
737         (match_operand:DF 1 "general_operand"      "rFm,rG"))]
738   "ok_for_simple_move_operands (operands, DFmode)"
739   "#"
740   [(set_attr "type" "multi")])
742 (define_split
743   [(set (match_operand:DF 0 "nonimmediate_operand" "")
744         (match_operand:DF 1 "general_operand" ""))]
745   "reload_completed"
746   [(set (match_dup 2) (match_dup 3))
747    (set (match_dup 4) (match_dup 5))]
749   visium_split_double_move (operands, DFmode);
753 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
755 ;; Integer Add
757 ;; Modes QI, HI, SI and DI are supported directly.
759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
762 (define_expand "add<mode>3"
763   [(set (match_operand:QHI 0 "register_operand" "")
764         (plus:QHI (match_operand:QHI 1 "register_operand" "")
765                   (match_operand:QHI 2 "register_operand" "")))]
766   "")
768 (define_expand "uaddv<mode>4"
769   [(set (match_operand:I 0 "register_operand" "")
770         (plus:I (match_operand:I 1 "register_operand" "")
771                 (match_operand:I 2 "register_operand" "")))
772    (set (pc)
773         (if_then_else (ltu (match_dup 0) (match_dup 1))
774                       (label_ref (match_operand 3 ""))
775                       (pc)))]
776   "")
778 (define_expand "addv<mode>4"
779   [(set (match_operand:I 0 "register_operand" "")
780         (plus:I (match_operand:I 1 "register_operand" "")
781                 (match_operand:I 2 "register_operand" "")))
782    (set (pc)
783         (if_then_else (ne (match_dup 0)
784                           (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))
785                       (label_ref (match_operand 3 ""))
786                       (pc)))]
787   "")
789 (define_insn_and_split "*add<mode>3_insn"
790   [(set (match_operand:QHI 0 "register_operand" "=r")
791         (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
792                   (match_operand:QHI 2 "register_operand" "r")))]
793   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
794   "#"
795   "reload_completed"
796   [(parallel [(set (match_dup 0)
797                    (plus:QHI (match_dup 1) (match_dup 2)))
798               (clobber (reg:CC R_FLAGS))])]
799   ""
800   [(set_attr "type" "arith")])
802 (define_insn "*add<mode>3_insn<subst_arith>"
803   [(set (match_operand:QHI 0 "register_operand" "=r")
804         (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
805                   (match_operand:QHI 2 "register_operand" "r")))
806    (clobber (reg:CC R_FLAGS))]
807   "reload_completed"
808   "add<s>   %0,%1,%2"
809   [(set_attr "type" "arith")])
811 (define_insn "*add<mode>3_insn_set_carry"
812   [(set (reg:CCC R_FLAGS)
813         (compare:CCC (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
814                                (match_operand:QHI 2 "register_operand" "r"))
815                      (match_dup 1)))
816    (set (match_operand:QHI 0 "register_operand" "=r")
817         (plus:QHI (match_dup 1) (match_dup 2)))]
818   "reload_completed"
819   "add<s>   %0,%1,%2"
820   [(set_attr "type" "arith")])
822 (define_insn "*add<mode>3_insn_set_overflow"
823   [(set (reg:CCV R_FLAGS)
824         (compare:CCV (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
825                                (match_operand:QHI 2 "register_operand" "r"))
826                      (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
827    (set (match_operand:QHI 0 "register_operand" "=r")
828         (plus:QHI (match_dup 1) (match_dup 2)))]
829   "reload_completed"
830   "add<s>   %0,%1,%2"
831   [(set_attr "type" "arith")])
833 (define_expand "addsi3"
834   [(set (match_operand:SI 0 "register_operand" "")
835         (plus:SI (match_operand:SI 1 "register_operand" "")
836                  (match_operand:SI 2 "add_operand" "")))]
837   "")
839 (define_expand "addsi3_flags"
840   [(parallel [(set (match_operand:SI 0 "register_operand" "")
841                    (plus:SI (match_operand:SI 1 "register_operand" "")
842                             (match_operand:SI 2 "add_operand" "")))
843               (clobber (reg:CC R_FLAGS))])]
844   "reload_completed"
845   "")
847 (define_insn_and_split "*addsi3_insn"
848   [(set (match_operand:SI 0 "register_operand"          "=r,r,r")
849         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
850                  (match_operand:SI 2 "add_operand"      " L,r,J")))]
851   "ok_for_simple_arith_logic_operands (operands, SImode)"
852   "#"
853   "reload_completed"
854   [(parallel [(set (match_dup 0)
855                    (plus:SI (match_dup 1) (match_dup 2)))
856               (clobber (reg:CC R_FLAGS))])]
857   ""
858   [(set_attr "type" "arith")])
860 ; Favour the addition of small negative constants, since they are
861 ; expensive to load into a register.
863 (define_insn "*addsi3_insn<subst_arith>"
864   [(set (match_operand:SI 0 "register_operand"          "=r,r,r")
865         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
866                  (match_operand:SI 2 "add_operand"      " L,r,J")))
867    (clobber (reg:CC R_FLAGS))]
868   "reload_completed"
869   "@
870     subi    %0,%n2
871     add.l   %0,%1,%2
872     addi    %0,%2"
873   [(set_attr "type" "arith")])
875 (define_insn "addsi3_insn_set_carry"
876   [(set (reg:CCC R_FLAGS)
877         (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
878                               (match_operand:SI 2 "real_add_operand" " r,J"))
879                      (match_dup 1)))
880    (set (match_operand:SI 0 "register_operand"          "=r,r")
881         (plus:SI (match_dup 1) (match_dup 2)))]
882   "reload_completed"
883   "@
884     add.l   %0,%1,%2
885     addi    %0,%2"
886   [(set_attr "type" "arith")])
888 (define_insn "*addsi3_insn_set_overflow"
889   [(set (reg:CCV R_FLAGS)
890         (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
891                               (match_operand:SI 2 "real_add_operand" " r,J"))
892                      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
893    (set (match_operand:SI 0 "register_operand"          "=r,r")
894         (plus:SI (match_dup 1) (match_dup 2)))]
895   "reload_completed"
896   "@
897     add.l   %0,%1,%2
898     addi    %0,%2"
899   [(set_attr "type" "arith")])
901 (define_expand "adddi3"
902   [(set (match_operand:DI 0 "register_operand" "")
903         (plus:DI (match_operand:DI 1 "register_operand" "")
904                  (match_operand:DI 2 "add_operand" "")))]
905   "")
907 ; Disfavour the use of add.l because of the early clobber.
909 (define_insn_and_split "*addi3_insn"
910   [(set (match_operand:DI 0 "register_operand"          "=r,r,&r")
911         (plus:DI (match_operand:DI 1 "register_operand" "%0,0, r")
912                  (match_operand:DI 2 "add_operand"      " L,J, r")))]
913   "ok_for_simple_arith_logic_operands (operands, DImode)"
914   "#"
915   "reload_completed"
916   [(const_int 0)]
918   visium_split_double_add (PLUS, operands[0], operands[1], operands[2]);
919   DONE;
921   [(set_attr "type" "arith2")])
924 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
926 ;; Integer Add with Carry
928 ;; Only SI mode is supported.
930 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
933 (define_insn "*<scc_str><subst_arith>"
934   [(set (match_operand:SI 0 "register_operand" "=r")
935         (any_scc:SI (reg R_FLAGS) (const_int 0)))
936    (clobber (reg:CC R_FLAGS))]
937   "reload_completed"
938   "adc.l   %0,r0,r0"
939   [(set_attr "type" "arith")])
941 (define_insn "*plus_<scc_str><subst_arith>"
942   [(set (match_operand:SI 0 "register_operand" "=r")
943         (plus:SI (match_operand:SI 1 "register_operand" "r")
944                  (any_scc:SI (reg R_FLAGS) (const_int 0))))
945    (clobber (reg:CC R_FLAGS))]
946   "reload_completed"
947   "adc.l   %0,%1,r0"
948   [(set_attr "type" "arith")])
950 (define_insn "*plus_plus_sltu<subst_arith>"
951   [(set (match_operand:SI 0 "register_operand" "=r")
952         (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
953                           (match_operand:SI 2 "register_operand" "r"))
954                  (ltu:SI (reg R_FLAGS) (const_int 0))))
955    (clobber (reg:CC R_FLAGS))]
956   "reload_completed"
957   "adc.l   %0,%1,%2"
958   [(set_attr "type" "arith")])
961 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
963 ;; Integer Subtract
965 ;; Modes QI, HI, SI and DI are supported directly.
967 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
970 (define_expand "sub<mode>3"
971   [(set (match_operand:QHI 0 "register_operand" "")
972         (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "")
973                    (match_operand:QHI 2 "register_operand" "")))]
974   "")
976 (define_expand "usubv<mode>4"
977   [(set (match_operand:I 0 "register_operand" "")
978         (minus:I (match_operand:I 1 "reg_or_0_operand" "")
979                  (match_operand:I 2 "register_operand" "")))
980    (set (pc)
981         (if_then_else (ltu (match_dup 1) (match_dup 2))
982                       (label_ref (match_operand 3 ""))
983                       (pc)))]
984   ""
986   if (operands[1] == const0_rtx)
987     {
988       emit_insn (gen_unegv<mode>3 (operands[0], operands[2], operands[3]));
989       DONE;
990     }
993 (define_expand "subv<mode>4"
994   [(set (match_operand:I 0 "register_operand" "")
995         (minus:I (match_operand:I 1 "register_operand" "")
996                  (match_operand:I 2 "register_operand" "")))
997    (set (pc)
998         (if_then_else (ne (match_dup 0)
999                           (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))
1000                       (label_ref (match_operand 3 ""))
1001                       (pc)))]
1002   "")
1004 (define_insn_and_split "*sub<mode>3_insn"
1005   [(set (match_operand:QHI 0 "register_operand" "=r")
1006         (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
1007                    (match_operand:QHI 2 "register_operand" "r")))]
1008   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1009   "#"
1010   "reload_completed"
1011   [(parallel [(set (match_dup 0)
1012                    (minus:QHI (match_dup 1) (match_dup 2)))
1013               (clobber (reg:CC R_FLAGS))])]
1014  ""
1015   [(set_attr "type" "arith")])
1017 (define_insn "*sub<mode>3_insn<subst_arith>"
1018   [(set (match_operand:QHI 0 "register_operand" "=r")
1019         (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
1020                    (match_operand:QHI 2 "register_operand" "r")))
1021    (clobber (reg:CC R_FLAGS))]
1022   "reload_completed"
1023   "sub<s>   %0,%r1,%2"
1024   [(set_attr "type" "arith")])
1026 (define_insn "*sub<mode>3_insn_set_carry"
1027   [(set (reg:CC R_FLAGS)
1028         (compare:CC (match_operand:QHI 1 "reg_or_0_operand" "r0")
1029                     (match_operand:QHI 2 "register_operand" "r")))
1030    (set (match_operand:QHI 0 "register_operand" "=r")
1031         (minus:QHI (match_dup 1) (match_dup 2)))]
1032   "reload_completed"
1033   "sub<s>   %0,%r1,%2"
1034   [(set_attr "type" "arith")])
1036 (define_insn "*sub<mode>3_insn_set_overflow"
1037   [(set (reg:CCV R_FLAGS)
1038         (compare:CCV (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "r0")
1039                                 (match_operand:QHI 2 "register_operand" "r"))
1040                      (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
1041    (set (match_operand:QHI 0 "register_operand" "=r")
1042         (minus:QHI (match_dup 1) (match_dup 2)))]
1043   "reload_completed"
1044   "sub<s>   %0,%r1,%2"
1045   [(set_attr "type" "arith")])
1047 (define_expand "subsi3"
1048   [(set (match_operand:SI 0 "register_operand" "")
1049         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
1050                   (match_operand:SI 2 "add_operand" "")))]
1051   "")
1053 (define_expand "subsi3_flags"
1054   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1055                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
1056                              (match_operand:SI 2 "add_operand" "")))
1057               (clobber (reg:CC R_FLAGS))])]
1058   "reload_completed"
1059   "")
1061 (define_insn_and_split "*subsi3_insn"
1062   [(set (match_operand:SI 0 "register_operand"           "=r,r, r")
1063         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
1064                   (match_operand:SI 2 "add_operand"      " L,r, J")))]
1065   "ok_for_simple_arith_logic_operands (operands, SImode)"
1066   "#"
1067   "reload_completed"
1068   [(parallel [(set (match_dup 0)
1069                    (minus:SI (match_dup 1) (match_dup 2)))
1070               (clobber (reg:CC R_FLAGS))])]
1071  ""
1072   [(set_attr "type" "arith")])
1074 ; Favour the subtraction of small negative constants, since they are
1075 ; expensive to load into a register.
1077 (define_insn "*subsi3_insn<subst_arith>"
1078   [(set (match_operand:SI 0 "register_operand"           "=r,r, r")
1079         (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
1080                   (match_operand:SI 2 "add_operand"      " L,r, J")))
1081    (clobber (reg:CC R_FLAGS))]
1082   "reload_completed"
1083   "@
1084     addi    %0,%n2
1085     sub.l   %0,%r1,%2
1086     subi    %0,%2"
1087   [(set_attr "type" "arith")])
1089 (define_insn "subsi3_insn_set_carry"
1090   [(set (reg:CC R_FLAGS)
1091         (compare:CC (match_operand:SI 1 "register_operand" "r,0")
1092                     (match_operand:SI 2 "real_add_operand" "r,J")))
1093    (set (match_operand:SI 0 "register_operand"           "=r,r")
1094         (minus:SI (match_dup 1) (match_dup 2)))]
1095   "reload_completed"
1096   "@
1097     sub.l   %0,%r1,%2
1098     subi    %0,%2"
1099   [(set_attr "type" "arith")])
1101 (define_insn "*subsi3_insn_set_overflow"
1102   [(set (reg:CCV R_FLAGS)
1103         (compare:CCV (minus:SI (match_operand:SI 1 "register_operand" "r,0")
1104                                (match_operand:SI 2 "real_add_operand" "r,J"))
1105                      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
1106    (set (match_operand:SI 0 "register_operand"           "=r,r")
1107         (minus:SI (match_dup 1) (match_dup 2)))]
1108   "reload_completed"
1109   "@
1110     sub.l   %0,%1,%2
1111     subi    %0,%2"
1112   [(set_attr "type" "arith")])
1114 (define_expand "subdi3"
1115   [(set (match_operand:DI 0 "register_operand" "")
1116         (minus:DI (match_operand:DI 1 "register_operand" "")
1117                   (match_operand:DI 2 "add_operand" "")))]
1118   "")
1120 ; Disfavour the use of the sub.l because of the early clobber.
1122 (define_insn_and_split "*subdi3_insn"
1123   [(set (match_operand:DI 0 "register_operand"           "=r,r,&r")
1124         (minus:DI (match_operand:DI 1 "register_operand" " 0,0, r")
1125                   (match_operand:DI 2 "add_operand"      " L,J, r")))]
1126   "ok_for_simple_arith_logic_operands (operands, DImode)"
1127   "#"
1128   "reload_completed"
1129   [(const_int 0)]
1131   visium_split_double_add (MINUS, operands[0], operands[1], operands[2]);
1132   DONE;
1134   [(set_attr "type" "arith2")])
1137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1139 ;; Integer Subtract with Carry
1141 ;; Only SI mode is supported.
1143 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1146 (define_insn "*neg_<scc_str><subst_arith>"
1147   [(set (match_operand:SI 0 "register_operand" "=r")
1148         (neg:SI (any_scc:SI (reg R_FLAGS) (const_int 0))))
1149    (clobber (reg:CC R_FLAGS))]
1150   "reload_completed"
1151   "subc.l  %0,r0,r0"
1152   [(set_attr "type" "arith")])
1154 (define_insn "*minus_<scc_str><subst_arith>"
1155   [(set (match_operand:SI 0 "register_operand" "=r")
1156         (minus:SI (match_operand:SI 1 "register_operand" "r")
1157                   (any_scc:SI (reg R_FLAGS) (const_int 0))))
1158    (clobber (reg:CC R_FLAGS))]
1159   "reload_completed"
1160   "subc.l  %0,%1,r0"
1161   [(set_attr "type" "arith")])
1163 (define_insn "*minus_minus_sltu<subst_arith>"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1166                             (match_operand:SI 2 "register_operand" "r"))
1167                   (ltu:SI (reg R_FLAGS) (const_int 0))))
1168    (clobber (reg:CC R_FLAGS))]
1169   "reload_completed"
1170   "subc.l  %0,%r1,%2"
1171   [(set_attr "type" "arith")])
1174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1176 ;; Integer Negate
1178 ;; Modes QI, HI, SI and DI are supported directly.
1180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1183 (define_expand "neg<mode>2"
1184   [(set (match_operand:I 0 "register_operand" "")
1185         (neg:I (match_operand:I 1 "register_operand" "")))]
1186   "")
1188 (define_expand "unegv<mode>3"
1189   [(set (match_operand:I 0 "register_operand" "")
1190         (neg:I (match_operand:I 1 "register_operand" "")))
1191    (set (pc)
1192         (if_then_else (ne (match_dup 0) (const_int 0))
1193                       (label_ref (match_operand 2 ""))
1194                       (pc)))]
1195   "")
1197 (define_expand "negv<mode>3"
1198   [(set (match_operand:I 0 "register_operand" "")
1199         (neg:I (match_operand:I 1 "register_operand" "")))
1200    (set (pc)
1201         (if_then_else (ne (match_dup 0)
1202                           (unspec:I [(match_dup 1)] UNSPEC_NEGV))
1203                       (label_ref (match_operand 2 ""))
1204                       (pc)))]
1205   "")
1207 (define_insn_and_split "*neg<mode>2_insn"
1208   [(set (match_operand:I 0 "register_operand" "=r")
1209         (neg:I (match_operand:I 1 "register_operand" "r")))]
1210   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1211   "#"
1212   "reload_completed"
1213   [(parallel [(set (match_dup 0) (neg:I (match_dup 1)))
1214               (clobber (reg:CC R_FLAGS))])]
1215   ""
1216   [(set_attr "type" "arith")])
1218 (define_insn "*neg<mode>2_insn<subst_arith>"
1219   [(set (match_operand:I 0 "register_operand" "=r")
1220         (neg:I (match_operand:I 1 "register_operand" "r")))
1221    (clobber (reg:CC R_FLAGS))]
1222   "reload_completed"
1223   "sub<s>   %0,r0,%1"
1224   [(set_attr "type" "arith")])
1226 (define_insn "neg<mode>2_insn_set_carry"
1227   [(set (reg:CCC R_FLAGS)
1228         (compare:CCC (not:I (neg:I (match_operand:I 1 "register_operand" "r")))
1229                      (const_int -1)))
1230    (set (match_operand:I 0 "register_operand" "=r")
1231         (neg:I (match_dup 1)))]
1232   "reload_completed"
1233   "sub<s>   %0,r0,%1"
1234   [(set_attr "type" "arith")])
1236 (define_insn "*neg<mode>2_insn_set_overflow"
1237   [(set (reg:CCV R_FLAGS)
1238         (compare:CCV (neg:I (match_operand:I 1 "register_operand" "r"))
1239                      (unspec:I [(match_dup 1)] UNSPEC_NEGV)))
1240    (set (match_operand:I 0 "register_operand" "=r")
1241         (neg:I (match_dup 1)))]
1242   "reload_completed"
1243   "sub<s>   %0,r0,%1"
1244   [(set_attr "type" "arith")])
1246 (define_expand "negdi2"
1247   [(set (match_operand:DI 0 "register_operand" "")
1248         (neg:DI (match_operand:DI 1 "register_operand" "")))]
1249   "")
1251 (define_insn_and_split "*negdi2_insn"
1252   [(set (match_operand:DI 0 "register_operand" "=&r")
1253         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
1254   "ok_for_simple_arith_logic_operands (operands, DImode)"
1255   "#"
1256   "reload_completed"
1257   [(const_int 0)]
1259   visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]);
1260   DONE;
1262   [(set_attr "type" "arith2")])
1265 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1267 ;; Integer Multiply (non-widening and widening, signed and unsigned)
1269 ;; Only SI mode is supported.
1271 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1274 ; The mults and multu instructions clear MDC but we only pretend that they
1275 ; clobber it to keep things relatively simple.
1277 (define_insn "mulsi3"
1278   [(set (match_operand:SI 0 "register_operand" "=b")
1279          (mult:SI (match_operand:SI 1 "register_operand" "%r")
1280                   (match_operand:SI 2 "register_operand" "r")))
1281    (clobber (reg:SI R_MDC))]
1282   ""
1283   "mults   %1,%2"
1284   [(set_attr "type" "mul")])
1286 ; The names are mulsidi3 and umulsidi3 here.
1288 (define_insn "<u>mulsidi3"
1289   [(set (match_operand:DI 0 "register_operand" "=b")
1290         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1291                  (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))
1292    (clobber (reg:SI R_MDC))]
1293   ""
1294   "mult<su>   %1,%2"
1295   [(set_attr "type" "mul")])
1297 ; But they are smulsi3_highpart and umulsi3_highpart here.
1299 (define_insn_and_split "<su>mulsi3_highpart"
1300   [(set (match_operand:SI 0 "register_operand" "=r")
1301         (truncate:SI
1302           (ashiftrt:DI
1303             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1304                      (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
1305             (const_int 32))))
1306    (clobber (reg:DI R_MDB))
1307    (clobber (reg:SI R_MDC))]
1308   ""
1309   "#"
1310   "reload_completed"
1311   [(parallel [(set (reg:DI R_MDB)
1312                    (mult:DI (any_extend:DI (match_dup 1))
1313                             (any_extend:DI (match_dup 2))))
1314               (clobber (reg:SI R_MDC))])
1315    (set (match_dup 0) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
1316   ""
1317   [(set_attr "type" "multi")])
1320 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1322 ;; Integer divide and modulus (signed and unsigned)
1324 ;; Only SI mode is supported.
1326 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1329 (define_insn "*divmodsi4_insn"
1330   [(set (match_operand:SI 0 "register_operand" "=b")
1331         (div:SI (match_operand:SI 1 "register_operand" "0")
1332                 (match_operand:SI 2 "register_operand" "r")))
1333    (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))]
1334   ""
1335   "divs    %2"
1336   [(set_attr "type" "div")])
1338 (define_insn_and_split "divmodsi4"
1339   [(set (match_operand:SI 0 "register_operand" "=b")
1340         (div:SI (match_operand:SI 1 "register_operand" "0")
1341                 (match_operand:SI 2 "register_operand" "r")))
1342    (set (match_operand:SI 3 "register_operand" "=r")
1343         (mod:SI (match_dup 1) (match_dup 2)))
1344    (clobber (reg:SI R_MDC))]
1345   ""
1346   "#"
1347   "reload_completed"
1348   [(parallel [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2)))
1349               (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))])
1350    (set (match_dup 3) (reg:SI R_MDC))]
1351   ""
1352   [(set_attr "type" "multi")])
1354 (define_insn "*udivmodsi4_insn"
1355   [(set (match_operand:SI 0 "register_operand" "=b")
1356         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1357                  (match_operand:SI 2 "register_operand" "r")))
1358    (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))]
1359   ""
1360   "divu    %2"
1361   [(set_attr "type" "div")])
1363 (define_insn_and_split "udivmodsi4"
1364   [(set (match_operand:SI 0 "register_operand" "=b")
1365         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1366                  (match_operand:SI 2 "register_operand" "r")))
1367    (set (match_operand:SI 3 "register_operand" "=r")
1368         (umod:SI (match_dup 1) (match_dup 2)))
1369    (clobber (reg:SI R_MDC))]
1370   ""
1371   "#"
1372   "reload_completed"
1373   [(parallel [(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2)))
1374               (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))])
1375    (set (match_dup 3) (reg:SI R_MDC))]
1376   ""
1377   [(set_attr "type" "multi")])
1379 ; FIXME. How do we persuade the compiler to use 64/32 bit divides directly ?
1381 (define_insn "*divds"
1382   [(set (reg:DI R_MDB)
1383         (div:DI (reg:DI R_MDB) (sign_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1384    (set (reg:SI R_MDC) (truncate:SI (mod:DI (reg:DI R_MDB) (sign_extend:DI (match_dup 0)))))]
1385   ""
1386   "divds   %0"
1387   [(set_attr "type" "divd")])
1389 (define_insn "*divdu"
1390   [(set (reg:DI R_MDB)
1391         (udiv:DI (reg:DI R_MDB) (zero_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1392    (set (reg:SI R_MDC) (truncate:SI (umod:DI (reg:DI R_MDB) (zero_extend:DI (match_dup 0)))))]
1393   ""
1394   "divdu   %0"
1395   [(set_attr "type" "divd")])
1397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399 ;; Bitwise Logical AND
1401 ;; Modes QI, HI and SI are supported directly.
1403 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1406 (define_expand "and<mode>3"
1407   [(set (match_operand:I 0 "register_operand" "")
1408         (and:I (match_operand:I 1 "register_operand" "")
1409                (match_operand:I 2 "register_operand" "")))]
1410   "")
1412 (define_insn_and_split "*and<mode>3_insn"
1413   [(set (match_operand:I 0 "register_operand" "=r")
1414         (and:I (match_operand:I 1 "register_operand" "%r")
1415                (match_operand:I 2 "register_operand" "r")))]
1416   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1417   "#"
1418   "reload_completed"
1419   [(parallel [(set (match_dup 0)
1420                    (and:I (match_dup 1) (match_dup 2)))
1421               (clobber (reg:CC R_FLAGS))])]
1422   ""
1423   [(set_attr "type" "logic")])
1425 (define_insn "*and<mode>3_insn<subst_logic>"
1426   [(set (match_operand:I 0 "register_operand" "=r")
1427         (and:I (match_operand:I 1 "register_operand" "%r")
1428                (match_operand:I 2 "register_operand" "r")))
1429    (clobber (reg:CC R_FLAGS))]
1430   "reload_completed"
1431   "and<s>   %0,%1,%2"
1432   [(set_attr "type" "logic")])
1435 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1437 ;; Bitwise Inclusive Logical OR
1439 ;; Modes QI, HI and SI are supported directly.
1441 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1444 (define_expand "ior<mode>3"
1445   [(set (match_operand:I 0 "register_operand" "")
1446         (ior:I (match_operand:I 1 "register_operand" "")
1447                (match_operand:I 2 "register_operand" "")))]
1448   "")
1450 (define_insn_and_split "*ior<mode>3_insn"
1451   [(set (match_operand:I 0 "register_operand" "=r")
1452         (ior:I (match_operand:I 1 "register_operand" "%r")
1453                (match_operand:I 2 "register_operand" "r")))]
1454   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1455   "#"
1456   "reload_completed"
1457   [(parallel [(set (match_dup 0)
1458                    (ior:I (match_dup 1) (match_dup 2)))
1459               (clobber (reg:CC R_FLAGS))])]
1460   ""
1461   [(set_attr "type" "logic")])
1463 (define_insn "*ior<mode>3_insn<subst_logic>"
1464   [(set (match_operand:I 0 "register_operand" "=r")
1465         (ior:I (match_operand:I 1 "register_operand" "%r")
1466                (match_operand:I 2 "register_operand" "r")))
1467    (clobber (reg:CC R_FLAGS))]
1468   "reload_completed"
1469   "or<s>    %0,%1,%2"
1470   [(set_attr "type" "logic")])
1473 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1475 ;; Bitwise Exclusive Logical OR
1477 ;; Modes QI, HI and SI are supported directly.
1479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1482 (define_expand "xor<mode>3"
1483   [(set (match_operand:I 0 "register_operand" "")
1484         (xor:I (match_operand:I 1 "register_operand" "")
1485                 (match_operand:I 2 "register_operand" "")))]
1486   "")
1488 (define_insn_and_split "*xor<mode>3_insn"
1489   [(set (match_operand:I 0 "register_operand" "=r")
1490         (xor:I (match_operand:I 1 "register_operand" "%r")
1491                (match_operand:I 2 "register_operand" "r")))]
1492   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1493   "#"
1494   "reload_completed"
1495   [(parallel [(set (match_dup 0)
1496                    (xor:I (match_dup 1) (match_dup 2)))
1497               (clobber (reg:CC R_FLAGS))])]
1498   ""
1499   [(set_attr "type" "logic")])
1501 (define_insn "*xor<mode>3_insn<subst_logic>"
1502   [(set (match_operand:I 0 "register_operand" "=r")
1503         (xor:I (match_operand:I 1 "register_operand" "%r")
1504                (match_operand:I 2 "register_operand" "r")))
1505    (clobber (reg:CC R_FLAGS))]
1506   "reload_completed"
1507   "xor<s>   %0,%1,%2"
1508   [(set_attr "type" "logic")])
1511 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1513 ;; Bitwise Logical NOT
1515 ;; Modes QI, HI and SI are supported directly.
1517 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1520 (define_expand "one_cmpl<mode>2"
1521   [(set (match_operand:I 0 "register_operand" "")
1522         (not:I (match_operand:I 1 "reg_or_0_operand" "")))]
1523   "")
1525 (define_insn_and_split "*one_cmpl<mode>2_insn"
1526   [(set (match_operand:I 0 "register_operand" "=r")
1527         (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))]
1528   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1529   "#"
1530   "reload_completed"
1531   [(parallel [(set (match_dup 0) (not:I (match_dup 1)))
1532               (clobber (reg:CC R_FLAGS))])]
1533   ""
1534   [(set_attr "type" "logic")])
1536 (define_insn "*one_cmpl<mode>2_insn<subst_logic>"
1537   [(set (match_operand:I 0 "register_operand" "=r")
1538         (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))
1539    (clobber (reg:CC R_FLAGS))]
1540   "reload_completed"
1541   "not<s>   %0,%r1"
1542   [(set_attr "type" "logic")])
1545 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1547 ;; Arithmetic Shift Left
1549 ;; Modes QI, HI, SI and DI are supported directly.
1551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1554 (define_expand "ashl<mode>3"
1555   [(set (match_operand:I 0 "register_operand" "")
1556         (ashift:I (match_operand:I  1 "register_operand"     "")
1557                   (match_operand:QI 2 "reg_or_shift_operand" "")))]
1558   "")
1560 (define_insn_and_split "*ashl<mode>3_insn"
1561   [(set (match_operand:I 0 "register_operand" "=r,r")
1562         (ashift:I (match_operand:I  1 "register_operand"     "r,r")
1563                   (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1564   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1565   "#"
1566   "reload_completed"
1567   [(parallel [(set (match_dup 0)
1568                    (ashift:I (match_dup 1) (match_dup 2)))
1569               (clobber (reg:CC R_FLAGS))])]
1570   ""
1571   [(set_attr "type" "arith")])
1573 (define_insn "*ashl<mode>3_insn<subst_arith>"
1574   [(set (match_operand:I 0 "register_operand" "=r,r")
1575         (ashift:I (match_operand:I  1 "register_operand"     "r,r")
1576                   (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1577    (clobber (reg:CC R_FLAGS))]
1578   "reload_completed"
1579   "asl<s>   %0,%1,%2"
1580   [(set_attr "type" "arith")])
1582 (define_insn "ashldi3"
1583   [(set (match_operand:DI 0 "register_operand" "=b,r")
1584         (ashift:DI (match_operand:DI 1 "register_operand" "0,r")
1585                    (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1586    (clobber (reg:SI R_MDC))]
1587   ""
1588   "@
1589     asld    %2
1590     #"
1591   [(set_attr "type" "shiftdi,multi")])
1593 (define_split
1594   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1595         (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
1596                    (const_int 32)))
1597    (clobber (reg:SI R_MDC))]
1598   "reload_completed"
1599   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 4))
1600    (set (subreg:SI (match_dup 0) 4) (const_int 0))]
1601   "")
1604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1606 ;; Arithmetic Shift Right
1608 ;; Modes QI, HI, SI and DI are supported directly.
1610 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1613 (define_expand "ashr<mode>3"
1614   [(set (match_operand:I 0 "register_operand" "")
1615         (ashiftrt:I (match_operand:I  1 "register_operand"     "")
1616                     (match_operand:QI 2 "reg_or_shift_operand" "")))]
1617   "")
1619 (define_insn_and_split "*ashr<mode>3_insn"
1620   [(set (match_operand:I 0 "register_operand" "=r,r")
1621         (ashiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1622                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1623   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1624   "#"
1625   "reload_completed"
1626   [(parallel [(set (match_dup 0)
1627                    (ashiftrt:I (match_dup 1) (match_dup 2)))
1628               (clobber (reg:CC R_FLAGS))])]
1629   ""
1630   [(set_attr "type" "logic")])
1632 (define_insn "*ashr<mode>3_insn<subst_logic>"
1633   [(set (match_operand:I 0 "register_operand" "=r,r")
1634         (ashiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1635                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1636    (clobber (reg:CC R_FLAGS))]
1637   "reload_completed"
1638   "asr<s>   %0,%1,%2"
1639   [(set_attr "type" "logic")])
1641 (define_insn "ashrdi3"
1642   [(set (match_operand:DI 0 "register_operand" "=b,r")
1643         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1644                      (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1645    (clobber (reg:SI R_MDC))]
1646   ""
1647   "@
1648     asrd    %2
1649     #"
1650   [(set_attr "type" "shiftdi,multi")])
1652 (define_split
1653   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1654         (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1655                      (const_int 32)))
1656    (clobber (reg:SI R_MDC))]
1657   "reload_completed"
1658   [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1659    (parallel [(set (subreg:SI (match_dup 0) 0)
1660                    (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))
1661               (clobber (reg:CC R_FLAGS))])]
1662   "")
1665 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1667 ;; Logical Shift Right
1669 ;; Modes QI, HI, SI and DI are supported directly.
1671 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1674 (define_expand "lshr<mode>3"
1675   [(set (match_operand:I 0 "register_operand" "")
1676         (lshiftrt:I (match_operand:I  1 "register_operand"     "")
1677                     (match_operand:QI 2 "reg_or_shift_operand" "")))]
1678   "")
1680 (define_insn_and_split "*lshr<mode>3_insn"
1681   [(set (match_operand:I 0 "register_operand" "=r,r")
1682         (lshiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1683                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1684   "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1685   "#"
1686   "reload_completed"
1687   [(parallel [(set (match_dup 0)
1688                    (lshiftrt:I (match_dup 1) (match_dup 2)))
1689               (clobber (reg:CC R_FLAGS))])]
1690   ""
1691   [(set_attr "type" "logic")])
1693 (define_insn "*lshr<mode>3_insn<subst_logic>"
1694   [(set (match_operand:I 0 "register_operand" "=r,r")
1695         (lshiftrt:I (match_operand:I  1 "register_operand"     "r,r")
1696                     (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1697    (clobber (reg:CC R_FLAGS))]
1698   "reload_completed"
1699   "lsr<s>   %0,%1,%2"
1700   [(set_attr "type" "logic")])
1702 (define_insn "lshrdi3"
1703   [(set (match_operand:DI 0 "register_operand" "=b,r")
1704         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1705                      (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1706    (clobber (reg:SI R_MDC))]
1707   ""
1708   "@
1709     lsrd    %2
1710     #"
1711   [(set_attr "type" "shiftdi,multi")])
1713 (define_split
1714   [(set (match_operand:DI 0 "gpc_reg_operand" "")
1715         (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1716                      (const_int 32)))
1717    (clobber (reg:SI R_MDC))]
1718   "reload_completed"
1719   [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1720    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
1721   "")
1724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1726 ;; Truncate
1728 ;; Truncations among modes QI, HI, SI and DI are supported directly.
1730 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1733 (define_expand "trunchiqi2"
1734   [(set (match_operand:QI 0 "register_operand" "")
1735          (truncate:QI (match_operand:HI 1 "register_operand" "")))]
1736   "")
1738 (define_insn_and_split "*trunchiqi2_insn"
1739   [(set (match_operand:QI 0 "register_operand" "=r")
1740         (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
1741   "ok_for_simple_arith_logic_operands (operands, QImode)"
1742   "#"
1743   "reload_completed"
1744   [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1)))
1745               (clobber (reg:CC R_FLAGS))])]
1746   ""
1747   [(set_attr "type" "logic")])
1749 (define_insn "*trunchiqi2_insn<subst_logic>"
1750   [(set (match_operand:QI 0 "register_operand" "=r")
1751         (truncate:QI (match_operand:HI 1 "register_operand" "r")))
1752    (clobber (reg:CC R_FLAGS))]
1753   "reload_completed"
1754   "move.b  %0,%1"
1755   [(set_attr "type" "logic")])
1757 (define_expand "truncsihi2"
1758   [(set (match_operand:HI 0 "register_operand" "")
1759         (truncate:HI (match_operand:SI 1 "register_operand" "")))]
1760   "")
1762 (define_insn_and_split "*truncsihi2_insn"
1763   [(set (match_operand:HI 0 "register_operand" "=r")
1764         (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
1765   "ok_for_simple_arith_logic_operands (operands, HImode)"
1766   "#"
1767   "reload_completed"
1768   [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1)))
1769               (clobber (reg:CC R_FLAGS))])]
1770   ""
1771   [(set_attr "type" "logic")])
1773 (define_insn "*truncsihi2_insn<subst_logic>"
1774   [(set (match_operand:HI 0 "register_operand" "=r")
1775         (truncate:HI (match_operand:SI 1 "register_operand" "r")))
1776    (clobber (reg:CC R_FLAGS))]
1777   "reload_completed"
1778   "move.w  %0,%1"
1779   [(set_attr "type" "logic")])
1781 (define_expand "truncdisi2"
1782   [(set (match_operand:SI 0 "register_operand" "")
1783         (truncate:SI (match_operand:DI 1 "register_operand" "")))]
1784   "")
1786 (define_insn_and_split "*truncdisi2_insn"
1787   [(set (match_operand:SI 0 "register_operand" "=r")
1788         (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
1789   "ok_for_simple_arith_logic_operands (operands, SImode)"
1790   "#"
1791   "reload_completed"
1792   [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1)))
1793               (clobber (reg:CC R_FLAGS))])]
1794   ""
1795   [(set_attr "type" "logic")])
1797 (define_insn "*truncdisi2_insn<subst_logic>"
1798   [(set (match_operand:SI 0 "register_operand" "=r")
1799         (truncate:SI (match_operand:DI 1 "register_operand" "r")))
1800    (clobber (reg:CC R_FLAGS))]
1801   "reload_completed"
1802   "move.l  %0,%d1"
1803   [(set_attr "type" "logic")])
1806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1808 ;; Sign-extend
1810 ;; Sign-extensions among modes QI, HI, SI and DI are supported directly.
1812 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1815 (define_expand "extendqihi2"
1816   [(set (match_operand:HI 0 "register_operand" "")
1817         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1818   "")
1820 (define_insn_and_split "*extendqihi2_insn"
1821   [(set (match_operand:HI 0 "register_operand" "=r")
1822         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1823   "ok_for_simple_arith_logic_operands (operands, HImode)"
1824   "#"
1825   "reload_completed"
1826   [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
1827               (clobber (reg:CC R_FLAGS))])]
1828   ""
1829   [(set_attr "type" "logic")])
1831 (define_insn "*extendqihi2_insn<subst_logic>"
1832   [(set (match_operand:HI 0 "register_operand" "=r")
1833         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))
1834    (clobber (reg:CC R_FLAGS))]
1835   "reload_completed"
1836   "extb.w  %0,%1"
1837   [(set_attr "type" "logic")])
1839 (define_expand "extendqisi2"
1840   [(set (match_operand:SI 0 "register_operand" "")
1841         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1842   "")
1844 (define_insn_and_split "*extendqisi2_insn"
1845   [(set (match_operand:SI 0 "register_operand" "=r")
1846         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1847   "ok_for_simple_arith_logic_operands (operands, SImode)"
1848   "#"
1849   "reload_completed"
1850   [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
1851               (clobber (reg:CC R_FLAGS))])]
1852   ""
1853   [(set_attr "type" "logic")])
1855 (define_insn "*extendqisi2_insn<subst_logic>"
1856   [(set (match_operand:SI 0 "register_operand" "=r")
1857         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))
1858    (clobber (reg:CC R_FLAGS))]
1859   "reload_completed"
1860   "extb.l  %0,%1"
1861   [(set_attr "type" "logic")])
1863 (define_expand "extendhisi2"
1864   [(set (match_operand:SI 0 "register_operand" "")
1865         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1866   "")
1868 (define_insn_and_split "*extendhisi2_insn"
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1871   "ok_for_simple_arith_logic_operands (operands, SImode)"
1872   "#"
1873   "reload_completed"
1874   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1875                    (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
1876               (clobber (reg:CC R_FLAGS))])]
1877   ""
1878   [(set_attr "type" "logic")])
1880 (define_insn "*extendhisi2_insn<subst_logic>"
1881   [(set (match_operand:SI 0 "register_operand" "=r")
1882         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))
1883    (clobber (reg:CC R_FLAGS))]
1884   "reload_completed"
1885   "extw.l  %0,%1"
1886   [(set_attr "type" "logic")])
1888 (define_expand "extendsidi2"
1889   [(set (match_operand:DI 0 "register_operand" "")
1890         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
1891   "")
1893 (define_insn_and_split "*extendsidi2_insn"
1894   [(set (match_operand:DI 0 "register_operand" "=r")
1895         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1896   "ok_for_simple_arith_logic_operands (operands, DImode)"
1897   "#"
1898   "reload_completed"
1899   [(parallel [(set (match_dup 3) (match_dup 1))
1900               (clobber (reg:CC R_FLAGS))])
1901    (parallel [(set (match_dup 2)
1902                    (ashiftrt:SI (match_dup 1) (const_int 31)))
1903               (clobber (reg:CC R_FLAGS))])]
1905   operands[2] = operand_subword (operands[0], 0, 0, DImode);
1906   operands[3] = operand_subword (operands[0], 1, 0, DImode);
1908   [(set_attr "type" "multi")])
1911 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1913 ;; Zero-extend
1915 ;; Zero-extensions among modes QI, HI, SI and DI are supported directly.
1917 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1920 ; QI is zero-extended to wider modes by shifting left and then performing
1921 ; a logical shift right to insert the zeroes. This avoids the need to use
1922 ; another register.
1924 (define_expand "zero_extendqihi2"
1925   [(set (match_operand:HI 0 "register_operand" "")
1926         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1927   "")
1929 (define_insn_and_split "*zero_extendqihi2_insn"
1930   [(set (match_operand:HI 0 "register_operand" "=r")
1931         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1932   "ok_for_simple_arith_logic_operands (operands, HImode)"
1933   "#"
1934   "reload_completed"
1935   [(parallel [(set (match_dup 0)
1936                    (ashift:HI (match_dup 2) (const_int 8)))
1937               (clobber (reg:CC R_FLAGS))])
1938    (parallel [(set (match_dup 0)
1939                    (lshiftrt:HI (match_dup 0) (const_int 8)))
1940               (clobber (reg:CC R_FLAGS))])]
1942   operands[2] = gen_rtx_SUBREG (HImode, operands[1], 0);
1944   [(set_attr "type" "multi")])
1946 (define_expand "zero_extendqisi2"
1947   [(set (match_operand:SI 0 "register_operand" "")
1948         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1949   "")
1951 (define_insn_and_split "*zero_extendqisi2_insn"
1952   [(set (match_operand:SI 0 "register_operand" "=r")
1953         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1954   "ok_for_simple_arith_logic_operands (operands, SImode)"
1955   "#"
1956   "reload_completed"
1957   [(parallel [(set (match_dup 0)
1958                    (ashift:SI (match_dup 2) (const_int 24)))
1959               (clobber (reg:CC R_FLAGS))])
1960    (parallel [(set (match_dup 0)
1961                    (lshiftrt:SI (match_dup 0) (const_int 24)))
1962               (clobber (reg:CC R_FLAGS))])]
1964   operands[2] = gen_rtx_SUBREG (SImode, operands[1], 0);
1966   [(set_attr "type" "multi")])
1968 (define_insn "zero_extendhisi2"
1969   [(set (match_operand:SI 0 "register_operand" "=r")
1970         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1971   ""
1972   "moviu   %0,0"
1973   [(set_attr "type" "imm_reg")])
1975 (define_expand "zero_extendsidi2"
1976   [(set (match_operand:DI 0 "register_operand" "")
1977         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
1978   "")
1980 (define_insn_and_split "*zero_extendsidi2_insn"
1981   [(set (match_operand:DI 0 "register_operand" "=r")
1982         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1983   "ok_for_simple_arith_logic_operands (operands, DImode)"
1984   "#"
1985   "reload_completed"
1986   [(parallel [(set (match_dup 3) (match_dup 1))
1987               (clobber (reg:CC R_FLAGS))])
1988    (set (match_dup 2) (const_int 0))]
1990   operands[2] = operand_subword (operands[0], 0, 0, DImode);
1991   operands[3] = operand_subword (operands[0], 1, 0, DImode);
1993   [(set_attr "type" "multi")])
1996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1998 ;; Bit Test
2000 ;; Only SI mode is supported directly.
2002 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2005 ; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB.
2007 (define_insn "*btst<mode>"
2008   [(set (reg:CCC R_FLAGS)
2009         (compare:CCC (zero_extract:I
2010                        (match_operand:I 0 "register_operand" "r")
2011                        (const_int 1)
2012                        (match_operand:QI 1 "const_shift_operand" "K"))
2013                      (const_int 0)))]
2014   "reload_completed"
2015   "lsr<s>   r0,%0,<b>-%1"
2016   [(set_attr "type" "logic")])
2019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2021 ;; Integer overflow tests
2023 ;; Modes QI, HI and SI are supported directly.
2025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2028 (define_insn "*addv_tst<mode>"
2029   [(set (reg:CCV R_FLAGS)
2030         (compare:CCV (match_operand:I 0 "register_operand" "r")
2031                      (unspec:I [(match_operand:I 1 "register_operand" "%r")
2032                                 (match_operand:I 2 "register_operand" "r")]
2033                                UNSPEC_ADDV)))]
2034   "reload_completed"
2035   "add<s>   r0,%1,%2"
2036   [(set_attr "type" "arith")])
2038 (define_insn "*subv_tst<mode>"
2039   [(set (reg:CCV R_FLAGS)
2040         (compare:CCV (match_operand:I 0 "register_operand" "r")
2041                      (unspec:I [(match_operand:I 1 "reg_or_0_operand" "rO")
2042                                 (match_operand:I 2 "register_operand" "r")]
2043                                UNSPEC_SUBV)))]
2044   "reload_completed"
2045   "sub<s>   r0,%r1,%2"
2046   [(set_attr "type" "arith")])
2048 (define_insn "*negv_tst<mode>"
2049   [(set (reg:CCV R_FLAGS)
2050         (compare:CCV (match_operand:I 0 "register_operand" "r")
2051                      (unspec:I [(match_operand:I 1 "register_operand" "r")]
2052                                UNSPEC_NEGV)))]
2053   "reload_completed"
2054   "sub<s>   r0,r0,%1"
2055   [(set_attr "type" "arith")])
2058 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2060 ;; Integer comparisons
2062 ;; Modes QI, HI and SI are supported directly.
2064 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2067 (define_insn "*cmp<mode>"
2068   [(set (reg:CC R_FLAGS)
2069         (compare:CC (match_operand:I 0 "register_operand" "r")
2070                     (match_operand:I 1 "reg_or_0_operand" "rO")))]
2071   "reload_completed"
2072   "cmp<s>   %0,%r1"
2073   [(set_attr "type" "cmp")])
2075 (define_insn "*cmp<mode>_sne"
2076   [(set (reg:CCC R_FLAGS)
2077         (compare:CCC (not:I (match_operand:I 0 "register_operand" "r"))
2078                      (const_int -1)))]
2079   "reload_completed"
2080   "cmp<s>   r0,%0"
2081   [(set_attr "type" "cmp")])
2084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2086 ;; Single float operations
2088 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2091 (define_insn "addsf3"
2092   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2093         (plus:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2094                  (match_operand:SF 2 "fp_reg_operand" "f")))]
2095   "TARGET_FPU"
2096   "fadd    %0,%1,%2"
2097   [(set_attr "type" "fp")])
2099 (define_insn "subsf3"
2100   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2101         (minus:SF (match_operand:SF 1 "fp_reg_operand" "f")
2102                   (match_operand:SF 2 "fp_reg_operand" "f")))]
2103   "TARGET_FPU"
2104   "fsub    %0,%1,%2"
2105   [(set_attr "type" "fp")])
2107 (define_insn "mulsf3"
2108   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2109         (mult:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2110                  (match_operand:SF 2 "fp_reg_operand" "f")))]
2111   "TARGET_FPU"
2112   "fmult   %0,%1,%2"
2113   [(set_attr "type" "fp")])
2115 (define_insn "divsf3"
2116   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2117         (div:SF (match_operand:SF 1 "fp_reg_operand" "f")
2118                 (match_operand:SF 2 "fp_reg_operand" "f")))]
2119   "TARGET_FPU"
2120   "fdiv    %0,%1,%2"
2121   [(set_attr "type" "fdiv")])
2123 (define_insn "sqrtsf2"
2124   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2125         (sqrt:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2126   "TARGET_FPU"
2127   "fsqrt   %0,%1"
2128   [(set_attr "type" "fsqrt")])
2130 (define_insn "negsf2"
2131   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2132         (neg:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2133   "TARGET_FPU"
2134   "fneg    %0,%1"
2135   [(set_attr "type" "fmove")])
2137 (define_insn "abssf2"
2138   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2139         (abs:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2140   "TARGET_FPU"
2141   "fabs    %0,%1"
2142   [(set_attr "type" "fmove")])
2144 (define_expand "copysignsf3"
2145   [(match_operand:SF 0 "register_operand" "")
2146    (match_operand:SF 1 "nonmemory_operand" "")
2147    (match_operand:SF 2 "register_operand" "")]
2148   "TARGET_FPU && !TARGET_FPU_IEEE"
2150   visium_expand_copysign (operands, SFmode);
2151   DONE;
2155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2157 ;; Single float <-> single integer conversions for !TARGET_FPU_IEEE
2159 ;; An FMOVE instruction converts a signalling NaN (zero high order bit of the
2160 ;; mantissa) to a quiet NaN (-1). This is acceptable when the data to be
2161 ;; moved is in fact a floating-point number, but to avoid nasty surprises
2162 ;; integers must in general be kept out of the floating-point registers.
2163 ;; TARGET_HARD_REGNO_MODE_OK thus only allows SFmode in these registers.
2164 ;; However, since FTOI and ITOF use floating-point registers for both their
2165 ;; inputs and outputs, to use these instructions integers must transiently
2166 ;; occupy such registers. To disguise this from the compiler, UNSPECs are
2167 ;; used for floating-point operations on integers and floating from general
2168 ;; register to floating-point register and fixing in the reverse direction
2169 ;; are only split into the individual UNSPEC operations after reload.
2171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2174 (define_insn "*fload_no_ieee"
2175   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2176         (unspec:SF [(match_operand:SI 1 "register_operand" "r")] UNSPEC_FLOAD))]
2177   "TARGET_FPU && !TARGET_FPU_IEEE"
2178   "fload   %0,%1"
2179   [(set_attr "type" "reg_fp")])
2181 (define_insn "*itof_no_ieee"
2182   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2183         (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_ITOF))]
2184   "TARGET_FPU && !TARGET_FPU_IEEE"
2185   "itof    %0,%1"
2186   [(set_attr "type" "itof")])
2188 (define_insn_and_split "*floatsisf2_no_ieee"
2189   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2190         (float:SF (match_operand:SI 1 "register_operand" "r")))]
2191   "TARGET_FPU && !TARGET_FPU_IEEE"
2192   "#"
2193   "&& reload_completed"
2194   [(set (match_dup 0)
2195         (unspec:SF [(match_dup 1)] UNSPEC_FLOAD))
2196    (set (match_dup 0)
2197         (unspec:SF [(match_dup 0)] UNSPEC_ITOF))]
2198   ""
2199   [(set_attr "type" "multi")])
2201 (define_insn "*ftoi_no_ieee"
2202   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2203         (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FTOI))]
2204   "TARGET_FPU && !TARGET_FPU_IEEE"
2205   "ftoi    %0,%1"
2206   [(set_attr "type" "ftoi")])
2208 (define_insn "*fstore_no_ieee"
2209   [(set (match_operand:SI 0 "register_operand" "=r")
2210         (unspec:SI [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FSTORE))]
2211   "TARGET_FPU && !TARGET_FPU_IEEE"
2212   "fstore  %0,%1"
2213   [(set_attr "type" "fp_reg")])
2215 (define_insn_and_split "fix_truncsfsi2_no_ieee"
2216   [(set (match_operand:SI 0 "register_operand" "=r")
2217         (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))
2218    (clobber (match_scratch:SF 2 "=1"))]
2219   "TARGET_FPU && !TARGET_FPU_IEEE"
2220   "#"
2221   "&& reload_completed"
2222   [(set (match_dup 1)
2223         (unspec:SF [(match_dup 1)] UNSPEC_FTOI))
2224    (set (match_dup 0)
2225         (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))]
2226   ""
2227   [(set_attr "type" "multi")])
2230 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2232 ;; Single float <-> single integer conversions
2234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2237 (define_insn "*itof"
2238   [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2239         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2240   "TARGET_FPU_IEEE"
2241   "itof    %0,%1"
2242   [(set_attr "type" "itof")])
2244 (define_expand "floatsisf2"
2245   [(set (match_operand:SF 0 "fp_reg_operand" "")
2246         (float:SF (match_operand:SI 1 "register_operand" "")))]
2247   "TARGET_FPU"
2248   "")
2250 (define_insn "*ftoi"
2251   [(set (match_operand:SI 0 "register_operand" "=f")
2252         (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))]
2253   "TARGET_FPU_IEEE"
2254   "ftoi    %0,%1"
2255   [(set_attr "type" "ftoi")])
2257 (define_expand "fix_truncsfsi2"
2258   [(set (match_operand:SI 0 "register_operand" "")
2259         (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" ""))))]
2260   "TARGET_FPU"
2262   if (!TARGET_FPU_IEEE)
2263     {
2264       emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1]));
2265       DONE;
2266     }
2270 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2272 ;; Single float comparisons
2274 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2277 (define_insn "*cmpsf_fp"
2278   [(set (reg:CCFP R_FLAGS)
2279         (compare:CCFP (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2280                       (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2281   "TARGET_FPU && reload_completed"
2282   "fcmp    r0,%f0,%f1"
2283   [(set_attr "type" "fcmp")])
2285 (define_insn "*cmpsf_fpe"
2286   [(set (reg:CCFPE R_FLAGS)
2287         (compare:CCFPE (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2288                        (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2289   "TARGET_FPU && reload_completed"
2290   "fcmpe   r0,%f0,%f1"
2291   [(set_attr "type" "fcmp")])
2294 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2296 ;; Conditional branch instructions
2298 ;; Note - we do not specify the two instructions necessary to perform
2299 ;; a compare-and-branch in the cbranch<mode>4 pattern because that would
2300 ;; allow the comparison to be moved away from the jump before the reload
2301 ;; pass has completed.  That would be problematical because reload can
2302 ;; generate instructions in between which would clobber the CC register.
2304 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2307 (define_expand "cbranch<mode>4"
2308   [(set (pc)
2309         (if_then_else (match_operator 0 "ordered_comparison_operator"
2310                        [(match_operand:I 1 "register_operand")
2311                         (match_operand:I 2 "reg_or_0_operand")])
2312                       (label_ref (match_operand 3 ""))
2313                       (pc)))]
2314   ""
2317 (define_insn_and_split "*cbranch<mode>4_insn"
2318   [(set (pc)
2319         (if_then_else (match_operator 0 "ordered_comparison_operator"
2320                        [(match_operand:I 1 "register_operand" "r")
2321                         (match_operand:I 2 "reg_or_0_operand" "rO")])
2322                       (label_ref (match_operand 3 ""))
2323                       (pc)))]
2324   ""
2325   "#"
2326   "reload_completed"
2327   [(const_int 0)]
2329   visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2330                         operands[3]);
2331   DONE;
2333   [(set_attr "type" "cmp")])
2335 (define_insn_and_split "*cbranch<mode>4_addv_insn"
2336   [(set (pc)
2337         (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2338                        [(match_operand:I 1 "register_operand" "r")
2339                         (unspec:I [(match_operand:I 2 "register_operand" "%r")
2340                                    (match_operand:I 3 "register_operand" "r")]
2341                                   UNSPEC_ADDV)])
2342                       (label_ref (match_operand 4 ""))
2343                       (pc)))]
2344   ""
2345   "#"
2346   "reload_completed"
2347   [(const_int 0)]
2349   visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2350                         XEXP (operands[0], 1), operands[4]);
2351   DONE;
2353   [(set_attr "type" "cmp")])
2355 (define_insn_and_split "*cbranch<mode>4_subv_insn"
2356   [(set (pc)
2357         (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2358                        [(match_operand:I 1 "register_operand" "r")
2359                         (unspec:I [(match_operand:I 2 "reg_or_0_operand" "rO")
2360                                    (match_operand:I 3 "register_operand" "r")]
2361                                   UNSPEC_SUBV)])
2362                       (label_ref (match_operand 4 ""))
2363                       (pc)))]
2364   ""
2365   "#"
2366   "reload_completed"
2367   [(const_int 0)]
2369   visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2370                         XEXP (operands[0], 1), operands[4]);
2371   DONE;
2373   [(set_attr "type" "cmp")])
2375 (define_insn_and_split "*cbranch<mode>4_negv_insn"
2376   [(set (pc)
2377         (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2378                        [(match_operand:I 1 "register_operand" "r")
2379                         (unspec:I [(match_operand:I 2 "register_operand" "r")]
2380                                   UNSPEC_NEGV)])
2381                       (label_ref (match_operand 3 ""))
2382                       (pc)))]
2383   ""
2384   "#"
2385   "reload_completed"
2386   [(const_int 0)]
2388   visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2389                         XEXP (operands[0], 1), operands[3]);
2390   DONE;
2392   [(set_attr "type" "cmp")])
2394 (define_insn_and_split "*cbranch<mode>4_btst_insn"
2395   [(set (pc)
2396         (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2397                        [(zero_extract:I
2398                            (match_operand:I 1 "register_operand" "r")
2399                            (const_int 1)
2400                            (match_operand:QI 2 "const_shift_operand" "K"))
2401                         (const_int 0)])
2402                       (label_ref (match_operand 3 ""))
2403                       (pc)))]
2404   ""
2405   "#"
2406   "reload_completed"
2407   [(const_int 0)]
2409   visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2410                         XEXP (operands[0], 1), operands[3]);
2411   DONE;
2413   [(set_attr "type" "cmp")])
2415 (define_expand "cbranchsf4"
2416   [(set (pc)
2417         (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2418                        [(match_operand:SF 1 "fp_reg_operand")
2419                         (match_operand:SF 2 "fp_reg_or_0_operand")])
2420                       (label_ref (match_operand 3 ""))
2421                       (pc)))]
2422   "TARGET_FPU"
2425 (define_insn_and_split "*cbranchsf4_insn"
2426   [(set (pc)
2427         (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2428                        [(match_operand:SF 1 "fp_reg_operand" "f")
2429                         (match_operand:SF 2 "fp_reg_or_0_operand" "fG")])
2430                       (label_ref (match_operand 3 ""))
2431                       (pc)))]
2432   "TARGET_FPU"
2433   "#"
2434   "&& reload_completed"
2435   [(const_int 0)]
2437   visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2438                         operands[3]);
2439   DONE;
2441   [(set_attr "type" "fcmp")])
2443 ; Now match both normal and inverted branches.
2445 (define_insn "*normal_branch"
2446   [(set (pc)
2447         (if_then_else (match_operator 1 "visium_branch_operator"
2448                        [(reg R_FLAGS) (const_int 0)])
2449                       (label_ref (match_operand 0 ""))
2450                       (pc)))]
2451   "reload_completed"
2453   return output_cbranch (operands[0], GET_CODE (operands[1]),
2454                          GET_MODE (XEXP (operands[1], 0)), 0, insn);
2456   [(set_attr "type" "branch")])
2458 (define_insn "*inverted_branch"
2459   [(set (pc)
2460         (if_then_else (match_operator 1 "visium_branch_operator"
2461                        [(reg R_FLAGS) (const_int 0)])
2462                       (pc)
2463                       (label_ref (match_operand 0 ""))))]
2464   "reload_completed"
2466   return output_cbranch (operands[0], GET_CODE (operands[1]),
2467                          GET_MODE (XEXP (operands[1], 0)), 1, insn);
2469   [(set_attr "type" "branch")])
2471 ; And then match both normal and inverted returns.
2473 (define_insn "*cond_<return_str>return"
2474   [(set (pc)
2475         (if_then_else (match_operator 0 "visium_branch_operator"
2476                        [(reg R_FLAGS) (const_int 0)])
2477                       (any_return)
2478                       (pc)))]
2479   "<return_pred> && reload_completed"
2481   return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2482                          GET_MODE (XEXP (operands[0], 0)), 0, insn);
2484   [(set_attr "type" "ret")])
2486 (define_insn "*inverted_cond_<return_str>return"
2487   [(set (pc)
2488         (if_then_else (match_operator 0 "visium_branch_operator"
2489                        [(reg R_FLAGS) (const_int 0)])
2490                       (pc)
2491                       (any_return)))]
2492   "<return_pred> && reload_completed"
2494   return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2495                          GET_MODE (XEXP (operands[0], 0)), 1, insn);
2497   [(set_attr "type" "ret")])
2500 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2502 ;; Unconditional branch instructions
2504 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2507 (define_insn "jump"
2508   [(set (pc)
2509         (label_ref (match_operand 0 "" "")))]
2510   ""
2512   return output_ubranch (operands[0], insn);
2514   [(set_attr "type" "branch")])
2516 (define_insn "indirect_jump"
2517   [(set (pc)
2518         (match_operand:SI 0 "register_operand" "r"))]
2519   ""
2520   "bra     tr,%0,r0%#           ;indirect jump"
2521   [(set_attr "type" "abs_branch")])
2523 (define_insn "tablejump"
2524   [(set (pc)
2525         (match_operand:SI 0 "register_operand" "r"))
2526    (use (label_ref (match_operand 1 "" "")))]
2527   ""
2528   "bra     tr,%0,r0%#           ;tablejump"
2529   [(set_attr "type" "abs_branch")])
2532 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2534 ;; trap instructions
2536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2539 (define_insn "trap"
2540   [(trap_if (const_int 1) (const_int 0))]
2541   ""
2542   "stop    0,r0"
2543   [(set_attr "type" "trap")])
2546 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2548 ;; Subprogram call instructions
2550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2553 ; Subroutine call instruction returning no value.  Operand 0 is the function
2554 ; to call; operand 1 is the number of bytes of arguments pushed (in mode
2555 ; 'SImode', except it is normally a 'const_int'); operand 2 is the number of
2556 ; registers used as operands.
2558 (define_expand "call"
2559   [(parallel [(call (match_operand 0 "" "")
2560                     (match_operand 1 "" ""))
2561               (use (match_operand 2 "" ""))
2562               (clobber (match_dup 3))])]
2563   ""
2565   if (GET_CODE (XEXP (operands[0], 0)) != REG)
2566     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2568   if (!operands[2])
2569     operands[2] =  const0_rtx;
2571   operands[3] = gen_rtx_REG (Pmode, R_LINK);
2574 (define_insn "*call_internal"
2575   [(call (mem:SI (match_operand:SI 0 "register_operand" "l,!r"))
2576          (match_operand 1 "" ""))
2577    (use (match_operand 2 "" ""))
2578    (clobber (match_operand 3 "" ""))]
2579   "!SIBLING_CALL_P (insn)"
2580   "bra     tr,%0,%3%#           ;call"
2581   [(set_attr "type" "call")])
2583 ; Subroutine call instruction returning a value.  Operand 0 is the hard
2584 ; register in which the value is returned.  There are three more operands, the
2585 ; same as the three operands of the 'call' instruction (but with numbers
2586 ; increased by one).
2588 (define_expand "call_value"
2589   [(parallel [(set (match_operand 0 "register_operand" "")
2590                    (call (match_operand 1 "" "")
2591                          (match_operand 2 "" "")))
2592               (use (match_operand 3 "" ""))
2593               (clobber (match_dup 4))])]
2594   ""
2596   if (GET_CODE (XEXP (operands[1], 0)) != REG)
2597     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2599   if (!operands[3])
2600     operands[3] = const0_rtx;
2602   operands[4] = gen_rtx_REG (Pmode, R_LINK);
2605 (define_insn "*call_value_internal"
2606   [(set (match_operand 0 "register_operand" "")
2607         (call (mem:SI (match_operand:SI 1 "register_operand" "l,!r"))
2608               (match_operand 2 "" "")))
2609         (use (match_operand 3 "" ""))
2610         (clobber (match_operand 4 "" ""))]
2611   "!SIBLING_CALL_P (insn)"
2612   "bra     tr,%1,%4%#           ;call value"
2613   [(set_attr "type" "call")])
2615 ; Tail calls are similar, except that the link register is not used.  But
2616 ; we don't use r0 as the destination register of the branch because we want
2617 ; the Branch Pre-decode Logic of the GR6 to use the Address Load Array to
2618 ; predict the branch target.
2620 (define_expand "sibcall"
2621   [(parallel [(call (match_operand 0 "" "")
2622                     (match_operand 1 "" ""))
2623               (use (match_operand 2 "" ""))
2624               (clobber (match_dup 3))])]
2625   ""
2627   if (GET_CODE (XEXP (operands[0], 0)) != REG)
2628     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2630   if (!operands[2])
2631     operands[2] = const0_rtx;
2633   operands[3] = gen_rtx_SCRATCH (SImode);
2636 (define_insn "*sibcall_internal"
2637   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
2638          (match_operand 1 "" ""))
2639    (use (match_operand 2 "" ""))
2640    (clobber (match_scratch:SI 3 "=0"))]
2641   "SIBLING_CALL_P (insn)"
2642   "bra     tr,%0,%0%#           ;sibcall"
2643   [(set_attr "type" "call")])
2645 (define_expand "sibcall_value"
2646   [(parallel [(set (match_operand 0 "register_operand" "")
2647                    (call (match_operand 1 "" "")
2648                          (match_operand 2 "" "")))
2649               (use (match_operand 3 "" ""))
2650               (clobber (match_dup 4))])]
2651   ""
2653   if (GET_CODE (XEXP (operands[1], 0)) != REG)
2654     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2656   if (!operands[3])
2657     operands[3] = const0_rtx;
2659   operands[4] = gen_rtx_SCRATCH (SImode);
2662 (define_insn "*sibcall_value_internal"
2663   [(set (match_operand 0 "register_operand" "")
2664         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
2665               (match_operand 2 "" "")))
2666    (use (match_operand 3 "" ""))
2667    (clobber (match_scratch:SI 4 "=1"))]
2668   "SIBLING_CALL_P (insn)"
2669   "bra     tr,%1,%1%#           ;sibcall value"
2670   [(set_attr "type" "call")])
2672 ; Call subroutine returning any type.
2673 (define_expand "untyped_call"
2674   [(parallel [(call (match_operand 0 "" "")
2675                     (const_int 0))
2676               (match_operand 1 "" "")
2677               (match_operand 2 "" "")])]
2678   ""
2680   int i;
2682   emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
2684   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2685     {
2686       rtx set = XVECEXP (operands[2], 0, i);
2687       emit_move_insn (SET_DEST (set), SET_SRC (set));
2688     }
2690   /* The optimizer does not know that the call sets the function value
2691      registers we stored in the result block.  We avoid problems by
2692      claiming that all hard registers are used and clobbered at this
2693      point.  */
2694   emit_insn (gen_blockage ());
2696   DONE;
2700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2702 ;; Compare-and-store instructions
2704 ;; Modes QI, HI, SI and SF are supported directly.
2706 ;; Note - we do not specify the two instructions necessary to perform
2707 ;; a compare-and-store in the cstore<mode>4 pattern because that would
2708 ;; allow the comparison to be moved away from the store before the reload
2709 ;; pass has completed.  That would be problematical because reload can
2710 ;; generate instructions in between which would clobber the CC register.
2712 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2715 (define_expand "cstore<mode>4"
2716   [(set (match_operand:SI 0)
2717         (match_operator:SI 1 "visium_int_cstore_operator"
2718          [(match_operand:I 2 "register_operand")
2719           (match_operand:I 3 "reg_or_0_operand")]))]
2720   ""
2722   visium_expand_int_cstore (operands, <MODE>mode);
2723   DONE;
2726 (define_insn_and_split "*cstore<mode>4_insn"
2727   [(set (match_operand:SI 0 "register_operand" "=r")
2728         (ltu:SI (match_operand:I 1 "register_operand" "r")
2729                 (match_operand:I 2 "reg_or_0_operand" "rO")))]
2730   ""
2731   "#"
2732   "reload_completed"
2733   [(const_int 0)]
2735   visium_split_cstore (SET, operands[0], NULL_RTX,
2736                        LTU, operands[1], operands[2]);
2737   DONE;
2739   [(set_attr "type" "cmp")])
2741 (define_insn_and_split "*neg_cstore<mode>4_insn"
2742   [(set (match_operand:SI 0 "register_operand" "=r")
2743         (neg:SI (ltu:SI (match_operand:I 1 "register_operand" "r")
2744                         (match_operand:I 2 "reg_or_0_operand" "rO"))))]
2745   ""
2746   "#"
2747   "reload_completed"
2748   [(const_int 0)]
2750   visium_split_cstore (NEG, operands[0], NULL_RTX,
2751                        LTU, operands[1], operands[2]);
2752   DONE;
2754   [(set_attr "type" "cmp")])
2756 (define_insn_and_split "*<add_str>_cstore<mode>4_insn"
2757   [(set (match_operand:SI 0 "register_operand" "=r")
2758         (any_add:SI (match_operand:SI 1 "register_operand" "r")
2759                     (ltu:SI (match_operand:I 2 "register_operand" "r")
2760                             (match_operand:I 3 "reg_or_0_operand" "rO"))))]
2761   ""
2762   "#"
2763   "reload_completed"
2764   [(const_int 0)]
2766   visium_split_cstore (<add_op>, operands[0], operands[1],
2767                        LTU, operands[2], operands[3]);
2768   DONE;
2770   [(set_attr "type" "cmp")])
2772 (define_insn_and_split "*cstore<mode>4_sne_insn"
2773   [(set (match_operand:SI 0 "register_operand" "=r")
2774         (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2775                 (const_int -1)))]
2776   ""
2777   "#"
2778   "reload_completed"
2779   [(const_int 0)]
2781   visium_split_cstore (SET, operands[0], NULL_RTX,
2782                        LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2783   DONE;
2785   [(set_attr "type" "cmp")])
2787 (define_insn_and_split "*neg_cstore<mode>4_sne_insn"
2788   [(set (match_operand:SI 0 "register_operand" "=r")
2789         (neg:SI (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2790                         (const_int -1))))]
2791   ""
2792   "#"
2793   "reload_completed"
2794   [(const_int 0)]
2796   visium_split_cstore (NEG, operands[0], NULL_RTX,
2797                        LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2798   DONE;
2800   [(set_attr "type" "cmp")])
2802 (define_insn_and_split "*<add_str>_cstore<mode>4_sne_insn"
2803   [(set (match_operand:SI 0 "register_operand" "=r")
2804         (any_add:SI (match_operand:SI 1 "register_operand" "r")
2805                     (ltu:SI (not:I (match_operand:I 2 "register_operand" "r"))
2806                             (const_int -1))))]
2807   ""
2808   "#"
2809   "reload_completed"
2810   [(const_int 0)]
2812   visium_split_cstore (<add_op>, operands[0], operands[1],
2813                        LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx);
2814   DONE;
2816   [(set_attr "type" "cmp")])
2818 (define_expand "cstoresf4"
2819   [(set (match_operand:SI 0)
2820         (match_operator:SI 1 "visium_fp_cstore_operator"
2821          [(match_operand:SF 2 "fp_reg_operand")
2822           (match_operand:SF 3 "fp_reg_or_0_operand")]))]
2823   "TARGET_FPU"
2825   visium_expand_fp_cstore (operands, SFmode);
2826   DONE;
2829 (define_insn_and_split "*cstoresf4_insn"
2830   [(set (match_operand:SI 0 "register_operand" "=r")
2831         (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2832                (match_operand:SF 2 "fp_reg_or_0_operand" "fG")))]
2833   "TARGET_FPU"
2834   "#"
2835   "&& reload_completed"
2836   [(const_int 0)]
2838   visium_split_cstore (SET, operands [0], NULL_RTX,
2839                        LT, operands[1], operands[2]);
2840   DONE;
2842   [(set_attr "type" "fcmp")])
2844 (define_insn_and_split "*neg_cstoresf4_insn"
2845   [(set (match_operand:SI 0 "register_operand" "=r")
2846         (neg:SI (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2847                        (match_operand:SF 2 "fp_reg_or_0_operand" "fG"))))]
2848   "TARGET_FPU"
2849   "#"
2850   "&& reload_completed"
2851   [(const_int 0)]
2853   visium_split_cstore (NEG, operands [0], NULL_RTX,
2854                        LT, operands[1], operands[2]);
2855   DONE;
2857   [(set_attr "type" "fcmp")])
2859 (define_insn_and_split "*<add_str>_cstoresf4_insn"
2860   [(set (match_operand:SI 0 "register_operand" "=r")
2861         (any_add:SI (match_operand:SI 1 "register_operand" "r")
2862                     (lt:SI (match_operand:SF 2 "fp_reg_or_0_operand" "fG")
2863                            (match_operand:SF 3 "fp_reg_or_0_operand" "fG"))))]
2864   "TARGET_FPU"
2865   "#"
2866   "&& reload_completed"
2867   [(const_int 0)]
2869   visium_split_cstore (<add_op>, operands [0], operands[1],
2870                        LT, operands[2], operands[3]);
2871   DONE;
2873   [(set_attr "type" "fcmp")])
2876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2878 ;; RTL pro/epilogue support
2880 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2883 ; Expand prologue in RTL
2884 (define_expand "prologue"
2885   [(const_int 0)]
2886   ""
2888   visium_expand_prologue ();
2889   DONE;
2892 ; Expand epilogue in RTL
2893 (define_expand "epilogue"
2894   [(return)]
2895   ""
2897   visium_expand_epilogue ();
2900 ; Expand epilogue without a final jump in RTL
2901 (define_expand "sibcall_epilogue"
2902   [(return)]
2903   ""
2905   visium_expand_epilogue ();
2906   DONE;
2909 ; The artificial dependency on the link register is to prevent the
2910 ; frame instruction from being put in a call delay slot, which can
2911 ; confuse the CFI machinery.
2913 (define_insn "stack_save"
2914   [(set (reg:SI R_FP) (reg:SI R_SP))
2915    (use (reg:SI R_LINK))
2916    (clobber (reg:CC R_FLAGS))]
2917   "reload_completed"
2918   "move.l  fp,sp                ;stack_save"
2919   [(set_attr "type" "logic")])
2921 ; The construct (mem:BLK (scratch)) is considered to alias all other
2922 ; memory accesses.  Thus it can be used as a memory barrier in stack
2923 ; deallocation patterns.
2925 (define_insn "stack_restore"
2926   [(set (reg:SI R_SP) (reg:SI R_FP))
2927    (clobber (mem:BLK (scratch)))
2928    (clobber (reg:CC R_FLAGS))]
2929   "reload_completed"
2930   "move.l  sp,fp                ;stack_restore"
2931   [(set_attr "type" "logic")])
2933 (define_insn "stack_pop"
2934   [(set (reg:SI R_SP)
2935         (plus:SI (reg:SI R_SP) (match_operand:SI 0 "add_operand" "J,r")))
2936    (clobber (mem:BLK (scratch)))
2937    (clobber (reg:CC R_FLAGS))]
2938   "reload_completed"
2939   "@
2940     addi    sp,%0               ;stack pop
2941     add.l   sp,sp,%0            ;stack pop"
2942   [(set_attr "type" "arith")])
2944 (define_expand "<return_str>return"
2945   [(any_return)]
2946   "<return_pred>"
2947   "")
2949 (define_insn "*<return_str>return_internal"
2950   [(any_return)]
2951   "!visium_interrupt_function_p ()"
2953   return output_ubranch (pc_rtx, insn);
2955   [(set_attr "type" "ret")])
2957 (define_insn "*return_internal_interrupt"
2958   [(return)]
2959   "visium_interrupt_function_p ()"
2960   "rfi\n\t nop                          ;return from interrupt"
2961   [(set_attr "type" "rfi")])
2963 (define_insn "dsi"
2964   [(unspec_volatile [(const_int 0)] UNSPECV_DSI)]
2965   ""
2966   "dsi"
2967   [(set_attr "type" "dsi")])
2970 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2972 ;; NOP (no-op instruction)
2974 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2977 (define_insn "nop"
2978   [(const_int 0)]
2979   ""
2980   "nop                  ;generated"
2981   [(set_attr "type" "nop")])
2983 (define_insn "hazard_nop"
2984   [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
2985   ""
2986   "nop                  ;hazard avoidance"
2987   [(set_attr "type" "nop")])
2989 (define_insn "blockage"
2990   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2991   ""
2992   ""
2993   [(set_attr "type" "nop")])
2996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2998 ;; String/block operations
3000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3003 ;; String/block move insn.
3004 ;; Argument 0 is the destination
3005 ;; Argument 1 is the source
3006 ;; Argument 2 is the length
3007 ;; Argument 3 is the alignment
3009 (define_expand "cpymemsi"
3010   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3011                    (match_operand:BLK 1 "memory_operand" ""))
3012               (use (match_operand:SI  2 "general_operand" ""))
3013               (use (match_operand:SI  3 "const_int_operand" ""))])]
3014   ""
3016   if (visium_expand_block_move (operands))
3017     DONE;
3018   else
3019     FAIL;
3022 (define_insn "*bmd"
3023   [(set (mem:BLK (reg:SI R_R1))
3024         (mem:BLK (reg:SI R_R2)))
3025    (use (reg:SI R_R3))
3026    (clobber (reg:SI R_R1))
3027    (clobber (reg:SI R_R2))
3028    (clobber (reg:SI R_R3))
3029    (clobber (reg:SI R_R4))
3030    (clobber (reg:SI R_R5))
3031    (clobber (reg:SI R_R6))]
3032   "TARGET_BMI"
3033   "bmd     r1,r2,r3"
3034   [(set_attr "type" "bmi")])
3036 ;; String/block set insn.
3037 ;; Argument 0 is the destination
3038 ;; Argument 1 is the length
3039 ;; Argument 2 is the value
3040 ;; Argument 3 is the alignment
3042 (define_expand "setmemsi"
3043   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3044                    (match_operand 2 "nonmemory_operand" ""))
3045               (use (match_operand:SI  1 "general_operand" ""))
3046               (use (match_operand:SI  3 "const_int_operand" ""))])]
3047   ""
3049   if (visium_expand_block_set (operands))
3050     DONE;
3051   else
3052     FAIL;