From 2c4a9cffc197eade5c7b6e7135a85fc218a92b66 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Tue, 8 Jul 2003 01:45:30 +0000 Subject: [PATCH] configure.in: Test for PowerPC mfcr field support in assembler. 2003-07-07 David Edelsohn Fariborz Jahanian * configure.in: Test for PowerPC mfcr field support in assembler. * config.in, configure: Regenderated. * config/rs6000/power4.md: Add mfcrf reservation. * config/rs6000/rs6000-protos.h (mfcr_operation): Declare. * config/rs6000/rs6000.c (mfcr_operation): Define. (print_operand): Add 'Q' case for mfcrf. * config/rs6000/rs6000.h (TARGET_MFCRF): New. * config/rs6000/rs6000.md (attribute "type"): Add mfcrf. (movcc_internal1): Emit optional field operand for mfcr and set "type" attribute appropriately. (mfcr SCC): Likewise. (movesi_from_cr_one): New. Co-Authored-By: Fariborz Jahanian From-SVN: r69064 --- gcc/ChangeLog | 17 +++++++ gcc/config.in | 3 ++ gcc/config/rs6000/power4.md | 14 ++++-- gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 60 ++++++++++++++++++++++++- gcc/config/rs6000/rs6000.h | 10 +++++ gcc/config/rs6000/rs6000.md | 75 ++++++++++++++++++++++++++----- gcc/configure | 49 ++++++++++++++++++++ gcc/configure.in | 35 +++++++++++++++ 9 files changed, 247 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index db88e3d978e..0d9300b12d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2003-07-07 David Edelsohn + Fariborz Jahanian + + * configure.in: Test for PowerPC mfcr field support in assembler. + * config.in, configure: Regenderated. + + * config/rs6000/power4.md: Add mfcrf reservation. + * config/rs6000/rs6000-protos.h (mfcr_operation): Declare. + * config/rs6000/rs6000.c (mfcr_operation): Define. + (print_operand): Add 'Q' case for mfcrf. + * config/rs6000/rs6000.h (TARGET_MFCRF): New. + * config/rs6000/rs6000.md (attribute "type"): Add mfcrf. + (movcc_internal1): Emit optional field operand for mfcr and set + "type" attribute appropriately. + (mfcr SCC): Likewise. + (movesi_from_cr_one): New. + 2003-07-07 Roger Sayle * config/i386/i386.md: Correct check-in of incorrect version. diff --git a/gcc/config.in b/gcc/config.in index a6be70a5a3b..997094c5964 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -572,6 +572,9 @@ /* Define if your assembler supports ltoffx and ldxmov relocations. */ #undef HAVE_AS_LTOFFX_LDXMOV_RELOCS +/* Define if your assembler supports mfcr field. */ +#undef HAVE_AS_MFCRF + /* Define if your assembler supports dwarf2 .file/.loc directives, and preserves file table indices exactly as given. */ #undef HAVE_AS_DWARF2_DEBUG_LINE diff --git a/gcc/config/rs6000/power4.md b/gcc/config/rs6000/power4.md index 7f54ff0a739..fabc1de34aa 100644 --- a/gcc/config/rs6000/power4.md +++ b/gcc/config/rs6000/power4.md @@ -202,7 +202,7 @@ |(du2_power4+du3_power4,iu2_power4,iu2_power4)\ |(du3_power4+du4_power4,nothing,iu2_power4,iu1_power4)") -(define_bypass 4 "power4-compare" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr") +(define_bypass 4 "power4-compare" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_insn_reservation "power4-lmul-cmp" 7 (and (eq_attr "type" "lmul_compare") @@ -212,7 +212,7 @@ |(du3_power4+du4_power4,iu2_power4*6,iu1_power4)") ; |(du3_power4+du4_power4,nothing,iu2_power4*6,iu1_power4)") -(define_bypass 10 "power4-lmul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr") +(define_bypass 10 "power4-lmul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_insn_reservation "power4-imul-cmp" 5 (and (eq_attr "type" "imul_compare") @@ -222,7 +222,7 @@ |(du3_power4+du4_power4,iu2_power4*4,iu1_power4)") ; |(du3_power4+du4_power4,nothing,iu2_power4*4,iu1_power4)") -(define_bypass 8 "power4-imul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr") +(define_bypass 8 "power4-imul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_insn_reservation "power4-lmul" 7 (and (eq_attr "type" "lmul") @@ -305,6 +305,12 @@ du1_power4+du2_power4+du3_power4+du4_power4+cru_power4,\ cru_power4,cru_power4,cru_power4") +; mfcrf (1 field) +(define_insn_reservation "power4-mfcrf" 3 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power4")) + "du1_power4,cru_power4") + ; mtcrf (1 field) (define_insn_reservation "power4-mtcr" 4 (and (eq_attr "type" "mtcr") @@ -379,7 +385,7 @@ (define_bypass 9 "power4-vecfloat" "power4-vecperm") (define_bypass 5 "power4-vecsimple,power4-veccomplex" - "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr") + "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") (define_bypass 4 "power4-vecsimple,power4-vecperm" "power4-vecstore") (define_bypass 7 "power4-veccomplex" "power4-vecstore") diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 327ab1fa216..fc7e9cb96d8 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -122,6 +122,7 @@ extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx)); extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx)); extern void rs6000_fatal_bad_address PARAMS ((rtx)); extern int stmw_operation PARAMS ((rtx, enum machine_mode)); +extern int mfcr_operation PARAMS ((rtx, enum machine_mode)); extern int mtcrf_operation PARAMS ((rtx, enum machine_mode)); extern int lmw_operation PARAMS ((rtx, enum machine_mode)); extern struct rtx_def *create_TOC_reference PARAMS ((rtx)); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index f3b6c30b836..7ff59de6b76 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -7294,6 +7294,56 @@ vrsave_operation (op, mode) return 1; } +/* Return 1 for an PARALLEL suitable for mfcr. */ + +int +mfcr_operation (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + int count = XVECLEN (op, 0); + int i; + + /* Perform a quick check so we don't blow up below. */ + if (count < 1 + || GET_CODE (XVECEXP (op, 0, 0)) != SET + || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC + || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) + return 0; + + for (i = 0; i < count; i++) + { + rtx exp = XVECEXP (op, 0, i); + rtx unspec; + int maskval; + rtx src_reg; + + src_reg = XVECEXP (SET_SRC (exp), 0, 0); + + if (GET_CODE (src_reg) != REG + || GET_MODE (src_reg) != CCmode + || ! CR_REGNO_P (REGNO (src_reg))) + return 0; + + if (GET_CODE (exp) != SET + || GET_CODE (SET_DEST (exp)) != REG + || GET_MODE (SET_DEST (exp)) != SImode + || ! INT_REGNO_P (REGNO (SET_DEST (exp)))) + return 0; + unspec = SET_SRC (exp); + maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg)); + + if (GET_CODE (unspec) != UNSPEC + || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR + || XVECLEN (unspec, 0) != 2 + || XVECEXP (unspec, 0, 0) != src_reg + || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT + || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) + return 0; + } + return 1; +} + /* Return 1 for an PARALLEL suitable for mtcrf. */ int @@ -8499,6 +8549,13 @@ print_operand (file, x, code) } return; + case 'Q': + if (TARGET_MFCRF) + fputc (',',file); + /* FALLTHRU */ + else + return; + case 'R': /* X is a CR register. Print the mask for `mtcrf'. */ if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) @@ -13198,7 +13255,8 @@ rs6000_variable_issue (stream, verbose, insn, more) { enum attr_type type = get_attr_type (insn); if (type == TYPE_LOAD_EXT_U || type == TYPE_LOAD_EXT_UX - || type == TYPE_LOAD_UX || type == TYPE_STORE_UX) + || type == TYPE_LOAD_UX || type == TYPE_STORE_UX + || type == TYPE_MFCR) return 0; else if (type == TYPE_LOAD_U || type == TYPE_STORE_U || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index d27d42cb6d6..e91571967d5 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -475,6 +475,16 @@ extern int rs6000_alignment_flags; #define TARGET_ALIGN_NATURAL 0 #endif +/* Define TARGET_MFCRF if the target assembler supports the optional + field operand for mfcr and the target processor supports the + instruction. */ + +#ifdef HAVE_AS_MFCRF +#define TARGET_MFCRF (rs6000_cpu == PROCESSOR_POWER4) +#else +#define TARGET_MFCRF 0 +#endif + #define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128) #define TARGET_ALTIVEC_ABI rs6000_altivec_abi #define TARGET_ALTIVEC_VRSAVE rs6000_altivec_vrsave diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 1d471efbf85..bf778e2e22c 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -62,7 +62,7 @@ ;; Define an insn type attribute. This is used in function unit delay ;; computations. -(define_attr "type" "integer,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv" +(define_attr "type" "integer,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv" (const_string "integer")) ;; Length (in bytes). @@ -7800,15 +7800,33 @@ mcrf %0,%1 mtcrf 128,%1 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff - mfcr %0 - mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 + mfcr %0%Q1 + mfcr %0%Q1\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 mr %0,%1 mf%1 %0 mt%0 %1 mt%0 %1 {l%U1%X1|lwz%U1%X1} %0,%1 {st%U0%U1|stw%U0%U1} %1,%0" - [(set_attr "type" "cr_logical,mtcr,mtcr,mfcr,mfcr,*,mfjmpr,*,mtjmpr,load,store") + [(set (attr "type") + (cond [(eq_attr "alternative" "0") + (const_string "cr_logical") + (eq_attr "alternative" "1,2") + (const_string "mtcr") + (eq_attr "alternative" "5,7") + (const_string "integer") + (eq_attr "alternative" "6") + (const_string "mfjmpr") + (eq_attr "alternative" "8") + (const_string "mtjmpr") + (eq_attr "alternative" "9") + (const_string "load") + (eq_attr "alternative" "10") + (const_string "store") + (ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) (set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")]) ;; For floating-point, we normally deal with the floating-point registers @@ -11368,8 +11386,12 @@ [(match_operand 2 "cc_reg_operand" "y") (const_int 0)]))] "" - "mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" - [(set_attr "type" "mfcr") + "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1" + [(set (attr "type") + (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) (set_attr "length" "12")]) ;; Same as above, but get the OV/ORDERED bit. @@ -11387,8 +11409,12 @@ [(match_operand 2 "cc_reg_operand" "y") (const_int 0)]))] "TARGET_POWERPC64" - "mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" - [(set_attr "type" "mfcr") + "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1" + [(set (attr "type") + (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) (set_attr "length" "12")]) (define_insn "" @@ -11401,7 +11427,7 @@ (match_op_dup 1 [(match_dup 2) (const_int 0)]))] "! TARGET_POWERPC64" "@ - mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1 + mfcr %3%Q2\;{rlinm.|rlwinm.} %3,%3,%J1,1 #" [(set_attr "type" "delayed_compare") (set_attr "length" "12,16")]) @@ -11443,9 +11469,13 @@ operands[4] = GEN_INT (count); operands[5] = GEN_INT (put_bit); - return \"mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; + return \"mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; }" - [(set_attr "type" "mfcr") + [(set (attr "type") + (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0)) + (const_string "mfcrf") + ] + (const_string "mfcr"))) (set_attr "length" "12")]) (define_insn "" @@ -11478,7 +11508,7 @@ operands[5] = GEN_INT (count); operands[6] = GEN_INT (put_bit); - return \"mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; + return \"mfcr %4%Q2\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; }" [(set_attr "type" "delayed_compare") (set_attr "length" "12,16")]) @@ -14434,6 +14464,27 @@ DONE; }") +(define_insn "*movesi_from_cr_one" + [(match_parallel 0 "mfcr_operation" + [(set (match_operand:SI 1 "gpc_reg_operand" "=r") + (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") + (match_operand 3 "immediate_operand" "n")] + UNSPEC_MOVESI_FROM_CR))])] + "TARGET_MFCRF" + "* +{ + int mask = 0; + int i; + for (i = 0; i < XVECLEN (operands[0], 0); i++) + { + mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); + operands[4] = GEN_INT (mask); + output_asm_insn (\"mfcr %1,%4\", operands); + } + return \"\"; +}" + [(set_attr "type" "mfcrf")]) + (define_insn "movesi_from_cr" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) diff --git a/gcc/configure b/gcc/configure index 3778953f465..d80504cd144 100755 --- a/gcc/configure +++ b/gcc/configure @@ -8319,6 +8319,55 @@ echo "$ac_t""$gcc_cv_as_ltoffx_ldxmov_relocs" 1>&6 if test "x$gcc_cv_as_ltoffx_ldxmov_relocs" = xyes; then cat >> confdefs.h <<\EOF #define HAVE_AS_LTOFFX_LDXMOV_RELOCS 1 +EOF + + fi + ;; + powerpc*-*-*) + echo $ac_n "checking assembler supports mfcr field""... $ac_c" 1>&6 +echo "configure:8174: checking assembler supports mfcr field" >&5 +if eval "test \"`echo '$''{'gcc_cv_as_mfcrf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + gcc_cv_as_mfcrf=unknown + if test $in_tree_gas = yes ; then + if test $gcc_cv_gas_major_version -eq 2 \ +&& test $gcc_cv_gas_minor_version -ge 14 \ +|| test $gcc_cv_gas_major_version -gt 2 ; then + + + gcc_cv_as_mfcrf=yes + + +fi + + elif test x$gcc_cv_as != x; then + cat > conftest.s << 'EOF' + case "$target" in + *-*-aix*) + .csect .text[PR] + ;; + *) + .text + ;; + esac + mfcr 3,128 +EOF + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_mfcrf=yes + else + gcc_cv_as_mfcrf=no + fi + rm -f conftest.s conftest.o + fi + +fi + +echo "$ac_t""$gcc_cv_as_mfcrf" 1>&6 + if test "x$gcc_cv_as_mfcrf" = xyes; then + cat >> confdefs.h <<\EOF +#define HAVE_AS_MFCRF 1 EOF fi diff --git a/gcc/configure.in b/gcc/configure.in index 4d1558f0013..483b02ca80a 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -2462,6 +2462,41 @@ changequote([,])dnl [Define if your assembler supports ltoffx and ldxmov relocations.]) fi ;; + powerpc*-*-*) + AC_CACHE_CHECK([assembler supports mfcr field], + gcc_cv_as_mfcrf, [ + gcc_cv_as_mfcrf=unknown + if test $in_tree_gas = yes ; then + gcc_GAS_VERSION_GTE_IFELSE(2,14,0,[ + gcc_cv_as_mfcrf=yes + ]) + elif test x$gcc_cv_as != x; then + cat > conftest.s << 'EOF' + case "$target" in +changequote(,)dnl + *-*-aix*) + .csect .text[PR] + ;; + *) + .text + ;; + esac + mfcr 3,128 +EOF +changequote([,])dnl + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_mfcrf=yes + else + gcc_cv_as_mfcrf=no + fi + rm -f conftest.s conftest.o + fi + ]) + if test "x$gcc_cv_as_mfcrf" = xyes; then + AC_DEFINE(HAVE_AS_MFCRF, 1, + [Define if your assembler supports mfcr field.]) + fi + ;; esac AC_MSG_CHECKING(assembler dwarf2 debug_line support) -- 2.30.2