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 first 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 (reg:CC R_FLAGS)
255 (compare:CC (match_dup 1) (const_int 0)))
256 (set (match_dup 0) (match_dup 1))])
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 (reg:CCNZ R_FLAGS)
265 (compare:CCNZ (match_dup 1) (const_int 0)))
266 (set (match_dup 0) (match_dup 1))])
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 (reg:CCC R_FLAGS)
798 (compare:CCC (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
799 (match_operand:QHI 2 "register_operand" "r"))
801 (set (match_operand:QHI 0 "register_operand" "=r")
802 (plus:QHI (match_dup 1) (match_dup 2)))]
805 [(set_attr "type" "arith")])
807 (define_insn "*add<mode>3_insn_set_overflow"
808 [(set (reg:CCV R_FLAGS)
809 (compare:CCV (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
810 (match_operand:QHI 2 "register_operand" "r"))
811 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
812 (set (match_operand:QHI 0 "register_operand" "=r")
813 (plus:QHI (match_dup 1) (match_dup 2)))]
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 (reg:CCC R_FLAGS)
862 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
863 (match_operand:SI 2 "real_add_operand" " r,J"))
865 (set (match_operand:SI 0 "register_operand" "=r,r")
866 (plus:SI (match_dup 1) (match_dup 2)))]
871 [(set_attr "type" "arith")])
873 (define_insn "*addsi3_insn_set_overflow"
874 [(set (reg:CCV R_FLAGS)
875 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
876 (match_operand:SI 2 "real_add_operand" " r,J"))
877 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
878 (set (match_operand:SI 0 "register_operand" "=r,r")
879 (plus:SI (match_dup 1) (match_dup 2)))]
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 (reg:CC R_FLAGS)
1013 (compare:CC (match_operand:QHI 1 "reg_or_0_operand" "r0")
1014 (match_operand:QHI 2 "register_operand" "r")))
1015 (set (match_operand:QHI 0 "register_operand" "=r")
1016 (minus:QHI (match_dup 1) (match_dup 2)))]
1019 [(set_attr "type" "arith")])
1021 (define_insn "*sub<mode>3_insn_set_overflow"
1022 [(set (reg:CCV R_FLAGS)
1023 (compare:CCV (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "r0")
1024 (match_operand:QHI 2 "register_operand" "r"))
1025 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
1026 (set (match_operand:QHI 0 "register_operand" "=r")
1027 (minus:QHI (match_dup 1) (match_dup 2)))]
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 (reg:CC R_FLAGS)
1076 (compare:CC (match_operand:SI 1 "register_operand" "r,0")
1077 (match_operand:SI 2 "real_add_operand" "r,J")))
1078 (set (match_operand:SI 0 "register_operand" "=r,r")
1079 (minus:SI (match_dup 1) (match_dup 2)))]
1084 [(set_attr "type" "arith")])
1086 (define_insn "*subsi3_insn_set_overflow"
1087 [(set (reg:CCV R_FLAGS)
1088 (compare:CCV (minus:SI (match_operand:SI 1 "register_operand" "r,0")
1089 (match_operand:SI 2 "real_add_operand" "r,J"))
1090 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
1091 (set (match_operand:SI 0 "register_operand" "=r,r")
1092 (minus:SI (match_dup 1) (match_dup 2)))]
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 (reg:CCC R_FLAGS)
1213 (compare:CCC (not:SI (match_operand:SI 1 "register_operand" "r"))
1215 (set (match_operand:SI 0 "register_operand" "=r")
1216 (neg:SI (match_dup 1)))]
1219 [(set_attr "type" "arith")])
1221 (define_insn "*neg<mode>2_insn_set_overflow"
1222 [(set (reg:CCV R_FLAGS)
1223 (compare:CCV (neg:I (match_operand:I 1 "register_operand" "r"))
1224 (unspec:I [(match_dup 1)] UNSPEC_NEGV)))
1225 (set (match_operand:I 0 "register_operand" "=r")
1226 (neg:I (match_dup 1)))]
1229 [(set_attr "type" "arith")])
1231 (define_expand "negdi2"
1232 [(set (match_operand:DI 0 "register_operand" "")
1233 (neg:DI (match_operand:DI 1 "register_operand" "")))]
1236 (define_insn_and_split "*negdi2_insn"
1237 [(set (match_operand:DI 0 "register_operand" "=&r")
1238 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
1239 "ok_for_simple_arith_logic_operands (operands, DImode)"
1244 visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]);
1247 [(set_attr "type" "arith2")])
1250 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1252 ;; Integer Multiply (non-widening and widening, signed and unsigned)
1254 ;; Only SI mode is supported.
1256 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1259 ; The mults and multu instructions clear MDC but we only pretend that they
1260 ; clobber it to keep things relatively simple.
1262 (define_insn "mulsi3"
1263 [(set (match_operand:SI 0 "register_operand" "=b")
1264 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1265 (match_operand:SI 2 "register_operand" "r")))
1266 (clobber (reg:SI R_MDC))]
1269 [(set_attr "type" "mul")])
1271 ; The names are mulsidi3 and umulsidi3 here.
1273 (define_insn "<u>mulsidi3"
1274 [(set (match_operand:DI 0 "register_operand" "=b")
1275 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1276 (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))
1277 (clobber (reg:SI R_MDC))]
1280 [(set_attr "type" "mul")])
1282 ; But they are smulsi3_highpart and umulsi3_highpart here.
1284 (define_insn_and_split "<su>mulsi3_highpart"
1285 [(set (match_operand:SI 0 "register_operand" "=r")
1288 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1289 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
1291 (clobber (reg:DI R_MDB))
1292 (clobber (reg:SI R_MDC))]
1296 [(parallel [(set (reg:DI R_MDB)
1297 (mult:DI (any_extend:DI (match_dup 1))
1298 (any_extend:DI (match_dup 2))))
1299 (clobber (reg:SI R_MDC))])
1300 (set (match_dup 0) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
1302 [(set_attr "type" "multi")])
1305 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1307 ;; Integer divide and modulus (signed and unsigned)
1309 ;; Only SI mode is supported.
1311 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1314 (define_insn "*divmodsi4_insn"
1315 [(set (match_operand:SI 0 "register_operand" "=b")
1316 (div:SI (match_operand:SI 1 "register_operand" "0")
1317 (match_operand:SI 2 "register_operand" "r")))
1318 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))]
1321 [(set_attr "type" "div")])
1323 (define_insn_and_split "divmodsi4"
1324 [(set (match_operand:SI 0 "register_operand" "=b")
1325 (div:SI (match_operand:SI 1 "register_operand" "0")
1326 (match_operand:SI 2 "register_operand" "r")))
1327 (set (match_operand:SI 3 "register_operand" "=r")
1328 (mod:SI (match_dup 1) (match_dup 2)))
1329 (clobber (reg:SI R_MDC))]
1333 [(parallel [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2)))
1334 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))])
1335 (set (match_dup 3) (reg:SI R_MDC))]
1337 [(set_attr "type" "multi")])
1339 (define_insn "*udivmodsi4_insn"
1340 [(set (match_operand:SI 0 "register_operand" "=b")
1341 (udiv:SI (match_operand:SI 1 "register_operand" "0")
1342 (match_operand:SI 2 "register_operand" "r")))
1343 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))]
1346 [(set_attr "type" "div")])
1348 (define_insn_and_split "udivmodsi4"
1349 [(set (match_operand:SI 0 "register_operand" "=b")
1350 (udiv:SI (match_operand:SI 1 "register_operand" "0")
1351 (match_operand:SI 2 "register_operand" "r")))
1352 (set (match_operand:SI 3 "register_operand" "=r")
1353 (umod:SI (match_dup 1) (match_dup 2)))
1354 (clobber (reg:SI R_MDC))]
1358 [(parallel [(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2)))
1359 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))])
1360 (set (match_dup 3) (reg:SI R_MDC))]
1362 [(set_attr "type" "multi")])
1364 ; FIXME. How do we persuade the compiler to use 64/32 bit divides directly ?
1366 (define_insn "*divds"
1367 [(set (reg:DI R_MDB)
1368 (div:DI (reg:DI R_MDB) (sign_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1369 (set (reg:SI R_MDC) (truncate:SI (mod:DI (reg:DI R_MDB) (sign_extend:DI (match_dup 0)))))]
1372 [(set_attr "type" "divd")])
1374 (define_insn "*divdu"
1375 [(set (reg:DI R_MDB)
1376 (udiv:DI (reg:DI R_MDB) (zero_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1377 (set (reg:SI R_MDC) (truncate:SI (umod:DI (reg:DI R_MDB) (zero_extend:DI (match_dup 0)))))]
1380 [(set_attr "type" "divd")])
1382 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1384 ;; Bitwise Logical AND
1386 ;; Modes QI, HI and SI are supported directly.
1388 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1391 (define_expand "and<mode>3"
1392 [(set (match_operand:I 0 "register_operand" "")
1393 (and:I (match_operand:I 1 "register_operand" "")
1394 (match_operand:I 2 "register_operand" "")))]
1397 (define_insn_and_split "*and<mode>3_insn"
1398 [(set (match_operand:I 0 "register_operand" "=r")
1399 (and:I (match_operand:I 1 "register_operand" "%r")
1400 (match_operand:I 2 "register_operand" "r")))]
1401 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1404 [(parallel [(set (match_dup 0)
1405 (and:I (match_dup 1) (match_dup 2)))
1406 (clobber (reg:CC R_FLAGS))])]
1408 [(set_attr "type" "logic")])
1410 (define_insn "*and<mode>3_insn<subst_logic>"
1411 [(set (match_operand:I 0 "register_operand" "=r")
1412 (and:I (match_operand:I 1 "register_operand" "%r")
1413 (match_operand:I 2 "register_operand" "r")))
1414 (clobber (reg:CC R_FLAGS))]
1417 [(set_attr "type" "logic")])
1420 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1422 ;; Bitwise Inclusive Logical OR
1424 ;; Modes QI, HI and SI are supported directly.
1426 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1429 (define_expand "ior<mode>3"
1430 [(set (match_operand:I 0 "register_operand" "")
1431 (ior:I (match_operand:I 1 "register_operand" "")
1432 (match_operand:I 2 "register_operand" "")))]
1435 (define_insn_and_split "*ior<mode>3_insn"
1436 [(set (match_operand:I 0 "register_operand" "=r")
1437 (ior:I (match_operand:I 1 "register_operand" "%r")
1438 (match_operand:I 2 "register_operand" "r")))]
1439 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1442 [(parallel [(set (match_dup 0)
1443 (ior:I (match_dup 1) (match_dup 2)))
1444 (clobber (reg:CC R_FLAGS))])]
1446 [(set_attr "type" "logic")])
1448 (define_insn "*ior<mode>3_insn<subst_logic>"
1449 [(set (match_operand:I 0 "register_operand" "=r")
1450 (ior:I (match_operand:I 1 "register_operand" "%r")
1451 (match_operand:I 2 "register_operand" "r")))
1452 (clobber (reg:CC R_FLAGS))]
1455 [(set_attr "type" "logic")])
1458 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1460 ;; Bitwise Exclusive Logical OR
1462 ;; Modes QI, HI and SI are supported directly.
1464 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1467 (define_expand "xor<mode>3"
1468 [(set (match_operand:I 0 "register_operand" "")
1469 (xor:I (match_operand:I 1 "register_operand" "")
1470 (match_operand:I 2 "register_operand" "")))]
1473 (define_insn_and_split "*xor<mode>3_insn"
1474 [(set (match_operand:I 0 "register_operand" "=r")
1475 (xor:I (match_operand:I 1 "register_operand" "%r")
1476 (match_operand:I 2 "register_operand" "r")))]
1477 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1480 [(parallel [(set (match_dup 0)
1481 (xor:I (match_dup 1) (match_dup 2)))
1482 (clobber (reg:CC R_FLAGS))])]
1484 [(set_attr "type" "logic")])
1486 (define_insn "*xor<mode>3_insn<subst_logic>"
1487 [(set (match_operand:I 0 "register_operand" "=r")
1488 (xor:I (match_operand:I 1 "register_operand" "%r")
1489 (match_operand:I 2 "register_operand" "r")))
1490 (clobber (reg:CC R_FLAGS))]
1493 [(set_attr "type" "logic")])
1496 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1498 ;; Bitwise Logical NOT
1500 ;; Modes QI, HI and SI are supported directly.
1502 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1505 (define_expand "one_cmpl<mode>2"
1506 [(set (match_operand:I 0 "register_operand" "")
1507 (not:I (match_operand:I 1 "reg_or_0_operand" "")))]
1510 (define_insn_and_split "*one_cmpl<mode>2_insn"
1511 [(set (match_operand:I 0 "register_operand" "=r")
1512 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))]
1513 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1516 [(parallel [(set (match_dup 0) (not:I (match_dup 1)))
1517 (clobber (reg:CC R_FLAGS))])]
1519 [(set_attr "type" "logic")])
1521 (define_insn "*one_cmpl<mode>2_insn<subst_logic>"
1522 [(set (match_operand:I 0 "register_operand" "=r")
1523 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))
1524 (clobber (reg:CC R_FLAGS))]
1527 [(set_attr "type" "logic")])
1530 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1532 ;; Arithmetic Shift Left
1534 ;; Modes QI, HI, SI and DI are supported directly.
1536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1539 (define_expand "ashl<mode>3"
1540 [(set (match_operand:I 0 "register_operand" "")
1541 (ashift:I (match_operand:I 1 "register_operand" "")
1542 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1545 (define_insn_and_split "*ashl<mode>3_insn"
1546 [(set (match_operand:I 0 "register_operand" "=r,r")
1547 (ashift:I (match_operand:I 1 "register_operand" "r,r")
1548 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1549 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1552 [(parallel [(set (match_dup 0)
1553 (ashift:I (match_dup 1) (match_dup 2)))
1554 (clobber (reg:CC R_FLAGS))])]
1556 [(set_attr "type" "arith")])
1558 (define_insn "*ashl<mode>3_insn<subst_arith>"
1559 [(set (match_operand:I 0 "register_operand" "=r,r")
1560 (ashift:I (match_operand:I 1 "register_operand" "r,r")
1561 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1562 (clobber (reg:CC R_FLAGS))]
1565 [(set_attr "type" "arith")])
1567 (define_insn "ashldi3"
1568 [(set (match_operand:DI 0 "register_operand" "=b,r")
1569 (ashift:DI (match_operand:DI 1 "register_operand" "0,r")
1570 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1571 (clobber (reg:SI R_MDC))]
1576 [(set_attr "type" "shiftdi,multi")])
1579 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1580 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
1582 (clobber (reg:SI R_MDC))]
1584 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 4))
1585 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
1589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1591 ;; Arithmetic Shift Right
1593 ;; Modes QI, HI, SI and DI are supported directly.
1595 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1598 (define_expand "ashr<mode>3"
1599 [(set (match_operand:I 0 "register_operand" "")
1600 (ashiftrt:I (match_operand:I 1 "register_operand" "")
1601 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1604 (define_insn_and_split "*ashr<mode>3_insn"
1605 [(set (match_operand:I 0 "register_operand" "=r,r")
1606 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r")
1607 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1608 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1611 [(parallel [(set (match_dup 0)
1612 (ashiftrt:I (match_dup 1) (match_dup 2)))
1613 (clobber (reg:CC R_FLAGS))])]
1615 [(set_attr "type" "logic")])
1617 (define_insn "*ashr<mode>3_insn<subst_logic>"
1618 [(set (match_operand:I 0 "register_operand" "=r,r")
1619 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r")
1620 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1621 (clobber (reg:CC R_FLAGS))]
1624 [(set_attr "type" "logic")])
1626 (define_insn "ashrdi3"
1627 [(set (match_operand:DI 0 "register_operand" "=b,r")
1628 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1629 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1630 (clobber (reg:SI R_MDC))]
1635 [(set_attr "type" "shiftdi,multi")])
1638 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1639 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1641 (clobber (reg:SI R_MDC))]
1643 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1644 (parallel [(set (subreg:SI (match_dup 0) 0)
1645 (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))
1646 (clobber (reg:CC R_FLAGS))])]
1650 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1652 ;; Logical Shift Right
1654 ;; Modes QI, HI, SI and DI are supported directly.
1656 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1659 (define_expand "lshr<mode>3"
1660 [(set (match_operand:I 0 "register_operand" "")
1661 (lshiftrt:I (match_operand:I 1 "register_operand" "")
1662 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1665 (define_insn_and_split "*lshr<mode>3_insn"
1666 [(set (match_operand:I 0 "register_operand" "=r,r")
1667 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r")
1668 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1669 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1672 [(parallel [(set (match_dup 0)
1673 (lshiftrt:I (match_dup 1) (match_dup 2)))
1674 (clobber (reg:CC R_FLAGS))])]
1676 [(set_attr "type" "logic")])
1678 (define_insn "*lshr<mode>3_insn<subst_logic>"
1679 [(set (match_operand:I 0 "register_operand" "=r,r")
1680 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r")
1681 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1682 (clobber (reg:CC R_FLAGS))]
1685 [(set_attr "type" "logic")])
1687 (define_insn "lshrdi3"
1688 [(set (match_operand:DI 0 "register_operand" "=b,r")
1689 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1690 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1691 (clobber (reg:SI R_MDC))]
1696 [(set_attr "type" "shiftdi,multi")])
1699 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1700 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1702 (clobber (reg:SI R_MDC))]
1704 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1705 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
1709 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1713 ;; Truncations among modes QI, HI, SI and DI are supported directly.
1715 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1718 (define_expand "trunchiqi2"
1719 [(set (match_operand:QI 0 "register_operand" "")
1720 (truncate:QI (match_operand:HI 1 "register_operand" "")))]
1723 (define_insn_and_split "*trunchiqi2_insn"
1724 [(set (match_operand:QI 0 "register_operand" "=r")
1725 (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
1726 "ok_for_simple_arith_logic_operands (operands, QImode)"
1729 [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1)))
1730 (clobber (reg:CC R_FLAGS))])]
1732 [(set_attr "type" "logic")])
1734 (define_insn "*trunchiqi2_insn<subst_logic>"
1735 [(set (match_operand:QI 0 "register_operand" "=r")
1736 (truncate:QI (match_operand:HI 1 "register_operand" "r")))
1737 (clobber (reg:CC R_FLAGS))]
1740 [(set_attr "type" "logic")])
1742 (define_expand "truncsihi2"
1743 [(set (match_operand:HI 0 "register_operand" "")
1744 (truncate:HI (match_operand:SI 1 "register_operand" "")))]
1747 (define_insn_and_split "*truncsihi2_insn"
1748 [(set (match_operand:HI 0 "register_operand" "=r")
1749 (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
1750 "ok_for_simple_arith_logic_operands (operands, HImode)"
1753 [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1)))
1754 (clobber (reg:CC R_FLAGS))])]
1756 [(set_attr "type" "logic")])
1758 (define_insn "*truncsihi2_insn<subst_logic>"
1759 [(set (match_operand:HI 0 "register_operand" "=r")
1760 (truncate:HI (match_operand:SI 1 "register_operand" "r")))
1761 (clobber (reg:CC R_FLAGS))]
1764 [(set_attr "type" "logic")])
1766 (define_expand "truncdisi2"
1767 [(set (match_operand:SI 0 "register_operand" "")
1768 (truncate:SI (match_operand:DI 1 "register_operand" "")))]
1771 (define_insn_and_split "*truncdisi2_insn"
1772 [(set (match_operand:SI 0 "register_operand" "=r")
1773 (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
1774 "ok_for_simple_arith_logic_operands (operands, SImode)"
1777 [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1)))
1778 (clobber (reg:CC R_FLAGS))])]
1780 [(set_attr "type" "logic")])
1782 (define_insn "*truncdisi2_insn<subst_logic>"
1783 [(set (match_operand:SI 0 "register_operand" "=r")
1784 (truncate:SI (match_operand:DI 1 "register_operand" "r")))
1785 (clobber (reg:CC R_FLAGS))]
1788 [(set_attr "type" "logic")])
1791 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1795 ;; Sign-extensions among modes QI, HI, SI and DI are supported directly.
1797 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1800 (define_expand "extendqihi2"
1801 [(set (match_operand:HI 0 "register_operand" "")
1802 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1805 (define_insn_and_split "*extendqihi2_insn"
1806 [(set (match_operand:HI 0 "register_operand" "=r")
1807 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1808 "ok_for_simple_arith_logic_operands (operands, HImode)"
1811 [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
1812 (clobber (reg:CC R_FLAGS))])]
1814 [(set_attr "type" "logic")])
1816 (define_insn "*extendqihi2_insn<subst_logic>"
1817 [(set (match_operand:HI 0 "register_operand" "=r")
1818 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))
1819 (clobber (reg:CC R_FLAGS))]
1822 [(set_attr "type" "logic")])
1824 (define_expand "extendqisi2"
1825 [(set (match_operand:SI 0 "register_operand" "")
1826 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1829 (define_insn_and_split "*extendqisi2_insn"
1830 [(set (match_operand:SI 0 "register_operand" "=r")
1831 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1832 "ok_for_simple_arith_logic_operands (operands, SImode)"
1835 [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
1836 (clobber (reg:CC R_FLAGS))])]
1838 [(set_attr "type" "logic")])
1840 (define_insn "*extendqisi2_insn<subst_logic>"
1841 [(set (match_operand:SI 0 "register_operand" "=r")
1842 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))
1843 (clobber (reg:CC R_FLAGS))]
1846 [(set_attr "type" "logic")])
1848 (define_expand "extendhisi2"
1849 [(set (match_operand:SI 0 "register_operand" "")
1850 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1853 (define_insn_and_split "*extendhisi2_insn"
1854 [(set (match_operand:SI 0 "register_operand" "=r")
1855 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1856 "ok_for_simple_arith_logic_operands (operands, SImode)"
1859 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1860 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
1861 (clobber (reg:CC R_FLAGS))])]
1863 [(set_attr "type" "logic")])
1865 (define_insn "*extendhisi2_insn<subst_logic>"
1866 [(set (match_operand:SI 0 "register_operand" "=r")
1867 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))
1868 (clobber (reg:CC R_FLAGS))]
1871 [(set_attr "type" "logic")])
1873 (define_expand "extendsidi2"
1874 [(set (match_operand:DI 0 "register_operand" "")
1875 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
1878 (define_insn_and_split "*extendsidi2_insn"
1879 [(set (match_operand:DI 0 "register_operand" "=r")
1880 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1881 "ok_for_simple_arith_logic_operands (operands, DImode)"
1884 [(parallel [(set (match_dup 3) (match_dup 1))
1885 (clobber (reg:CC R_FLAGS))])
1886 (parallel [(set (match_dup 2)
1887 (ashiftrt:SI (match_dup 1) (const_int 31)))
1888 (clobber (reg:CC R_FLAGS))])]
1890 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1891 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1893 [(set_attr "type" "multi")])
1896 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1900 ;; Zero-extensions among modes QI, HI, SI and DI are supported directly.
1902 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1905 ; QI is zero-extended to wider modes by shifting left and then performing
1906 ; a logical shift right to insert the zeroes. This avoids the need to use
1909 (define_expand "zero_extendqihi2"
1910 [(set (match_operand:HI 0 "register_operand" "")
1911 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1914 (define_insn_and_split "*zero_extendqihi2_insn"
1915 [(set (match_operand:HI 0 "register_operand" "=r")
1916 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1917 "ok_for_simple_arith_logic_operands (operands, HImode)"
1920 [(parallel [(set (match_dup 0)
1921 (ashift:HI (match_dup 2) (const_int 8)))
1922 (clobber (reg:CC R_FLAGS))])
1923 (parallel [(set (match_dup 0)
1924 (lshiftrt:HI (match_dup 0) (const_int 8)))
1925 (clobber (reg:CC R_FLAGS))])]
1927 operands[2] = gen_rtx_SUBREG (HImode, operands[1], 0);
1929 [(set_attr "type" "multi")])
1931 (define_expand "zero_extendqisi2"
1932 [(set (match_operand:SI 0 "register_operand" "")
1933 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1936 (define_insn_and_split "*zero_extendqisi2_insn"
1937 [(set (match_operand:SI 0 "register_operand" "=r")
1938 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1939 "ok_for_simple_arith_logic_operands (operands, SImode)"
1942 [(parallel [(set (match_dup 0)
1943 (ashift:SI (match_dup 2) (const_int 24)))
1944 (clobber (reg:CC R_FLAGS))])
1945 (parallel [(set (match_dup 0)
1946 (lshiftrt:SI (match_dup 0) (const_int 24)))
1947 (clobber (reg:CC R_FLAGS))])]
1949 operands[2] = gen_rtx_SUBREG (SImode, operands[1], 0);
1951 [(set_attr "type" "multi")])
1953 (define_insn "zero_extendhisi2"
1954 [(set (match_operand:SI 0 "register_operand" "=r")
1955 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1958 [(set_attr "type" "imm_reg")])
1960 (define_expand "zero_extendsidi2"
1961 [(set (match_operand:DI 0 "register_operand" "")
1962 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
1965 (define_insn_and_split "*zero_extendsidi2_insn"
1966 [(set (match_operand:DI 0 "register_operand" "=r")
1967 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1968 "ok_for_simple_arith_logic_operands (operands, DImode)"
1971 [(parallel [(set (match_dup 3) (match_dup 1))
1972 (clobber (reg:CC R_FLAGS))])
1973 (set (match_dup 2) (const_int 0))]
1975 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1976 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1978 [(set_attr "type" "multi")])
1981 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1985 ;; Only SI mode is supported directly.
1987 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1990 ; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB.
1992 (define_insn "*btst<mode>"
1993 [(set (reg:CCC R_FLAGS)
1994 (compare:CCC (zero_extract:I
1995 (match_operand:I 0 "register_operand" "r")
1997 (match_operand:QI 1 "const_shift_operand" "K"))
2000 "lsr<s> r0,%0,<b>-%1"
2001 [(set_attr "type" "logic")])
2004 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2006 ;; Integer overflow tests
2008 ;; Modes QI, HI and SI are supported directly.
2010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2013 (define_insn "*addv_tst<mode>"
2014 [(set (reg:CCV R_FLAGS)
2015 (compare:CCV (match_operand:I 0 "register_operand" "r")
2016 (unspec:I [(match_operand:I 1 "register_operand" "%r")
2017 (match_operand:I 2 "register_operand" "r")]
2021 [(set_attr "type" "arith")])
2023 (define_insn "*subv_tst<mode>"
2024 [(set (reg:CCV R_FLAGS)
2025 (compare:CCV (match_operand:I 0 "register_operand" "r")
2026 (unspec:I [(match_operand:I 1 "reg_or_0_operand" "rO")
2027 (match_operand:I 2 "register_operand" "r")]
2031 [(set_attr "type" "arith")])
2033 (define_insn "*negv_tst<mode>"
2034 [(set (reg:CCV R_FLAGS)
2035 (compare:CCV (match_operand:I 0 "register_operand" "r")
2036 (unspec:I [(match_operand:I 1 "register_operand" "r")]
2040 [(set_attr "type" "arith")])
2043 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2045 ;; Integer comparisons
2047 ;; Modes QI, HI and SI are supported directly.
2049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2052 (define_insn "*cmp<mode>"
2053 [(set (reg:CC R_FLAGS)
2054 (compare:CC (match_operand:I 0 "register_operand" "r")
2055 (match_operand:I 1 "reg_or_0_operand" "rO")))]
2058 [(set_attr "type" "cmp")])
2060 (define_insn "*cmp<mode>_sne"
2061 [(set (reg:CCC R_FLAGS)
2062 (compare:CCC (not:I (match_operand:I 0 "register_operand" "r"))
2066 [(set_attr "type" "cmp")])
2069 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2071 ;; Single float operations
2073 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2076 (define_insn "addsf3"
2077 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2078 (plus:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2079 (match_operand:SF 2 "fp_reg_operand" "f")))]
2082 [(set_attr "type" "fp")])
2084 (define_insn "subsf3"
2085 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2086 (minus:SF (match_operand:SF 1 "fp_reg_operand" "f")
2087 (match_operand:SF 2 "fp_reg_operand" "f")))]
2090 [(set_attr "type" "fp")])
2092 (define_insn "mulsf3"
2093 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2094 (mult:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2095 (match_operand:SF 2 "fp_reg_operand" "f")))]
2098 [(set_attr "type" "fp")])
2100 (define_insn "divsf3"
2101 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2102 (div:SF (match_operand:SF 1 "fp_reg_operand" "f")
2103 (match_operand:SF 2 "fp_reg_operand" "f")))]
2106 [(set_attr "type" "fdiv")])
2108 (define_insn "sqrtsf2"
2109 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2110 (sqrt:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2113 [(set_attr "type" "fsqrt")])
2115 (define_insn "negsf2"
2116 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2117 (neg:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2120 [(set_attr "type" "fmove")])
2122 (define_insn "abssf2"
2123 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2124 (abs:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2127 [(set_attr "type" "fmove")])
2129 (define_expand "copysignsf3"
2130 [(match_operand:SF 0 "register_operand" "")
2131 (match_operand:SF 1 "nonmemory_operand" "")
2132 (match_operand:SF 2 "register_operand" "")]
2133 "TARGET_FPU && !TARGET_FPU_IEEE"
2135 visium_expand_copysign (operands, SFmode);
2140 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2142 ;; Single float <-> single integer conversions for !TARGET_FPU_IEEE
2144 ;; An FMOVE instruction converts a signalling NaN (zero high order bit of the
2145 ;; mantissa) to a quiet NaN (-1). This is acceptable when the data to be
2146 ;; moved is in fact a floating-point number, but to avoid nasty surprises
2147 ;; integers must in general be kept out of the floating-point registers.
2148 ;; TARGET_HARD_REGNO_MODE_OK thus only allows SFmode in these registers.
2149 ;; However, since FTOI and ITOF use floating-point registers for both their
2150 ;; inputs and outputs, to use these instructions integers must transiently
2151 ;; occupy such registers. To disguise this from the compiler, UNSPECs are
2152 ;; used for floating-point operations on integers and floating from general
2153 ;; register to floating-point register and fixing in the reverse direction
2154 ;; are only split into the individual UNSPEC operations after reload.
2156 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2159 (define_insn "*fload_no_ieee"
2160 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2161 (unspec:SF [(match_operand:SI 1 "register_operand" "r")] UNSPEC_FLOAD))]
2162 "TARGET_FPU && !TARGET_FPU_IEEE"
2164 [(set_attr "type" "reg_fp")])
2166 (define_insn "*itof_no_ieee"
2167 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2168 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_ITOF))]
2169 "TARGET_FPU && !TARGET_FPU_IEEE"
2171 [(set_attr "type" "itof")])
2173 (define_insn_and_split "*floatsisf2_no_ieee"
2174 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2175 (float:SF (match_operand:SI 1 "register_operand" "r")))]
2176 "TARGET_FPU && !TARGET_FPU_IEEE"
2178 "&& reload_completed"
2180 (unspec:SF [(match_dup 1)] UNSPEC_FLOAD))
2182 (unspec:SF [(match_dup 0)] UNSPEC_ITOF))]
2184 [(set_attr "type" "multi")])
2186 (define_insn "*ftoi_no_ieee"
2187 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2188 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FTOI))]
2189 "TARGET_FPU && !TARGET_FPU_IEEE"
2191 [(set_attr "type" "ftoi")])
2193 (define_insn "*fstore_no_ieee"
2194 [(set (match_operand:SI 0 "register_operand" "=r")
2195 (unspec:SI [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FSTORE))]
2196 "TARGET_FPU && !TARGET_FPU_IEEE"
2198 [(set_attr "type" "fp_reg")])
2200 (define_insn_and_split "fix_truncsfsi2_no_ieee"
2201 [(set (match_operand:SI 0 "register_operand" "=r")
2202 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))
2203 (clobber (match_scratch:SF 2 "=1"))]
2204 "TARGET_FPU && !TARGET_FPU_IEEE"
2206 "&& reload_completed"
2208 (unspec:SF [(match_dup 1)] UNSPEC_FTOI))
2210 (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))]
2212 [(set_attr "type" "multi")])
2215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2217 ;; Single float <-> single integer conversions
2219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2222 (define_insn "*itof"
2223 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2224 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2227 [(set_attr "type" "itof")])
2229 (define_expand "floatsisf2"
2230 [(set (match_operand:SF 0 "fp_reg_operand" "")
2231 (float:SF (match_operand:SI 1 "register_operand" "")))]
2235 (define_insn "*ftoi"
2236 [(set (match_operand:SI 0 "register_operand" "=f")
2237 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))]
2240 [(set_attr "type" "ftoi")])
2242 (define_expand "fix_truncsfsi2"
2243 [(set (match_operand:SI 0 "register_operand" "")
2244 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" ""))))]
2247 if (!TARGET_FPU_IEEE)
2249 emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1]));
2255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2257 ;; Single float comparisons
2259 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2262 (define_insn "*cmpsf_fp"
2263 [(set (reg:CCFP R_FLAGS)
2264 (compare:CCFP (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2265 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2266 "TARGET_FPU && reload_completed"
2268 [(set_attr "type" "fcmp")])
2270 (define_insn "*cmpsf_fpe"
2271 [(set (reg:CCFPE R_FLAGS)
2272 (compare:CCFPE (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2273 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2274 "TARGET_FPU && reload_completed"
2276 [(set_attr "type" "fcmp")])
2279 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2281 ;; Conditional branch instructions
2283 ;; Note - we do not specify the two instructions necessary to perform
2284 ;; a compare-and-branch in the cbranch<mode>4 pattern because that would
2285 ;; allow the comparison to be moved away from the jump before the reload
2286 ;; pass has completed. That would be problematical because reload can
2287 ;; generate instructions in between which would clobber the CC register.
2289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2292 (define_expand "cbranch<mode>4"
2294 (if_then_else (match_operator 0 "ordered_comparison_operator"
2295 [(match_operand:I 1 "register_operand")
2296 (match_operand:I 2 "reg_or_0_operand")])
2297 (label_ref (match_operand 3 ""))
2302 (define_insn_and_split "*cbranch<mode>4_insn"
2304 (if_then_else (match_operator 0 "ordered_comparison_operator"
2305 [(match_operand:I 1 "register_operand" "r")
2306 (match_operand:I 2 "reg_or_0_operand" "rO")])
2307 (label_ref (match_operand 3 ""))
2314 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2318 [(set_attr "type" "cmp")])
2320 (define_insn_and_split "*cbranch<mode>4_addv_insn"
2322 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2323 [(match_operand:I 1 "register_operand" "r")
2324 (unspec:I [(match_operand:I 2 "register_operand" "%r")
2325 (match_operand:I 3 "register_operand" "r")]
2327 (label_ref (match_operand 4 ""))
2334 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2335 XEXP (operands[0], 1), operands[4]);
2338 [(set_attr "type" "cmp")])
2340 (define_insn_and_split "*cbranch<mode>4_subv_insn"
2342 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2343 [(match_operand:I 1 "register_operand" "r")
2344 (unspec:I [(match_operand:I 2 "reg_or_0_operand" "rO")
2345 (match_operand:I 3 "register_operand" "r")]
2347 (label_ref (match_operand 4 ""))
2354 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2355 XEXP (operands[0], 1), operands[4]);
2358 [(set_attr "type" "cmp")])
2360 (define_insn_and_split "*cbranch<mode>4_negv_insn"
2362 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2363 [(match_operand:I 1 "register_operand" "r")
2364 (unspec:I [(match_operand:I 2 "register_operand" "r")]
2366 (label_ref (match_operand 3 ""))
2373 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2374 XEXP (operands[0], 1), operands[3]);
2377 [(set_attr "type" "cmp")])
2379 (define_insn_and_split "*cbranch<mode>4_btst_insn"
2381 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2383 (match_operand:I 1 "register_operand" "r")
2385 (match_operand:QI 2 "const_shift_operand" "K"))
2387 (label_ref (match_operand 3 ""))
2394 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2395 XEXP (operands[0], 1), operands[3]);
2398 [(set_attr "type" "cmp")])
2400 (define_expand "cbranchsf4"
2402 (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2403 [(match_operand:SF 1 "fp_reg_operand")
2404 (match_operand:SF 2 "fp_reg_or_0_operand")])
2405 (label_ref (match_operand 3 ""))
2410 (define_insn_and_split "*cbranchsf4_insn"
2412 (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2413 [(match_operand:SF 1 "fp_reg_operand" "f")
2414 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")])
2415 (label_ref (match_operand 3 ""))
2419 "&& reload_completed"
2422 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2426 [(set_attr "type" "fcmp")])
2428 ; Now match both normal and inverted branches.
2430 (define_insn "*normal_branch"
2432 (if_then_else (match_operator 1 "visium_branch_operator"
2433 [(reg R_FLAGS) (const_int 0)])
2434 (label_ref (match_operand 0 ""))
2438 return output_cbranch (operands[0], GET_CODE (operands[1]),
2439 GET_MODE (XEXP (operands[1], 0)), 0, insn);
2441 [(set_attr "type" "branch")])
2443 (define_insn "*inverted_branch"
2445 (if_then_else (match_operator 1 "visium_branch_operator"
2446 [(reg R_FLAGS) (const_int 0)])
2448 (label_ref (match_operand 0 ""))))]
2451 return output_cbranch (operands[0], GET_CODE (operands[1]),
2452 GET_MODE (XEXP (operands[1], 0)), 1, insn);
2454 [(set_attr "type" "branch")])
2456 ; And then match both normal and inverted returns.
2458 (define_insn "*cond_<return_str>return"
2460 (if_then_else (match_operator 0 "visium_branch_operator"
2461 [(reg R_FLAGS) (const_int 0)])
2464 "<return_pred> && reload_completed"
2466 return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2467 GET_MODE (XEXP (operands[0], 0)), 0, insn);
2469 [(set_attr "type" "ret")])
2471 (define_insn "*inverted_cond_<return_str>return"
2473 (if_then_else (match_operator 0 "visium_branch_operator"
2474 [(reg R_FLAGS) (const_int 0)])
2477 "<return_pred> && reload_completed"
2479 return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2480 GET_MODE (XEXP (operands[0], 0)), 1, insn);
2482 [(set_attr "type" "ret")])
2485 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2487 ;; Unconditional branch instructions
2489 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2494 (label_ref (match_operand 0 "" "")))]
2497 return output_ubranch (operands[0], insn);
2499 [(set_attr "type" "branch")])
2501 (define_insn "indirect_jump"
2503 (match_operand:SI 0 "register_operand" "r"))]
2505 "bra tr,%0,r0%# ;indirect jump"
2506 [(set_attr "type" "abs_branch")])
2508 (define_insn "tablejump"
2510 (match_operand:SI 0 "register_operand" "r"))
2511 (use (label_ref (match_operand 1 "" "")))]
2513 "bra tr,%0,r0%# ;tablejump"
2514 [(set_attr "type" "abs_branch")])
2517 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2519 ;; trap instructions
2521 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2525 [(trap_if (const_int 1) (const_int 0))]
2528 [(set_attr "type" "trap")])
2531 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2533 ;; Subprogram call instructions
2535 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2538 ; Subroutine call instruction returning no value. Operand 0 is the function
2539 ; to call; operand 1 is the number of bytes of arguments pushed (in mode
2540 ; 'SImode', except it is normally a 'const_int'); operand 2 is the number of
2541 ; registers used as operands.
2543 (define_expand "call"
2544 [(parallel [(call (match_operand 0 "" "")
2545 (match_operand 1 "" ""))
2546 (use (match_operand 2 "" ""))
2547 (clobber (match_dup 3))])]
2550 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2551 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2554 operands[2] = const0_rtx;
2556 operands[3] = gen_rtx_REG (Pmode, R_LINK);
2559 (define_insn "*call_internal"
2560 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,!r"))
2561 (match_operand 1 "" ""))
2562 (use (match_operand 2 "" ""))
2563 (clobber (match_operand 3 "" ""))]
2564 "!SIBLING_CALL_P (insn)"
2565 "bra tr,%0,%3%# ;call"
2566 [(set_attr "type" "call")])
2568 ; Subroutine call instruction returning a value. Operand 0 is the hard
2569 ; register in which the value is returned. There are three more operands, the
2570 ; same as the three operands of the 'call' instruction (but with numbers
2571 ; increased by one).
2573 (define_expand "call_value"
2574 [(parallel [(set (match_operand 0 "register_operand" "")
2575 (call (match_operand 1 "" "")
2576 (match_operand 2 "" "")))
2577 (use (match_operand 3 "" ""))
2578 (clobber (match_dup 4))])]
2581 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2582 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2585 operands[3] = const0_rtx;
2587 operands[4] = gen_rtx_REG (Pmode, R_LINK);
2590 (define_insn "*call_value_internal"
2591 [(set (match_operand 0 "register_operand" "")
2592 (call (mem:SI (match_operand:SI 1 "register_operand" "l,!r"))
2593 (match_operand 2 "" "")))
2594 (use (match_operand 3 "" ""))
2595 (clobber (match_operand 4 "" ""))]
2596 "!SIBLING_CALL_P (insn)"
2597 "bra tr,%1,%4%# ;call value"
2598 [(set_attr "type" "call")])
2600 ; Tail calls are similar, except that the link register is not used. But
2601 ; we don't use r0 as the destination register of the branch because we want
2602 ; the Branch Pre-decode Logic of the GR6 to use the Address Load Array to
2603 ; predict the branch target.
2605 (define_expand "sibcall"
2606 [(parallel [(call (match_operand 0 "" "")
2607 (match_operand 1 "" ""))
2608 (use (match_operand 2 "" ""))
2609 (clobber (match_dup 3))])]
2612 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2613 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2616 operands[2] = const0_rtx;
2618 operands[3] = gen_rtx_SCRATCH (SImode);
2621 (define_insn "*sibcall_internal"
2622 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
2623 (match_operand 1 "" ""))
2624 (use (match_operand 2 "" ""))
2625 (clobber (match_scratch:SI 3 "=0"))]
2626 "SIBLING_CALL_P (insn)"
2627 "bra tr,%0,%0%# ;sibcall"
2628 [(set_attr "type" "call")])
2630 (define_expand "sibcall_value"
2631 [(parallel [(set (match_operand 0 "register_operand" "")
2632 (call (match_operand 1 "" "")
2633 (match_operand 2 "" "")))
2634 (use (match_operand 3 "" ""))
2635 (clobber (match_dup 4))])]
2638 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2639 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2642 operands[3] = const0_rtx;
2644 operands[4] = gen_rtx_SCRATCH (SImode);
2647 (define_insn "*sibcall_value_internal"
2648 [(set (match_operand 0 "register_operand" "")
2649 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
2650 (match_operand 2 "" "")))
2651 (use (match_operand 3 "" ""))
2652 (clobber (match_scratch:SI 4 "=1"))]
2653 "SIBLING_CALL_P (insn)"
2654 "bra tr,%1,%1%# ;sibcall value"
2655 [(set_attr "type" "call")])
2657 ; Call subroutine returning any type.
2658 (define_expand "untyped_call"
2659 [(parallel [(call (match_operand 0 "" "")
2661 (match_operand 1 "" "")
2662 (match_operand 2 "" "")])]
2667 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
2669 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2671 rtx set = XVECEXP (operands[2], 0, i);
2672 emit_move_insn (SET_DEST (set), SET_SRC (set));
2675 /* The optimizer does not know that the call sets the function value
2676 registers we stored in the result block. We avoid problems by
2677 claiming that all hard registers are used and clobbered at this
2679 emit_insn (gen_blockage ());
2685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2687 ;; Compare-and-store instructions
2689 ;; Modes QI, HI, SI and SF are supported directly.
2691 ;; Note - we do not specify the two instructions necessary to perform
2692 ;; a compare-and-store in the cstore<mode>4 pattern because that would
2693 ;; allow the comparison to be moved away from the store before the reload
2694 ;; pass has completed. That would be problematical because reload can
2695 ;; generate instructions in between which would clobber the CC register.
2697 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2700 (define_expand "cstore<mode>4"
2701 [(set (match_operand:SI 0)
2702 (match_operator:SI 1 "visium_int_cstore_operator"
2703 [(match_operand:I 2 "register_operand")
2704 (match_operand:I 3 "reg_or_0_operand")]))]
2707 visium_expand_int_cstore (operands, <MODE>mode);
2711 (define_insn_and_split "*cstore<mode>4_insn"
2712 [(set (match_operand:SI 0 "register_operand" "=r")
2713 (ltu:SI (match_operand:I 1 "register_operand" "r")
2714 (match_operand:I 2 "reg_or_0_operand" "rO")))]
2720 visium_split_cstore (SET, operands[0], NULL_RTX,
2721 LTU, operands[1], operands[2]);
2724 [(set_attr "type" "cmp")])
2726 (define_insn_and_split "*neg_cstore<mode>4_insn"
2727 [(set (match_operand:SI 0 "register_operand" "=r")
2728 (neg:SI (ltu:SI (match_operand:I 1 "register_operand" "r")
2729 (match_operand:I 2 "reg_or_0_operand" "rO"))))]
2735 visium_split_cstore (NEG, operands[0], NULL_RTX,
2736 LTU, operands[1], operands[2]);
2739 [(set_attr "type" "cmp")])
2741 (define_insn_and_split "*<add_str>_cstore<mode>4_insn"
2742 [(set (match_operand:SI 0 "register_operand" "=r")
2743 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2744 (ltu:SI (match_operand:I 2 "register_operand" "r")
2745 (match_operand:I 3 "reg_or_0_operand" "rO"))))]
2751 visium_split_cstore (<add_op>, operands[0], operands[1],
2752 LTU, operands[2], operands[3]);
2755 [(set_attr "type" "cmp")])
2757 (define_insn_and_split "*cstore<mode>4_sne_insn"
2758 [(set (match_operand:SI 0 "register_operand" "=r")
2759 (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2766 visium_split_cstore (SET, operands[0], NULL_RTX,
2767 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2770 [(set_attr "type" "cmp")])
2772 (define_insn_and_split "*neg_cstore<mode>4_sne_insn"
2773 [(set (match_operand:SI 0 "register_operand" "=r")
2774 (neg:SI (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2781 visium_split_cstore (NEG, 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 "*<add_str>_cstore<mode>4_sne_insn"
2788 [(set (match_operand:SI 0 "register_operand" "=r")
2789 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2790 (ltu:SI (not:I (match_operand:I 2 "register_operand" "r"))
2797 visium_split_cstore (<add_op>, operands[0], operands[1],
2798 LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx);
2801 [(set_attr "type" "cmp")])
2803 (define_expand "cstoresf4"
2804 [(set (match_operand:SI 0)
2805 (match_operator:SI 1 "visium_fp_cstore_operator"
2806 [(match_operand:SF 2 "fp_reg_operand")
2807 (match_operand:SF 3 "fp_reg_or_0_operand")]))]
2810 visium_expand_fp_cstore (operands, SFmode);
2814 (define_insn_and_split "*cstoresf4_insn"
2815 [(set (match_operand:SI 0 "register_operand" "=r")
2816 (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2817 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")))]
2820 "&& reload_completed"
2823 visium_split_cstore (SET, operands [0], NULL_RTX,
2824 LT, operands[1], operands[2]);
2827 [(set_attr "type" "fcmp")])
2829 (define_insn_and_split "*neg_cstoresf4_insn"
2830 [(set (match_operand:SI 0 "register_operand" "=r")
2831 (neg:SI (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 (NEG, operands [0], NULL_RTX,
2839 LT, operands[1], operands[2]);
2842 [(set_attr "type" "fcmp")])
2844 (define_insn_and_split "*<add_str>_cstoresf4_insn"
2845 [(set (match_operand:SI 0 "register_operand" "=r")
2846 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2847 (lt:SI (match_operand:SF 2 "fp_reg_or_0_operand" "fG")
2848 (match_operand:SF 3 "fp_reg_or_0_operand" "fG"))))]
2851 "&& reload_completed"
2854 visium_split_cstore (<add_op>, operands [0], operands[1],
2855 LT, operands[2], operands[3]);
2858 [(set_attr "type" "fcmp")])
2861 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2863 ;; RTL pro/epilogue support
2865 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2868 ; Expand prologue in RTL
2869 (define_expand "prologue"
2873 visium_expand_prologue ();
2877 ; Expand epilogue in RTL
2878 (define_expand "epilogue"
2882 visium_expand_epilogue ();
2885 ; Expand epilogue without a final jump in RTL
2886 (define_expand "sibcall_epilogue"
2890 visium_expand_epilogue ();
2894 ; The artificial dependency on the link register is to prevent the
2895 ; frame instruction from being put in a call delay slot, which can
2896 ; confuse the CFI machinery.
2898 (define_insn "stack_save"
2899 [(set (reg:SI R_FP) (reg:SI R_SP))
2900 (use (reg:SI R_LINK))
2901 (clobber (reg:CC R_FLAGS))]
2903 "move.l fp,sp ;stack_save"
2904 [(set_attr "type" "logic")])
2906 ; The construct (mem:BLK (scratch)) is considered to alias all other
2907 ; memory accesses. Thus it can be used as a memory barrier in stack
2908 ; deallocation patterns.
2910 (define_insn "stack_restore"
2911 [(set (reg:SI R_SP) (reg:SI R_FP))
2912 (clobber (mem:BLK (scratch)))
2913 (clobber (reg:CC R_FLAGS))]
2915 "move.l sp,fp ;stack_restore"
2916 [(set_attr "type" "logic")])
2918 (define_insn "stack_pop"
2920 (plus:SI (reg:SI R_SP) (match_operand:SI 0 "add_operand" "J,r")))
2921 (clobber (mem:BLK (scratch)))
2922 (clobber (reg:CC R_FLAGS))]
2925 addi sp,%0 ;stack pop
2926 add.l sp,sp,%0 ;stack pop"
2927 [(set_attr "type" "arith")])
2929 (define_expand "<return_str>return"
2934 (define_insn "*<return_str>return_internal"
2936 "!visium_interrupt_function_p ()"
2938 return output_ubranch (pc_rtx, insn);
2940 [(set_attr "type" "ret")])
2942 (define_insn "*return_internal_interrupt"
2944 "visium_interrupt_function_p ()"
2945 "rfi\n\t nop ;return from interrupt"
2946 [(set_attr "type" "rfi")])
2949 [(unspec_volatile [(const_int 0)] UNSPECV_DSI)]
2952 [(set_attr "type" "dsi")])
2955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2957 ;; NOP (no-op instruction)
2959 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2965 "nop ;generated nop"
2966 [(set_attr "type" "nop")])
2968 (define_insn "hazard_nop"
2969 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
2971 "nop ;hazard avoidance nop"
2972 [(set_attr "type" "nop")])
2974 (define_insn "blockage"
2975 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2978 [(set_attr "type" "nop")])
2981 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2983 ;; String/block operations
2985 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2988 ;; String/block move insn.
2989 ;; Argument 0 is the destination
2990 ;; Argument 1 is the source
2991 ;; Argument 2 is the length
2992 ;; Argument 3 is the alignment
2994 (define_expand "movmemsi"
2995 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
2996 (match_operand:BLK 1 "memory_operand" ""))
2997 (use (match_operand:SI 2 "general_operand" ""))
2998 (use (match_operand:SI 3 "const_int_operand" ""))])]
3001 if (visium_expand_block_move (operands))
3008 [(set (mem:BLK (reg:SI R_R1))
3009 (mem:BLK (reg:SI R_R2)))
3011 (clobber (reg:SI R_R1))
3012 (clobber (reg:SI R_R2))
3013 (clobber (reg:SI R_R3))
3014 (clobber (reg:SI R_R4))
3015 (clobber (reg:SI R_R5))
3016 (clobber (reg:SI R_R6))]
3019 [(set_attr "type" "bmi")])
3021 ;; String/block set insn.
3022 ;; Argument 0 is the destination
3023 ;; Argument 1 is the length
3024 ;; Argument 2 is the value
3025 ;; Argument 3 is the alignment
3027 (define_expand "setmemsi"
3028 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3029 (match_operand 2 "nonmemory_operand" ""))
3030 (use (match_operand:SI 1 "general_operand" ""))
3031 (use (match_operand:SI 3 "const_int_operand" ""))])]
3034 if (visium_expand_block_set (operands))