1 ;; Machine description for Visium.
2 ;; Copyright (C) 2002-2017 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
108 ;imm_reg Move of immediate value to register.
109 ;mem_reg Move from memory to register.
110 ;eam_reg Move from EAM to register.
111 ;fp_reg Move from FPU to register.
112 ;reg_mem Move from register to memory.
113 ;reg_eam Move from register to EAM.
114 ;reg_fp Move from register to FPU.
115 ;arith Arithmetic operation, result in register, sets overflow.
116 ;arith2 Two successive arithmetic operations.
117 ;logic Logical operation, result in register, does not set overflow.
118 ;abs_branch Absolute branch.
121 ;call Call to subprogram.
122 ;ret Return from subprogram.
123 ;rfi Return from interrupt.
124 ;dsi Disable interrupts.
125 ;cmp Compare or test.
126 ;div EAM 32/32 division.
127 ;divd EAM 64/32 division.
128 ;mul EAM 32 * 32 -> 64 multiplication.
129 ;shiftdi EAM 64 bit shift.
130 ;fdiv Floating point divide.
131 ;fsqrt Floating point square root.
132 ;ftoi Fix float to integer.
134 ;fmove Floating point move w/ or w/o change of sign: fmove, fabs, fneg.
135 ;fcmp Floating point compare or test.
136 ;fp Other floating point operations.
138 ;multi Multiple instructions which split.
139 ;asm User asm instructions.
140 ;trap Trap instructions.
143 "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"))
145 ; Those insns that occupy 4 bytes.
146 (define_attr "single_insn" "no,yes"
147 (if_then_else (eq_attr "type" "arith2,rfi,multi")
149 (const_string "yes")))
151 ; True if branch or call will be emitting a nop into its delay slot.
152 (define_attr "empty_delay_slot" "false,true"
153 (symbol_ref "(empty_delay_slot (insn)
154 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
157 ; The allowed range for the offset of short branches is [-131072;131068]
158 ; and it is counted from the address of the insn so we need to subtract
159 ; 8 for forward branches because (pc) points to the next insn for them.
160 (define_attr "length" ""
161 (cond [(eq_attr "type" "abs_branch,call,ret")
162 (if_then_else (eq_attr "empty_delay_slot" "true")
165 (eq_attr "type" "branch")
166 (if_then_else (leu (plus (minus (match_dup 0) (pc))
169 (if_then_else (eq_attr "empty_delay_slot" "true")
173 (eq_attr "single_insn" "no")
174 (const_int 8)] (const_int 4)))
176 (define_asm_attributes [(set_attr "type" "asm")])
179 (define_delay (eq_attr "type" "abs_branch,branch,call,ret")
180 [(and (eq_attr "type" "!abs_branch,branch,call,ret,rfi,bmi,mul,div,divd,fdiv,fsqrt,asm")
181 (eq_attr "single_insn" "yes"))
185 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
187 ;; Processor pipeline description.
189 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
192 ; Attribute for cpu type.
193 ; These must match the values for enum processor_type in visium-opts.h.
194 (define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr")))
200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
207 (define_mode_iterator QHI [QI HI])
208 (define_mode_iterator I [QI HI SI])
209 (define_mode_attr b [(QI "8") (HI "16") (SI "32")])
210 (define_mode_attr s [(QI ".b") (HI ".w") (SI ".l")])
212 ; This code iterator allows signed and unsigned widening multiplications
213 ; to use the same template.
214 (define_code_iterator any_extend [sign_extend zero_extend])
216 ; <u> expands to an empty string when doing a signed operation and
217 ; "u" when doing an unsigned operation.
218 (define_code_attr u [(sign_extend "") (zero_extend "u")])
220 ; <su> is like <u>, but the signed form expands to "s" rather than "".
221 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
223 ; This code iterator allows returns and simple returns to use the same template.
224 (define_code_iterator any_return [return simple_return])
225 (define_code_attr return_pred [(return "visium_can_use_return_insn_p ()")
226 (simple_return "!visium_interrupt_function_p ()")])
227 (define_code_attr return_str [(return "") (simple_return "simple_")])
229 ; This code iterator allows integer and FP cstores to use the same template.
230 (define_code_iterator any_scc [ltu lt])
231 (define_code_attr scc_str [(ltu "sltu") (lt "slt")])
233 ;This code iterator allows cstore splitters to use the same template.
234 (define_code_iterator any_add [plus minus])
235 (define_code_attr add_op [(plus "PLUS") (minus "MINUS")])
236 (define_code_attr add_str [(plus "plus") (minus "minus")])
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
243 ;; They are used to define the second instruction of the pairs required by
244 ;; the postreload compare elimination pass, with a first variant for the
245 ;; logical insns and a second variant for the arithmetic insns.
247 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
250 (define_subst "flags_subst_logic"
251 [(set (match_operand 0 "") (match_operand 1 ""))
252 (clobber (reg:CC R_FLAGS))]
254 [(set (match_dup 0) (match_dup 1))
255 (set (reg:CC R_FLAGS)
256 (compare:CC (match_dup 1) (const_int 0)))])
258 (define_subst_attr "subst_logic" "flags_subst_logic" "_flags" "_set_flags")
260 (define_subst "flags_subst_arith"
261 [(set (match_operand 0 "") (match_operand 1 ""))
262 (clobber (reg:CC R_FLAGS))]
264 [(set (match_dup 0) (match_dup 1))
265 (set (reg:CCNZ R_FLAGS)
266 (compare:CCNZ (match_dup 1) (const_int 0)))])
268 (define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags")
271 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
275 ;; For moving among registers we use the move.b instruction. This is
276 ;; actually an OR instruction using an alias. For moving between register
277 ;; and memory we need the address of the memory location in a register.
278 ;; However, we can accept an expression (reg + offset) where offset is in
279 ;; the range 0 .. 31.
281 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
284 (define_expand "movqi"
285 [(set (match_operand:QI 0 "nonimmediate_operand" "")
286 (match_operand:QI 1 "general_operand" ""))]
289 prepare_move_operands (operands, QImode);
292 (define_insn "*movqi_insn"
293 [(set (match_operand:QI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
294 (match_operand:QI 1 "general_operand" " r,rO, r, r,?b,?c,i,m"))]
295 "ok_for_simple_move_operands (operands, QImode)"
299 writemd %1,r0 ;movqi ?b r
300 writemdc %1 ;movqi ?c r
301 readmda %0 ;movqi r ?b
302 readmdc %0 ;movqi r ?c
303 moviq %0,%b1 ;movqi r i
305 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
307 (define_insn "*movqi_insn<subst_logic>"
308 [(set (match_operand:QI 0 "gpc_reg_operand" "=r")
309 (match_operand:QI 1 "gpc_reg_operand" "r"))
310 (clobber (reg:CC R_FLAGS))]
313 [(set_attr "type" "logic")])
316 [(set (match_operand:QI 0 "gpc_reg_operand" "")
317 (match_operand:QI 1 "gpc_reg_operand" ""))]
319 [(parallel [(set (match_dup 0) (match_dup 1))
320 (clobber (reg:CC R_FLAGS))])]
323 (define_expand "movstrictqi"
324 [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
325 (match_operand:QI 1 "general_operand" ""))]
328 (define_insn "*movstrictqi_insn"
329 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r,r"))
330 (match_operand:QI 1 "general_operand" "rO,m"))]
331 "ok_for_simple_move_strict_operands (operands, QImode)"
335 [(set_attr "type" "logic,mem_reg")])
337 (define_insn "*movstrictqi_insn<subst_logic>"
338 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
339 (match_operand:QI 1 "reg_or_0_operand" "rO"))
340 (clobber (reg:CC R_FLAGS))]
343 [(set_attr "type" "logic")])
346 [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
347 (match_operand:QI 1 "reg_or_0_operand" ""))]
349 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
350 (clobber (reg:CC R_FLAGS))])]
354 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
358 ;; For moving among registers we use the move.w instruction. This is
359 ;; actually an OR instruction using an alias. For moving between register
360 ;; and memory we need the address of the memory location in a register.
361 ;; However, we can accept an expression (reg + offset) where offset is in
362 ;; the range 0 .. 62 and is shifted right one place in the assembled
365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
368 (define_expand "movhi"
369 [(set (match_operand:HI 0 "nonimmediate_operand" "")
370 (match_operand:HI 1 "general_operand" ""))]
373 prepare_move_operands (operands, HImode);
376 (define_insn "*movhi_insn"
377 [(set (match_operand:HI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
378 (match_operand:HI 1 "general_operand" " r,rO, r, r,?b,?c,i,m"))]
379 "ok_for_simple_move_operands (operands, HImode)"
383 writemd %1,r0 ;movhi ?b r
384 writemdc %1 ;movhi ?c r
385 readmda %0 ;movhi r ?b
386 readmdc %0 ;movhi r ?c
387 moviq %0,%w1 ;movhi r i
389 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
391 (define_insn "*movhi_insn<subst_logic>"
392 [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
393 (match_operand:HI 1 "gpc_reg_operand" "r"))
394 (clobber (reg:CC R_FLAGS))]
397 [(set_attr "type" "logic")])
400 [(set (match_operand:HI 0 "gpc_reg_operand" "")
401 (match_operand:HI 1 "gpc_reg_operand" ""))]
403 [(parallel [(set (match_dup 0) (match_dup 1))
404 (clobber (reg:CC R_FLAGS))])]
407 (define_expand "movstricthi"
408 [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
409 (match_operand:HI 1 "general_operand" ""))]
412 (define_insn "*movstricthi_insn"
413 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r,r,r"))
414 (match_operand:HI 1 "general_operand" " r,i,m"))]
415 "ok_for_simple_move_strict_operands (operands, HImode)"
420 [(set_attr "type" "logic,imm_reg,mem_reg")])
422 (define_insn "*movstricthi_insn<subst_logic>"
423 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
424 (match_operand:HI 1 "register_operand" "r"))
425 (clobber (reg:CC R_FLAGS))]
428 [(set_attr "type" "logic")])
431 [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
432 (match_operand:HI 1 "register_operand" ""))]
434 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
435 (clobber (reg:CC R_FLAGS))])]
439 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
443 ;; For moving among registers we use the move.l instruction. This is
444 ;; actually an OR instruction using an alias. For moving between register
445 ;; and memory we need the address of the memory location in a register.
446 ;; However, we can accept an expression (reg + offset) where offset is in
447 ;; the range 0 .. 124 and is shifted right two places in the assembled
450 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
453 (define_expand "movsi"
454 [(set (match_operand:SI 0 "nonimmediate_operand" "")
455 (match_operand:SI 1 "general_operand" ""))]
458 prepare_move_operands (operands, SImode);
461 (define_insn "*movsi_high"
462 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
463 (high:SI (match_operand:SI 1 "immediate_operand" "n,i")) )]
468 [(set_attr "type" "imm_reg")])
470 ; We only care about the lower 16 bits of the constant
471 ; being inserted into the upper 16 bits of the register.
472 (define_insn "*moviu"
473 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
476 (match_operand:SI 1 "const_int_operand" "n"))]
479 [(set_attr "type" "imm_reg")])
481 (define_insn "*movsi_losum"
482 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
483 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
484 (match_operand:SI 2 "immediate_operand" "n,i")))]
489 [(set_attr "type" "imm_reg")])
491 (define_insn "*movil"
492 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
495 (match_operand:SI 1 "const_int_operand" "n"))]
498 [(set_attr "type" "imm_reg")])
500 (define_insn "*movsi_insn_no_ieee"
501 [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,!f")
502 (match_operand:SI 1 "general_operand" " r,rO, r, r,?b,?c,J,M,i,m,!f, r"))]
503 "!TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
507 writemd %1,r0 ;movsi ?b r
508 writemdc %1 ;movsi ?c r
509 readmda %0 ;movsi r ?b
510 readmdc %0 ;movsi r ?c
511 moviq %0,%1 ;movsi r J
517 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp")])
519 (define_insn "*movsi_insn"
520 [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,?f,f")
521 (match_operand:SI 1 "general_operand" " r,rO, r, r,?b,?c,J,M,i,m,?f, r,f"))]
522 "TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
526 writemd %1,r0 ;movsi ?b r
527 writemdc %1 ;movsi ?c r
528 readmda %0 ;movsi r ?b
529 readmdc %0 ;movsi r ?c
530 moviq %0,%1 ;movsi r J
537 [(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")])
539 (define_insn "*movsi_insn<subst_logic>"
540 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
541 (match_operand:SI 1 "gpc_reg_operand" "r"))
542 (clobber (reg:CC R_FLAGS))]
545 [(set_attr "type" "logic")])
547 (define_insn "*movsi_insn_m1<subst_logic>"
548 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
550 (clobber (reg:CC R_FLAGS))]
553 [(set_attr "type" "logic")])
556 [(set (match_operand:SI 0 "gpc_reg_operand" "")
557 (match_operand:SI 1 "gpc_reg_operand" ""))]
559 [(parallel [(set (match_dup 0) (match_dup 1))
560 (clobber (reg:CC R_FLAGS))])]
564 [(set (match_operand:SI 0 "gpc_reg_operand" "")
567 [(parallel [(set (match_dup 0) (const_int -1))
568 (clobber (reg:CC R_FLAGS))])]
571 (define_insn "*movsi_mdbhi"
572 [(set (match_operand:SI 0 "register_operand" "=r")
573 (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
576 [(set_attr "type" "eam_reg")])
579 [(set (match_operand:SI 0 "gpc_reg_operand" "")
580 (match_operand:SI 1 "large_immediate_operand" ""))]
583 (high:SI (match_dup 1)) )
585 (lo_sum:SI (match_dup 0) (match_dup 1)))]
589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
593 ;; When the destination is the EAM register MDB, then we use the writemd
594 ;; instruction. In all other cases we split the move into two 32-bit moves.
596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
599 (define_expand "movdi"
600 [(set (match_operand:DI 0 "nonimmediate_operand" "")
601 (match_operand:DI 1 "general_operand" ""))]
604 prepare_move_operands (operands, DImode);
607 (define_insn "*movdi_insn"
608 [(set (match_operand:DI 0 "nonimmediate_operand" "= r, m, r,??b")
609 (match_operand:DI 1 "general_operand" "rim,rO,?b, r"))]
610 "ok_for_simple_move_operands (operands, DImode)"
615 writemd %d1,%1 ;movdi ?b r"
616 [(set_attr "type" "multi,multi,multi,reg_eam")])
619 [(set (match_operand:DI 0 "gpc_reg_operand" "") (reg:DI R_MDB))]
621 [(set (match_dup 1) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))
622 (set (match_dup 2) (reg:SI R_MDB))]
624 operands[1] = operand_subword (operands[0], 0, 1, DImode);
625 operands[2] = operand_subword (operands[0], 1, 1, DImode);
629 [(set (match_operand:DI 0 "non_eam_dst_operand" "")
630 (match_operand:DI 1 "non_eam_src_operand" ""))]
632 [(set (match_dup 2) (match_dup 3))
633 (set (match_dup 4) (match_dup 5))]
635 visium_split_double_move (operands, DImode);
639 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
643 ;; Constants are constructed in a GP register and moved to the FP register.
645 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
648 (define_expand "movsf"
649 [(set (match_operand:SF 0 "nonimmediate_operand" "")
650 (match_operand:SF 1 "general_operand" ""))]
653 prepare_move_operands (operands, SFmode);
656 (define_insn "*movsf_insn"
657 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,r,r, m,r,r,r")
658 (match_operand:SF 1 "general_operand" " f,G,r,f,r,rG,G,F,m"))]
659 "ok_for_simple_move_operands (operands, SFmode)"
670 [(set_attr "type" "fmove,fmove,reg_fp,fp_reg,logic,reg_mem,imm_reg,multi,mem_reg")])
672 (define_insn "*movsf_insn"
673 [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
674 (match_operand:SF 1 "gpc_reg_operand" "r"))
675 (clobber (reg:CC R_FLAGS))]
678 [(set_attr "type" "logic")])
681 [(set (match_operand:SF 0 "gpc_reg_operand" "")
682 (match_operand:SF 1 "gpc_reg_operand" ""))]
684 [(parallel [(set (match_dup 0) (match_dup 1))
685 (clobber (reg:CC R_FLAGS))])]
689 [(set (match_operand:SF 0 "gpc_reg_operand" "")
690 (match_operand:SF 1 "const_double_operand" ""))]
692 [(set (match_dup 2) (match_dup 3))]
696 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
698 operands[2] = operand_subword (operands[0], 0, 0, SFmode);
699 operands[3] = GEN_INT (trunc_int_for_mode (l, SImode));
703 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
707 ;; We always split a DFmode move into two SImode moves.
709 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
712 (define_expand "movdf"
713 [(set (match_operand:DF 0 "nonimmediate_operand" "")
714 (match_operand:DF 1 "general_operand" ""))]
717 prepare_move_operands (operands, DFmode);
720 (define_insn "*movdf_insn"
721 [(set (match_operand:DF 0 "nonimmediate_operand" "= r, m")
722 (match_operand:DF 1 "general_operand" "rFm,rG"))]
723 "ok_for_simple_move_operands (operands, DFmode)"
725 [(set_attr "type" "multi")])
728 [(set (match_operand:DF 0 "nonimmediate_operand" "")
729 (match_operand:DF 1 "general_operand" ""))]
731 [(set (match_dup 2) (match_dup 3))
732 (set (match_dup 4) (match_dup 5))]
734 visium_split_double_move (operands, DFmode);
738 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
742 ;; Modes QI, HI, SI and DI are supported directly.
744 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
747 (define_expand "add<mode>3"
748 [(set (match_operand:QHI 0 "register_operand" "")
749 (plus:QHI (match_operand:QHI 1 "register_operand" "")
750 (match_operand:QHI 2 "register_operand" "")))]
753 (define_expand "uaddv<mode>4"
754 [(set (match_operand:I 0 "register_operand" "")
755 (plus:I (match_operand:I 1 "register_operand" "")
756 (match_operand:I 2 "register_operand" "")))
758 (if_then_else (ltu (match_dup 0) (match_dup 1))
759 (label_ref (match_operand 3 ""))
763 (define_expand "addv<mode>4"
764 [(set (match_operand:I 0 "register_operand" "")
765 (plus:I (match_operand:I 1 "register_operand" "")
766 (match_operand:I 2 "register_operand" "")))
768 (if_then_else (ne (match_dup 0)
769 (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))
770 (label_ref (match_operand 3 ""))
774 (define_insn_and_split "*add<mode>3_insn"
775 [(set (match_operand:QHI 0 "register_operand" "=r")
776 (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
777 (match_operand:QHI 2 "register_operand" "r")))]
778 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
781 [(parallel [(set (match_dup 0)
782 (plus:QHI (match_dup 1) (match_dup 2)))
783 (clobber (reg:CC R_FLAGS))])]
785 [(set_attr "type" "arith")])
787 (define_insn "*add<mode>3_insn<subst_arith>"
788 [(set (match_operand:QHI 0 "register_operand" "=r")
789 (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
790 (match_operand:QHI 2 "register_operand" "r")))
791 (clobber (reg:CC R_FLAGS))]
794 [(set_attr "type" "arith")])
796 (define_insn "*add<mode>3_insn_set_carry"
797 [(set (match_operand:QHI 0 "register_operand" "=r")
798 (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
799 (match_operand:QHI 2 "register_operand" "r")))
800 (set (reg:CCC R_FLAGS)
801 (compare:CCC (plus:QHI (match_dup 1) (match_dup 2))
805 [(set_attr "type" "arith")])
807 (define_insn "*add<mode>3_insn_set_overflow"
808 [(set (match_operand:QHI 0 "register_operand" "=r")
809 (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
810 (match_operand:QHI 2 "register_operand" "r")))
811 (set (reg:CCV R_FLAGS)
812 (compare:CCV (plus:QHI (match_dup 1) (match_dup 2))
813 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))]
816 [(set_attr "type" "arith")])
818 (define_expand "addsi3"
819 [(set (match_operand:SI 0 "register_operand" "")
820 (plus:SI (match_operand:SI 1 "register_operand" "")
821 (match_operand:SI 2 "add_operand" "")))]
824 (define_expand "addsi3_flags"
825 [(parallel [(set (match_operand:SI 0 "register_operand" "")
826 (plus:SI (match_operand:SI 1 "register_operand" "")
827 (match_operand:SI 2 "add_operand" "")))
828 (clobber (reg:CC R_FLAGS))])]
832 (define_insn_and_split "*addsi3_insn"
833 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
834 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
835 (match_operand:SI 2 "add_operand" " L,r,J")))]
836 "ok_for_simple_arith_logic_operands (operands, SImode)"
839 [(parallel [(set (match_dup 0)
840 (plus:SI (match_dup 1) (match_dup 2)))
841 (clobber (reg:CC R_FLAGS))])]
843 [(set_attr "type" "arith")])
845 ; Favour the addition of small negative constants, since they are
846 ; expensive to load into a register.
848 (define_insn "*addsi3_insn<subst_arith>"
849 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
850 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
851 (match_operand:SI 2 "add_operand" " L,r,J")))
852 (clobber (reg:CC R_FLAGS))]
858 [(set_attr "type" "arith")])
860 (define_insn "addsi3_insn_set_carry"
861 [(set (match_operand:SI 0 "register_operand" "=r,r")
862 (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
863 (match_operand:SI 2 "real_add_operand" " r,J")))
864 (set (reg:CCC R_FLAGS)
865 (compare:CCC (plus:SI (match_dup 1) (match_dup 2))
871 [(set_attr "type" "arith")])
873 (define_insn "*addsi3_insn_set_overflow"
874 [(set (match_operand:SI 0 "register_operand" "=r,r")
875 (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
876 (match_operand:SI 2 "real_add_operand" " r,J")))
877 (set (reg:CCV R_FLAGS)
878 (compare:CCV (plus:SI (match_dup 1) (match_dup 2))
879 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))]
884 [(set_attr "type" "arith")])
886 (define_expand "adddi3"
887 [(set (match_operand:DI 0 "register_operand" "")
888 (plus:DI (match_operand:DI 1 "register_operand" "")
889 (match_operand:DI 2 "add_operand" "")))]
892 ; Disfavour the use of add.l because of the early clobber.
894 (define_insn_and_split "*addi3_insn"
895 [(set (match_operand:DI 0 "register_operand" "=r,r,&r")
896 (plus:DI (match_operand:DI 1 "register_operand" "%0,0, r")
897 (match_operand:DI 2 "add_operand" " L,J, r")))]
898 "ok_for_simple_arith_logic_operands (operands, DImode)"
903 visium_split_double_add (PLUS, operands[0], operands[1], operands[2]);
906 [(set_attr "type" "arith2")])
909 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
911 ;; Integer Add with Carry
913 ;; Only SI mode is supported.
915 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
918 (define_insn "*<scc_str><subst_arith>"
919 [(set (match_operand:SI 0 "register_operand" "=r")
920 (any_scc:SI (reg R_FLAGS) (const_int 0)))
921 (clobber (reg:CC R_FLAGS))]
924 [(set_attr "type" "arith")])
926 (define_insn "*plus_<scc_str><subst_arith>"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (plus:SI (match_operand:SI 1 "register_operand" "r")
929 (any_scc:SI (reg R_FLAGS) (const_int 0))))
930 (clobber (reg:CC R_FLAGS))]
933 [(set_attr "type" "arith")])
935 (define_insn "*plus_plus_sltu<subst_arith>"
936 [(set (match_operand:SI 0 "register_operand" "=r")
937 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
938 (match_operand:SI 2 "register_operand" "r"))
939 (ltu:SI (reg R_FLAGS) (const_int 0))))
940 (clobber (reg:CC R_FLAGS))]
943 [(set_attr "type" "arith")])
946 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
950 ;; Modes QI, HI, SI and DI are supported directly.
952 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
955 (define_expand "sub<mode>3"
956 [(set (match_operand:QHI 0 "register_operand" "")
957 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "")
958 (match_operand:QHI 2 "register_operand" "")))]
961 (define_expand "usubv<mode>4"
962 [(set (match_operand:I 0 "register_operand" "")
963 (minus:I (match_operand:I 1 "reg_or_0_operand" "")
964 (match_operand:I 2 "register_operand" "")))
966 (if_then_else (ltu (match_dup 1) (match_dup 2))
967 (label_ref (match_operand 3 ""))
971 if (operands[1] == const0_rtx)
973 emit_insn (gen_unegv<mode>3 (operands[0], operands[2], operands[3]));
978 (define_expand "subv<mode>4"
979 [(set (match_operand:I 0 "register_operand" "")
980 (minus:I (match_operand:I 1 "register_operand" "")
981 (match_operand:I 2 "register_operand" "")))
983 (if_then_else (ne (match_dup 0)
984 (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))
985 (label_ref (match_operand 3 ""))
989 (define_insn_and_split "*sub<mode>3_insn"
990 [(set (match_operand:QHI 0 "register_operand" "=r")
991 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
992 (match_operand:QHI 2 "register_operand" "r")))]
993 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
996 [(parallel [(set (match_dup 0)
997 (minus:QHI (match_dup 1) (match_dup 2)))
998 (clobber (reg:CC R_FLAGS))])]
1000 [(set_attr "type" "arith")])
1002 (define_insn "*sub<mode>3_insn<subst_arith>"
1003 [(set (match_operand:QHI 0 "register_operand" "=r")
1004 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
1005 (match_operand:QHI 2 "register_operand" "r")))
1006 (clobber (reg:CC R_FLAGS))]
1009 [(set_attr "type" "arith")])
1011 (define_insn "*sub<mode>3_insn_set_carry"
1012 [(set (match_operand:QHI 0 "register_operand" "=r")
1013 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
1014 (match_operand:QHI 2 "register_operand" "r")))
1015 (set (reg:CC R_FLAGS)
1016 (compare:CC (match_dup 1) (match_dup 2)))]
1019 [(set_attr "type" "arith")])
1021 (define_insn "*sub<mode>3_insn_set_overflow"
1022 [(set (match_operand:QHI 0 "register_operand" "=r")
1023 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
1024 (match_operand:QHI 2 "register_operand" "r")))
1025 (set (reg:CCV R_FLAGS)
1026 (compare:CCV (minus:QHI (match_dup 1) (match_dup 2))
1027 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))]
1030 [(set_attr "type" "arith")])
1032 (define_expand "subsi3"
1033 [(set (match_operand:SI 0 "register_operand" "")
1034 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
1035 (match_operand:SI 2 "add_operand" "")))]
1038 (define_expand "subsi3_flags"
1039 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1040 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
1041 (match_operand:SI 2 "add_operand" "")))
1042 (clobber (reg:CC R_FLAGS))])]
1046 (define_insn_and_split "*subsi3_insn"
1047 [(set (match_operand:SI 0 "register_operand" "=r,r, r")
1048 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
1049 (match_operand:SI 2 "add_operand" " L,r, J")))]
1050 "ok_for_simple_arith_logic_operands (operands, SImode)"
1053 [(parallel [(set (match_dup 0)
1054 (minus:SI (match_dup 1) (match_dup 2)))
1055 (clobber (reg:CC R_FLAGS))])]
1057 [(set_attr "type" "arith")])
1059 ; Favour the subtraction of small negative constants, since they are
1060 ; expensive to load into a register.
1062 (define_insn "*subsi3_insn<subst_arith>"
1063 [(set (match_operand:SI 0 "register_operand" "=r,r, r")
1064 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
1065 (match_operand:SI 2 "add_operand" " L,r, J")))
1066 (clobber (reg:CC R_FLAGS))]
1072 [(set_attr "type" "arith")])
1074 (define_insn "subsi3_insn_set_carry"
1075 [(set (match_operand:SI 0 "register_operand" "=r,r")
1076 (minus:SI (match_operand:SI 1 "register_operand" " r,0")
1077 (match_operand:SI 2 "real_add_operand" " r,J")))
1078 (set (reg:CC R_FLAGS)
1079 (compare:CC (match_dup 1) (match_dup 2)))]
1084 [(set_attr "type" "arith")])
1086 (define_insn "*subsi3_insn_set_overflow"
1087 [(set (match_operand:SI 0 "register_operand" "=r,r")
1088 (minus:SI (match_operand:SI 1 "register_operand" " r,0")
1089 (match_operand:SI 2 "real_add_operand" " r,J")))
1090 (set (reg:CCV R_FLAGS)
1091 (compare:CCV (minus:SI (match_dup 1) (match_dup 2))
1092 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))]
1097 [(set_attr "type" "arith")])
1099 (define_expand "subdi3"
1100 [(set (match_operand:DI 0 "register_operand" "")
1101 (minus:DI (match_operand:DI 1 "register_operand" "")
1102 (match_operand:DI 2 "add_operand" "")))]
1105 ; Disfavour the use of the sub.l because of the early clobber.
1107 (define_insn_and_split "*subdi3_insn"
1108 [(set (match_operand:DI 0 "register_operand" "=r,r,&r")
1109 (minus:DI (match_operand:DI 1 "register_operand" " 0,0, r")
1110 (match_operand:DI 2 "add_operand" " L,J, r")))]
1111 "ok_for_simple_arith_logic_operands (operands, DImode)"
1116 visium_split_double_add (MINUS, operands[0], operands[1], operands[2]);
1119 [(set_attr "type" "arith2")])
1122 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1124 ;; Integer Subtract with Carry
1126 ;; Only SI mode is supported.
1128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1131 (define_insn "*neg_<scc_str><subst_arith>"
1132 [(set (match_operand:SI 0 "register_operand" "=r")
1133 (neg:SI (any_scc:SI (reg R_FLAGS) (const_int 0))))
1134 (clobber (reg:CC R_FLAGS))]
1137 [(set_attr "type" "arith")])
1139 (define_insn "*minus_<scc_str><subst_arith>"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (minus:SI (match_operand:SI 1 "register_operand" "r")
1142 (any_scc:SI (reg R_FLAGS) (const_int 0))))
1143 (clobber (reg:CC R_FLAGS))]
1146 [(set_attr "type" "arith")])
1148 (define_insn "*minus_minus_sltu<subst_arith>"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1151 (match_operand:SI 2 "register_operand" "r"))
1152 (ltu:SI (reg R_FLAGS) (const_int 0))))
1153 (clobber (reg:CC R_FLAGS))]
1156 [(set_attr "type" "arith")])
1159 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1163 ;; Modes QI, HI, SI and DI are supported directly.
1165 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1168 (define_expand "neg<mode>2"
1169 [(set (match_operand:I 0 "register_operand" "")
1170 (neg:I (match_operand:I 1 "register_operand" "")))]
1173 (define_expand "unegv<mode>3"
1174 [(set (match_operand:I 0 "register_operand" "")
1175 (neg:I (match_operand:I 1 "register_operand" "")))
1177 (if_then_else (ne (match_dup 0) (const_int 0))
1178 (label_ref (match_operand 2 ""))
1182 (define_expand "negv<mode>3"
1183 [(set (match_operand:I 0 "register_operand" "")
1184 (neg:I (match_operand:I 1 "register_operand" "")))
1186 (if_then_else (ne (match_dup 0)
1187 (unspec:I [(match_dup 1)] UNSPEC_NEGV))
1188 (label_ref (match_operand 2 ""))
1192 (define_insn_and_split "*neg<mode>2_insn"
1193 [(set (match_operand:I 0 "register_operand" "=r")
1194 (neg:I (match_operand:I 1 "register_operand" "r")))]
1195 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1198 [(parallel [(set (match_dup 0) (neg:I (match_dup 1)))
1199 (clobber (reg:CC R_FLAGS))])]
1201 [(set_attr "type" "arith")])
1203 (define_insn "*neg<mode>2_insn<subst_arith>"
1204 [(set (match_operand:I 0 "register_operand" "=r")
1205 (neg:I (match_operand:I 1 "register_operand" "r")))
1206 (clobber (reg:CC R_FLAGS))]
1209 [(set_attr "type" "arith")])
1211 (define_insn "negsi2_insn_set_carry"
1212 [(set (match_operand:SI 0 "register_operand" "=r")
1213 (neg:SI (match_operand:SI 1 "register_operand" "r")))
1214 (set (reg:CCC R_FLAGS)
1215 (compare:CCC (not:SI (match_dup 1)) (const_int -1)))]
1218 [(set_attr "type" "arith")])
1220 (define_insn "*neg<mode>2_insn_set_overflow"
1221 [(set (match_operand:I 0 "register_operand" "=r")
1222 (neg:I (match_operand:I 1 "register_operand" "r")))
1223 (set (reg:CCV R_FLAGS)
1224 (compare:CCV (neg:I (match_dup 1))
1225 (unspec:I [(match_dup 1)] UNSPEC_NEGV)))]
1228 [(set_attr "type" "arith")])
1230 (define_expand "negdi2"
1231 [(set (match_operand:DI 0 "register_operand" "")
1232 (neg:DI (match_operand:DI 1 "register_operand" "")))]
1235 (define_insn_and_split "*negdi2_insn"
1236 [(set (match_operand:DI 0 "register_operand" "=&r")
1237 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
1238 "ok_for_simple_arith_logic_operands (operands, DImode)"
1243 visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]);
1246 [(set_attr "type" "arith2")])
1249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1251 ;; Integer Multiply (non-widening and widening, signed and unsigned)
1253 ;; Only SI mode is supported.
1255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1258 ; The mults and multu instructions clear MDC but we only pretend that they
1259 ; clobber it to keep things relatively simple.
1261 (define_insn "mulsi3"
1262 [(set (match_operand:SI 0 "register_operand" "=b")
1263 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1264 (match_operand:SI 2 "register_operand" "r")))
1265 (clobber (reg:SI R_MDC))]
1268 [(set_attr "type" "mul")])
1270 ; The names are mulsidi3 and umulsidi3 here.
1272 (define_insn "<u>mulsidi3"
1273 [(set (match_operand:DI 0 "register_operand" "=b")
1274 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1275 (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))
1276 (clobber (reg:SI R_MDC))]
1279 [(set_attr "type" "mul")])
1281 ; But they are smulsi3_highpart and umulsi3_highpart here.
1283 (define_insn_and_split "<su>mulsi3_highpart"
1284 [(set (match_operand:SI 0 "register_operand" "=r")
1287 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1288 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
1290 (clobber (reg:DI R_MDB))
1291 (clobber (reg:SI R_MDC))]
1295 [(parallel [(set (reg:DI R_MDB)
1296 (mult:DI (any_extend:DI (match_dup 1))
1297 (any_extend:DI (match_dup 2))))
1298 (clobber (reg:SI R_MDC))])
1299 (set (match_dup 0) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
1301 [(set_attr "type" "multi")])
1304 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1306 ;; Integer divide and modulus (signed and unsigned)
1308 ;; Only SI mode is supported.
1310 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1313 (define_insn "*divmodsi4_insn"
1314 [(set (match_operand:SI 0 "register_operand" "=b")
1315 (div:SI (match_operand:SI 1 "register_operand" "0")
1316 (match_operand:SI 2 "register_operand" "r")))
1317 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))]
1320 [(set_attr "type" "div")])
1322 (define_insn_and_split "divmodsi4"
1323 [(set (match_operand:SI 0 "register_operand" "=b")
1324 (div:SI (match_operand:SI 1 "register_operand" "0")
1325 (match_operand:SI 2 "register_operand" "r")))
1326 (set (match_operand:SI 3 "register_operand" "=r")
1327 (mod:SI (match_dup 1) (match_dup 2)))
1328 (clobber (reg:SI R_MDC))]
1332 [(parallel [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2)))
1333 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))])
1334 (set (match_dup 3) (reg:SI R_MDC))]
1336 [(set_attr "type" "multi")])
1338 (define_insn "*udivmodsi4_insn"
1339 [(set (match_operand:SI 0 "register_operand" "=b")
1340 (udiv:SI (match_operand:SI 1 "register_operand" "0")
1341 (match_operand:SI 2 "register_operand" "r")))
1342 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))]
1345 [(set_attr "type" "div")])
1347 (define_insn_and_split "udivmodsi4"
1348 [(set (match_operand:SI 0 "register_operand" "=b")
1349 (udiv:SI (match_operand:SI 1 "register_operand" "0")
1350 (match_operand:SI 2 "register_operand" "r")))
1351 (set (match_operand:SI 3 "register_operand" "=r")
1352 (umod:SI (match_dup 1) (match_dup 2)))
1353 (clobber (reg:SI R_MDC))]
1357 [(parallel [(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2)))
1358 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))])
1359 (set (match_dup 3) (reg:SI R_MDC))]
1361 [(set_attr "type" "multi")])
1363 ; FIXME. How do we persuade the compiler to use 64/32 bit divides directly ?
1365 (define_insn "*divds"
1366 [(set (reg:DI R_MDB)
1367 (div:DI (reg:DI R_MDB) (sign_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1368 (set (reg:SI R_MDC) (truncate:SI (mod:DI (reg:DI R_MDB) (sign_extend:DI (match_dup 0)))))]
1371 [(set_attr "type" "divd")])
1373 (define_insn "*divdu"
1374 [(set (reg:DI R_MDB)
1375 (udiv:DI (reg:DI R_MDB) (zero_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1376 (set (reg:SI R_MDC) (truncate:SI (umod:DI (reg:DI R_MDB) (zero_extend:DI (match_dup 0)))))]
1379 [(set_attr "type" "divd")])
1381 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1383 ;; Bitwise Logical AND
1385 ;; Modes QI, HI and SI are supported directly.
1387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1390 (define_expand "and<mode>3"
1391 [(set (match_operand:I 0 "register_operand" "")
1392 (and:I (match_operand:I 1 "register_operand" "")
1393 (match_operand:I 2 "register_operand" "")))]
1396 (define_insn_and_split "*and<mode>3_insn"
1397 [(set (match_operand:I 0 "register_operand" "=r")
1398 (and:I (match_operand:I 1 "register_operand" "%r")
1399 (match_operand:I 2 "register_operand" "r")))]
1400 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1403 [(parallel [(set (match_dup 0)
1404 (and:I (match_dup 1) (match_dup 2)))
1405 (clobber (reg:CC R_FLAGS))])]
1407 [(set_attr "type" "logic")])
1409 (define_insn "*and<mode>3_insn<subst_logic>"
1410 [(set (match_operand:I 0 "register_operand" "=r")
1411 (and:I (match_operand:I 1 "register_operand" "%r")
1412 (match_operand:I 2 "register_operand" "r")))
1413 (clobber (reg:CC R_FLAGS))]
1416 [(set_attr "type" "logic")])
1419 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1421 ;; Bitwise Inclusive Logical OR
1423 ;; Modes QI, HI and SI are supported directly.
1425 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1428 (define_expand "ior<mode>3"
1429 [(set (match_operand:I 0 "register_operand" "")
1430 (ior:I (match_operand:I 1 "register_operand" "")
1431 (match_operand:I 2 "register_operand" "")))]
1434 (define_insn_and_split "*ior<mode>3_insn"
1435 [(set (match_operand:I 0 "register_operand" "=r")
1436 (ior:I (match_operand:I 1 "register_operand" "%r")
1437 (match_operand:I 2 "register_operand" "r")))]
1438 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1441 [(parallel [(set (match_dup 0)
1442 (ior:I (match_dup 1) (match_dup 2)))
1443 (clobber (reg:CC R_FLAGS))])]
1445 [(set_attr "type" "logic")])
1447 (define_insn "*ior<mode>3_insn<subst_logic>"
1448 [(set (match_operand:I 0 "register_operand" "=r")
1449 (ior:I (match_operand:I 1 "register_operand" "%r")
1450 (match_operand:I 2 "register_operand" "r")))
1451 (clobber (reg:CC R_FLAGS))]
1454 [(set_attr "type" "logic")])
1457 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1459 ;; Bitwise Exclusive Logical OR
1461 ;; Modes QI, HI and SI are supported directly.
1463 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1466 (define_expand "xor<mode>3"
1467 [(set (match_operand:I 0 "register_operand" "")
1468 (xor:I (match_operand:I 1 "register_operand" "")
1469 (match_operand:I 2 "register_operand" "")))]
1472 (define_insn_and_split "*xor<mode>3_insn"
1473 [(set (match_operand:I 0 "register_operand" "=r")
1474 (xor:I (match_operand:I 1 "register_operand" "%r")
1475 (match_operand:I 2 "register_operand" "r")))]
1476 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1479 [(parallel [(set (match_dup 0)
1480 (xor:I (match_dup 1) (match_dup 2)))
1481 (clobber (reg:CC R_FLAGS))])]
1483 [(set_attr "type" "logic")])
1485 (define_insn "*xor<mode>3_insn<subst_logic>"
1486 [(set (match_operand:I 0 "register_operand" "=r")
1487 (xor:I (match_operand:I 1 "register_operand" "%r")
1488 (match_operand:I 2 "register_operand" "r")))
1489 (clobber (reg:CC R_FLAGS))]
1492 [(set_attr "type" "logic")])
1495 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1497 ;; Bitwise Logical NOT
1499 ;; Modes QI, HI and SI are supported directly.
1501 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1504 (define_expand "one_cmpl<mode>2"
1505 [(set (match_operand:I 0 "register_operand" "")
1506 (not:I (match_operand:I 1 "reg_or_0_operand" "")))]
1509 (define_insn_and_split "*one_cmpl<mode>2_insn"
1510 [(set (match_operand:I 0 "register_operand" "=r")
1511 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))]
1512 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1515 [(parallel [(set (match_dup 0) (not:I (match_dup 1)))
1516 (clobber (reg:CC R_FLAGS))])]
1518 [(set_attr "type" "logic")])
1520 (define_insn "*one_cmpl<mode>2_insn<subst_logic>"
1521 [(set (match_operand:I 0 "register_operand" "=r")
1522 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))
1523 (clobber (reg:CC R_FLAGS))]
1526 [(set_attr "type" "logic")])
1529 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1531 ;; Arithmetic Shift Left
1533 ;; Modes QI, HI, SI and DI are supported directly.
1535 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1538 (define_expand "ashl<mode>3"
1539 [(set (match_operand:I 0 "register_operand" "")
1540 (ashift:I (match_operand:I 1 "register_operand" "")
1541 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1544 (define_insn_and_split "*ashl<mode>3_insn"
1545 [(set (match_operand:I 0 "register_operand" "=r,r")
1546 (ashift:I (match_operand:I 1 "register_operand" "r,r")
1547 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1548 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1551 [(parallel [(set (match_dup 0)
1552 (ashift:I (match_dup 1) (match_dup 2)))
1553 (clobber (reg:CC R_FLAGS))])]
1555 [(set_attr "type" "arith")])
1557 (define_insn "*ashl<mode>3_insn<subst_arith>"
1558 [(set (match_operand:I 0 "register_operand" "=r,r")
1559 (ashift:I (match_operand:I 1 "register_operand" "r,r")
1560 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1561 (clobber (reg:CC R_FLAGS))]
1564 [(set_attr "type" "arith")])
1566 (define_insn "ashldi3"
1567 [(set (match_operand:DI 0 "register_operand" "=b,r")
1568 (ashift:DI (match_operand:DI 1 "register_operand" "0,r")
1569 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1570 (clobber (reg:SI R_MDC))]
1575 [(set_attr "type" "shiftdi,multi")])
1578 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1579 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
1581 (clobber (reg:SI R_MDC))]
1583 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 4))
1584 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
1588 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1590 ;; Arithmetic Shift Right
1592 ;; Modes QI, HI, SI and DI are supported directly.
1594 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1597 (define_expand "ashr<mode>3"
1598 [(set (match_operand:I 0 "register_operand" "")
1599 (ashiftrt:I (match_operand:I 1 "register_operand" "")
1600 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1603 (define_insn_and_split "*ashr<mode>3_insn"
1604 [(set (match_operand:I 0 "register_operand" "=r,r")
1605 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r")
1606 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1607 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1610 [(parallel [(set (match_dup 0)
1611 (ashiftrt:I (match_dup 1) (match_dup 2)))
1612 (clobber (reg:CC R_FLAGS))])]
1614 [(set_attr "type" "logic")])
1616 (define_insn "*ashr<mode>3_insn<subst_logic>"
1617 [(set (match_operand:I 0 "register_operand" "=r,r")
1618 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r")
1619 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1620 (clobber (reg:CC R_FLAGS))]
1623 [(set_attr "type" "logic")])
1625 (define_insn "ashrdi3"
1626 [(set (match_operand:DI 0 "register_operand" "=b,r")
1627 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1628 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1629 (clobber (reg:SI R_MDC))]
1634 [(set_attr "type" "shiftdi,multi")])
1637 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1638 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1640 (clobber (reg:SI R_MDC))]
1642 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1643 (parallel [(set (subreg:SI (match_dup 0) 0)
1644 (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))
1645 (clobber (reg:CC R_FLAGS))])]
1649 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1651 ;; Logical Shift Right
1653 ;; Modes QI, HI, SI and DI are supported directly.
1655 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1658 (define_expand "lshr<mode>3"
1659 [(set (match_operand:I 0 "register_operand" "")
1660 (lshiftrt:I (match_operand:I 1 "register_operand" "")
1661 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1664 (define_insn_and_split "*lshr<mode>3_insn"
1665 [(set (match_operand:I 0 "register_operand" "=r,r")
1666 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r")
1667 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1668 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1671 [(parallel [(set (match_dup 0)
1672 (lshiftrt:I (match_dup 1) (match_dup 2)))
1673 (clobber (reg:CC R_FLAGS))])]
1675 [(set_attr "type" "logic")])
1677 (define_insn "*lshr<mode>3_insn<subst_logic>"
1678 [(set (match_operand:I 0 "register_operand" "=r,r")
1679 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r")
1680 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1681 (clobber (reg:CC R_FLAGS))]
1684 [(set_attr "type" "logic")])
1686 (define_insn "lshrdi3"
1687 [(set (match_operand:DI 0 "register_operand" "=b,r")
1688 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1689 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1690 (clobber (reg:SI R_MDC))]
1695 [(set_attr "type" "shiftdi,multi")])
1698 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1699 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1701 (clobber (reg:SI R_MDC))]
1703 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1704 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
1708 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1712 ;; Truncations among modes QI, HI, SI and DI are supported directly.
1714 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1717 (define_expand "trunchiqi2"
1718 [(set (match_operand:QI 0 "register_operand" "")
1719 (truncate:QI (match_operand:HI 1 "register_operand" "")))]
1722 (define_insn_and_split "*trunchiqi2_insn"
1723 [(set (match_operand:QI 0 "register_operand" "=r")
1724 (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
1725 "ok_for_simple_arith_logic_operands (operands, QImode)"
1728 [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1)))
1729 (clobber (reg:CC R_FLAGS))])]
1731 [(set_attr "type" "logic")])
1733 (define_insn "*trunchiqi2_insn<subst_logic>"
1734 [(set (match_operand:QI 0 "register_operand" "=r")
1735 (truncate:QI (match_operand:HI 1 "register_operand" "r")))
1736 (clobber (reg:CC R_FLAGS))]
1739 [(set_attr "type" "logic")])
1741 (define_expand "truncsihi2"
1742 [(set (match_operand:HI 0 "register_operand" "")
1743 (truncate:HI (match_operand:SI 1 "register_operand" "")))]
1746 (define_insn_and_split "*truncsihi2_insn"
1747 [(set (match_operand:HI 0 "register_operand" "=r")
1748 (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
1749 "ok_for_simple_arith_logic_operands (operands, HImode)"
1752 [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1)))
1753 (clobber (reg:CC R_FLAGS))])]
1755 [(set_attr "type" "logic")])
1757 (define_insn "*truncsihi2_insn<subst_logic>"
1758 [(set (match_operand:HI 0 "register_operand" "=r")
1759 (truncate:HI (match_operand:SI 1 "register_operand" "r")))
1760 (clobber (reg:CC R_FLAGS))]
1763 [(set_attr "type" "logic")])
1765 (define_expand "truncdisi2"
1766 [(set (match_operand:SI 0 "register_operand" "")
1767 (truncate:SI (match_operand:DI 1 "register_operand" "")))]
1770 (define_insn_and_split "*truncdisi2_insn"
1771 [(set (match_operand:SI 0 "register_operand" "=r")
1772 (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
1773 "ok_for_simple_arith_logic_operands (operands, SImode)"
1776 [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1)))
1777 (clobber (reg:CC R_FLAGS))])]
1779 [(set_attr "type" "logic")])
1781 (define_insn "*truncdisi2_insn<subst_logic>"
1782 [(set (match_operand:SI 0 "register_operand" "=r")
1783 (truncate:SI (match_operand:DI 1 "register_operand" "r")))
1784 (clobber (reg:CC R_FLAGS))]
1787 [(set_attr "type" "logic")])
1790 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1794 ;; Sign-extensions among modes QI, HI, SI and DI are supported directly.
1796 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1799 (define_expand "extendqihi2"
1800 [(set (match_operand:HI 0 "register_operand" "")
1801 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1804 (define_insn_and_split "*extendqihi2_insn"
1805 [(set (match_operand:HI 0 "register_operand" "=r")
1806 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1807 "ok_for_simple_arith_logic_operands (operands, HImode)"
1810 [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
1811 (clobber (reg:CC R_FLAGS))])]
1813 [(set_attr "type" "logic")])
1815 (define_insn "*extendqihi2_insn<subst_logic>"
1816 [(set (match_operand:HI 0 "register_operand" "=r")
1817 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))
1818 (clobber (reg:CC R_FLAGS))]
1821 [(set_attr "type" "logic")])
1823 (define_expand "extendqisi2"
1824 [(set (match_operand:SI 0 "register_operand" "")
1825 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1828 (define_insn_and_split "*extendqisi2_insn"
1829 [(set (match_operand:SI 0 "register_operand" "=r")
1830 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1831 "ok_for_simple_arith_logic_operands (operands, SImode)"
1834 [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
1835 (clobber (reg:CC R_FLAGS))])]
1837 [(set_attr "type" "logic")])
1839 (define_insn "*extendqisi2_insn<subst_logic>"
1840 [(set (match_operand:SI 0 "register_operand" "=r")
1841 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))
1842 (clobber (reg:CC R_FLAGS))]
1845 [(set_attr "type" "logic")])
1847 (define_expand "extendhisi2"
1848 [(set (match_operand:SI 0 "register_operand" "")
1849 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1852 (define_insn_and_split "*extendhisi2_insn"
1853 [(set (match_operand:SI 0 "register_operand" "=r")
1854 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1855 "ok_for_simple_arith_logic_operands (operands, SImode)"
1858 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1859 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
1860 (clobber (reg:CC R_FLAGS))])]
1862 [(set_attr "type" "logic")])
1864 (define_insn "*extendhisi2_insn<subst_logic>"
1865 [(set (match_operand:SI 0 "register_operand" "=r")
1866 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))
1867 (clobber (reg:CC R_FLAGS))]
1870 [(set_attr "type" "logic")])
1872 (define_expand "extendsidi2"
1873 [(set (match_operand:DI 0 "register_operand" "")
1874 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
1877 (define_insn_and_split "*extendsidi2_insn"
1878 [(set (match_operand:DI 0 "register_operand" "=r")
1879 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1880 "ok_for_simple_arith_logic_operands (operands, DImode)"
1883 [(parallel [(set (match_dup 3) (match_dup 1))
1884 (clobber (reg:CC R_FLAGS))])
1885 (parallel [(set (match_dup 2)
1886 (ashiftrt:SI (match_dup 1) (const_int 31)))
1887 (clobber (reg:CC R_FLAGS))])]
1889 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1890 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1892 [(set_attr "type" "multi")])
1895 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1899 ;; Zero-extensions among modes QI, HI, SI and DI are supported directly.
1901 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1904 ; QI is zero-extended to wider modes by shifting left and then performing
1905 ; a logical shift right to insert the zeroes. This avoids the need to use
1908 (define_expand "zero_extendqihi2"
1909 [(set (match_operand:HI 0 "register_operand" "")
1910 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1913 (define_insn_and_split "*zero_extendqihi2_insn"
1914 [(set (match_operand:HI 0 "register_operand" "=r")
1915 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1916 "ok_for_simple_arith_logic_operands (operands, HImode)"
1919 [(parallel [(set (match_dup 0)
1920 (ashift:HI (match_dup 2) (const_int 8)))
1921 (clobber (reg:CC R_FLAGS))])
1922 (parallel [(set (match_dup 0)
1923 (lshiftrt:HI (match_dup 0) (const_int 8)))
1924 (clobber (reg:CC R_FLAGS))])]
1926 operands[2] = gen_rtx_SUBREG (HImode, operands[1], 0);
1928 [(set_attr "type" "multi")])
1930 (define_expand "zero_extendqisi2"
1931 [(set (match_operand:SI 0 "register_operand" "")
1932 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1935 (define_insn_and_split "*zero_extendqisi2_insn"
1936 [(set (match_operand:SI 0 "register_operand" "=r")
1937 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1938 "ok_for_simple_arith_logic_operands (operands, SImode)"
1941 [(parallel [(set (match_dup 0)
1942 (ashift:SI (match_dup 2) (const_int 24)))
1943 (clobber (reg:CC R_FLAGS))])
1944 (parallel [(set (match_dup 0)
1945 (lshiftrt:SI (match_dup 0) (const_int 24)))
1946 (clobber (reg:CC R_FLAGS))])]
1948 operands[2] = gen_rtx_SUBREG (SImode, operands[1], 0);
1950 [(set_attr "type" "multi")])
1952 (define_insn "zero_extendhisi2"
1953 [(set (match_operand:SI 0 "register_operand" "=r")
1954 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1957 [(set_attr "type" "imm_reg")])
1959 (define_expand "zero_extendsidi2"
1960 [(set (match_operand:DI 0 "register_operand" "")
1961 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
1964 (define_insn_and_split "*zero_extendsidi2_insn"
1965 [(set (match_operand:DI 0 "register_operand" "=r")
1966 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1967 "ok_for_simple_arith_logic_operands (operands, DImode)"
1970 [(parallel [(set (match_dup 3) (match_dup 1))
1971 (clobber (reg:CC R_FLAGS))])
1972 (set (match_dup 2) (const_int 0))]
1974 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1975 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1977 [(set_attr "type" "multi")])
1980 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1984 ;; Only SI mode is supported directly.
1986 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1989 ; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB.
1991 (define_insn "*btst<mode>"
1992 [(set (reg:CCC R_FLAGS)
1993 (compare:CCC (zero_extract:I
1994 (match_operand:I 0 "register_operand" "r")
1996 (match_operand:QI 1 "const_shift_operand" "K"))
1999 "lsr<s> r0,%0,<b>-%1"
2000 [(set_attr "type" "logic")])
2003 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2005 ;; Integer overflow tests
2007 ;; Modes QI, HI and SI are supported directly.
2009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2012 (define_insn "*addv_tst<mode>"
2013 [(set (reg:CCV R_FLAGS)
2014 (compare:CCV (match_operand:I 0 "register_operand" "r")
2015 (unspec:I [(match_operand:I 1 "register_operand" "%r")
2016 (match_operand:I 2 "register_operand" "r")]
2020 [(set_attr "type" "arith")])
2022 (define_insn "*subv_tst<mode>"
2023 [(set (reg:CCV R_FLAGS)
2024 (compare:CCV (match_operand:I 0 "register_operand" "r")
2025 (unspec:I [(match_operand:I 1 "reg_or_0_operand" "rO")
2026 (match_operand:I 2 "register_operand" "r")]
2030 [(set_attr "type" "arith")])
2032 (define_insn "*negv_tst<mode>"
2033 [(set (reg:CCV R_FLAGS)
2034 (compare:CCV (match_operand:I 0 "register_operand" "r")
2035 (unspec:I [(match_operand:I 1 "register_operand" "r")]
2039 [(set_attr "type" "arith")])
2042 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2044 ;; Integer comparisons
2046 ;; Modes QI, HI and SI are supported directly.
2048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2051 (define_insn "*cmp<mode>"
2052 [(set (reg:CC R_FLAGS)
2053 (compare:CC (match_operand:I 0 "register_operand" "r")
2054 (match_operand:I 1 "reg_or_0_operand" "rO")))]
2057 [(set_attr "type" "cmp")])
2059 (define_insn "*cmp<mode>_sne"
2060 [(set (reg:CCC R_FLAGS)
2061 (compare:CCC (not:I (match_operand:I 0 "register_operand" "r"))
2065 [(set_attr "type" "cmp")])
2068 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2070 ;; Single float operations
2072 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2075 (define_insn "addsf3"
2076 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2077 (plus:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2078 (match_operand:SF 2 "fp_reg_operand" "f")))]
2081 [(set_attr "type" "fp")])
2083 (define_insn "subsf3"
2084 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2085 (minus:SF (match_operand:SF 1 "fp_reg_operand" "f")
2086 (match_operand:SF 2 "fp_reg_operand" "f")))]
2089 [(set_attr "type" "fp")])
2091 (define_insn "mulsf3"
2092 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2093 (mult: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 "divsf3"
2100 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2101 (div:SF (match_operand:SF 1 "fp_reg_operand" "f")
2102 (match_operand:SF 2 "fp_reg_operand" "f")))]
2105 [(set_attr "type" "fdiv")])
2107 (define_insn "sqrtsf2"
2108 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2109 (sqrt:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2112 [(set_attr "type" "fsqrt")])
2114 (define_insn "negsf2"
2115 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2116 (neg:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2119 [(set_attr "type" "fmove")])
2121 (define_insn "abssf2"
2122 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2123 (abs:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2126 [(set_attr "type" "fmove")])
2128 (define_expand "copysignsf3"
2129 [(match_operand:SF 0 "register_operand" "")
2130 (match_operand:SF 1 "nonmemory_operand" "")
2131 (match_operand:SF 2 "register_operand" "")]
2132 "TARGET_FPU && !TARGET_FPU_IEEE"
2134 visium_expand_copysign (operands, SFmode);
2139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2141 ;; Single float <-> single integer conversions for !TARGET_FPU_IEEE
2143 ;; An FMOVE instruction converts a signalling NaN (zero high order bit of the
2144 ;; mantissa) to a quiet NaN (-1). This is acceptable when the data to be
2145 ;; moved is in fact a floating-point number, but to avoid nasty surprises
2146 ;; integers must in general be kept out of the floating-point registers.
2147 ;; HARD_REGNO_MODE_OK thus only allows SFmode in these registers.
2148 ;; However, since FTOI and ITOF use floating-point registers for both their
2149 ;; inputs and outputs, to use these instructions integers must transiently
2150 ;; occupy such registers. To disguise this from the compiler, UNSPECs are
2151 ;; used for floating-point operations on integers and floating from general
2152 ;; register to floating-point register and fixing in the reverse direction
2153 ;; are only split into the individual UNSPEC operations after reload.
2155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2158 (define_insn "*fload_no_ieee"
2159 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2160 (unspec:SF [(match_operand:SI 1 "register_operand" "r")] UNSPEC_FLOAD))]
2161 "TARGET_FPU && !TARGET_FPU_IEEE"
2163 [(set_attr "type" "reg_fp")])
2165 (define_insn "*itof_no_ieee"
2166 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2167 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_ITOF))]
2168 "TARGET_FPU && !TARGET_FPU_IEEE"
2170 [(set_attr "type" "itof")])
2172 (define_insn_and_split "*floatsisf2_no_ieee"
2173 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2174 (float:SF (match_operand:SI 1 "register_operand" "r")))]
2175 "TARGET_FPU && !TARGET_FPU_IEEE"
2177 "&& reload_completed"
2179 (unspec:SF [(match_dup 1)] UNSPEC_FLOAD))
2181 (unspec:SF [(match_dup 0)] UNSPEC_ITOF))]
2183 [(set_attr "type" "multi")])
2185 (define_insn "*ftoi_no_ieee"
2186 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2187 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FTOI))]
2188 "TARGET_FPU && !TARGET_FPU_IEEE"
2190 [(set_attr "type" "ftoi")])
2192 (define_insn "*fstore_no_ieee"
2193 [(set (match_operand:SI 0 "register_operand" "=r")
2194 (unspec:SI [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FSTORE))]
2195 "TARGET_FPU && !TARGET_FPU_IEEE"
2197 [(set_attr "type" "fp_reg")])
2199 (define_insn_and_split "fix_truncsfsi2_no_ieee"
2200 [(set (match_operand:SI 0 "register_operand" "=r")
2201 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))
2202 (clobber (match_scratch:SF 2 "=1"))]
2203 "TARGET_FPU && !TARGET_FPU_IEEE"
2205 "&& reload_completed"
2207 (unspec:SF [(match_dup 1)] UNSPEC_FTOI))
2209 (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))]
2211 [(set_attr "type" "multi")])
2214 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2216 ;; Single float <-> single integer conversions
2218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2221 (define_insn "*itof"
2222 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2223 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2226 [(set_attr "type" "itof")])
2228 (define_expand "floatsisf2"
2229 [(set (match_operand:SF 0 "fp_reg_operand" "")
2230 (float:SF (match_operand:SI 1 "register_operand" "")))]
2234 (define_insn "*ftoi"
2235 [(set (match_operand:SI 0 "register_operand" "=f")
2236 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))]
2239 [(set_attr "type" "ftoi")])
2241 (define_expand "fix_truncsfsi2"
2242 [(set (match_operand:SI 0 "register_operand" "")
2243 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" ""))))]
2246 if (!TARGET_FPU_IEEE)
2248 emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1]));
2254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2256 ;; Single float comparisons
2258 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2261 (define_insn "*cmpsf_fp"
2262 [(set (reg:CCFP R_FLAGS)
2263 (compare:CCFP (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2264 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2265 "TARGET_FPU && reload_completed"
2267 [(set_attr "type" "fcmp")])
2269 (define_insn "*cmpsf_fpe"
2270 [(set (reg:CCFPE R_FLAGS)
2271 (compare:CCFPE (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2272 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2273 "TARGET_FPU && reload_completed"
2275 [(set_attr "type" "fcmp")])
2278 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2280 ;; Conditional branch instructions
2282 ;; Note - we do not specify the two instructions necessary to perform
2283 ;; a compare-and-branch in the cbranch<mode>4 pattern because that would
2284 ;; allow the comparison to be moved away from the jump before the reload
2285 ;; pass has completed. That would be problematical because reload can
2286 ;; generate instructions in between which would clobber the CC register.
2288 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2291 (define_expand "cbranch<mode>4"
2293 (if_then_else (match_operator 0 "ordered_comparison_operator"
2294 [(match_operand:I 1 "register_operand")
2295 (match_operand:I 2 "reg_or_0_operand")])
2296 (label_ref (match_operand 3 ""))
2301 (define_insn_and_split "*cbranch<mode>4_insn"
2303 (if_then_else (match_operator 0 "ordered_comparison_operator"
2304 [(match_operand:I 1 "register_operand" "r")
2305 (match_operand:I 2 "reg_or_0_operand" "rO")])
2306 (label_ref (match_operand 3 ""))
2313 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2317 [(set_attr "type" "cmp")])
2319 (define_insn_and_split "*cbranch<mode>4_addv_insn"
2321 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2322 [(match_operand:I 1 "register_operand" "r")
2323 (unspec:I [(match_operand:I 2 "register_operand" "%r")
2324 (match_operand:I 3 "register_operand" "r")]
2326 (label_ref (match_operand 4 ""))
2333 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2334 XEXP (operands[0], 1), operands[4]);
2337 [(set_attr "type" "cmp")])
2339 (define_insn_and_split "*cbranch<mode>4_subv_insn"
2341 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2342 [(match_operand:I 1 "register_operand" "r")
2343 (unspec:I [(match_operand:I 2 "reg_or_0_operand" "rO")
2344 (match_operand:I 3 "register_operand" "r")]
2346 (label_ref (match_operand 4 ""))
2353 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2354 XEXP (operands[0], 1), operands[4]);
2357 [(set_attr "type" "cmp")])
2359 (define_insn_and_split "*cbranch<mode>4_negv_insn"
2361 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2362 [(match_operand:I 1 "register_operand" "r")
2363 (unspec:I [(match_operand:I 2 "register_operand" "r")]
2365 (label_ref (match_operand 3 ""))
2372 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2373 XEXP (operands[0], 1), operands[3]);
2376 [(set_attr "type" "cmp")])
2378 (define_insn_and_split "*cbranch<mode>4_btst_insn"
2380 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2382 (match_operand:I 1 "register_operand" "r")
2384 (match_operand:QI 2 "const_shift_operand" "K"))
2386 (label_ref (match_operand 3 ""))
2393 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2394 XEXP (operands[0], 1), operands[3]);
2397 [(set_attr "type" "cmp")])
2399 (define_expand "cbranchsf4"
2401 (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2402 [(match_operand:SF 1 "fp_reg_operand")
2403 (match_operand:SF 2 "fp_reg_or_0_operand")])
2404 (label_ref (match_operand 3 ""))
2409 (define_insn_and_split "*cbranchsf4_insn"
2411 (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2412 [(match_operand:SF 1 "fp_reg_operand" "f")
2413 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")])
2414 (label_ref (match_operand 3 ""))
2418 "&& reload_completed"
2421 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2425 [(set_attr "type" "fcmp")])
2427 ; Now match both normal and inverted branches.
2429 (define_insn "*normal_branch"
2431 (if_then_else (match_operator 1 "visium_branch_operator"
2432 [(reg R_FLAGS) (const_int 0)])
2433 (label_ref (match_operand 0 ""))
2437 return output_cbranch (operands[0], GET_CODE (operands[1]),
2438 GET_MODE (XEXP (operands[1], 0)), 0, insn);
2440 [(set_attr "type" "branch")])
2442 (define_insn "*inverted_branch"
2444 (if_then_else (match_operator 1 "visium_branch_operator"
2445 [(reg R_FLAGS) (const_int 0)])
2447 (label_ref (match_operand 0 ""))))]
2450 return output_cbranch (operands[0], GET_CODE (operands[1]),
2451 GET_MODE (XEXP (operands[1], 0)), 1, insn);
2453 [(set_attr "type" "branch")])
2455 ; And then match both normal and inverted returns.
2457 (define_insn "*cond_<return_str>return"
2459 (if_then_else (match_operator 0 "visium_branch_operator"
2460 [(reg R_FLAGS) (const_int 0)])
2463 "<return_pred> && reload_completed"
2465 return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2466 GET_MODE (XEXP (operands[0], 0)), 0, insn);
2468 [(set_attr "type" "ret")])
2470 (define_insn "*inverted_cond_<return_str>return"
2472 (if_then_else (match_operator 0 "visium_branch_operator"
2473 [(reg R_FLAGS) (const_int 0)])
2476 "<return_pred> && reload_completed"
2478 return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2479 GET_MODE (XEXP (operands[0], 0)), 1, insn);
2481 [(set_attr "type" "ret")])
2484 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2486 ;; Unconditional branch instructions
2488 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2493 (label_ref (match_operand 0 "" "")))]
2496 return output_ubranch (operands[0], insn);
2498 [(set_attr "type" "branch")])
2500 (define_insn "indirect_jump"
2502 (match_operand:SI 0 "register_operand" "r"))]
2504 "bra tr,%0,r0%# ;indirect jump"
2505 [(set_attr "type" "abs_branch")])
2507 (define_insn "tablejump"
2509 (match_operand:SI 0 "register_operand" "r"))
2510 (use (label_ref (match_operand 1 "" "")))]
2512 "bra tr,%0,r0%# ;tablejump"
2513 [(set_attr "type" "abs_branch")])
2516 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2518 ;; trap instructions
2520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2524 [(trap_if (const_int 1) (const_int 0))]
2527 [(set_attr "type" "trap")])
2530 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2532 ;; Subprogram call instructions
2534 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2537 ; Subroutine call instruction returning no value. Operand 0 is the function
2538 ; to call; operand 1 is the number of bytes of arguments pushed (in mode
2539 ; 'SImode', except it is normally a 'const_int'); operand 2 is the number of
2540 ; registers used as operands.
2542 (define_expand "call"
2543 [(parallel [(call (match_operand 0 "" "")
2544 (match_operand 1 "" ""))
2545 (use (match_operand 2 "" ""))
2546 (clobber (match_dup 3))])]
2549 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2550 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2553 operands[2] = const0_rtx;
2555 operands[3] = gen_rtx_REG (Pmode, R_LINK);
2558 (define_insn "*call_internal"
2559 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,!r"))
2560 (match_operand 1 "" ""))
2561 (use (match_operand 2 "" ""))
2562 (clobber (match_operand 3 "" ""))]
2563 "!SIBLING_CALL_P (insn)"
2564 "bra tr,%0,%3%# ;call"
2565 [(set_attr "type" "call")])
2567 ; Subroutine call instruction returning a value. Operand 0 is the hard
2568 ; register in which the value is returned. There are three more operands, the
2569 ; same as the three operands of the 'call' instruction (but with numbers
2570 ; increased by one).
2572 (define_expand "call_value"
2573 [(parallel [(set (match_operand 0 "register_operand" "")
2574 (call (match_operand 1 "" "")
2575 (match_operand 2 "" "")))
2576 (use (match_operand 3 "" ""))
2577 (clobber (match_dup 4))])]
2580 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2581 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2584 operands[3] = const0_rtx;
2586 operands[4] = gen_rtx_REG (Pmode, R_LINK);
2589 (define_insn "*call_value_internal"
2590 [(set (match_operand 0 "register_operand" "")
2591 (call (mem:SI (match_operand:SI 1 "register_operand" "l,!r"))
2592 (match_operand 2 "" "")))
2593 (use (match_operand 3 "" ""))
2594 (clobber (match_operand 4 "" ""))]
2595 "!SIBLING_CALL_P (insn)"
2596 "bra tr,%1,%4%# ;call value"
2597 [(set_attr "type" "call")])
2599 ; Tail calls are similar, except that the link register is not used. But
2600 ; we don't use r0 as the destination register of the branch because we want
2601 ; the Branch Pre-decode Logic of the GR6 to use the Address Load Array to
2602 ; predict the branch target.
2604 (define_expand "sibcall"
2605 [(parallel [(call (match_operand 0 "" "")
2606 (match_operand 1 "" ""))
2607 (use (match_operand 2 "" ""))
2608 (clobber (match_dup 3))])]
2611 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2612 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2615 operands[2] = const0_rtx;
2617 operands[3] = gen_rtx_SCRATCH (SImode);
2620 (define_insn "*sibcall_internal"
2621 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
2622 (match_operand 1 "" ""))
2623 (use (match_operand 2 "" ""))
2624 (clobber (match_scratch:SI 3 "=0"))]
2625 "SIBLING_CALL_P (insn)"
2626 "bra tr,%0,%0%# ;sibcall"
2627 [(set_attr "type" "call")])
2629 (define_expand "sibcall_value"
2630 [(parallel [(set (match_operand 0 "register_operand" "")
2631 (call (match_operand 1 "" "")
2632 (match_operand 2 "" "")))
2633 (use (match_operand 3 "" ""))
2634 (clobber (match_dup 4))])]
2637 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2638 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2641 operands[3] = const0_rtx;
2643 operands[4] = gen_rtx_SCRATCH (SImode);
2646 (define_insn "*sibcall_value_internal"
2647 [(set (match_operand 0 "register_operand" "")
2648 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
2649 (match_operand 2 "" "")))
2650 (use (match_operand 3 "" ""))
2651 (clobber (match_scratch:SI 4 "=1"))]
2652 "SIBLING_CALL_P (insn)"
2653 "bra tr,%1,%1%# ;sibcall value"
2654 [(set_attr "type" "call")])
2656 ; Call subroutine returning any type.
2657 (define_expand "untyped_call"
2658 [(parallel [(call (match_operand 0 "" "")
2660 (match_operand 1 "" "")
2661 (match_operand 2 "" "")])]
2666 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
2668 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2670 rtx set = XVECEXP (operands[2], 0, i);
2671 emit_move_insn (SET_DEST (set), SET_SRC (set));
2674 /* The optimizer does not know that the call sets the function value
2675 registers we stored in the result block. We avoid problems by
2676 claiming that all hard registers are used and clobbered at this
2678 emit_insn (gen_blockage ());
2684 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2686 ;; Compare-and-store instructions
2688 ;; Modes QI, HI, SI and SF are supported directly.
2690 ;; Note - we do not specify the two instructions necessary to perform
2691 ;; a compare-and-store in the cstore<mode>4 pattern because that would
2692 ;; allow the comparison to be moved away from the store before the reload
2693 ;; pass has completed. That would be problematical because reload can
2694 ;; generate instructions in between which would clobber the CC register.
2696 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2699 (define_expand "cstore<mode>4"
2700 [(set (match_operand:SI 0)
2701 (match_operator:SI 1 "visium_int_cstore_operator"
2702 [(match_operand:I 2 "register_operand")
2703 (match_operand:I 3 "reg_or_0_operand")]))]
2706 visium_expand_int_cstore (operands, <MODE>mode);
2710 (define_insn_and_split "*cstore<mode>4_insn"
2711 [(set (match_operand:SI 0 "register_operand" "=r")
2712 (ltu:SI (match_operand:I 1 "register_operand" "r")
2713 (match_operand:I 2 "reg_or_0_operand" "rO")))]
2719 visium_split_cstore (SET, operands[0], NULL_RTX,
2720 LTU, operands[1], operands[2]);
2723 [(set_attr "type" "cmp")])
2725 (define_insn_and_split "*neg_cstore<mode>4_insn"
2726 [(set (match_operand:SI 0 "register_operand" "=r")
2727 (neg:SI (ltu:SI (match_operand:I 1 "register_operand" "r")
2728 (match_operand:I 2 "reg_or_0_operand" "rO"))))]
2734 visium_split_cstore (NEG, operands[0], NULL_RTX,
2735 LTU, operands[1], operands[2]);
2738 [(set_attr "type" "cmp")])
2740 (define_insn_and_split "*<add_str>_cstore<mode>4_insn"
2741 [(set (match_operand:SI 0 "register_operand" "=r")
2742 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2743 (ltu:SI (match_operand:I 2 "register_operand" "r")
2744 (match_operand:I 3 "reg_or_0_operand" "rO"))))]
2750 visium_split_cstore (<add_op>, operands[0], operands[1],
2751 LTU, operands[2], operands[3]);
2754 [(set_attr "type" "cmp")])
2756 (define_insn_and_split "*cstore<mode>4_sne_insn"
2757 [(set (match_operand:SI 0 "register_operand" "=r")
2758 (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2765 visium_split_cstore (SET, operands[0], NULL_RTX,
2766 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2769 [(set_attr "type" "cmp")])
2771 (define_insn_and_split "*neg_cstore<mode>4_sne_insn"
2772 [(set (match_operand:SI 0 "register_operand" "=r")
2773 (neg:SI (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2780 visium_split_cstore (NEG, operands[0], NULL_RTX,
2781 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2784 [(set_attr "type" "cmp")])
2786 (define_insn_and_split "*<add_str>_cstore<mode>4_sne_insn"
2787 [(set (match_operand:SI 0 "register_operand" "=r")
2788 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2789 (ltu:SI (not:I (match_operand:I 2 "register_operand" "r"))
2796 visium_split_cstore (<add_op>, operands[0], operands[1],
2797 LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx);
2800 [(set_attr "type" "cmp")])
2802 (define_expand "cstoresf4"
2803 [(set (match_operand:SI 0)
2804 (match_operator:SI 1 "visium_fp_cstore_operator"
2805 [(match_operand:SF 2 "fp_reg_operand")
2806 (match_operand:SF 3 "fp_reg_or_0_operand")]))]
2809 visium_expand_fp_cstore (operands, SFmode);
2813 (define_insn_and_split "*cstoresf4_insn"
2814 [(set (match_operand:SI 0 "register_operand" "=r")
2815 (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2816 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")))]
2819 "&& reload_completed"
2822 visium_split_cstore (SET, operands [0], NULL_RTX,
2823 LT, operands[1], operands[2]);
2826 [(set_attr "type" "fcmp")])
2828 (define_insn_and_split "*neg_cstoresf4_insn"
2829 [(set (match_operand:SI 0 "register_operand" "=r")
2830 (neg:SI (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2831 (match_operand:SF 2 "fp_reg_or_0_operand" "fG"))))]
2834 "&& reload_completed"
2837 visium_split_cstore (NEG, operands [0], NULL_RTX,
2838 LT, operands[1], operands[2]);
2841 [(set_attr "type" "fcmp")])
2843 (define_insn_and_split "*<add_str>_cstoresf4_insn"
2844 [(set (match_operand:SI 0 "register_operand" "=r")
2845 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2846 (lt:SI (match_operand:SF 2 "fp_reg_or_0_operand" "fG")
2847 (match_operand:SF 3 "fp_reg_or_0_operand" "fG"))))]
2850 "&& reload_completed"
2853 visium_split_cstore (<add_op>, operands [0], operands[1],
2854 LT, operands[2], operands[3]);
2857 [(set_attr "type" "fcmp")])
2860 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2862 ;; RTL pro/epilogue support
2864 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2867 ; Expand prologue in RTL
2868 (define_expand "prologue"
2872 visium_expand_prologue ();
2876 ; Expand epilogue in RTL
2877 (define_expand "epilogue"
2881 visium_expand_epilogue ();
2884 ; Expand epilogue without a final jump in RTL
2885 (define_expand "sibcall_epilogue"
2889 visium_expand_epilogue ();
2893 ; The artificial dependency on the link register is to prevent the
2894 ; frame instruction from being put in a call delay slot, which can
2895 ; confuse the CFI machinery.
2897 (define_insn "stack_save"
2898 [(set (reg:SI R_FP) (reg:SI R_SP))
2899 (use (reg:SI R_LINK))
2900 (clobber (reg:CC R_FLAGS))]
2902 "move.l fp,sp ;stack_save"
2903 [(set_attr "type" "logic")])
2905 ; The construct (mem:BLK (scratch)) is considered to alias all other
2906 ; memory accesses. Thus it can be used as a memory barrier in stack
2907 ; deallocation patterns.
2909 (define_insn "stack_restore"
2910 [(set (reg:SI R_SP) (reg:SI R_FP))
2911 (clobber (mem:BLK (scratch)))
2912 (clobber (reg:CC R_FLAGS))]
2914 "move.l sp,fp ;stack_restore"
2915 [(set_attr "type" "logic")])
2917 (define_insn "stack_pop"
2919 (plus:SI (reg:SI R_SP) (match_operand:SI 0 "add_operand" "J,r")))
2920 (clobber (mem:BLK (scratch)))
2921 (clobber (reg:CC R_FLAGS))]
2924 addi sp,%0 ;stack pop
2925 add.l sp,sp,%0 ;stack pop"
2926 [(set_attr "type" "arith")])
2928 (define_expand "<return_str>return"
2933 (define_insn "*<return_str>return_internal"
2935 "!visium_interrupt_function_p ()"
2937 return output_ubranch (pc_rtx, insn);
2939 [(set_attr "type" "ret")])
2941 (define_insn "*return_internal_interrupt"
2943 "visium_interrupt_function_p ()"
2944 "rfi\n\t nop ;return from interrupt"
2945 [(set_attr "type" "rfi")])
2948 [(unspec_volatile [(const_int 0)] UNSPECV_DSI)]
2951 [(set_attr "type" "dsi")])
2954 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2956 ;; NOP (no-op instruction)
2958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2964 "nop ;generated nop"
2965 [(set_attr "type" "nop")])
2967 (define_insn "hazard_nop"
2968 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
2970 "nop ;hazard avoidance nop"
2971 [(set_attr "type" "nop")])
2973 (define_insn "blockage"
2974 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2977 [(set_attr "type" "nop")])
2980 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2982 ;; String/block operations
2984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2987 ;; String/block move insn.
2988 ;; Argument 0 is the destination
2989 ;; Argument 1 is the source
2990 ;; Argument 2 is the length
2991 ;; Argument 3 is the alignment
2993 (define_expand "movmemsi"
2994 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
2995 (match_operand:BLK 1 "memory_operand" ""))
2996 (use (match_operand:SI 2 "general_operand" ""))
2997 (use (match_operand:SI 3 "const_int_operand" ""))])]
3000 if (visium_expand_block_move (operands))
3007 [(set (mem:BLK (reg:SI R_R1))
3008 (mem:BLK (reg:SI R_R2)))
3010 (clobber (reg:SI R_R1))
3011 (clobber (reg:SI R_R2))
3012 (clobber (reg:SI R_R3))
3013 (clobber (reg:SI R_R4))
3014 (clobber (reg:SI R_R5))
3015 (clobber (reg:SI R_R6))]
3018 [(set_attr "type" "bmi")])
3020 ;; String/block set insn.
3021 ;; Argument 0 is the destination
3022 ;; Argument 1 is the length
3023 ;; Argument 2 is the value
3024 ;; Argument 3 is the alignment
3026 (define_expand "setmemsi"
3027 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3028 (match_operand 2 "nonmemory_operand" ""))
3029 (use (match_operand:SI 1 "general_operand" ""))
3030 (use (match_operand:SI 3 "const_int_operand" ""))])]
3033 if (visium_expand_block_set (operands))