aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAndrew Pinski <andrew_pinski@playstation.sony.com>2006-12-01 02:38:47 +0000
committerAndrew Pinski <pinskia@gcc.gnu.org>2006-11-30 18:38:47 -0800
commitb66b813d47ff264118b496f2e086591813049ba8 (patch)
tree889e37877b45963f8f463bbc84dc45b268651cc4 /gcc/config
parent8521c41417b57bf46fc57efccf3befaf6fc0a712 (diff)
downloadgcc-b66b813d47ff264118b496f2e086591813049ba8.zip
gcc-b66b813d47ff264118b496f2e086591813049ba8.tar.gz
gcc-b66b813d47ff264118b496f2e086591813049ba8.tar.bz2
spu.c (spu_builtin_range): Move from spu-c.c
2006-11-30 Andrew Pinski <andrew_pinski@playstation.sony.com> * config/spu/spu.c (spu_builtin_range): Move from spu-c.c (TARGET_RESOLVE_OVERLOADED_BUILTIN): Delete. (spu_cpu_cpp_builtins): Remove. (spu_override_options): Don't set warn_main. (spu_force_reg): Move from spu-c.c. (spu_check_builtin_parm): Likewise. (expand_builtin_args): Likewise. (spu_expand_builtin_1): Likewise. (spu_expand_builtin): Likewise. * config/spu/spu.h (REGISTER_TARGET_PRAGMAS): Define, set warn_main and targetm.resolve_overloaded_builtin. * config/spu/spu-c.c (spu_builtin_range): Remove. (spu_check_builtin_parm): Remove. (expand_builtin_args): Remove. (spu_expand_builtin_1): Remove. (spu_expand_builtin): Remove. (spu_cpu_cpp_builtins): Moved from spu.c (spu_force_reg): Remove. From-SVN: r119397
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/spu/spu-c.c291
-rw-r--r--gcc/config/spu/spu.c301
-rw-r--r--gcc/config/spu/spu.h6
3 files changed, 297 insertions, 301 deletions
diff --git a/gcc/config/spu/spu-c.c b/gcc/config/spu/spu-c.c
index 80a5701..b975e83 100644
--- a/gcc/config/spu/spu-c.c
+++ b/gcc/config/spu/spu-c.c
@@ -34,35 +34,6 @@
#include "recog.h"
#include "optabs.h"
#include "spu-builtins.h"
-
-static rtx spu_expand_builtin_1 (struct spu_builtin_description *d,
- tree arglist, rtx target);
-static void spu_check_builtin_parm (struct spu_builtin_description *, rtx,
- int);
-static void expand_builtin_args (struct spu_builtin_description *, tree, rtx,
- rtx[]);
-static rtx spu_force_reg (enum machine_mode mode, rtx op);
-
-/* Builtin types, data and prototypes. */
-struct spu_builtin_range
-{
- int low, high;
-};
-
-static struct spu_builtin_range spu_builtin_range[] = {
- {-0x40ll, 0x7fll}, /* SPU_BTI_7 */
- {-0x40ll, 0x3fll}, /* SPU_BTI_S7 */
- {0ll, 0x7fll}, /* SPU_BTI_U7 */
- {-0x200ll, 0x1ffll}, /* SPU_BTI_S10 */
- {-0x2000ll, 0x1fffll}, /* SPU_BTI_S10_4 */
- {0ll, 0x3fffll}, /* SPU_BTI_U14 */
- {-0x8000ll, 0xffffll}, /* SPU_BTI_16 */
- {-0x8000ll, 0x7fffll}, /* SPU_BTI_S16 */
- {-0x20000ll, 0x1ffffll}, /* SPU_BTI_S16_2 */
- {0ll, 0xffffll}, /* SPU_BTI_U16 */
- {0ll, 0x3ffffll}, /* SPU_BTI_U16_2 */
- {0ll, 0x3ffffll}, /* SPU_BTI_U18 */
-};
/* Helper for spu_resolve_overloaded_builtin. */
@@ -181,263 +152,13 @@ spu_resolve_overloaded_builtin (tree fndecl, tree fnargs)
return spu_build_overload_builtin (match, fnargs);
}
-static void
-spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p)
-{
- HOST_WIDE_INT v = 0;
- int lsbits;
- /* Check the range of immediate operands. */
- if (p >= SPU_BTI_7 && p <= SPU_BTI_U18)
- {
- int range = p - SPU_BTI_7;
- if (!CONSTANT_P (op)
- || (GET_CODE (op) == CONST_INT
- && (INTVAL (op) < spu_builtin_range[range].low
- || INTVAL (op) > spu_builtin_range[range].high)))
- error ("%s expects an integer literal in the range [%d, %d].",
- d->name,
- spu_builtin_range[range].low, spu_builtin_range[range].high);
-
- if (GET_CODE (op) == CONST
- && (GET_CODE (XEXP (op, 0)) == PLUS
- || GET_CODE (XEXP (op, 0)) == MINUS))
- {
- v = INTVAL (XEXP (XEXP (op, 0), 1));
- op = XEXP (XEXP (op, 0), 0);
- }
- else if (GET_CODE (op) == CONST_INT)
- v = INTVAL (op);
-
- switch (p)
- {
- case SPU_BTI_S10_4:
- lsbits = 4;
- break;
- case SPU_BTI_U16_2:
- /* This is only used in lqa, and stqa. Even though the insns
- encode 16 bits of the address (all but the 2 least
- significant), only 14 bits are used because it is masked to
- be 16 byte aligned. */
- lsbits = 4;
- break;
- case SPU_BTI_S16_2:
- /* This is used for lqr and stqr. */
- lsbits = 2;
- break;
- default:
- lsbits = 0;
- }
-
- if (GET_CODE (op) == LABEL_REF
- || (GET_CODE (op) == SYMBOL_REF
- && SYMBOL_REF_FUNCTION_P (op))
- || (INTVAL (op) & ((1 << lsbits) - 1)) != 0)
- warning (0, "%d least significant bits of %s are ignored.", lsbits,
- d->name);
- }
-}
-
-static void
-expand_builtin_args (struct spu_builtin_description *d, tree arglist,
- rtx target, rtx ops[])
-{
- enum insn_code icode = d->icode;
- int i = 0;
-
- /* Expand the arguments into rtl. */
-
- if (d->parm[0] != SPU_BTI_VOID)
- ops[i++] = target;
-
- for (; i < insn_data[icode].n_operands; i++)
- {
- tree arg = TREE_VALUE (arglist);
- if (arg == 0)
- abort ();
- ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0);
- arglist = TREE_CHAIN (arglist);
- }
-}
-
-static rtx
-spu_expand_builtin_1 (struct spu_builtin_description *d,
- tree arglist, rtx target)
-{
- rtx pat;
- rtx ops[8];
- enum insn_code icode = d->icode;
- enum machine_mode mode, tmode;
- int i, p;
- tree return_type;
-
- /* Set up ops[] with values from arglist. */
- expand_builtin_args (d, arglist, target, ops);
-
- /* Handle the target operand which must be operand 0. */
- i = 0;
- if (d->parm[0] != SPU_BTI_VOID)
- {
-
- /* We prefer the mode specified for the match_operand otherwise
- use the mode from the builtin function prototype. */
- tmode = insn_data[d->icode].operand[0].mode;
- if (tmode == VOIDmode)
- tmode = TYPE_MODE (spu_builtin_types[d->parm[0]]);
-
- /* Try to use target because not using it can lead to extra copies
- and when we are using all of the registers extra copies leads
- to extra spills. */
- if (target && GET_CODE (target) == REG && GET_MODE (target) == tmode)
- ops[0] = target;
- else
- target = ops[0] = gen_reg_rtx (tmode);
-
- if (!(*insn_data[icode].operand[0].predicate) (ops[0], tmode))
- abort ();
-
- i++;
- }
-
- /* Ignore align_hint, but still expand it's args in case they have
- side effects. */
- if (icode == CODE_FOR_spu_align_hint)
- return 0;
-
- /* Handle the rest of the operands. */
- for (p = 1; i < insn_data[icode].n_operands; i++, p++)
- {
- if (insn_data[d->icode].operand[i].mode != VOIDmode)
- mode = insn_data[d->icode].operand[i].mode;
- else
- mode = TYPE_MODE (spu_builtin_types[d->parm[i]]);
-
- /* mode can be VOIDmode here for labels */
-
- /* For specific intrinsics with an immediate operand, e.g.,
- si_ai(), we sometimes need to convert the scalar argument to a
- vector argument by splatting the scalar. */
- if (VECTOR_MODE_P (mode)
- && (GET_CODE (ops[i]) == CONST_INT
- || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_INT
- || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_FLOAT))
- {
- if (GET_CODE (ops[i]) == CONST_INT)
- ops[i] = spu_const (mode, INTVAL (ops[i]));
- else
- {
- rtx reg = gen_reg_rtx (mode);
- enum machine_mode imode = GET_MODE_INNER (mode);
- if (!spu_nonmem_operand (ops[i], GET_MODE (ops[i])))
- ops[i] = force_reg (GET_MODE (ops[i]), ops[i]);
- if (imode != GET_MODE (ops[i]))
- ops[i] = convert_to_mode (imode, ops[i],
- TYPE_UNSIGNED (spu_builtin_types
- [d->parm[i]]));
- emit_insn (gen_spu_splats (reg, ops[i]));
- ops[i] = reg;
- }
- }
-
- if (!(*insn_data[icode].operand[i].predicate) (ops[i], mode))
- ops[i] = spu_force_reg (mode, ops[i]);
-
- spu_check_builtin_parm (d, ops[i], d->parm[p]);
- }
-
- switch (insn_data[icode].n_operands)
- {
- case 0:
- pat = GEN_FCN (icode) (0);
- break;
- case 1:
- pat = GEN_FCN (icode) (ops[0]);
- break;
- case 2:
- pat = GEN_FCN (icode) (ops[0], ops[1]);
- break;
- case 3:
- pat = GEN_FCN (icode) (ops[0], ops[1], ops[2]);
- break;
- case 4:
- pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]);
- break;
- case 5:
- pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4]);
- break;
- case 6:
- pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4], ops[5]);
- break;
- default:
- abort ();
- }
-
- if (!pat)
- abort ();
-
- if (d->type == B_CALL || d->type == B_BISLED)
- emit_call_insn (pat);
- else if (d->type == B_JUMP)
- {
- emit_jump_insn (pat);
- emit_barrier ();
- }
- else
- emit_insn (pat);
-
- return_type = spu_builtin_types[d->parm[0]];
- if (d->parm[0] != SPU_BTI_VOID
- && GET_MODE (target) != TYPE_MODE (return_type))
- {
- /* target is the return value. It should always be the mode of
- the builtin function prototype. */
- target = spu_force_reg (TYPE_MODE (return_type), target);
- }
- return target;
-}
-
-rtx
-spu_expand_builtin (tree exp,
- rtx target,
- rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
+void
+spu_cpu_cpp_builtins (struct cpp_reader *pfile)
{
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
- tree arglist = TREE_OPERAND (exp, 1);
- struct spu_builtin_description *d;
-
- if (fcode < NUM_SPU_BUILTINS)
- {
- d = &spu_builtins[fcode];
-
- return spu_expand_builtin_1 (d, arglist, target);
- }
- abort ();
+ builtin_define_std ("__SPU__");
+ cpp_assert (pfile, "cpu=spu");
+ cpp_assert (pfile, "machine=spu");
+ builtin_define_std ("__vector=__attribute__((__spu_vector__))");
}
-static rtx
-spu_force_reg (enum machine_mode mode, rtx op)
-{
- rtx x, r;
- if (GET_MODE (op) == VOIDmode || GET_MODE (op) == BLKmode)
- {
- if ((SCALAR_INT_MODE_P (mode) && GET_CODE (op) == CONST_INT)
- || GET_MODE (op) == BLKmode)
- return force_reg (mode, convert_to_mode (mode, op, 0));
- abort ();
- }
-
- r = force_reg (GET_MODE (op), op);
- if (GET_MODE_SIZE (GET_MODE (op)) == GET_MODE_SIZE (mode))
- {
- x = simplify_gen_subreg (mode, r, GET_MODE (op), 0);
- if (x)
- return x;
- }
-
- x = gen_reg_rtx (mode);
- emit_insn (gen_spu_convert (x, r));
- return x;
-}
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index fc0ed19..a1158e7 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -54,6 +54,28 @@
#include "tree-gimple.h"
#include "tm-constrs.h"
#include "spu-builtins.h"
+
+/* Builtin types, data and prototypes. */
+struct spu_builtin_range
+{
+ int low, high;
+};
+
+static struct spu_builtin_range spu_builtin_range[] = {
+ {-0x40ll, 0x7fll}, /* SPU_BTI_7 */
+ {-0x40ll, 0x3fll}, /* SPU_BTI_S7 */
+ {0ll, 0x7fll}, /* SPU_BTI_U7 */
+ {-0x200ll, 0x1ffll}, /* SPU_BTI_S10 */
+ {-0x2000ll, 0x1fffll}, /* SPU_BTI_S10_4 */
+ {0ll, 0x3fffll}, /* SPU_BTI_U14 */
+ {-0x8000ll, 0xffffll}, /* SPU_BTI_16 */
+ {-0x8000ll, 0x7fffll}, /* SPU_BTI_S16 */
+ {-0x20000ll, 0x1ffffll}, /* SPU_BTI_S16_2 */
+ {0ll, 0xffffll}, /* SPU_BTI_U16 */
+ {0ll, 0x3ffffll}, /* SPU_BTI_U16_2 */
+ {0ll, 0x3ffffll}, /* SPU_BTI_U18 */
+};
+
/* Target specific attribute specifications. */
char regs_ever_allocated[FIRST_PSEUDO_REGISTER];
@@ -133,9 +155,6 @@ tree spu_builtin_types[SPU_BTI_MAX];
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS spu_init_builtins
-#undef TARGET_RESOLVE_OVERLOADED_BUILTIN
-#define TARGET_RESOLVE_OVERLOADED_BUILTIN spu_resolve_overloaded_builtin
-
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN spu_expand_builtin
@@ -213,16 +232,6 @@ const struct attribute_spec spu_attribute_table[];
struct gcc_target targetm = TARGET_INITIALIZER;
-void
-spu_cpu_cpp_builtins (struct cpp_reader *pfile)
-{
- extern void builtin_define_std (const char *);
- builtin_define_std ("__SPU__");
- cpp_assert (pfile, "cpu=spu");
- cpp_assert (pfile, "machine=spu");
- builtin_define_std ("__vector=__attribute__((__spu_vector__))");
-}
-
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
OVERRIDE_OPTIONS to take account of this. This macro, if defined, is
@@ -231,9 +240,6 @@ void
spu_override_options (void)
{
- /* Don't give warnings about the main() function. */
- warn_main = 0;
-
/* Override some of the default param values. With so many registers
larger values are better for these params. */
if (MAX_UNROLLED_INSNS == 100)
@@ -4467,3 +4473,266 @@ spu_expand_vector_init (rtx target, rtx vals)
}
}
}
+
+static rtx
+spu_force_reg (enum machine_mode mode, rtx op)
+{
+ rtx x, r;
+ if (GET_MODE (op) == VOIDmode || GET_MODE (op) == BLKmode)
+ {
+ if ((SCALAR_INT_MODE_P (mode) && GET_CODE (op) == CONST_INT)
+ || GET_MODE (op) == BLKmode)
+ return force_reg (mode, convert_to_mode (mode, op, 0));
+ abort ();
+ }
+
+ r = force_reg (GET_MODE (op), op);
+ if (GET_MODE_SIZE (GET_MODE (op)) == GET_MODE_SIZE (mode))
+ {
+ x = simplify_gen_subreg (mode, r, GET_MODE (op), 0);
+ if (x)
+ return x;
+ }
+
+ x = gen_reg_rtx (mode);
+ emit_insn (gen_spu_convert (x, r));
+ return x;
+}
+
+static void
+spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p)
+{
+ HOST_WIDE_INT v = 0;
+ int lsbits;
+ /* Check the range of immediate operands. */
+ if (p >= SPU_BTI_7 && p <= SPU_BTI_U18)
+ {
+ int range = p - SPU_BTI_7;
+ if (!CONSTANT_P (op)
+ || (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) < spu_builtin_range[range].low
+ || INTVAL (op) > spu_builtin_range[range].high)))
+ error ("%s expects an integer literal in the range [%d, %d].",
+ d->name,
+ spu_builtin_range[range].low, spu_builtin_range[range].high);
+
+ if (GET_CODE (op) == CONST
+ && (GET_CODE (XEXP (op, 0)) == PLUS
+ || GET_CODE (XEXP (op, 0)) == MINUS))
+ {
+ v = INTVAL (XEXP (XEXP (op, 0), 1));
+ op = XEXP (XEXP (op, 0), 0);
+ }
+ else if (GET_CODE (op) == CONST_INT)
+ v = INTVAL (op);
+
+ switch (p)
+ {
+ case SPU_BTI_S10_4:
+ lsbits = 4;
+ break;
+ case SPU_BTI_U16_2:
+ /* This is only used in lqa, and stqa. Even though the insns
+ encode 16 bits of the address (all but the 2 least
+ significant), only 14 bits are used because it is masked to
+ be 16 byte aligned. */
+ lsbits = 4;
+ break;
+ case SPU_BTI_S16_2:
+ /* This is used for lqr and stqr. */
+ lsbits = 2;
+ break;
+ default:
+ lsbits = 0;
+ }
+
+ if (GET_CODE (op) == LABEL_REF
+ || (GET_CODE (op) == SYMBOL_REF
+ && SYMBOL_REF_FUNCTION_P (op))
+ || (INTVAL (op) & ((1 << lsbits) - 1)) != 0)
+ warning (0, "%d least significant bits of %s are ignored.", lsbits,
+ d->name);
+ }
+}
+
+
+static void
+expand_builtin_args (struct spu_builtin_description *d, tree arglist,
+ rtx target, rtx ops[])
+{
+ enum insn_code icode = d->icode;
+ int i = 0;
+
+ /* Expand the arguments into rtl. */
+
+ if (d->parm[0] != SPU_BTI_VOID)
+ ops[i++] = target;
+
+ for (; i < insn_data[icode].n_operands; i++)
+ {
+ tree arg = TREE_VALUE (arglist);
+ if (arg == 0)
+ abort ();
+ ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0);
+ arglist = TREE_CHAIN (arglist);
+ }
+}
+
+static rtx
+spu_expand_builtin_1 (struct spu_builtin_description *d,
+ tree arglist, rtx target)
+{
+ rtx pat;
+ rtx ops[8];
+ enum insn_code icode = d->icode;
+ enum machine_mode mode, tmode;
+ int i, p;
+ tree return_type;
+
+ /* Set up ops[] with values from arglist. */
+ expand_builtin_args (d, arglist, target, ops);
+
+ /* Handle the target operand which must be operand 0. */
+ i = 0;
+ if (d->parm[0] != SPU_BTI_VOID)
+ {
+
+ /* We prefer the mode specified for the match_operand otherwise
+ use the mode from the builtin function prototype. */
+ tmode = insn_data[d->icode].operand[0].mode;
+ if (tmode == VOIDmode)
+ tmode = TYPE_MODE (spu_builtin_types[d->parm[0]]);
+
+ /* Try to use target because not using it can lead to extra copies
+ and when we are using all of the registers extra copies leads
+ to extra spills. */
+ if (target && GET_CODE (target) == REG && GET_MODE (target) == tmode)
+ ops[0] = target;
+ else
+ target = ops[0] = gen_reg_rtx (tmode);
+
+ if (!(*insn_data[icode].operand[0].predicate) (ops[0], tmode))
+ abort ();
+
+ i++;
+ }
+
+ /* Ignore align_hint, but still expand it's args in case they have
+ side effects. */
+ if (icode == CODE_FOR_spu_align_hint)
+ return 0;
+
+ /* Handle the rest of the operands. */
+ for (p = 1; i < insn_data[icode].n_operands; i++, p++)
+ {
+ if (insn_data[d->icode].operand[i].mode != VOIDmode)
+ mode = insn_data[d->icode].operand[i].mode;
+ else
+ mode = TYPE_MODE (spu_builtin_types[d->parm[i]]);
+
+ /* mode can be VOIDmode here for labels */
+
+ /* For specific intrinsics with an immediate operand, e.g.,
+ si_ai(), we sometimes need to convert the scalar argument to a
+ vector argument by splatting the scalar. */
+ if (VECTOR_MODE_P (mode)
+ && (GET_CODE (ops[i]) == CONST_INT
+ || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_INT
+ || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_FLOAT))
+ {
+ if (GET_CODE (ops[i]) == CONST_INT)
+ ops[i] = spu_const (mode, INTVAL (ops[i]));
+ else
+ {
+ rtx reg = gen_reg_rtx (mode);
+ enum machine_mode imode = GET_MODE_INNER (mode);
+ if (!spu_nonmem_operand (ops[i], GET_MODE (ops[i])))
+ ops[i] = force_reg (GET_MODE (ops[i]), ops[i]);
+ if (imode != GET_MODE (ops[i]))
+ ops[i] = convert_to_mode (imode, ops[i],
+ TYPE_UNSIGNED (spu_builtin_types
+ [d->parm[i]]));
+ emit_insn (gen_spu_splats (reg, ops[i]));
+ ops[i] = reg;
+ }
+ }
+
+ if (!(*insn_data[icode].operand[i].predicate) (ops[i], mode))
+ ops[i] = spu_force_reg (mode, ops[i]);
+
+ spu_check_builtin_parm (d, ops[i], d->parm[p]);
+ }
+
+ switch (insn_data[icode].n_operands)
+ {
+ case 0:
+ pat = GEN_FCN (icode) (0);
+ break;
+ case 1:
+ pat = GEN_FCN (icode) (ops[0]);
+ break;
+ case 2:
+ pat = GEN_FCN (icode) (ops[0], ops[1]);
+ break;
+ case 3:
+ pat = GEN_FCN (icode) (ops[0], ops[1], ops[2]);
+ break;
+ case 4:
+ pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]);
+ break;
+ case 5:
+ pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4]);
+ break;
+ case 6:
+ pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4], ops[5]);
+ break;
+ default:
+ abort ();
+ }
+
+ if (!pat)
+ abort ();
+
+ if (d->type == B_CALL || d->type == B_BISLED)
+ emit_call_insn (pat);
+ else if (d->type == B_JUMP)
+ {
+ emit_jump_insn (pat);
+ emit_barrier ();
+ }
+ else
+ emit_insn (pat);
+
+ return_type = spu_builtin_types[d->parm[0]];
+ if (d->parm[0] != SPU_BTI_VOID
+ && GET_MODE (target) != TYPE_MODE (return_type))
+ {
+ /* target is the return value. It should always be the mode of
+ the builtin function prototype. */
+ target = spu_force_reg (TYPE_MODE (return_type), target);
+ }
+
+ return target;
+}
+
+rtx
+spu_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
+ tree arglist = TREE_OPERAND (exp, 1);
+ struct spu_builtin_description *d;
+
+ if (fcode < NUM_SPU_BUILTINS)
+ {
+ d = &spu_builtins[fcode];
+
+ return spu_expand_builtin_1 (d, arglist, target);
+ }
+ abort ();
+}
+
diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h
index a9714cb..b56ff14 100644
--- a/gcc/config/spu/spu.h
+++ b/gcc/config/spu/spu.h
@@ -238,6 +238,12 @@ enum reg_class {
((GET_MODE_SIZE (FROM) > 4 || GET_MODE_SIZE (TO) > 4) \
&& GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+#define REGISTER_TARGET_PRAGMAS() do { \
+targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
+ /* Don't give warnings about the main() function. */ \
+warn_main = 0; \
+}while (0);
+
/* Frame Layout */