diff options
Diffstat (limited to 'gcc/config/i960/i960.md')
-rw-r--r-- | gcc/config/i960/i960.md | 2673 |
1 files changed, 0 insertions, 2673 deletions
diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md deleted file mode 100644 index 32acd924ed1..00000000000 --- a/gcc/config/i960/i960.md +++ /dev/null @@ -1,2673 +0,0 @@ -;;- Machine description for Intel 80960 chip for GNU C compiler -;; Copyright (C) 1992, 1995 Free Software Foundation, Inc. -;; Contributed by Steven McGeady, Intel Corp. -;; Additional work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson -;; Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support. - -;; This file is part of GNU CC. - -;; GNU CC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; There are very few (4) 'f' registers, they can't be loaded/stored from/to -;; memory, and some instructions explicitly require them, so we get better -;; code by discouraging pseudo-registers from being allocated to them. -;; However, we do want to allow all patterns which can store to them to -;; include them in their constraints, so we always use '*f' in a destination -;; constraint except when 'f' is the only alternative. - -;; Insn attributes which describe the i960. - -;; Modscan is not used, since the compiler never emits any of these insns. -(define_attr "type" - "move,arith,alu2,mult,div,modscan,load,store,branch,call,address,compare,fpload,fpstore,fpmove,fpcvt,fpcc,fpadd,fpmul,fpdiv,multi,misc" - (const_string "arith")) - -;; Length (in # of insns). -(define_attr "length" "" - (cond [(eq_attr "type" "load,fpload") - (if_then_else (match_operand 1 "symbolic_memory_operand" "") - (const_int 2) - (const_int 1)) - (eq_attr "type" "store,fpstore") - (if_then_else (match_operand 0 "symbolic_memory_operand" "") - (const_int 2) - (const_int 1)) - (eq_attr "type" "address") - (const_int 2)] - (const_int 1))) - -(define_asm_attributes - [(set_attr "length" "1") - (set_attr "type" "multi")]) - -;; (define_function_unit {name} {num-units} {n-users} {test} -;; {ready-delay} {issue-delay} [{conflict-list}]) - -;; The integer ALU -(define_function_unit "alu" 2 0 (eq_attr "type" "arith,compare,move,address") 1 0) -(define_function_unit "alu" 2 0 (eq_attr "type" "alu2") 2 0) -(define_function_unit "alu" 2 0 (eq_attr "type" "mult") 5 0) -(define_function_unit "alu" 2 0 (eq_attr "type" "div") 35 0) -(define_function_unit "alu" 2 0 (eq_attr "type" "modscan") 3 0) - -;; Memory with load-delay of 1 (i.e., 2 cycle load). -(define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0) - -;; Floating point operations. -(define_function_unit "fp" 1 2 (eq_attr "type" "fpmove") 5 0) -(define_function_unit "fp" 1 2 (eq_attr "type" "fpcvt") 35 0) -(define_function_unit "fp" 1 2 (eq_attr "type" "fpcc") 10 0) -(define_function_unit "fp" 1 2 (eq_attr "type" "fpadd") 10 0) -(define_function_unit "fp" 1 2 (eq_attr "type" "fpmul") 20 0) -(define_function_unit "fp" 1 2 (eq_attr "type" "fpdiv") 35 0) - -;; Compare instructions. -;; This controls RTL generation and register allocation. - -;; We generate RTL for comparisons and branches by having the cmpxx -;; patterns store away the operands. Then, the scc and bcc patterns -;; emit RTL for both the compare and the branch. -;; -;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match -;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc -;; insns that actually require more than one machine instruction. - -;; Put cmpsi first because it is expected to be the most common. - -(define_expand "cmpsi" - [(set (reg:CC 36) - (compare:CC (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "general_operand" "")))] - "" - " -{ - i960_compare_op0 = operands[0]; - i960_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpdf" - [(set (reg:CC 36) - (compare:CC (match_operand:DF 0 "register_operand" "r") - (match_operand:DF 1 "nonmemory_operand" "rGH")))] - "TARGET_NUMERICS" - " -{ - i960_compare_op0 = operands[0]; - i960_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpsf" - [(set (reg:CC 36) - (compare:CC (match_operand:SF 0 "register_operand" "r") - (match_operand:SF 1 "nonmemory_operand" "rGH")))] - "TARGET_NUMERICS" - " -{ - i960_compare_op0 = operands[0]; - i960_compare_op1 = operands[1]; - DONE; -}") - -;; Now the DEFINE_INSNs for the compare and scc cases. First the compares. - -(define_insn "" - [(set (reg:CC 36) - (compare:CC (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "arith_operand" "dI")))] - "" - "cmpi %0,%1" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC_UNS 36) - (compare:CC_UNS (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "arith_operand" "dI")))] - "" - "cmpo %0,%1" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 36) - (compare:CC (match_operand:DF 0 "register_operand" "r") - (match_operand:DF 1 "nonmemory_operand" "rGH")))] - "TARGET_NUMERICS" - "cmprl %0,%1" - [(set_attr "type" "fpcc")]) - -(define_insn "" - [(set (reg:CC 36) - (compare:CC (match_operand:SF 0 "register_operand" "r") - (match_operand:SF 1 "nonmemory_operand" "rGH")))] - "TARGET_NUMERICS" - "cmpr %0,%1" - [(set_attr "type" "fpcc")]) - -;; Instruction definitions for branch-on-bit-set and clear insns. - -(define_insn "" - [(set (pc) - (if_then_else - (ne (sign_extract:SI (match_operand:SI 1 "register_operand" "d") - (const_int 1) - (match_operand:SI 2 "arith_operand" "dI")) - (const_int 0)) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - "bbs %2,%1,%l3" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (sign_extract:SI (match_operand:SI 1 "register_operand" "d") - (const_int 1) - (match_operand:SI 2 "arith_operand" "dI")) - (const_int 0)) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - "bbc %2,%1,%l3" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 1 "register_operand" "d") - (const_int 1) - (match_operand:SI 2 "arith_operand" "dI")) - (const_int 0)) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - "bbs %2,%1,%l3" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:SI 1 "register_operand" "d") - (const_int 1) - (match_operand:SI 2 "arith_operand" "dI")) - (const_int 0)) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - "bbc %2,%1,%l3" - [(set_attr "type" "branch")]) - -;; ??? These will never match. The LOG_LINKs necessary to make these match -;; are not created by flow. These remain as a reminder to make this work -;; some day. - -(define_insn "" - [(set (reg:CC 36) - (compare (match_operand:SI 0 "arith_operand" "d") - (match_operand:SI 1 "arith_operand" "d"))) - (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))] - "0" - "cmpinci %0,%1" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC_UNS 36) - (compare (match_operand:SI 0 "arith_operand" "d") - (match_operand:SI 1 "arith_operand" "d"))) - (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))] - "0" - "cmpinco %0,%1" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 36) - (compare (match_operand:SI 0 "arith_operand" "d") - (match_operand:SI 1 "arith_operand" "d"))) - (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))] - "0" - "cmpdeci %0,%1" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC_UNS 36) - (compare (match_operand:SI 0 "arith_operand" "d") - (match_operand:SI 1 "arith_operand" "d"))) - (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))] - "0" - "cmpdeco %0,%1" - [(set_attr "type" "compare")]) - -;; Templates to store result of condition. -;; '1' is stored if condition is true. -;; '0' is stored if condition is false. -;; These should use predicate "general_operand", since -;; gcc seems to be creating mem references which use these -;; templates. - -(define_expand "seq" - [(set (match_operand:SI 0 "general_operand" "=d") - (eq:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sne" - [(set (match_operand:SI 0 "general_operand" "=d") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sgt" - [(set (match_operand:SI 0 "general_operand" "=d") - (gt:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sgtu" - [(set (match_operand:SI 0 "general_operand" "=d") - (gtu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "slt" - [(set (match_operand:SI 0 "general_operand" "=d") - (lt:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sltu" - [(set (match_operand:SI 0 "general_operand" "=d") - (ltu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sge" - [(set (match_operand:SI 0 "general_operand" "=d") - (ge:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sgeu" - [(set (match_operand:SI 0 "general_operand" "=d") - (geu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sle" - [(set (match_operand:SI 0 "general_operand" "=d") - (le:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); -}") - -(define_expand "sleu" - [(set (match_operand:SI 0 "general_operand" "=d") - (leu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (eq:SI (match_operand:SI 1 "register_operand" "d") (const_int 0)))] - "" - "shro %1,1,%0" - [(set_attr "type" "alu2")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (match_operator:SI 1 "comparison_operator" [(reg:CC 36) (const_int 0)]))] - "" - "test%C1 %0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (match_operator:SI 1 "comparison_operator" [(reg:CC_UNS 36) (const_int 0)]))] - "" - "test%C1 %0" - [(set_attr "type" "compare")]) - -;; These control RTL generation for conditional jump insns -;; and match them for register allocation. - -(define_expand "beq" - [(set (pc) - (if_then_else (eq (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); }") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); }") - -(define_expand "ble" - [(set (pc) - (if_then_else (le (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); }") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1); }") - -;; Now the normal branch insns (forward and reverse). - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(reg:CC 36) (const_int 0)]) - (label_ref (match_operand 1 "" "")) - (pc)))] - "" - "b%C0 %l1" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(reg:CC 36) (const_int 0)]) - (pc) - (label_ref (match_operand 1 "" ""))))] - "" - "b%I0 %l1" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(reg:CC_UNS 36) (const_int 0)]) - (label_ref (match_operand 1 "" "")) - (pc)))] - "" - "b%C0 %l1" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(reg:CC_UNS 36) (const_int 0)]) - (pc) - (label_ref (match_operand 1 "" ""))))] - "" - "b%I0 %l1" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 0 "comparison_operator" - [(match_operand:SI 1 "arith_operand" "d") - (match_operand:SI 2 "arith_operand" "dI")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - "cmp%S0%B0%R0 %2,%1,%l3" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 0 "comparison_operator" - [(match_operand:SI 1 "arith_operand" "d") - (match_operand:SI 2 "arith_operand" "dI")]) - (pc) - (label_ref (match_operand 3 "" ""))))] - "" - "cmp%S0%B0%X0 %2,%1,%l3" - [(set_attr "type" "branch")]) - -;; Normal move instructions. -;; This code is based on the sparc machine description. - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, SImode)) - DONE; -}") - -;; The store case can not be separate, because reload may convert a register -;; to register move insn to a store (or load) insn without rerecognizing -;; the insn. - -;; The i960 does not have any store constant to memory instruction. However, -;; the calling convention is defined so that the arg pointer when it is not -;; overwise being used is zero. Thus, we can handle store zero to memory -;; by storing an unused arg pointer. The arg pointer will be unused if -;; current_function_args_size is zero and this is not a stdarg/varargs -;; function. This value of the former variable is not valid until after -;; all rtl generation is complete, including function inlining (because a -;; function that doesn't need an arg pointer may be inlined into a function -;; that does need an arg pointer), so we must also check that -;; rtx_equal_function_value_matters is zero. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d,d,d,m") - (match_operand:SI 1 "general_operand" "dI,i,m,dJ"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode) - || operands[1] == const0_rtx)" - "* -{ - switch (which_alternative) - { - case 0: - if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) - { - if (GET_CODE (operands[1]) == REG) - return \"lda (%1),%0\"; - else - return \"lda %1,%0\"; - } - return \"mov %1,%0\"; - case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ld %1,%0\"; - case 3: - if (operands[1] == const0_rtx) - return \"st g14,%0\"; - return \"st %1,%0\"; - } -}" - [(set_attr "type" "move,address,load,store") - (set_attr "length" "*,3,*,*")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d,d,d,m") - (match_operand:SI 1 "general_operand" "dI,i,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" - "* -{ - switch (which_alternative) - { - case 0: - if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) - { - if (GET_CODE (operands[1]) == REG) - return \"lda (%1),%0\"; - else - return \"lda %1,%0\"; - } - return \"mov %1,%0\"; - case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ld %1,%0\"; - case 3: - return \"st %1,%0\"; - } -}" - [(set_attr "type" "move,address,load,store") - (set_attr "length" "*,3,*,*")]) - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, HImode)) - DONE; -}") - -;; Special pattern for zero stores to memory for functions which don't use -;; the arg pointer. - -;; The store case can not be separate. See above. -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d,d,d,m") - (match_operand:HI 1 "general_operand" "dI,i,m,dJ"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], HImode) - || register_operand (operands[1], HImode) - || operands[1] == const0_rtx)" - "* -{ - switch (which_alternative) - { - case 0: - if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) - { - if (GET_CODE (operands[1]) == REG) - return \"lda (%1),%0\"; - else - return \"lda %1,%0\"; - } - return \"mov %1,%0\"; - case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldos %1,%0\"; - case 3: - if (operands[1] == const0_rtx) - return \"stos g14,%0\"; - return \"stos %1,%0\"; - } -}" - [(set_attr "type" "move,misc,load,store") - (set_attr "length" "*,3,*,*")]) - -;; The store case can not be separate. See above. -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d,d,d,m") - (match_operand:HI 1 "general_operand" "dI,i,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], HImode) - || register_operand (operands[1], HImode))" - "* -{ - switch (which_alternative) - { - case 0: - if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) - { - if (GET_CODE (operands[1]) == REG) - return \"lda (%1),%0\"; - else - return \"lda %1,%0\"; - } - return \"mov %1,%0\"; - case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldos %1,%0\"; - case 3: - return \"stos %1,%0\"; - } -}" - [(set_attr "type" "move,misc,load,store") - (set_attr "length" "*,3,*,*")]) - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, QImode)) - DONE; -}") - -;; The store case can not be separate. See comment above. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=d,d,d,m") - (match_operand:QI 1 "general_operand" "dI,i,m,dJ"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], QImode) - || register_operand (operands[1], QImode) - || operands[1] == const0_rtx)" - "* -{ - switch (which_alternative) - { - case 0: - if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) - { - if (GET_CODE (operands[1]) == REG) - return \"lda (%1),%0\"; - else - return \"lda %1,%0\"; - } - return \"mov %1,%0\"; - case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldob %1,%0\"; - case 3: - if (operands[1] == const0_rtx) - return \"stob g14,%0\"; - return \"stob %1,%0\"; - } -}" - [(set_attr "type" "move,misc,load,store") - (set_attr "length" "*,3,*,*")]) - -;; The store case can not be separate. See comment above. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=d,d,d,m") - (match_operand:QI 1 "general_operand" "dI,i,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], QImode) - || register_operand (operands[1], QImode))" - "* -{ - switch (which_alternative) - { - case 0: - if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) - { - if (GET_CODE (operands[1]) == REG) - return \"lda (%1),%0\"; - else - return \"lda %1,%0\"; - } - return \"mov %1,%0\"; - case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldob %1,%0\"; - case 3: - return \"stob %1,%0\"; - } -}" - [(set_attr "type" "move,misc,load,store") - (set_attr "length" "*,3,*,*")]) - -(define_expand "movdi" - [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, DImode)) - DONE; -}") - -;; The store case can not be separate. See comment above. -(define_insn "" - [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m,o") - (match_operand:DI 1 "general_operand" "d,I,i,m,d,J"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx)" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - case 3: - case 4: - return i960_output_move_double (operands[0], operands[1]); - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 5: - operands[1] = adj_offsettable_operand (operands[0], 4); - return \"st g14,%0\;st g14,%1\"; - } -}" - [(set_attr "type" "move,move,load,load,store,store")]) - -;; The store case can not be separate. See comment above. -(define_insn "" - [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m") - (match_operand:DI 1 "general_operand" "d,I,i,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode))" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - case 3: - case 4: - return i960_output_move_double (operands[0], operands[1]); - case 2: - return i960_output_ldconst (operands[0], operands[1]); - } -}" - [(set_attr "type" "move,move,load,load,store")]) - -(define_insn "*store_unaligned_di_reg" - [(set (match_operand:DI 0 "memory_operand" "=m") - (match_operand:DI 1 "register_operand" "d")) - (clobber (match_scratch:SI 2 "=&d"))] - "" - "* -{ - operands[3] = gen_rtx (MEM, word_mode, operands[2]); - operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD); - return \"lda %0,%2\;st %1,%3\;st %D1,%4\"; -}" - [(set_attr "type" "store")]) - -(define_expand "movti" - [(set (match_operand:TI 0 "general_operand" "") - (match_operand:TI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, TImode)) - DONE; -}") - -;; The store case can not be separate. See comment above. -(define_insn "" - [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m,o") - (match_operand:TI 1 "general_operand" "d,I,i,m,d,J"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], TImode) - || register_operand (operands[1], TImode) - || operands[1] == const0_rtx)" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - case 3: - case 4: - return i960_output_move_quad (operands[0], operands[1]); - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 5: - operands[1] = adj_offsettable_operand (operands[0], 4); - operands[2] = adj_offsettable_operand (operands[0], 8); - operands[3] = adj_offsettable_operand (operands[0], 12); - return \"st g14,%0\;st g14,%1\;st g14,%2\;st g14,%3\"; - } -}" - [(set_attr "type" "move,move,load,load,store,store")]) - -;; The store case can not be separate. See comment above. -(define_insn "" - [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m") - (match_operand:TI 1 "general_operand" "d,I,i,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], TImode) - || register_operand (operands[1], TImode))" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - case 3: - case 4: - return i960_output_move_quad (operands[0], operands[1]); - case 2: - return i960_output_ldconst (operands[0], operands[1]); - } -}" - [(set_attr "type" "move,move,load,load,store")]) - -(define_insn "*store_unaligned_ti_reg" - [(set (match_operand:TI 0 "memory_operand" "=m") - (match_operand:TI 1 "register_operand" "d")) - (clobber (match_scratch:SI 2 "=&d"))] - "" - "* -{ - operands[3] = gen_rtx (MEM, word_mode, operands[2]); - operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD); - operands[5] = adj_offsettable_operand (operands[4], UNITS_PER_WORD); - operands[6] = adj_offsettable_operand (operands[5], UNITS_PER_WORD); - return \"lda %0,%2\;st %1,%3\;st %D1,%4\;st %E1,%5\;st %F1,%6\"; -}" - [(set_attr "type" "store")]) - -(define_expand "store_multiple" - [(set (match_operand:SI 0 "" "") ;;- dest - (match_operand:SI 1 "" "")) ;;- src - (use (match_operand:SI 2 "" ""))] ;;- nregs - "" - " -{ - int regno; - int count; - rtx from; - int i; - - if (GET_CODE (operands[0]) != MEM - || GET_CODE (operands[1]) != REG - || GET_CODE (operands[2]) != CONST_INT) - FAIL; - - count = INTVAL (operands[2]); - if (count > 12) - FAIL; - - regno = REGNO (operands[1]); - from = memory_address (SImode, XEXP (operands[0], 0)); - while (count >= 4 && ((regno & 3) == 0)) - { - emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (MEM, TImode, from), - gen_rtx (REG, TImode, regno))); - count -= 4; - regno += 4; - from = memory_address (TImode, plus_constant (from, 16)); - } - while (count >= 2 && ((regno & 1) == 0)) - { - emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (MEM, DImode, from), - gen_rtx (REG, DImode, regno))); - count -= 2; - regno += 2; - from = memory_address (DImode, plus_constant (from, 8)); - } - while (count > 0) - { - emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (MEM, SImode, from), - gen_rtx (REG, SImode, regno))); - count -= 1; - regno += 1; - from = memory_address (SImode, plus_constant (from, 4)); - } - DONE; -}") - -;; Floating point move insns - -(define_expand "movdf" - [(set (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "fpmove_src_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, DFmode)) - DONE; -}") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o") - (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode) - || operands[1] == CONST0_RTX (DFmode))" - "* -{ - switch (which_alternative) - { - case 0: - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return \"movrl %1,%0\"; - else - return \"movl %1,%0\"; - case 1: - return \"movrl %1,%0\"; - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 3: - return \"ldl %1,%0\"; - case 4: - return \"stl %1,%0\"; - case 5: - operands[1] = adj_offsettable_operand (operands[0], 4); - return \"st g14,%0\;st g14,%1\"; - } -}" - [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")]) - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m") - (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "* -{ - switch (which_alternative) - { - case 0: - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return \"movrl %1,%0\"; - else - return \"movl %1,%0\"; - case 1: - return \"movrl %1,%0\"; - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 3: - return \"ldl %1,%0\"; - case 4: - return \"stl %1,%0\"; - } -}" - [(set_attr "type" "move,move,load,fpload,fpstore")]) - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "fpmove_src_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, SFmode)) - DONE; -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m") - (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))] - "(current_function_args_size == 0 - && current_function_varargs == 0 - && current_function_stdarg == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode) - || operands[1] == CONST0_RTX (SFmode))" - "* -{ - switch (which_alternative) - { - case 0: - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return \"movr %1,%0\"; - else - return \"mov %1,%0\"; - case 1: - return \"movr %1,%0\"; - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 3: - return \"ld %1,%0\"; - case 4: - if (operands[1] == CONST0_RTX (SFmode)) - return \"st g14,%0\"; - return \"st %1,%0\"; - } -}" - [(set_attr "type" "move,move,load,fpload,fpstore")]) - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m") - (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))] - "(current_function_args_size != 0 - || current_function_varargs != 0 - || current_function_stdarg != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))" - "* -{ - switch (which_alternative) - { - case 0: - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return \"movr %1,%0\"; - else - return \"mov %1,%0\"; - case 1: - return \"movr %1,%0\"; - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 3: - return \"ld %1,%0\"; - case 4: - return \"st %1,%0\"; - } -}" - [(set_attr "type" "move,move,load,fpload,fpstore")]) - -;; Mixed-mode moves with sign and zero-extension. - -;; Note that the one starting from HImode comes before those for QImode -;; so that a constant operand will match HImode, not QImode. - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "")))] - "" - " -{ - if (GET_CODE (operand1) == REG - || (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == REG)) - { - rtx temp = gen_reg_rtx (SImode); - rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); - int op1_subreg_word = 0; - - if (GET_CODE (operand1) == SUBREG) - { - op1_subreg_word = SUBREG_WORD (operand1); - operand1 = SUBREG_REG (operand1); - } - operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word); - - emit_insn (gen_ashlsi3 (temp, operand1, shift_16)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] - "" - "ldis %1,%0" - [(set_attr "type" "load")]) - -(define_expand "extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] - "" - " -{ - if (GET_CODE (operand1) == REG - || (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == REG)) - { - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - int op1_subreg_word = 0; - - if (GET_CODE (operand1) == SUBREG) - { - op1_subreg_word = SUBREG_WORD (operand1); - operand1 = SUBREG_REG (operand1); - } - operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word), - - emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] - "" - "ldib %1,%0" - [(set_attr "type" "load")]) - -(define_expand "extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (sign_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "")))] - "" - " -{ - if (GET_CODE (operand1) == REG - || (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == REG)) - { - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - int op0_subreg_word = 0; - int op1_subreg_word = 0; - - if (GET_CODE (operand1) == SUBREG) - { - op1_subreg_word = SUBREG_WORD (operand1); - operand1 = SUBREG_REG (operand1); - } - operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word); - - if (GET_CODE (operand0) == SUBREG) - { - op0_subreg_word = SUBREG_WORD (operand0); - operand0 = SUBREG_REG (operand0); - } - if (GET_MODE (operand0) != SImode) - operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subreg_word); - - emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=d") - (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] - "" - "ldib %1,%0" - [(set_attr "type" "load")]) - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "")))] - "" - " -{ - if (GET_CODE (operand1) == REG - || (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == REG)) - { - rtx temp = gen_reg_rtx (SImode); - rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); - int op1_subreg_word = 0; - - if (GET_CODE (operand1) == SUBREG) - { - op1_subreg_word = SUBREG_WORD (operand1); - operand1 = SUBREG_REG (operand1); - } - operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word); - - emit_insn (gen_ashlsi3 (temp, operand1, shift_16)); - emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] - "" - "ldos %1,%0" - [(set_attr "type" "load")]) - -;; Using shifts here generates much better code than doing an `and 255'. -;; This is mainly because the `and' requires loading the constant separately, -;; the constant is likely to get optimized, and then the compiler can't -;; optimize the `and' because it doesn't know that one operand is a constant. - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] - "" - " -{ - if (GET_CODE (operand1) == REG - || (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == REG)) - { - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - int op1_subreg_word = 0; - - if (GET_CODE (operand1) == SUBREG) - { - op1_subreg_word = SUBREG_WORD (operand1); - operand1 = SUBREG_REG (operand1); - } - operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word); - - emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); - emit_insn (gen_lshrsi3 (operand0, temp, shift_24)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] - "" - "ldob %1,%0" - [(set_attr "type" "load")]) - -(define_expand "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "")))] - "" - " -{ - if (GET_CODE (operand1) == REG - || (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == REG)) - { - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - int op0_subreg_word = 0; - int op1_subreg_word = 0; - - if (GET_CODE (operand1) == SUBREG) - { - op1_subreg_word = SUBREG_WORD (operand1); - operand1 = SUBREG_REG (operand1); - } - operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word); - - if (GET_CODE (operand0) == SUBREG) - { - op0_subreg_word = SUBREG_WORD (operand0); - operand0 = SUBREG_REG (operand0); - } - if (GET_MODE (operand0) != SImode) - operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subreg_word); - - emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); - emit_insn (gen_lshrsi3 (operand0, temp, shift_24)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=d") - (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] - "" - "ldob %1,%0" - [(set_attr "type" "load")]) - -;; Conversions between float and double. - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "=*f,d") - (float_extend:DF (match_operand:SF 1 "fp_arith_operand" "dGH,fGH")))] - "TARGET_NUMERICS" - "@ - movr %1,%0 - movrl %1,%0" - [(set_attr "type" "fpmove")]) - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "register_operand" "=d") - (float_truncate:SF - (match_operand:DF 1 "fp_arith_operand" "fGH")))] - "TARGET_NUMERICS" - "movr %1,%0" - [(set_attr "type" "fpmove")]) - -;; Conversion between fixed point and floating point. - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_NUMERICS" - "cvtir %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_insn "floatsisf2" - [(set (match_operand:SF 0 "register_operand" "=d*f") - (float:SF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_NUMERICS" - "cvtir %1,%0" - [(set_attr "type" "fpcvt")]) - -;; Convert a float to an actual integer. -;; Truncation is performed as part of the conversion. -;; The i960 requires conversion from DFmode to DImode to make -;; unsigned conversions work properly. - -(define_insn "fixuns_truncdfdi2" - [(set (match_operand:DI 0 "register_operand" "=d") - (unsigned_fix:DI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))] - "TARGET_NUMERICS" - "cvtzril %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_insn "fixuns_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "=d") - (unsigned_fix:DI (fix:SF (match_operand:SF 1 "fp_arith_operand" "fGH"))))] - "TARGET_NUMERICS" - "cvtzril %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))] - "TARGET_NUMERICS" - "cvtzri %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_expand "fixuns_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "") - (unsigned_fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" ""))))] - "TARGET_NUMERICS" - " -{ - rtx temp = gen_reg_rtx (DImode); - emit_insn (gen_rtx (SET, VOIDmode, temp, - gen_rtx (UNSIGNED_FIX, DImode, - gen_rtx (FIX, DFmode, operands[1])))); - emit_insn (gen_rtx (SET, VOIDmode, operands[0], - gen_rtx (SUBREG, SImode, temp, 0))); - DONE; -}") - -(define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" "dfGH"))))] - "TARGET_NUMERICS" - "cvtzri %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_expand "fixuns_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "") - (unsigned_fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" ""))))] - "TARGET_NUMERICS" - " -{ - rtx temp = gen_reg_rtx (DImode); - emit_insn (gen_rtx (SET, VOIDmode, temp, - gen_rtx (UNSIGNED_FIX, DImode, - gen_rtx (FIX, SFmode, operands[1])))); - emit_insn (gen_rtx (SET, VOIDmode, operands[0], - gen_rtx (SUBREG, SImode, temp, 0))); - DONE; -}") - -;; Arithmetic instructions. - -(define_insn "subsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (minus:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "subo %2,%1,%0") - -;; Try to generate an lda instruction when it would be faster than an -;; add instruction. -;; Some assemblers apparently won't accept two addresses added together. - -;; ??? The condition should be improved to reject the case of two -;; symbolic constants. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (plus:SI (match_operand:SI 1 "arith32_operand" "%dn,i,dn") - (match_operand:SI 2 "arith32_operand" "dn,dn,i")))] - "(TARGET_C_SERIES) && (CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - rtx tmp = operands[1]; - operands[1] = operands[2]; - operands[2] = tmp; - } - if (GET_CODE (operands[2]) == CONST_INT - && GET_CODE (operands[1]) == REG - && i960_last_insn_type != I_TYPE_REG) - { - if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) > -32) - return \"subo %n2,%1,%0\"; - else if (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32) - return \"addo %1,%2,%0\"; - } - /* Non-canonical results (op1 == const, op2 != const) have been seen - in reload output when both operands were symbols before reload, so - we deal with it here. This may be a fault of the constraints above. */ - if (CONSTANT_P (operands[1])) - { - if (CONSTANT_P (operands[2])) - return \"lda %1+%2,%0\"; - else - return \"lda %1(%2),%0\"; - } - return \"lda %2(%1),%0\"; -}") - -(define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "signed_arith_operand" "%dI") - (match_operand:SI 2 "signed_arith_operand" "dIK")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - return \"subo %n2,%1,%0\"; - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"addo %2,%1,%0\"; - return \"addo %1,%2,%0\"; -}") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (mult:SI (match_operand:SI 1 "arith_operand" "%dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "* -{ - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"mulo %2,%1,%0\"; - return \"mulo %1,%2,%0\"; -}" - [(set_attr "type" "mult")]) - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=d") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))] - "" - "* -{ - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"emul %2,%1,%0\"; - return \"emul %1,%2,%0\"; -}" - [(set_attr "type" "mult")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%d")) - (match_operand:SI 2 "literal" "I")))] - "" - "* -{ - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"emul %2,%1,%0\"; - return \"emul %1,%2,%0\"; -}" - [(set_attr "type" "mult")]) - -;; This goes after the move/add/sub/mul instructions -;; because those instructions are better when they apply. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (match_operand:SI 1 "address_operand" "p"))] - "" - "lda %a1,%0" - [(set_attr "type" "load")]) - -;; This will never be selected because of an "optimization" that GCC does. -;; It always converts divides by a power of 2 into a sequence of instructions -;; that does a right shift, and then corrects the result if it was negative. - -;; (define_insn "" -;; [(set (match_operand:SI 0 "register_operand" "=d") -;; (div:SI (match_operand:SI 1 "arith_operand" "dI") -;; (match_operand:SI 2 "power2_operand" "nI")))] -;; "" -;; "*{ -;; operands[2] = gen_rtx(CONST_INT, VOIDmode,bitpos (INTVAL (operands[2]))); -;; return \"shrdi %2,%1,%0\"; -;; }" - -(define_insn "divsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (div:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "divi %2,%1,%0" - [(set_attr "type" "div")]) - -(define_insn "udivsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (udiv:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "divo %2,%1,%0" - [(set_attr "type" "div")]) - -;; We must use `remi' not `modi' here, to ensure that `%' has the effects -;; specified by the ANSI C standard. - -(define_insn "modsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (mod:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "remi %2,%1,%0" - [(set_attr "type" "div")]) - -(define_insn "umodsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (umod:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "remo %2,%1,%0" - [(set_attr "type" "div")]) - -;; And instructions (with complement also). - -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (match_operand:SI 1 "register_operand" "%d") - (match_operand:SI 2 "logic_operand" "dIM")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - return \"andnot %C2,%1,%0\"; - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"and %2,%1,%0\"; - return \"and %1,%2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "cmplpower2_operand" "n")))] - "" - "* -{ - operands[2] = gen_rtx (CONST_INT, VOIDmode, - bitpos (~INTVAL (operands[2]))); - return \"clrbit %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "d")) - (match_operand:SI 2 "logic_operand" "dIM")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - return \"nor %C2,%1,%0\"; - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"notand %2,%1,%0\"; - return \"andnot %1,%2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ior:SI (not:SI (match_operand:SI 1 "register_operand" "%d")) - (not:SI (match_operand:SI 2 "register_operand" "d"))))] - "" - "* -{ - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"nand %2,%1,%0\"; - return \"nand %1,%2,%0\"; -}") - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ior:SI (match_operand:SI 1 "register_operand" "%d") - (match_operand:SI 2 "logic_operand" "dIM")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - return \"ornot %C2,%1,%0\"; - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"or %2,%1,%0\"; - return \"or %1,%2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ior:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "power2_operand" "n")))] - "" - "* -{ - operands[2] = gen_rtx (CONST_INT, VOIDmode, - bitpos (INTVAL (operands[2]))); - return \"setbit %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ior:SI (not:SI (match_operand:SI 1 "register_operand" "d")) - (match_operand:SI 2 "logic_operand" "dIM")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - return \"nand %C2,%1,%0\"; - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"notor %2,%1,%0\"; - return \"ornot %1,%2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "%d")) - (not:SI (match_operand:SI 2 "register_operand" "d"))))] - "" - "* -{ - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"nor %2,%1,%0\"; - return \"nor %1,%2,%0\"; -}") - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (xor:SI (match_operand:SI 1 "register_operand" "%d") - (match_operand:SI 2 "logic_operand" "dIM")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - return \"xnor %C2,%1,%0\"; - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"xor %2,%1,%0\"; - return \"xor %1,%2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (xor:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "power2_operand" "n")))] - "" - "* -{ - operands[2] = gen_rtx (CONST_INT, VOIDmode, - bitpos (INTVAL (operands[2]))); - return \"notbit %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%d") - (match_operand:SI 2 "register_operand" "d"))))] - "" - "* -{ - if (i960_bypass (insn, operands[1], operands[2], 0)) - return \"xnor %2,%1,%0\"; - return \"xnor %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ior:SI (ashift:SI (const_int 1) - (match_operand:SI 1 "register_operand" "d")) - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "setbit %1,%2,%0") - -;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg) -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (rotate:SI (const_int -2) - (match_operand:SI 1 "register_operand" "d")) - (match_operand:SI 2 "register_operand" "d")))] - "" - "clrbit %1,%2,%0") - -;; The above pattern canonicalizes to this when both the input and output -;; are the same pseudo-register. -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "=d") - (const_int 1) - (match_operand:SI 1 "register_operand" "d")) - (const_int 0))] - "" - "clrbit %1,%0,%0") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (xor:SI (ashift:SI (const_int 1) - (match_operand:SI 1 "register_operand" "d")) - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "notbit %1,%2,%0") - -(define_insn "negsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (neg:SI (match_operand:SI 1 "arith_operand" "dI")))] - "" - "subo %1,0,%0" - [(set_attr "length" "1")]) - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (not:SI (match_operand:SI 1 "arith_operand" "dI")))] - "" - "not %1,%0" - [(set_attr "length" "1")]) - -;; Floating point arithmetic instructions. - -(define_insn "adddf3" - [(set (match_operand:DF 0 "register_operand" "=d*f") - (plus:DF (match_operand:DF 1 "fp_arith_operand" "%rGH") - (match_operand:DF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "addrl %1,%2,%0" - [(set_attr "type" "fpadd")]) - -(define_insn "addsf3" - [(set (match_operand:SF 0 "register_operand" "=d*f") - (plus:SF (match_operand:SF 1 "fp_arith_operand" "%rGH") - (match_operand:SF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "addr %1,%2,%0" - [(set_attr "type" "fpadd")]) - - -(define_insn "subdf3" - [(set (match_operand:DF 0 "register_operand" "=d*f") - (minus:DF (match_operand:DF 1 "fp_arith_operand" "rGH") - (match_operand:DF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "subrl %2,%1,%0" - [(set_attr "type" "fpadd")]) - -(define_insn "subsf3" - [(set (match_operand:SF 0 "register_operand" "=d*f") - (minus:SF (match_operand:SF 1 "fp_arith_operand" "rGH") - (match_operand:SF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "subr %2,%1,%0" - [(set_attr "type" "fpadd")]) - - -(define_insn "muldf3" - [(set (match_operand:DF 0 "register_operand" "=d*f") - (mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH") - (match_operand:DF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "mulrl %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "register_operand" "=d*f") - (mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH") - (match_operand:SF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "mulr %1,%2,%0" - [(set_attr "type" "fpmul")]) - - -(define_insn "divdf3" - [(set (match_operand:DF 0 "register_operand" "=d*f") - (div:DF (match_operand:DF 1 "fp_arith_operand" "rGH") - (match_operand:DF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "divrl %2,%1,%0" - [(set_attr "type" "fpdiv")]) - -(define_insn "divsf3" - [(set (match_operand:SF 0 "register_operand" "=d*f") - (div:SF (match_operand:SF 1 "fp_arith_operand" "rGH") - (match_operand:SF 2 "fp_arith_operand" "rGH")))] - "TARGET_NUMERICS" - "divr %2,%1,%0" - [(set_attr "type" "fpdiv")]) - -(define_insn "negdf2" - [(set (match_operand:DF 0 "register_operand" "=d,d*f") - (neg:DF (match_operand:DF 1 "register_operand" "d,r")))] - "" - "* -{ - if (which_alternative == 0) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"notbit 31,%D1,%D0\"; - return \"mov %1,%0\;notbit 31,%D1,%D0\"; - } - return \"subrl %1,0f0.0,%0\"; -}" - [(set_attr "type" "fpadd")]) - -(define_insn "negsf2" - [(set (match_operand:SF 0 "register_operand" "=d,d*f") - (neg:SF (match_operand:SF 1 "register_operand" "d,r")))] - "" - "@ - notbit 31,%1,%0 - subr %1,0f0.0,%0" - [(set_attr "type" "fpadd")]) - -;;; The abs patterns also work even if the target machine doesn't have -;;; floating point, because in that case dstreg and srcreg will always be -;;; less than 32. - -(define_insn "absdf2" - [(set (match_operand:DF 0 "register_operand" "=d*f") - (abs:DF (match_operand:DF 1 "register_operand" "df")))] - "" - "* -{ - int dstreg = REGNO (operands[0]); - int srcreg = REGNO (operands[1]); - - if (dstreg < 32) - { - if (srcreg < 32) - { - if (dstreg != srcreg) - output_asm_insn (\"mov %1,%0\", operands); - return \"clrbit 31,%D1,%D0\"; - } - /* Src is an fp reg. */ - return \"movrl %1,%0\;clrbit 31,%D1,%D0\"; - } - if (srcreg >= 32) - return \"cpysre %1,0f0.0,%0\"; - return \"movrl %1,%0\;cpysre %0,0f0.0,%0\"; -}" - [(set_attr "type" "multi")]) - -(define_insn "abssf2" - [(set (match_operand:SF 0 "register_operand" "=d*f") - (abs:SF (match_operand:SF 1 "register_operand" "df")))] - "" - "* -{ - int dstreg = REGNO (operands[0]); - int srcreg = REGNO (operands[1]); - - if (dstreg < 32 && srcreg < 32) - return \"clrbit 31,%1,%0\"; - - if (dstreg >= 32 && srcreg >= 32) - return \"cpysre %1,0f0.0,%0\"; - - if (dstreg < 32) - return \"movr %1,%0\;clrbit 31,%0,%0\"; - - return \"movr %1,%0\;cpysre %0,0f0.0,%0\"; -}" - [(set_attr "type" "multi")]) - -;; Tetra (16 byte) float support. - -(define_expand "cmpxf" - [(set (reg:CC 36) - (compare:CC (match_operand:XF 0 "register_operand" "") - (match_operand:XF 1 "nonmemory_operand" "")))] - "TARGET_NUMERICS" - " -{ - i960_compare_op0 = operands[0]; - i960_compare_op1 = operands[1]; - DONE; -}") - -(define_insn "" - [(set (reg:CC 36) - (compare:CC (match_operand:XF 0 "register_operand" "f") - (match_operand:XF 1 "nonmemory_operand" "fGH")))] - "TARGET_NUMERICS" - "cmpr %0,%1" - [(set_attr "type" "fpcc")]) - -(define_expand "movxf" - [(set (match_operand:XF 0 "general_operand" "") - (match_operand:XF 1 "fpmove_src_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, XFmode)) - DONE; -}") - -(define_insn "" - [(set (match_operand:XF 0 "general_operand" "=r,f,d,d,m") - (match_operand:XF 1 "fpmove_src_operand" "r,GH,F,m,d"))] - "register_operand (operands[0], XFmode) - || register_operand (operands[1], XFmode)" - "* -{ - switch (which_alternative) - { - case 0: - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return \"movre %1,%0\"; - else - return \"movq %1,%0\"; - case 1: - return \"movre %1,%0\"; - case 2: - return i960_output_ldconst (operands[0], operands[1]); - case 3: - return \"ldt %1,%0\"; - case 4: - return \"stt %1,%0\"; - } -}" - [(set_attr "type" "move,move,load,fpload,fpstore")]) - -(define_insn "extendsfxf2" - [(set (match_operand:XF 0 "register_operand" "=f,d") - (float_extend:XF - (match_operand:SF 1 "register_operand" "d,f")))] - "TARGET_NUMERICS" - "@ - movr %1,%0 - movre %1,%0" - [(set_attr "type" "fpmove")]) - -(define_insn "extenddfxf2" - [(set (match_operand:XF 0 "register_operand" "=f,d") - (float_extend:XF - (match_operand:DF 1 "register_operand" "d,f")))] - "TARGET_NUMERICS" - "@ - movrl %1,%0 - movre %1,%0" - [(set_attr "type" "fpmove")]) - -(define_insn "truncxfdf2" - [(set (match_operand:DF 0 "register_operand" "=d") - (float_truncate:DF - (match_operand:XF 1 "register_operand" "f")))] - "TARGET_NUMERICS" - "movrl %1,%0" - [(set_attr "type" "fpmove")]) - -(define_insn "truncxfsf2" - [(set (match_operand:SF 0 "register_operand" "=d") - (float_truncate:SF - (match_operand:XF 1 "register_operand" "f")))] - "TARGET_NUMERICS" - "movr %1,%0" - [(set_attr "type" "fpmove")]) - -(define_insn "floatsixf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (float:XF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_NUMERICS" - "cvtir %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_insn "fix_truncxfsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))] - "TARGET_NUMERICS" - "cvtzri %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_insn "fixuns_truncxfsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (unsigned_fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))] - "TARGET_NUMERICS" - "cvtzri %1,%0" - [(set_attr "type" "fpcvt")]) - -(define_insn "addxf3" - [(set (match_operand:XF 0 "register_operand" "=f") - (plus:XF (match_operand:XF 1 "nonmemory_operand" "%fGH") - (match_operand:XF 2 "nonmemory_operand" "fGH")))] - "TARGET_NUMERICS" - "addr %1,%2,%0" - [(set_attr "type" "fpadd")]) - -(define_insn "subxf3" - [(set (match_operand:XF 0 "register_operand" "=f") - (minus:XF (match_operand:XF 1 "nonmemory_operand" "fGH") - (match_operand:XF 2 "nonmemory_operand" "fGH")))] - "TARGET_NUMERICS" - "subr %2,%1,%0" - [(set_attr "type" "fpadd")]) - -(define_insn "mulxf3" - [(set (match_operand:XF 0 "register_operand" "=f") - (mult:XF (match_operand:XF 1 "nonmemory_operand" "%fGH") - (match_operand:XF 2 "nonmemory_operand" "fGH")))] - "TARGET_NUMERICS" - "mulr %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "divxf3" - [(set (match_operand:XF 0 "register_operand" "=f") - (div:XF (match_operand:XF 1 "nonmemory_operand" "fGH") - (match_operand:XF 2 "nonmemory_operand" "fGH")))] - "TARGET_NUMERICS" - "divr %2,%1,%0" - [(set_attr "type" "fpdiv")]) - -(define_insn "negxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (neg:XF (match_operand:XF 1 "register_operand" "f")))] - "TARGET_NUMERICS" - "subr %1,0f0.0,%0" - [(set_attr "type" "fpadd")]) - -(define_insn "absxf2" - [(set (match_operand:XF 0 "register_operand" "=f") - (abs:XF (match_operand:XF 1 "register_operand" "f")))] - "(TARGET_NUMERICS)" - "cpysre %1,0f0.0,%0" - [(set_attr "type" "fpmove")]) - -;; Arithmetic shift instructions. - -;; The shli instruction generates an overflow fault if the sign changes. -;; In the case of overflow, it does not give the natural result, it instead -;; gives the last shift value before the overflow. We can not use this -;; instruction because gcc thinks that arithmetic left shift and logical -;; left shift are identical, and sometimes canonicalizes the logical left -;; shift to an arithmetic left shift. Therefore we must always use the -;; logical left shift instruction. - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashift:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "shlo %2,%1,%0" - [(set_attr "type" "alu2")]) - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "shri %2,%1,%0" - [(set_attr "type" "alu2")]) - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI") - (match_operand:SI 2 "arith_operand" "dI")))] - "" - "shro %2,%1,%0" - [(set_attr "type" "alu2")]) - -;; Unconditional and other jump instructions. - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "b %l0" - [(set_attr "type" "branch")]) - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "address_operand" "p"))] - "" - "bx %a0" - [(set_attr "type" "branch")]) - -(define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "register_operand" "d")) - (use (label_ref (match_operand 1 "" "")))] - "" - "bx (%0)" - [(set_attr "type" "branch")]) - -;;- jump to subroutine - -(define_expand "call" - [(call (match_operand:SI 0 "memory_operand" "m") - (match_operand:SI 1 "immediate_operand" "i"))] - "" - " -{ - emit_insn (gen_call_internal (operands[0], operands[1], - virtual_outgoing_args_rtx)); - DONE; -}") - -;; We need a call saved register allocated for the match_scratch, so we use -;; 'l' because all local registers are call saved. - -;; ??? I would prefer to use a match_scratch here, but match_scratch allocated -;; registers can't be used for spills. In a function with lots of calls, -;; local-alloc may allocate all local registers to a match_scratch, leaving -;; no local registers available for spills. - -(define_insn "call_internal" - [(call (match_operand:SI 0 "memory_operand" "m") - (match_operand:SI 1 "immediate_operand" "i")) - (use (match_operand:SI 2 "address_operand" "p")) - (clobber (reg:SI 19))] - "" - "* return i960_output_call_insn (operands[0], operands[1], operands[2], - insn);" - [(set_attr "type" "call")]) - -(define_expand "call_value" - [(set (match_operand 0 "register_operand" "=d") - (call (match_operand:SI 1 "memory_operand" "m") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - " -{ - emit_insn (gen_call_value_internal (operands[0], operands[1], operands[2], - virtual_outgoing_args_rtx)); - DONE; -}") - -;; We need a call saved register allocated for the match_scratch, so we use -;; 'l' because all local registers are call saved. - -(define_insn "call_value_internal" - [(set (match_operand 0 "register_operand" "=d") - (call (match_operand:SI 1 "memory_operand" "m") - (match_operand:SI 2 "immediate_operand" "i"))) - (use (match_operand:SI 3 "address_operand" "p")) - (clobber (reg:SI 19))] - "" - "* return i960_output_call_insn (operands[1], operands[2], operands[3], - insn);" - [(set_attr "type" "call")]) - -(define_insn "return" - [(return)] - "" - "* return i960_output_ret_insn (insn);" - [(set_attr "type" "branch")]) - -(define_insn "nop" - [(const_int 0)] - "" - "") - -;; Various peephole optimizations for multiple-word moves, loads, and stores. -;; Multiple register moves. - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "register_operand" "r")) - (set (match_operand:SI 2 "register_operand" "=r") - (match_operand:SI 3 "register_operand" "r")) - (set (match_operand:SI 4 "register_operand" "=r") - (match_operand:SI 5 "register_operand" "r")) - (set (match_operand:SI 6 "register_operand" "=r") - (match_operand:SI 7 "register_operand" "r"))] - "((REGNO (operands[0]) & 3) == 0) - && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (REGNO (operands[1]) + 1 == REGNO (operands[3])) - && (REGNO (operands[0]) + 2 == REGNO (operands[4])) - && (REGNO (operands[1]) + 2 == REGNO (operands[5])) - && (REGNO (operands[0]) + 3 == REGNO (operands[6])) - && (REGNO (operands[1]) + 3 == REGNO (operands[7]))" - "movq %1,%0") - -;; Matched 4/17/92 -(define_peephole - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operand:DI 1 "register_operand" "r")) - (set (match_operand:DI 2 "register_operand" "=r") - (match_operand:DI 3 "register_operand" "r"))] - "((REGNO (operands[0]) & 3) == 0) - && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[0]) + 2 == REGNO (operands[2])) - && (REGNO (operands[1]) + 2 == REGNO (operands[3]))" - "movq %1,%0") - -;; Matched 4/17/92 -(define_peephole - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operand:DI 1 "register_operand" "r")) - (set (match_operand:SI 2 "register_operand" "=r") - (match_operand:SI 3 "register_operand" "r")) - (set (match_operand:SI 4 "register_operand" "=r") - (match_operand:SI 5 "register_operand" "r"))] - "((REGNO (operands[0]) & 3) == 0) - && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[0]) + 2 == REGNO (operands[2])) - && (REGNO (operands[1]) + 2 == REGNO (operands[3])) - && (REGNO (operands[0]) + 3 == REGNO (operands[4])) - && (REGNO (operands[1]) + 3 == REGNO (operands[5]))" - "movq %1,%0") - -;; Matched 4/17/92 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "register_operand" "r")) - (set (match_operand:SI 2 "register_operand" "=r") - (match_operand:SI 3 "register_operand" "r")) - (set (match_operand:DI 4 "register_operand" "=r") - (match_operand:DI 5 "register_operand" "r"))] - "((REGNO (operands[0]) & 3) == 0) - && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (REGNO (operands[1]) + 1 == REGNO (operands[3])) - && (REGNO (operands[0]) + 2 == REGNO (operands[4])) - && (REGNO (operands[1]) + 2 == REGNO (operands[5]))" - "movq %1,%0") - -;; Matched 4/17/92 -(define_peephole - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operand:DI 1 "register_operand" "r")) - (set (match_operand:SI 2 "register_operand" "=r") - (match_operand:SI 3 "register_operand" "r"))] - "((REGNO (operands[0]) & 3) == 0) - && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[0]) + 2 == REGNO (operands[2])) - && (REGNO (operands[1]) + 2 == REGNO (operands[3]))" - "movt %1,%0") - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "register_operand" "r")) - (set (match_operand:SI 2 "register_operand" "=r") - (match_operand:SI 3 "register_operand" "r")) - (set (match_operand:SI 4 "register_operand" "=r") - (match_operand:SI 5 "register_operand" "r"))] - "((REGNO (operands[0]) & 3) == 0) - && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (REGNO (operands[1]) + 1 == REGNO (operands[3])) - && (REGNO (operands[0]) + 2 == REGNO (operands[4])) - && (REGNO (operands[1]) + 2 == REGNO (operands[5]))" - "movt %1,%0") - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "register_operand" "r")) - (set (match_operand:SI 2 "register_operand" "=r") - (match_operand:SI 3 "register_operand" "r"))] - "((REGNO (operands[0]) & 1) == 0) - && ((REGNO (operands[1]) & 1) == 0) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (REGNO (operands[1]) + 1 == REGNO (operands[3]))" - "movl %1,%0") - -; Multiple register loads. - -;; Matched 6/15/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "immediate_operand" "n")))) - (set (match_operand:SI 3 "register_operand" "=r") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 4 "immediate_operand" "n")))) - (set (match_operand:SI 5 "register_operand" "=r") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 6 "immediate_operand" "n")))) - (set (match_operand:SI 7 "register_operand" "=r") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 8 "immediate_operand" "n"))))] - "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 1 == REGNO (operands[3])) - && (REGNO (operands[1]) != REGNO (operands[3])) - && (REGNO (operands[0]) + 2 == REGNO (operands[5])) - && (REGNO (operands[1]) != REGNO (operands[5])) - && (REGNO (operands[0]) + 3 == REGNO (operands[7])) - && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])) - && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])) - && (INTVAL (operands[2]) + 12 == INTVAL (operands[8])))" - "ldq %2(%1),%0") - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:DF 0 "register_operand" "=d") - (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "immediate_operand" "n")))) - (set (match_operand:DF 3 "register_operand" "=d") - (mem:DF (plus:SI (match_dup 1) - (match_operand:SI 4 "immediate_operand" "n"))))] - "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 2 == REGNO (operands[3])) - && (REGNO (operands[1]) != REGNO (operands[3])) - && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))" - "ldq %2(%1),%0") - -;; Matched 1/24/92 -(define_peephole - [(set (match_operand:DI 0 "register_operand" "=d") - (mem:DI (plus:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "immediate_operand" "n")))) - (set (match_operand:DI 3 "register_operand" "=d") - (mem:DI (plus:SI (match_dup 1) - (match_operand:SI 4 "immediate_operand" "n"))))] - "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 2 == REGNO (operands[3])) - && (REGNO (operands[1]) != REGNO (operands[3])) - && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))" - "ldq %2(%1),%0") - -;; Matched 4/17/92 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") - (mem:SI (match_operand:SI 1 "register_operand" "d"))) - (set (match_operand:SI 2 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 3 "immediate_operand" "n")))) - (set (match_operand:SI 4 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 5 "immediate_operand" "n")))) - (set (match_operand:SI 6 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 7 "immediate_operand" "n"))))] - "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (REGNO (operands[1]) != REGNO (operands[2])) - && (REGNO (operands[0]) + 2 == REGNO (operands[4])) - && (REGNO (operands[1]) != REGNO (operands[4])) - && (REGNO (operands[0]) + 3 == REGNO (operands[6])) - && (INTVAL (operands[3]) == 4) - && (INTVAL (operands[5]) == 8) - && (INTVAL (operands[7]) == 12))" - "ldq (%1),%0") - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") - (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "immediate_operand" "n")))) - (set (match_operand:SI 3 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 4 "immediate_operand" "n")))) - (set (match_operand:SI 5 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 6 "immediate_operand" "n"))))] - "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 1 == REGNO (operands[3])) - && (REGNO (operands[1]) != REGNO (operands[3])) - && (REGNO (operands[0]) + 2 == REGNO (operands[5])) - && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])) - && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])))" - "ldt %2(%1),%0") - -;; Matched 6/15/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") - (mem:SI (match_operand:SI 1 "register_operand" "d"))) - (set (match_operand:SI 2 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 3 "immediate_operand" "n")))) - (set (match_operand:SI 4 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 5 "immediate_operand" "n"))))] - "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (REGNO (operands[1]) != REGNO (operands[2])) - && (REGNO (operands[0]) + 2 == REGNO (operands[4])) - && (INTVAL (operands[3]) == 4) - && (INTVAL (operands[5]) == 8))" - "ldt (%1),%0") - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") - (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "immediate_operand" "n")))) - (set (match_operand:SI 3 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 4 "immediate_operand" "n"))))] - "(i960_si_di (operands[1], operands[2]) && ((REGNO (operands[0]) & 1) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 1 == REGNO (operands[3])) - && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])))" - "ldl %2(%1),%0") - -;; Matched 5/28/91 -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") - (mem:SI (match_operand:SI 1 "register_operand" "d"))) - (set (match_operand:SI 2 "register_operand" "=d") - (mem:SI (plus:SI (match_dup 1) - (match_operand:SI 3 "immediate_operand" "n"))))] - "(i960_si_di (operands[1], 0) && ((REGNO (operands[0]) & 1) == 0) - && (REGNO (operands[1]) != REGNO (operands[0])) - && (REGNO (operands[0]) + 1 == REGNO (operands[2])) - && (INTVAL (operands[3]) == 4))" - "ldl (%1),%0") - -; Multiple register stores. - -;; Matched 5/28/91 -(define_peephole - [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "immediate_operand" "n"))) - (match_operand:SI 2 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 3 "immediate_operand" "n"))) - (match_operand:SI 4 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 5 "immediate_operand" "n"))) - (match_operand:SI 6 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 7 "immediate_operand" "n"))) - (match_operand:SI 8 "register_operand" "d"))] - "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) - && (REGNO (operands[2]) + 1 == REGNO (operands[4])) - && (REGNO (operands[2]) + 2 == REGNO (operands[6])) - && (REGNO (operands[2]) + 3 == REGNO (operands[8])) - && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])) - && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])) - && (INTVAL (operands[1]) + 12 == INTVAL (operands[7])))" - "stq %2,%1(%0)") - -;; Matched 6/16/91 -(define_peephole - [(set (mem:DF (plus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "immediate_operand" "n"))) - (match_operand:DF 2 "register_operand" "d")) - (set (mem:DF (plus:SI (match_dup 0) - (match_operand:SI 3 "immediate_operand" "n"))) - (match_operand:DF 4 "register_operand" "d"))] - "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) - && (REGNO (operands[2]) + 2 == REGNO (operands[4])) - && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))" - "stq %2,%1(%0)") - -;; Matched 4/17/92 -(define_peephole - [(set (mem:DI (plus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "immediate_operand" "n"))) - (match_operand:DI 2 "register_operand" "d")) - (set (mem:DI (plus:SI (match_dup 0) - (match_operand:SI 3 "immediate_operand" "n"))) - (match_operand:DI 4 "register_operand" "d"))] - "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) - && (REGNO (operands[2]) + 2 == REGNO (operands[4])) - && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))" - "stq %2,%1(%0)") - -;; Matched 1/23/92 -(define_peephole - [(set (mem:SI (match_operand:SI 0 "register_operand" "d")) - (match_operand:SI 1 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 2 "immediate_operand" "n"))) - (match_operand:SI 3 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 4 "immediate_operand" "n"))) - (match_operand:SI 5 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 6 "immediate_operand" "n"))) - (match_operand:SI 7 "register_operand" "d"))] - "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[1]) + 1 == REGNO (operands[3])) - && (REGNO (operands[1]) + 2 == REGNO (operands[5])) - && (REGNO (operands[1]) + 3 == REGNO (operands[7])) - && (INTVAL (operands[2]) == 4) - && (INTVAL (operands[4]) == 8) - && (INTVAL (operands[6]) == 12))" - "stq %1,(%0)") - -;; Matched 5/29/91 -(define_peephole - [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "immediate_operand" "n"))) - (match_operand:SI 2 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 3 "immediate_operand" "n"))) - (match_operand:SI 4 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 5 "immediate_operand" "n"))) - (match_operand:SI 6 "register_operand" "d"))] - "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) - && (REGNO (operands[2]) + 1 == REGNO (operands[4])) - && (REGNO (operands[2]) + 2 == REGNO (operands[6])) - && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])) - && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])))" - "stt %2,%1(%0)") - -;; Matched 5/29/91 -(define_peephole - [(set (mem:SI (match_operand:SI 0 "register_operand" "d")) - (match_operand:SI 1 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 2 "immediate_operand" "n"))) - (match_operand:SI 3 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 4 "immediate_operand" "n"))) - (match_operand:SI 5 "register_operand" "d"))] - "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0) - && (REGNO (operands[1]) + 1 == REGNO (operands[3])) - && (REGNO (operands[1]) + 2 == REGNO (operands[5])) - && (INTVAL (operands[2]) == 4) - && (INTVAL (operands[4]) == 8))" - "stt %1,(%0)") - -;; Matched 5/28/91 -(define_peephole - [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "immediate_operand" "n"))) - (match_operand:SI 2 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 3 "immediate_operand" "n"))) - (match_operand:SI 4 "register_operand" "d"))] - "(i960_si_di (operands[0], operands[1]) && ((REGNO (operands[2]) & 1) == 0) - && (REGNO (operands[2]) + 1 == REGNO (operands[4])) - && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])))" - "stl %2,%1(%0)") - -;; Matched 5/28/91 -(define_peephole - [(set (mem:SI (match_operand:SI 0 "register_operand" "d")) - (match_operand:SI 1 "register_operand" "d")) - (set (mem:SI (plus:SI (match_dup 0) - (match_operand:SI 2 "immediate_operand" "n"))) - (match_operand:SI 3 "register_operand" "d"))] - "(i960_si_di (operands[0], 0) && ((REGNO (operands[1]) & 1) == 0) - && (REGNO (operands[1]) + 1 == REGNO (operands[3])) - && (INTVAL (operands[2]) == 4))" - "stl %1,(%0)") |