--- gcc/config/a29k/a29k.md 2018/04/24 18:10:25 1.1 +++ gcc/config/a29k/a29k.md 2018/04/24 18:29:17 1.1.1.4 @@ -1,6 +1,6 @@ ;;- Machine description for AMD Am29000 for GNU C compiler -;; Copyright (C) 1991, 1992 Free Software Foundation, Inc. -;; Contributed by Richard Kenner (kenner@nyu.edu) +;; Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -16,7 +16,8 @@ ;; 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. @@ -102,48 +103,38 @@ andn %0,%1,%C2") (define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "srcb_operand" "rI")) - (match_operand:SI 2 "gpc_reg_operand" "r")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (match_operand:SI 2 "cmplsrcb_operand" "r,K")))] "" - "andn %0,%2,%1") - + "@ + andn %0,%2,%1 + nor %0,%1,%C2") ;; CALLI ;; -;; Start with a subroutine to write out CLOBBERs starting at lr2 up to, -;; but not including, the next parameter register. If operand[0] is null, -;; it means that all the argument registers have been used. -(define_expand "clobbers_to" - [(clobber (match_operand:SI 0 "" ""))] +;; Each call pattern is duplicated so that we can add CLOBBERs to the +;; resulting insn. +;; +;; We indicate that LR0 is clobbered in the CALL_INSN itself. Otherwise, +;; reorg will think it is just clobbered by the called function. + +(define_expand "call" + [(use (match_operand:SI 0 "" "")) + (use (match_operand 1 "" "")) + (use (match_operand 2 "" ""))] "" " -{ - int i; - int high_regno; - - if (operands[0] == 0) - high_regno = R_LR (18); - else if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < R_LR (0) - || REGNO (operands[0]) > R_LR (18)) - abort (); - else - high_regno = REGNO (operands[0]); - - for (i = R_LR (2); i < high_regno; i++) - emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, i))); +{ rtx insn = emit_call_insn (gen_call_internal (operands[0], operands[1])); + a29k_clobbers_to (insn, operands[2]); DONE; }") - -;; We indicate that LR0 is clobbered in the CALL_INSN itself. Otherwise, -;; reorg will think it is just clobbered by the called function. - -(define_expand "call" + +(define_expand "call_internal" [(parallel [(call (match_operand:SI 0 "" "") (match_operand 1 "" "")) - (clobber (scratch:SI))]) - (match_operand 2 "" "")] + (clobber (scratch:SI))])] "" " { @@ -156,16 +147,27 @@ && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) operands[0] = gen_rtx (MEM, SImode, force_reg (Pmode, XEXP (operands[0], 0))); - - operands[2] = gen_clobbers_to (operands[2]); }") (define_expand "call_value" + [(use (match_operand:SI 0 "gpc_reg_operand" "")) + (use (match_operand:SI 1 "" "")) + (use (match_operand 2 "" "")) + (use (match_operand 3 "" ""))] + "" + " +{ rtx insn = emit_call_insn (gen_call_value_internal (operands[0], operands[1], + operands[2])); + + a29k_clobbers_to (insn, operands[3]); + DONE; +}") + +(define_expand "call_value_internal" [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (call (match_operand:SI 1 "" "") (match_operand 2 "" ""))) - (clobber (scratch:SI))]) - (match_operand 3 "" "")] + (clobber (scratch:SI))])] "" " { @@ -179,7 +181,6 @@ operands[1] = gen_rtx (MEM, SImode, force_reg (Pmode, XEXP (operands[1], 0))); - operands[3] = gen_clobbers_to (operands[3]); }") (define_insn "" @@ -277,61 +278,61 @@ (define_insn "fix_truncsfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (fix:SI (match_operand:SF 1 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,0,3,0,1") (define_insn "fix_truncdfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (fix:SI (match_operand:DF 1 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,0,3,0,2") (define_insn "fixuns_truncsfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,1,3,0,1") (define_insn "fixuns_truncdfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (unsigned_fix:SI (match_operand:DF 1 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,1,3,0,2") (define_insn "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=r") (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,0,4,1,2") (define_insn "extendsfdf2" [(set (match_operand:DF 0 "register_operand" "=r") (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,0,4,2,1") (define_insn "floatsisf2" [(set (match_operand:SF 0 "register_operand" "=r") (float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,0,4,1,0") (define_insn "floatsidf2" [(set (match_operand:DF 0 "register_operand" "=r") (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,0,4,2,0") (define_insn "floatunssisf2" [(set (match_operand:SF 0 "register_operand" "=r") (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,1,4,1,0") (define_insn "floatunssidf2" [(set (match_operand:DF 0 "register_operand" "=r") (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "convert %0,%1,1,4,2,0") ;; CPxxx, DEQ, DGT, DGE, FEQ, FGT, FGE @@ -348,7 +349,7 @@ (match_operator 3 "fp_comparison_operator" [(match_operand:SF 1 "register_operand" "r") (match_operand:SF 2 "register_operand" "r")]))] - "" + "! TARGET_SOFT_FLOAT" "f%J3 %0,%1,%2" [(set_attr "type" "fadd")]) @@ -357,7 +358,7 @@ (match_operator 3 "fp_comparison_operator" [(match_operand:DF 1 "register_operand" "r") (match_operand:DF 2 "register_operand" "r")]))] - "" + "! TARGET_SOFT_FLOAT" "d%J3 %0,%1,%2" [(set_attr "type" "fadd")]) @@ -366,7 +367,7 @@ [(set (match_operand:DF 0 "register_operand" "") (plus:DF (match_operand:DF 1 "register_operand" "") (match_operand:DF 2 "register_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" "") (define_insn "" @@ -392,7 +393,7 @@ [(set (match_operand:DF 0 "register_operand" "=r") (div:DF (match_operand:DF 1 "register_operand" "=r") (match_operand:DF 2 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "ddiv %0,%1,%2" [(set_attr "type" "ddiv")]) @@ -535,7 +536,7 @@ [(set (match_operand:DF 0 "register_operand" "") (mult:DF (match_operand:DF 1 "register_operand" "") (match_operand:DF 2 "register_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" "") (define_insn "" @@ -561,7 +562,7 @@ [(set (match_operand:DF 0 "register_operand" "=r") (minus:DF (match_operand:DF 1 "register_operand" "r") (match_operand:DF 2 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "") (define_insn "" @@ -731,7 +732,7 @@ [(set (match_operand:SF 0 "register_operand" "") (plus:SF (match_operand:SF 1 "register_operand" "") (match_operand:SF 2 "register_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" "") (define_insn "" @@ -757,7 +758,7 @@ [(set (match_operand:SF 0 "register_operand" "=r") (div:SF (match_operand:SF 1 "register_operand" "=r") (match_operand:SF 2 "register_operand" "r")))] - "" + "! TARGET_SOFT_FLOAT" "fdiv %0,%1,%2" [(set_attr "type" "fdiv")]) @@ -766,7 +767,7 @@ [(set (match_operand:DF 0 "register_operand" "=r") (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "%r")) (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))] - "" + "! TARGET_SOFT_FLOAT" "fdmul %0,%1,%2") ;; FMAC/FMSM @@ -847,7 +848,7 @@ [(set (match_operand:SF 0 "register_operand" "") (mult:SF (match_operand:SF 1 "register_operand" "") (match_operand:SF 2 "register_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" "") (define_insn "" @@ -873,7 +874,7 @@ [(set (match_operand:SF 0 "register_operand" "") (minus:SF (match_operand:SF 1 "register_operand" "") (match_operand:SF 2 "register_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" "") (define_insn "" @@ -1120,32 +1121,12 @@ "" "multiply %0,%1,%2") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (subreg:SI - (mult:DI - (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))) 0)) - (clobber (match_scratch:SI 3 "=&q"))] - "" - "multm %0,%1,%2") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (subreg:SI - (mult:DI - (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))) 0)) - (clobber (match_scratch:SI 3 "=&q"))] - "" - "multmu %0,%1,%2") - (define_insn "mulsidi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))) (clobber (match_scratch:SI 3 "=&q"))] - "" + "TARGET_MULTM" "multiply %L0,%1,%2\;multm %0,%1,%2" [(set_attr "type" "multi")]) @@ -1159,20 +1140,22 @@ (mult:SI (match_dup 1) (match_dup 2))) (clobber (reg:SI 180))]) (parallel [(set (match_dup 4) - (subreg:SI (mult:DI - (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) 0)) + (truncate:SI + (lshiftrt:DI + (mult:DI (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2))) + (const_int 32)))) (clobber (reg:SI 180))])] " { operands[3] = operand_subword (operands[0], 1, 1, DImode); - operands[4] = operand_subword (operands[1], 0, 1, DImode); } ") + operands[4] = operand_subword (operands[0], 0, 1, DImode); } ") (define_insn "umulsidi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))) (clobber (match_scratch:SI 3 "=&q"))] - "" + "TARGET_MULTM" "multiplu %L0,%1,%2\;multmu %0,%1,%2" [(set_attr "type" "multi")]) @@ -1186,18 +1169,43 @@ (mult:SI (match_dup 1) (match_dup 2))) (clobber (reg:SI 180))]) (parallel [(set (match_dup 4) - (subreg:SI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) 0)) + (truncate:SI + (lshiftrt:DI + (mult:DI (zero_extend:DI (match_dup 1)) + (zero_extend:DI (match_dup 2))) + (const_int 32)))) (clobber (reg:SI 180))])] " { operands[3] = operand_subword (operands[0], 1, 1, DImode); - operands[4] = operand_subword (operands[1], 0, 1, DImode); } ") + operands[4] = operand_subword (operands[0], 0, 1, DImode); } ") +(define_insn "smulsi3_highpart" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (truncate:SI + (lshiftrt:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) + (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=&q"))] + "TARGET_MULTM" + "multm %0,%1,%2") + +(define_insn "umulsi3_highpart" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (truncate:SI + (lshiftrt:DI + (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) + (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=&q"))] + "TARGET_MULTM" + "multmu %0,%1,%2") + ;; NAND (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (not:SI (match_operand:SI 2 "srcb_operand" "rI"))))] + (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))] "" "nand %0,%1,%2") @@ -1205,24 +1213,18 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (match_operand:SI 2 "const_int_operand" "K")))] - "((unsigned) ~ INTVAL (operands[2])) < 256" + ; Match TARGET_29050 in "orn" pattern for slightly better reload. + "! TARGET_29050 && ((unsigned) ~ INTVAL (operands[2])) < 256" "nand %0,%1,%C2") ;; NOR (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (not:SI (match_operand:SI 2 "srcb_operand" "rI"))))] + (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))] "" "nor %0,%1,%2") -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (match_operand:SI 2 "const_int_operand" "K")))] - "((unsigned) ~ INTVAL (operands[2])) < 256" - "nor %0,%1,%C2") - (define_insn "one_cmplsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] @@ -1247,12 +1249,21 @@ (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "srcb_operand" "rI,K")))] + (match_operand:SI 2 "and_operand" "rI,K")))] "TARGET_29050" "@ or %0,%1,%2 orn %0,%1,%C2") +(define_insn "" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) + (match_operand:SI 2 "cmplsrcb_operand" "r,K")))] + "TARGET_29050" + "@ + orn %0,%2,%1 + nand %0,%1,%C2") + ;; SLL (also used by move insn) (define_insn "nop" @@ -1513,17 +1524,20 @@ (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "srcb_operand" "rI"))))] + (match_operand:SI 2 "gpc_reg_operand" "r"))))] "" "xnor %0,%1,%2") ;; XOR + (define_insn "xorsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r") - (match_operand:SI 2 "srcb_operand" "rI")))] + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") + (match_operand:SI 2 "and_operand" "rI,K")))] "" - "xor %0,%1,%2") + "@ + xor %0,%1,%2 + xnor %0,%1,%C2") ;; Can use XOR to negate floating-point values, but we are better off not doing ;; it that way on the 29050 so it can combine with the fmac insns. @@ -1531,7 +1545,7 @@ [(parallel [(set (match_operand:SF 0 "register_operand" "") (neg:SF (match_operand:SF 1 "register_operand" ""))) (clobber (match_scratch:SI 2 ""))])] - "" + "! TARGET_SOFT_FLOAT" " { rtx result; @@ -1559,7 +1573,7 @@ [(parallel [(set (match_operand:DF 0 "register_operand" "") (neg:DF (match_operand:DF 1 "register_operand" ""))) (clobber (match_scratch:SI 2 ""))])] - "" + "! TARGET_SOFT_FLOAT" " { rtx result; @@ -1779,7 +1793,7 @@ { rtx general = gen_reg_rtx (SImode); rtx bp = gen_reg_rtx (PSImode); - rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]), + rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]), XEXP (operands[1], 0), general, bp); a29k_set_memflags (seq, operands[1]); @@ -1900,6 +1914,7 @@ a29k_set_memflags (seq, operands[0]); emit_insn (seq); + DONE; } } else if (GET_CODE (operands[1]) == MEM) @@ -2187,7 +2202,7 @@ "TARGET_NO_STOREM_BUG && (memory_operand (operands[0], TImode) || memory_operand (operands[1], TImode))" - [(set (reg:PSI 179) (const_int 1)) + [(set (reg:PSI 179) (const_int 3)) (parallel [(set (match_dup 0) (match_dup 1)) (use (reg:PSI 179)) (clobber (reg:PSI 179))])] @@ -2430,7 +2445,7 @@ [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "") (match_operand:SF 1 "gpc_reg_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" " { a29k_compare_op0 = operands[0]; @@ -2443,7 +2458,7 @@ [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "") (match_operand:DF 1 "gpc_reg_operand" "")))] - "" + "! TARGET_SOFT_FLOAT" " { a29k_compare_op0 = operands[0]; @@ -2663,7 +2678,7 @@ (match_operand 2 "gpc_reg_operand" ""))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ge:SI (match_dup 3) (const_int 0)))] - "" + "! TARGET_SOFT_FLOAT" " { operands[3] = gen_reg_rtx (SImode); }");