From 1823bf53abf47bcd2417da90df1cd4ba4c2bf094 Mon Sep 17 00:00:00 2001 From: James E Wilson Date: Mon, 13 Sep 2004 19:32:05 +0000 Subject: [PATCH] SB-1 specific MIPS vector instructions. * config/mips/mips.c (CODE_FOR_mips_sqrt_ps): New. (sb1_bdesc, bdesc_map, bdesc_arrays): New. (mips_expand_builtin): Add SB-1 support. Use bdesc_map and bdesc_arrays instead of mips_bdesc. (mips_init_builtins): Likewise. * config/mips/mips.h (TARGET_SB1): New. (HAVE_SQRT_P): Delete. * config/mips/mips.md (divide_condition): Support V2SF. (sqrt_condition, recip_condition): New. (div3): Use ANYF instead of SCALARF. (*div3): Use ANYF instead of SCALARF. Use UNITMODE instead of MODE. (*recip3, *rsqrta, *rsqrtb): Use recip_condition instead of ISA_HAS_FP4. Use ANYF instead of SCALARF. Use UNITMODE instead of MODE. (sqrt2): Use sqrt_condition instead of HAVE_SQRT_P. Use ANYF instead of SCALARF. Use UNITMODE instead of MODE. * gcc.target/mips/sb1-1.c: New testcase. From-SVN: r87446 --- gcc/ChangeLog | 20 ++++++++ gcc/config/mips/mips.c | 73 +++++++++++++++++++++++---- gcc/config/mips/mips.h | 6 +-- gcc/config/mips/mips.md | 66 +++++++++++++----------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.target/mips/sb1-1.c | 29 +++++++++++ 6 files changed, 155 insertions(+), 43 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/sb1-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72505d641ad..6eac4dc471b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2004-09-13 James E Wilson + + * config/mips/mips.c (CODE_FOR_mips_sqrt_ps): New. + (sb1_bdesc, bdesc_map, bdesc_arrays): New. + (mips_expand_builtin): Add SB-1 support. Use bdesc_map and + bdesc_arrays instead of mips_bdesc. + (mips_init_builtins): Likewise. + * config/mips/mips.h (TARGET_SB1): New. + (HAVE_SQRT_P): Delete. + * config/mips/mips.md (divide_condition): Support V2SF. + (sqrt_condition, recip_condition): New. + (div3): Use ANYF instead of SCALARF. + (*div3): Use ANYF instead of SCALARF. Use UNITMODE instead of + MODE. + (*recip3, *rsqrta, *rsqrtb): Use recip_condition + instead of ISA_HAS_FP4. Use ANYF instead of SCALARF. Use UNITMODE + instead of MODE. + (sqrt2): Use sqrt_condition instead of HAVE_SQRT_P. Use ANYF + instead of SCALARF. Use UNITMODE instead of MODE. + 2004-09-13 Zack Weinberg * config.in: Regenerate after removal of libbanshee. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f0887d5c5f5..c564f4e7f18 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -9410,6 +9410,36 @@ static const struct builtin_description mips_bdesc[] = MIPS_FP_CONDITIONS (CMP_BUILTINS) }; +/* Builtin functions for the SB-1 processor. */ + +#define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2 + +static const struct builtin_description sb1_bdesc[] = +{ + DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE) +}; + +/* This helps provide a mapping from builtin function codes to bdesc + arrays. */ + +struct bdesc_map +{ + /* The builtin function table that this entry describes. */ + const struct builtin_description *bdesc; + + /* The number of entries in the builtin function table. */ + unsigned int size; + + /* The target processor that supports these builtin functions. + PROCESSOR_DEFAULT means we enable them for all processors. */ + enum processor_type proc; +}; + +static const struct bdesc_map bdesc_arrays[] = +{ + { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_DEFAULT }, + { sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 } +}; /* Take the head of argument list *ARGLIST and convert it into a form suitable for input operand OP of instruction ICODE. Return the value @@ -9457,15 +9487,28 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, enum mips_builtin_type type; tree fndecl, arglist; unsigned int fcode; + const struct builtin_description *bdesc; + const struct bdesc_map *m; fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); arglist = TREE_OPERAND (exp, 1); fcode = DECL_FUNCTION_CODE (fndecl); - if (fcode >= ARRAY_SIZE (mips_bdesc)) + + bdesc = NULL; + for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++) + { + if (fcode < m->size) + { + bdesc = m->bdesc; + icode = bdesc[fcode].icode; + type = bdesc[fcode].builtin_type; + break; + } + fcode -= m->size; + } + if (bdesc == NULL) return 0; - icode = mips_bdesc[fcode].icode; - type = mips_bdesc[fcode].builtin_type; switch (type) { case MIPS_BUILTIN_DIRECT: @@ -9473,7 +9516,7 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case MIPS_BUILTIN_MOVT: case MIPS_BUILTIN_MOVF: - return mips_expand_builtin_movtf (type, icode, mips_bdesc[fcode].cond, + return mips_expand_builtin_movtf (type, icode, bdesc[fcode].cond, target, arglist); case MIPS_BUILTIN_CMP_ANY: @@ -9481,7 +9524,7 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case MIPS_BUILTIN_CMP_UPPER: case MIPS_BUILTIN_CMP_LOWER: case MIPS_BUILTIN_CMP_SINGLE: - return mips_expand_builtin_compare (type, icode, mips_bdesc[fcode].cond, + return mips_expand_builtin_compare (type, icode, bdesc[fcode].cond, target, arglist); default: @@ -9495,8 +9538,10 @@ void mips_init_builtins (void) { const struct builtin_description *d; + const struct bdesc_map *m; tree types[(int) MIPS_MAX_FTYPE_MAX]; tree V2SF_type_node; + unsigned int offset; /* We have only builtins for -mpaired-single and -mips3d. */ if (!TARGET_PAIRED_SINGLE_FLOAT) @@ -9561,10 +9606,20 @@ mips_init_builtins (void) = build_function_type_list (double_type_node, double_type_node, double_type_node, NULL_TREE); - for (d = mips_bdesc; d < &mips_bdesc[ARRAY_SIZE (mips_bdesc)]; d++) - if ((d->target_flags & target_flags) == d->target_flags) - lang_hooks.builtin_function (d->name, types[d->function_type], - d - mips_bdesc, BUILT_IN_MD, NULL, NULL); + /* Iterate through all of the bdesc arrays, initializing all of the + builtin functions. */ + + offset = 0; + for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++) + { + if (m->proc == PROCESSOR_DEFAULT || (m->proc == mips_arch)) + for (d = m->bdesc; d < &m->bdesc[m->size]; d++) + if ((d->target_flags & target_flags) == d->target_flags) + lang_hooks.builtin_function (d->name, types[d->function_type], + d - m->bdesc + offset, + BUILT_IN_MD, NULL, NULL); + offset += m->size; + } } /* Expand a MIPS_BUILTIN_DIRECT function. ICODE is the code of the diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 3428ac9a4fe..ddca621abfc 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -302,6 +302,7 @@ extern const struct mips_cpu_info *mips_tune_info; #define TARGET_MIPS5500 (mips_arch == PROCESSOR_R5500) #define TARGET_MIPS7000 (mips_arch == PROCESSOR_R7000) #define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000) +#define TARGET_SB1 (mips_arch == PROCESSOR_SB1) #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) /* Scheduling target defines. */ @@ -822,11 +823,6 @@ extern const struct mips_cpu_info *mips_tune_info; #define GENERATE_MULT3_DI ((TARGET_MIPS3900) \ && !TARGET_MIPS16) -/* Macros to decide whether certain features are available or not, - depending on the instruction set architecture level. */ - -#define HAVE_SQRT_P() (!ISA_MIPS1) - /* True if the ABI can only work with 64-bit integer registers. We generally allow ad-hoc variations for TARGET_SINGLE_FLOAT, but otherwise floating-point registers must also be 64-bit. */ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 9390ed03b21..fb50b3bdab2 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -381,7 +381,17 @@ ;; Therefore, we only allow div.s if not working around SB-1 rev2 ;; errata or if a slight loss of precision is OK. (define_mode_attr divide_condition - [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")]) + [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations") + (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")]) + +; This attribute gives the condition for which sqrt instructions exist. +(define_mode_attr sqrt_condition + [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) + +; This attribute gives the condition for which recip and rsqrt instructions +; exist. +(define_mode_attr recip_condition + [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")]) ;; This code macro allows all branch instructions to be generated from ;; a single define_expand template. @@ -1703,9 +1713,9 @@ ;; (define_expand "div3" - [(set (match_operand:SCALARF 0 "register_operand") - (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand") - (match_operand:SCALARF 2 "register_operand")))] + [(set (match_operand:ANYF 0 "register_operand") + (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand") + (match_operand:ANYF 2 "register_operand")))] "" { if (const_1_operand (operands[1], mode)) @@ -1726,9 +1736,9 @@ ;; long latency op destination register. (define_insn "*div3" - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] + [(set (match_operand:ANYF 0 "register_operand" "=f") + (div:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f")))] "" { if (TARGET_FIX_SB1) @@ -1737,17 +1747,17 @@ return "div.\t%0,%1,%2"; } [(set_attr "type" "fdiv") - (set_attr "mode" "") + (set_attr "mode" "") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (const_int 8) (const_int 4)))]) (define_insn "*recip3" - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "") - (match_operand:SCALARF 2 "register_operand" "f")))] - "ISA_HAS_FP4 && flag_unsafe_math_optimizations" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") + (match_operand:ANYF 2 "register_operand" "f")))] + " && flag_unsafe_math_optimizations" { if (TARGET_FIX_SB1) return "recip.\t%0,%2\;mov.\t%0,%0"; @@ -1755,7 +1765,7 @@ return "recip.\t%0,%2"; } [(set_attr "type" "frdiv") - (set_attr "mode" "") + (set_attr "mode" "") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (const_int 8) @@ -1798,9 +1808,9 @@ ;; "*div[sd]f3" comment for details). (define_insn "sqrt2" - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))] - "HAVE_SQRT_P()" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] + "" { if (TARGET_FIX_SB1) return "sqrt.\t%0,%1\;mov.\t%0,%0"; @@ -1808,18 +1818,17 @@ return "sqrt.\t%0,%1"; } [(set_attr "type" "fsqrt") - (set_attr "mode" "") + (set_attr "mode" "") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (const_int 8) (const_int 4)))]) (define_insn "*rsqrta" - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (div:SCALARF - (match_operand:SCALARF 1 "const_1_operand" "") - (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))] - "ISA_HAS_FP4 && flag_unsafe_math_optimizations" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") + (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))] + " && flag_unsafe_math_optimizations" { if (TARGET_FIX_SB1) return "rsqrt.\t%0,%2\;mov.\t%0,%0"; @@ -1827,18 +1836,17 @@ return "rsqrt.\t%0,%2"; } [(set_attr "type" "frsqrt") - (set_attr "mode" "") + (set_attr "mode" "") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (const_int 8) (const_int 4)))]) (define_insn "*rsqrtb" - [(set (match_operand:SCALARF 0 "register_operand" "=f") - (sqrt:SCALARF - (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "") - (match_operand:SCALARF 2 "register_operand" "f"))))] - "ISA_HAS_FP4 && flag_unsafe_math_optimizations" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") + (match_operand:ANYF 2 "register_operand" "f"))))] + " && flag_unsafe_math_optimizations" { if (TARGET_FIX_SB1) return "rsqrt.\t%0,%2\;mov.\t%0,%0"; @@ -1846,7 +1854,7 @@ return "rsqrt.\t%0,%2"; } [(set_attr "type" "frsqrt") - (set_attr "mode" "") + (set_attr "mode" "") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (const_int 8) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae42e1bf8b3..4736e13e528 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-09-13 James E Wilson + + * gcc.target/mips/sb1-1.c: New testcase. + 2004-09-12 Hans-Peter Nilsson * lib/g77-dg.exp: Remove unused file. diff --git a/gcc/testsuite/gcc.target/mips/sb1-1.c b/gcc/testsuite/gcc.target/mips/sb1-1.c new file mode 100644 index 00000000000..b6d671b7756 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/sb1-1.c @@ -0,0 +1,29 @@ +/* Test SB-1 v2sf extensions. */ +/* { dg-do compile { target mipsisa64*-*-* } } */ +/* { dg-options "-march=sb1 -O2 -mpaired-single -mhard-float -mfp64 -ffast-math" } */ +/* { dg-final { scan-assembler "div.ps" } } */ +/* { dg-final { scan-assembler "recip.ps" } } */ +/* { dg-final { scan-assembler "sqrt.ps" } } */ +/* { dg-final { scan-assembler "rsqrt.ps" } } */ + +typedef float v2sf __attribute__ ((vector_size (8))); + +v2sf divide (v2sf a, v2sf b) +{ + return a / b; +} + +v2sf recip (v2sf a) +{ + return ((v2sf) {1.0, 1.0}) / a; +} + +v2sf squareroot (v2sf a) +{ + return __builtin_mips_sqrt_ps (a); +} + +v2sf rsqrt (v2sf a) +{ + return ((v2sf) {1.0, 1.0}) / __builtin_mips_sqrt_ps (a); +} -- 2.30.2