Commit 1823bf53 by James E Wilson Committed by Jim Wilson

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.
(div<mode>3): Use ANYF instead of SCALARF.
(*div<mode>3): Use ANYF instead of SCALARF.  Use UNITMODE instead of
MODE.
(*recip<mode>3, *rsqrt<mode>a, *rsqrt<mode>b): Use recip_condition
instead of ISA_HAS_FP4.  Use ANYF instead of SCALARF.  Use UNITMODE
instead of MODE.
(sqrt<mode>2): 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
parent c8a52525
2004-09-13 James E Wilson <wilson@specifixinc.com>
* 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.
(div<mode>3): Use ANYF instead of SCALARF.
(*div<mode>3): Use ANYF instead of SCALARF. Use UNITMODE instead of
MODE.
(*recip<mode>3, *rsqrt<mode>a, *rsqrt<mode>b): Use recip_condition
instead of ISA_HAS_FP4. Use ANYF instead of SCALARF. Use UNITMODE
instead of MODE.
(sqrt<mode>2): Use sqrt_condition instead of HAVE_SQRT_P. Use ANYF
instead of SCALARF. Use UNITMODE instead of MODE.
2004-09-13 Zack Weinberg <zack@codesourcery.com>
* config.in: Regenerate after removal of libbanshee.
......
......@@ -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
......
......@@ -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. */
......
......@@ -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 "div<mode>3"
[(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")))]
"<divide_condition>"
{
if (const_1_operand (operands[1], <MODE>mode))
......@@ -1726,9 +1736,9 @@
;; long latency op destination register.
(define_insn "*div<mode>3"
[(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")))]
"<divide_condition>"
{
if (TARGET_FIX_SB1)
......@@ -1737,17 +1747,17 @@
return "div.<fmt>\t%0,%1,%2";
}
[(set_attr "type" "fdiv")
(set_attr "mode" "<MODE>")
(set_attr "mode" "<UNITMODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
(const_int 4)))])
(define_insn "*recip<mode>3"
[(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")))]
"<recip_condition> && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
......@@ -1755,7 +1765,7 @@
return "recip.<fmt>\t%0,%2";
}
[(set_attr "type" "frdiv")
(set_attr "mode" "<MODE>")
(set_attr "mode" "<UNITMODE>")
(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 "sqrt<mode>2"
[(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")))]
"<sqrt_condition>"
{
if (TARGET_FIX_SB1)
return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
......@@ -1808,18 +1818,17 @@
return "sqrt.<fmt>\t%0,%1";
}
[(set_attr "type" "fsqrt")
(set_attr "mode" "<MODE>")
(set_attr "mode" "<UNITMODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
(const_int 4)))])
(define_insn "*rsqrt<mode>a"
[(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"))))]
"<recip_condition> && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
......@@ -1827,18 +1836,17 @@
return "rsqrt.<fmt>\t%0,%2";
}
[(set_attr "type" "frsqrt")
(set_attr "mode" "<MODE>")
(set_attr "mode" "<UNITMODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
(const_int 4)))])
(define_insn "*rsqrt<mode>b"
[(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"))))]
"<recip_condition> && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
......@@ -1846,7 +1854,7 @@
return "rsqrt.<fmt>\t%0,%2";
}
[(set_attr "type" "frsqrt")
(set_attr "mode" "<MODE>")
(set_attr "mode" "<UNITMODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
......
2004-09-13 James E Wilson <wilson@specifixinc.com>
* gcc.target/mips/sb1-1.c: New testcase.
2004-09-12 Hans-Peter Nilsson <hp@bitrange.com>
* lib/g77-dg.exp: Remove unused file.
......
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment