1 ;; Machine description for Visium.
2 ;; Copyright (C) 2002-2024 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
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)
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
77 (define_c_enum "unspec" [
89 ;; UNSPEC_VOLATILE usage.
90 (define_c_enum "unspecv" [
95 (include "predicates.md")
96 (include "constraints.md")
99 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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")))
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.
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.
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.
142 ;multi Multiple instructions which split.
143 ;asm User asm instructions.
144 ;trap Trap instructions.
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")
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)"))
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))
175 (if_then_else (and (eq_attr "cpu" "gr6")
176 (eq (mod (pc) (const_int 8))
180 (eq_attr "type" "branch")
181 (if_then_else (leu (plus (minus (match_dup 0) (pc))
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (if_then_else (and (eq_attr "cpu" "gr6")
188 (eq (mod (pc) (const_int 8))
192 (eq_attr "single_insn" "no")
193 (const_int 8)] (const_int 4)))
195 (define_asm_attributes [(set_attr "type" "asm")])
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"))
204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
206 ;; Processor pipeline description.
208 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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))]
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))]
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" ""))]
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)"
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
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))]
328 [(set_attr "type" "logic")])
331 [(set (match_operand:QI 0 "gpc_reg_operand" "")
332 (match_operand:QI 1 "gpc_reg_operand" ""))]
334 [(parallel [(set (match_dup 0) (match_dup 1))
335 (clobber (reg:CC R_FLAGS))])]
338 (define_expand "movstrictqi"
339 [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
340 (match_operand:QI 1 "general_operand" ""))]
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)"
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))]
358 [(set_attr "type" "logic")])
361 [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
362 (match_operand:QI 1 "reg_or_0_operand" ""))]
364 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
365 (clobber (reg:CC R_FLAGS))])]
369 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
380 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
383 (define_expand "movhi"
384 [(set (match_operand:HI 0 "nonimmediate_operand" "")
385 (match_operand:HI 1 "general_operand" ""))]
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)"
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
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))]
412 [(set_attr "type" "logic")])
415 [(set (match_operand:HI 0 "gpc_reg_operand" "")
416 (match_operand:HI 1 "gpc_reg_operand" ""))]
418 [(parallel [(set (match_dup 0) (match_dup 1))
419 (clobber (reg:CC R_FLAGS))])]
422 (define_expand "movstricthi"
423 [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
424 (match_operand:HI 1 "general_operand" ""))]
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)"
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))]
443 [(set_attr "type" "logic")])
446 [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
447 (match_operand:HI 1 "register_operand" ""))]
449 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
450 (clobber (reg:CC R_FLAGS))])]
454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
465 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
468 (define_expand "movsi"
469 [(set (match_operand:SI 0 "nonimmediate_operand" "")
470 (match_operand:SI 1 "general_operand" ""))]
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")) )]
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")
491 (match_operand:SI 1 "const_int_operand" "n"))]
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")))]
504 [(set_attr "type" "imm_reg")])
506 (define_insn "*movil"
507 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
510 (match_operand:SI 1 "const_int_operand" "n"))]
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)"
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
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)"
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
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))]
560 [(set_attr "type" "logic")])
562 (define_insn "*movsi_insn_m1<subst_logic>"
563 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
565 (clobber (reg:CC R_FLAGS))]
568 [(set_attr "type" "logic")])
571 [(set (match_operand:SI 0 "gpc_reg_operand" "")
572 (match_operand:SI 1 "gpc_reg_operand" ""))]
574 [(parallel [(set (match_dup 0) (match_dup 1))
575 (clobber (reg:CC R_FLAGS))])]
579 [(set (match_operand:SI 0 "gpc_reg_operand" "")
582 [(parallel [(set (match_dup 0) (const_int -1))
583 (clobber (reg:CC R_FLAGS))])]
586 (define_insn "*movsi_mdbhi"
587 [(set (match_operand:SI 0 "register_operand" "=r")
588 (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
591 [(set_attr "type" "eam_reg")])
594 [(set (match_operand:SI 0 "gpc_reg_operand" "")
595 (match_operand:SI 1 "large_immediate_operand" ""))]
598 (high:SI (match_dup 1)) )
600 (lo_sum:SI (match_dup 0) (match_dup 1)))]
604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" ""))]
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)"
630 writemd %d1,%1 ;movdi ?b r"
631 [(set_attr "type" "multi,multi,multi,reg_eam")])
634 [(set (match_operand:DI 0 "gpc_reg_operand" "") (reg:DI R_MDB))]
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);
644 [(set (match_operand:DI 0 "non_eam_dst_operand" "")
645 (match_operand:DI 1 "non_eam_src_operand" ""))]
647 [(set (match_dup 2) (match_dup 3))
648 (set (match_dup 4) (match_dup 5))]
650 visium_split_double_move (operands, DImode);
654 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" ""))]
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)"
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))]
693 [(set_attr "type" "logic")])
696 [(set (match_operand:SF 0 "gpc_reg_operand" "")
697 (match_operand:SF 1 "gpc_reg_operand" ""))]
699 [(parallel [(set (match_dup 0) (match_dup 1))
700 (clobber (reg:CC R_FLAGS))])]
704 [(set (match_operand:SF 0 "gpc_reg_operand" "")
705 (match_operand:SF 1 "const_double_operand" ""))]
707 [(set (match_dup 2) (match_dup 3))]
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" ""))]
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)"
740 [(set_attr "type" "multi")])
743 [(set (match_operand:DF 0 "nonimmediate_operand" "")
744 (match_operand:DF 1 "general_operand" ""))]
746 [(set (match_dup 2) (match_dup 3))
747 (set (match_dup 4) (match_dup 5))]
749 visium_split_double_move (operands, DFmode);
753 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" "")))]
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" "")))
773 (if_then_else (ltu (match_dup 0) (match_dup 1))
774 (label_ref (match_operand 3 ""))
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" "")))
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 ""))
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)"
796 [(parallel [(set (match_dup 0)
797 (plus:QHI (match_dup 1) (match_dup 2)))
798 (clobber (reg:CC R_FLAGS))])]
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))]
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"))
816 (set (match_operand:QHI 0 "register_operand" "=r")
817 (plus:QHI (match_dup 1) (match_dup 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)))]
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" "")))]
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))])]
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)"
854 [(parallel [(set (match_dup 0)
855 (plus:SI (match_dup 1) (match_dup 2)))
856 (clobber (reg:CC R_FLAGS))])]
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))]
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"))
880 (set (match_operand:SI 0 "register_operand" "=r,r")
881 (plus:SI (match_dup 1) (match_dup 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)))]
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" "")))]
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)"
918 visium_split_double_add (PLUS, operands[0], operands[1], operands[2]);
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))]
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))]
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))]
958 [(set_attr "type" "arith")])
961 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" "")))]
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" "")))
981 (if_then_else (ltu (match_dup 1) (match_dup 2))
982 (label_ref (match_operand 3 ""))
986 if (operands[1] == const0_rtx)
988 emit_insn (gen_unegv<mode>3 (operands[0], operands[2], operands[3]));
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" "")))
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 ""))
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)"
1011 [(parallel [(set (match_dup 0)
1012 (minus:QHI (match_dup 1) (match_dup 2)))
1013 (clobber (reg:CC R_FLAGS))])]
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))]
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)))]
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)))]
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" "")))]
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))])]
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)"
1068 [(parallel [(set (match_dup 0)
1069 (minus:SI (match_dup 1) (match_dup 2)))
1070 (clobber (reg:CC R_FLAGS))])]
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))]
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)))]
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)))]
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" "")))]
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)"
1131 visium_split_double_add (MINUS, operands[0], operands[1], operands[2]);
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))]
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))]
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))]
1171 [(set_attr "type" "arith")])
1174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" "")))]
1188 (define_expand "unegv<mode>3"
1189 [(set (match_operand:I 0 "register_operand" "")
1190 (neg:I (match_operand:I 1 "register_operand" "")))
1192 (if_then_else (ne (match_dup 0) (const_int 0))
1193 (label_ref (match_operand 2 ""))
1197 (define_expand "negv<mode>3"
1198 [(set (match_operand:I 0 "register_operand" "")
1199 (neg:I (match_operand:I 1 "register_operand" "")))
1201 (if_then_else (ne (match_dup 0)
1202 (unspec:I [(match_dup 1)] UNSPEC_NEGV))
1203 (label_ref (match_operand 2 ""))
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)"
1213 [(parallel [(set (match_dup 0) (neg:I (match_dup 1)))
1214 (clobber (reg:CC R_FLAGS))])]
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))]
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")))
1230 (set (match_operand:I 0 "register_operand" "=r")
1231 (neg:I (match_dup 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)))]
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" "")))]
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)"
1259 visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]);
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))]
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))]
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")
1303 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1304 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
1306 (clobber (reg:DI R_MDB))
1307 (clobber (reg:SI R_MDC))]
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))]
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)))]
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))]
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))]
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)))]
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))]
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))]
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)))))]
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)))))]
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" "")))]
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)"
1419 [(parallel [(set (match_dup 0)
1420 (and:I (match_dup 1) (match_dup 2)))
1421 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1457 [(parallel [(set (match_dup 0)
1458 (ior:I (match_dup 1) (match_dup 2)))
1459 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1495 [(parallel [(set (match_dup 0)
1496 (xor:I (match_dup 1) (match_dup 2)))
1497 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1531 [(parallel [(set (match_dup 0) (not:I (match_dup 1)))
1532 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1567 [(parallel [(set (match_dup 0)
1568 (ashift:I (match_dup 1) (match_dup 2)))
1569 (clobber (reg:CC R_FLAGS))])]
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))]
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))]
1591 [(set_attr "type" "shiftdi,multi")])
1594 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1595 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
1597 (clobber (reg:SI R_MDC))]
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))]
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" "")))]
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)"
1626 [(parallel [(set (match_dup 0)
1627 (ashiftrt:I (match_dup 1) (match_dup 2)))
1628 (clobber (reg:CC R_FLAGS))])]
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))]
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))]
1650 [(set_attr "type" "shiftdi,multi")])
1653 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1654 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1656 (clobber (reg:SI R_MDC))]
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))])]
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" "")))]
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)"
1687 [(parallel [(set (match_dup 0)
1688 (lshiftrt:I (match_dup 1) (match_dup 2)))
1689 (clobber (reg:CC R_FLAGS))])]
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))]
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))]
1711 [(set_attr "type" "shiftdi,multi")])
1714 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1715 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1717 (clobber (reg:SI R_MDC))]
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))]
1724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" "")))]
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)"
1744 [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1)))
1745 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1768 [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1)))
1769 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1792 [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1)))
1793 (clobber (reg:CC R_FLAGS))])]
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))]
1803 [(set_attr "type" "logic")])
1806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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" "")))]
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)"
1826 [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
1827 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
1850 [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
1851 (clobber (reg:CC R_FLAGS))])]
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))]
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" "")))]
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)"
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))])]
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))]
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" "")))]
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)"
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
1924 (define_expand "zero_extendqihi2"
1925 [(set (match_operand:HI 0 "register_operand" "")
1926 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
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)"
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" "")))]
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)"
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")))]
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" "")))]
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)"
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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")
2012 (match_operand:QI 1 "const_shift_operand" "K"))
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")]
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")]
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")]
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")))]
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"))
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")))]
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")))]
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")))]
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")))]
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")))]
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")))]
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")))]
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);
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"
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"
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"
2193 "&& reload_completed"
2195 (unspec:SF [(match_dup 1)] UNSPEC_FLOAD))
2197 (unspec:SF [(match_dup 0)] UNSPEC_ITOF))]
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"
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"
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"
2221 "&& reload_completed"
2223 (unspec:SF [(match_dup 1)] UNSPEC_FTOI))
2225 (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))]
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")))]
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" "")))]
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"))))]
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" ""))))]
2262 if (!TARGET_FPU_IEEE)
2264 emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1]));
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"
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"
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"
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 ""))
2317 (define_insn_and_split "*cbranch<mode>4_insn"
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 ""))
2329 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2333 [(set_attr "type" "cmp")])
2335 (define_insn_and_split "*cbranch<mode>4_addv_insn"
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")]
2342 (label_ref (match_operand 4 ""))
2349 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2350 XEXP (operands[0], 1), operands[4]);
2353 [(set_attr "type" "cmp")])
2355 (define_insn_and_split "*cbranch<mode>4_subv_insn"
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")]
2362 (label_ref (match_operand 4 ""))
2369 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2370 XEXP (operands[0], 1), operands[4]);
2373 [(set_attr "type" "cmp")])
2375 (define_insn_and_split "*cbranch<mode>4_negv_insn"
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")]
2381 (label_ref (match_operand 3 ""))
2388 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2389 XEXP (operands[0], 1), operands[3]);
2392 [(set_attr "type" "cmp")])
2394 (define_insn_and_split "*cbranch<mode>4_btst_insn"
2396 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2398 (match_operand:I 1 "register_operand" "r")
2400 (match_operand:QI 2 "const_shift_operand" "K"))
2402 (label_ref (match_operand 3 ""))
2409 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2410 XEXP (operands[0], 1), operands[3]);
2413 [(set_attr "type" "cmp")])
2415 (define_expand "cbranchsf4"
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 ""))
2425 (define_insn_and_split "*cbranchsf4_insn"
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 ""))
2434 "&& reload_completed"
2437 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2441 [(set_attr "type" "fcmp")])
2443 ; Now match both normal and inverted branches.
2445 (define_insn "*normal_branch"
2447 (if_then_else (match_operator 1 "visium_branch_operator"
2448 [(reg R_FLAGS) (const_int 0)])
2449 (label_ref (match_operand 0 ""))
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"
2460 (if_then_else (match_operator 1 "visium_branch_operator"
2461 [(reg R_FLAGS) (const_int 0)])
2463 (label_ref (match_operand 0 ""))))]
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"
2475 (if_then_else (match_operator 0 "visium_branch_operator"
2476 [(reg R_FLAGS) (const_int 0)])
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"
2488 (if_then_else (match_operator 0 "visium_branch_operator"
2489 [(reg R_FLAGS) (const_int 0)])
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2509 (label_ref (match_operand 0 "" "")))]
2512 return output_ubranch (operands[0], insn);
2514 [(set_attr "type" "branch")])
2516 (define_insn "indirect_jump"
2518 (match_operand:SI 0 "register_operand" "r"))]
2520 "bra tr,%0,r0%# ;indirect jump"
2521 [(set_attr "type" "abs_branch")])
2523 (define_insn "tablejump"
2525 (match_operand:SI 0 "register_operand" "r"))
2526 (use (label_ref (match_operand 1 "" "")))]
2528 "bra tr,%0,r0%# ;tablejump"
2529 [(set_attr "type" "abs_branch")])
2532 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2534 ;; trap instructions
2536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2540 [(trap_if (const_int 1) (const_int 0))]
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))])]
2565 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2566 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
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))])]
2596 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2597 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
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))])]
2627 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2628 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
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))])]
2653 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2654 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
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 "" "")
2676 (match_operand 1 "" "")
2677 (match_operand 2 "" "")])]
2682 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
2684 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2686 rtx set = XVECEXP (operands[2], 0, i);
2687 emit_move_insn (SET_DEST (set), SET_SRC (set));
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
2694 emit_insn (gen_blockage ());
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")]))]
2722 visium_expand_int_cstore (operands, <MODE>mode);
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")))]
2735 visium_split_cstore (SET, operands[0], NULL_RTX,
2736 LTU, operands[1], operands[2]);
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"))))]
2750 visium_split_cstore (NEG, operands[0], NULL_RTX,
2751 LTU, operands[1], operands[2]);
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"))))]
2766 visium_split_cstore (<add_op>, operands[0], operands[1],
2767 LTU, operands[2], operands[3]);
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"))
2781 visium_split_cstore (SET, operands[0], NULL_RTX,
2782 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
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"))
2796 visium_split_cstore (NEG, operands[0], NULL_RTX,
2797 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
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"))
2812 visium_split_cstore (<add_op>, operands[0], operands[1],
2813 LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx);
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")]))]
2825 visium_expand_fp_cstore (operands, SFmode);
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")))]
2835 "&& reload_completed"
2838 visium_split_cstore (SET, operands [0], NULL_RTX,
2839 LT, operands[1], operands[2]);
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"))))]
2850 "&& reload_completed"
2853 visium_split_cstore (NEG, operands [0], NULL_RTX,
2854 LT, operands[1], operands[2]);
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"))))]
2866 "&& reload_completed"
2869 visium_split_cstore (<add_op>, operands [0], operands[1],
2870 LT, operands[2], operands[3]);
2873 [(set_attr "type" "fcmp")])
2876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2878 ;; RTL pro/epilogue support
2880 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2883 ; Expand prologue in RTL
2884 (define_expand "prologue"
2888 visium_expand_prologue ();
2892 ; Expand epilogue in RTL
2893 (define_expand "epilogue"
2897 visium_expand_epilogue ();
2900 ; Expand epilogue without a final jump in RTL
2901 (define_expand "sibcall_epilogue"
2905 visium_expand_epilogue ();
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))]
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))]
2930 "move.l sp,fp ;stack_restore"
2931 [(set_attr "type" "logic")])
2933 (define_insn "stack_pop"
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))]
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"
2949 (define_insn "*<return_str>return_internal"
2951 "!visium_interrupt_function_p ()"
2953 return output_ubranch (pc_rtx, insn);
2955 [(set_attr "type" "ret")])
2957 (define_insn "*return_internal_interrupt"
2959 "visium_interrupt_function_p ()"
2960 "rfi\n\t nop ;return from interrupt"
2961 [(set_attr "type" "rfi")])
2964 [(unspec_volatile [(const_int 0)] UNSPECV_DSI)]
2967 [(set_attr "type" "dsi")])
2970 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2972 ;; NOP (no-op instruction)
2974 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2981 [(set_attr "type" "nop")])
2983 (define_insn "hazard_nop"
2984 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
2986 "nop ;hazard avoidance"
2987 [(set_attr "type" "nop")])
2989 (define_insn "blockage"
2990 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
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" ""))])]
3016 if (visium_expand_block_move (operands))
3023 [(set (mem:BLK (reg:SI R_R1))
3024 (mem:BLK (reg:SI R_R2)))
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))]
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" ""))])]
3049 if (visium_expand_block_set (operands))