--- gcc/config/i960/i960.md 2018/04/24 18:10:26 1.1 +++ gcc/config/i960/i960.md 2018/04/24 18:30:28 1.1.1.3 @@ -1,5 +1,5 @@ ;;- Machine description for Intel 80960 chip for GNU C compiler -;; Copyright (C) 1992 Free Software Foundation, Inc. +;; 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. @@ -18,13 +18,14 @@ ;; 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, 675 Mass Ave, Cambridge, MA 02139, USA. +;; 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 psuedo-registers from being allocated to them. +;; 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. @@ -553,16 +554,19 @@ ;; 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. This value of this 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. +;; 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) @@ -597,6 +601,8 @@ [(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))" @@ -642,6 +648,8 @@ [(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) @@ -677,6 +685,8 @@ [(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))" @@ -719,6 +729,8 @@ [(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) @@ -754,6 +766,8 @@ [(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))" @@ -793,9 +807,11 @@ ;; The store case can not be separate. See comment above. (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=d,d,d,m,o") - (match_operand:DI 1 "general_operand" "dI,i,m,d,J"))] + [(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) @@ -805,25 +821,26 @@ switch (which_alternative) { case 0: - return \"movl %1,%0\"; case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldl %1,%0\"; case 3: - return \"stl %1,%0\"; 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,load,load,store,store")]) + [(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,m") - (match_operand:DI 1 "general_operand" "dI,i,m,d"))] + [(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))" @@ -832,16 +849,28 @@ switch (which_alternative) { case 0: - return \"movl %1,%0\"; case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldl %1,%0\"; case 3: - return \"stl %1,%0\"; + 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,load,load,store")]) + [(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" "") @@ -855,9 +884,11 @@ ;; The store case can not be separate. See comment above. (define_insn "" - [(set (match_operand:TI 0 "general_operand" "=d,d,d,m,o") - (match_operand:TI 1 "general_operand" "dI,i,m,d,J"))] + [(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) @@ -867,27 +898,28 @@ switch (which_alternative) { case 0: - return \"movq %1,%0\"; case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldq %1,%0\"; case 3: - return \"stq %1,%0\"; 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,load,load,store,store")]) + [(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,m") - (match_operand:TI 1 "general_operand" "dI,i,m,d"))] + [(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))" @@ -896,16 +928,30 @@ switch (which_alternative) { case 0: - return \"movq %1,%0\"; case 1: - return i960_output_ldconst (operands[0], operands[1]); - case 2: - return \"ldq %1,%0\"; case 3: - return \"stq %1,%0\"; + 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,load,load,store")]) + [(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 @@ -976,6 +1022,8 @@ [(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) @@ -1008,6 +1056,8 @@ [(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))" @@ -1046,6 +1096,8 @@ [(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) @@ -1077,6 +1129,8 @@ [(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))" @@ -1657,14 +1711,25 @@ return \"clrbit %2,%1,%0\"; }") +;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (ashift:SI (const_int 1) + (and:SI (rotate:SI (const_int -2) (match_operand:SI 1 "register_operand" "d")) - (match_operand:SI 2 "arith_operand" "dI")))] + (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 (match_operand:SI 1 "arith_operand" "dI") @@ -1907,65 +1972,41 @@ ;; Tetra (16 byte) float support. -(define_insn "cmptf" +(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:TF 0 "register_operand" "f") - (match_operand:TF 1 "nonmemory_operand" "fG")))] + (compare:CC (match_operand:XF 0 "register_operand" "f") + (match_operand:XF 1 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" - "cmpr %0,%1" + "cmpr %0,%1" [(set_attr "type" "fpcc")]) -(define_expand "movtf" - [(set (match_operand:TF 0 "general_operand" "") - (match_operand:TF 1 "fpmove_src_operand" ""))] +(define_expand "movxf" + [(set (match_operand:XF 0 "general_operand" "") + (match_operand:XF 1 "fpmove_src_operand" ""))] "" " { - if (emit_move_sequence (operands, TFmode)) + if (emit_move_sequence (operands, XFmode)) DONE; }") (define_insn "" - [(set (match_operand:TF 0 "general_operand" "=r,*f,d,d,m,o") - (match_operand:TF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))] - "(current_function_args_size == 0 - && rtx_equal_function_value_matters == 0) - && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode) - || operands[1] == CONST0_RTX (TFmode))" - "* -{ - 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 \"ldq %1,%0\"; - case 4: - return \"stq %1,%0\"; - 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,fpload,fpstore,fpstore")]) - -(define_insn "" - [(set (match_operand:TF 0 "general_operand" "=r,*f,d,d,m") - (match_operand:TF 1 "fpmove_src_operand" "r,GH,F,m,d"))] - "(current_function_args_size != 0 - || rtx_equal_function_value_matters != 0) - && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" + [(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) @@ -1980,16 +2021,16 @@ case 2: return i960_output_ldconst (operands[0], operands[1]); case 3: - return \"ldq %1,%0\"; + return \"ldt %1,%0\"; case 4: - return \"stq %1,%0\"; + return \"stt %1,%0\"; } }" [(set_attr "type" "move,move,load,fpload,fpstore")]) -(define_insn "extendsftf2" - [(set (match_operand:TF 0 "register_operand" "=*f,d") - (float_extend:TF +(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" "@ @@ -1997,9 +2038,9 @@ movre %1,%0" [(set_attr "type" "fpmove")]) -(define_insn "extenddftf2" - [(set (match_operand:TF 0 "register_operand" "=*f,d") - (float_extend:TF +(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" "@ @@ -2007,85 +2048,85 @@ movre %1,%0" [(set_attr "type" "fpmove")]) -(define_insn "trunctfdf2" +(define_insn "truncxfdf2" [(set (match_operand:DF 0 "register_operand" "=d") (float_truncate:DF - (match_operand:TF 1 "register_operand" "f")))] + (match_operand:XF 1 "register_operand" "f")))] "TARGET_NUMERICS" "movrl %1,%0" [(set_attr "type" "fpmove")]) -(define_insn "trunctfsf2" +(define_insn "truncxfsf2" [(set (match_operand:SF 0 "register_operand" "=d") (float_truncate:SF - (match_operand:TF 1 "register_operand" "f")))] + (match_operand:XF 1 "register_operand" "f")))] "TARGET_NUMERICS" "movr %1,%0" [(set_attr "type" "fpmove")]) -(define_insn "floatsitf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (float:TF (match_operand:SI 1 "register_operand" "d")))] +(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_trunctfsi2" +(define_insn "fix_truncxfsi2" [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] + (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))] "TARGET_NUMERICS" "cvtzri %1,%0" [(set_attr "type" "fpcvt")]) -(define_insn "fixuns_trunctfsi2" +(define_insn "fixuns_truncxfsi2" [(set (match_operand:SI 0 "register_operand" "=d") - (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] + (unsigned_fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))] "TARGET_NUMERICS" "cvtzri %1,%0" [(set_attr "type" "fpcvt")]) -(define_insn "addtf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (plus:TF (match_operand:TF 1 "nonmemory_operand" "%fG") - (match_operand:TF 2 "nonmemory_operand" "fG")))] +(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 "subtf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (minus:TF (match_operand:TF 1 "nonmemory_operand" "fG") - (match_operand:TF 2 "nonmemory_operand" "fG")))] +(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 "multf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (mult:TF (match_operand:TF 1 "nonmemory_operand" "%fG") - (match_operand:TF 2 "nonmemory_operand" "fG")))] +(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 "divtf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (div:TF (match_operand:TF 1 "nonmemory_operand" "fG") - (match_operand:TF 2 "nonmemory_operand" "fG")))] +(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 "negtf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (neg:TF (match_operand:TF 1 "register_operand" "f")))] +(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 "abstf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (abs:TF (match_operand:TF 1 "register_operand" "f")))] +(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")]) @@ -2149,7 +2190,7 @@ ;;- jump to subroutine (define_expand "call" - [(call (match_operand:SI 0 "general_operand" "g") + [(call (match_operand:SI 0 "memory_operand" "m") (match_operand:SI 1 "immediate_operand" "i"))] "" " @@ -2168,7 +2209,7 @@ ;; no local registers available for spills. (define_insn "call_internal" - [(call (match_operand:SI 0 "general_operand" "g") + [(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))] @@ -2179,7 +2220,7 @@ (define_expand "call_value" [(set (match_operand 0 "register_operand" "=d") - (call (match_operand:SI 1 "general_operand" "g") + (call (match_operand:SI 1 "memory_operand" "m") (match_operand:SI 2 "immediate_operand" "i")))] "" " @@ -2194,7 +2235,7 @@ (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=d") - (call (match_operand:SI 1 "general_operand" "g") + (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))]