OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [config/] [spu/] [spu-c.c] - Diff between revs 282 and 384

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 282 Rev 384
/* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
/* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 
   This file is free software; you can redistribute it and/or modify it under
   This file is free software; you can redistribute it and/or modify it under
   the terms of the GNU General Public License as published by the Free
   the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3 of the License, or (at your option)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This file is distributed in the hope that it will be useful, but WITHOUT
   This file is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   for more details.
   for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */
   <http://www.gnu.org/licenses/>.  */
 
 
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "cpplib.h"
#include "cpplib.h"
#include "tree.h"
#include "tree.h"
#include "c-tree.h"
#include "c-tree.h"
#include "c-pragma.h"
#include "c-pragma.h"
#include "function.h"
#include "function.h"
#include "rtl.h"
#include "rtl.h"
#include "expr.h"
#include "expr.h"
#include "tm_p.h"
#include "tm_p.h"
#include "langhooks.h"
#include "langhooks.h"
#include "insn-config.h"
#include "insn-config.h"
#include "insn-codes.h"
#include "insn-codes.h"
#include "recog.h"
#include "recog.h"
#include "optabs.h"
#include "optabs.h"


 
 
/* Keep the vector keywords handy for fast comparisons.  */
/* Keep the vector keywords handy for fast comparisons.  */
static GTY(()) tree __vector_keyword;
static GTY(()) tree __vector_keyword;
static GTY(()) tree vector_keyword;
static GTY(()) tree vector_keyword;
 
 
static cpp_hashnode *
static cpp_hashnode *
spu_categorize_keyword (const cpp_token *tok)
spu_categorize_keyword (const cpp_token *tok)
{
{
  if (tok->type == CPP_NAME)
  if (tok->type == CPP_NAME)
    {
    {
      cpp_hashnode *ident = tok->val.node.node;
      cpp_hashnode *ident = tok->val.node.node;
 
 
      if (ident == C_CPP_HASHNODE (vector_keyword)
      if (ident == C_CPP_HASHNODE (vector_keyword)
          || ident == C_CPP_HASHNODE (__vector_keyword))
          || ident == C_CPP_HASHNODE (__vector_keyword))
        return C_CPP_HASHNODE (__vector_keyword);
        return C_CPP_HASHNODE (__vector_keyword);
      else
      else
        return ident;
        return ident;
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Called to decide whether a conditional macro should be expanded.
/* Called to decide whether a conditional macro should be expanded.
   Since we have exactly one such macro (i.e, 'vector'), we do not
   Since we have exactly one such macro (i.e, 'vector'), we do not
   need to examine the 'tok' parameter.  */
   need to examine the 'tok' parameter.  */
 
 
static cpp_hashnode *
static cpp_hashnode *
spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
{
{
  cpp_hashnode *expand_this = tok->val.node.node;
  cpp_hashnode *expand_this = tok->val.node.node;
  cpp_hashnode *ident;
  cpp_hashnode *ident;
 
 
  ident = spu_categorize_keyword (tok);
  ident = spu_categorize_keyword (tok);
  if (ident == C_CPP_HASHNODE (__vector_keyword))
  if (ident == C_CPP_HASHNODE (__vector_keyword))
    {
    {
      tok = cpp_peek_token (pfile, 0);
      tok = cpp_peek_token (pfile, 0);
      ident = spu_categorize_keyword (tok);
      ident = spu_categorize_keyword (tok);
 
 
      if (ident)
      if (ident)
        {
        {
          enum rid rid_code = (enum rid)(ident->rid_code);
          enum rid rid_code = (enum rid)(ident->rid_code);
          if (ident->type == NT_MACRO)
          if (ident->type == NT_MACRO)
            {
            {
              (void) cpp_get_token (pfile);
              (void) cpp_get_token (pfile);
              tok = cpp_peek_token (pfile, 0);
              tok = cpp_peek_token (pfile, 0);
              ident = spu_categorize_keyword (tok);
              ident = spu_categorize_keyword (tok);
              if (ident)
              if (ident)
                rid_code = (enum rid)(ident->rid_code);
                rid_code = (enum rid)(ident->rid_code);
            }
            }
 
 
          if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
          if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
              || rid_code == RID_SHORT || rid_code == RID_SIGNED
              || rid_code == RID_SHORT || rid_code == RID_SIGNED
              || rid_code == RID_INT || rid_code == RID_CHAR
              || rid_code == RID_INT || rid_code == RID_CHAR
              || rid_code == RID_FLOAT || rid_code == RID_DOUBLE)
              || rid_code == RID_FLOAT || rid_code == RID_DOUBLE)
            expand_this = C_CPP_HASHNODE (__vector_keyword);
            expand_this = C_CPP_HASHNODE (__vector_keyword);
        }
        }
    }
    }
  return expand_this;
  return expand_this;
}
}
 
 
/* target hook for resolve_overloaded_builtin(). Returns a function call
/* target hook for resolve_overloaded_builtin(). Returns a function call
   RTX if we can resolve the overloaded builtin */
   RTX if we can resolve the overloaded builtin */
tree
tree
spu_resolve_overloaded_builtin (location_t loc, tree fndecl, void *passed_args)
spu_resolve_overloaded_builtin (location_t loc, tree fndecl, void *passed_args)
{
{
#define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
#define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
                          || SCALAR_FLOAT_TYPE_P (t) \
                          || SCALAR_FLOAT_TYPE_P (t) \
                          || POINTER_TYPE_P (t))
                          || POINTER_TYPE_P (t))
  VEC(tree,gc) *fnargs = (VEC(tree,gc) *) passed_args;
  VEC(tree,gc) *fnargs = (VEC(tree,gc) *) passed_args;
  unsigned int nargs = VEC_length (tree, fnargs);
  unsigned int nargs = VEC_length (tree, fnargs);
  int new_fcode, fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
  int new_fcode, fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
  struct spu_builtin_description *desc;
  struct spu_builtin_description *desc;
  tree match = NULL_TREE;
  tree match = NULL_TREE;
 
 
  /* The vector types are not available if the backend is not initialized.  */
  /* The vector types are not available if the backend is not initialized.  */
  gcc_assert (!flag_preprocess_only);
  gcc_assert (!flag_preprocess_only);
 
 
  desc = &spu_builtins[fcode];
  desc = &spu_builtins[fcode];
  if (desc->type != B_OVERLOAD)
  if (desc->type != B_OVERLOAD)
    return NULL_TREE;
    return NULL_TREE;
 
 
  /* Compare the signature of each internal builtin function with the
  /* Compare the signature of each internal builtin function with the
     function arguments until a match is found. */
     function arguments until a match is found. */
 
 
  for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
  for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
       new_fcode++)
       new_fcode++)
    {
    {
      tree decl = spu_builtins[new_fcode].fndecl;
      tree decl = spu_builtins[new_fcode].fndecl;
      tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
      tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
      tree param;
      tree param;
      bool all_scalar;
      bool all_scalar;
      unsigned int p;
      unsigned int p;
 
 
      /* Check whether all parameters are scalar.  */
      /* Check whether all parameters are scalar.  */
      all_scalar = true;
      all_scalar = true;
      for (param = params; param != void_list_node; param = TREE_CHAIN (param))
      for (param = params; param != void_list_node; param = TREE_CHAIN (param))
      if (!SCALAR_TYPE_P (TREE_VALUE (param)))
      if (!SCALAR_TYPE_P (TREE_VALUE (param)))
        all_scalar = false;
        all_scalar = false;
 
 
      for (param = params, p = 0;
      for (param = params, p = 0;
           param != void_list_node;
           param != void_list_node;
           param = TREE_CHAIN (param), p++)
           param = TREE_CHAIN (param), p++)
        {
        {
          tree var, arg_type, param_type = TREE_VALUE (param);
          tree var, arg_type, param_type = TREE_VALUE (param);
 
 
          if (p >= nargs)
          if (p >= nargs)
            {
            {
              error ("insufficient arguments to overloaded function %s",
              error ("insufficient arguments to overloaded function %s",
                     desc->name);
                     desc->name);
              return error_mark_node;
              return error_mark_node;
            }
            }
 
 
          var = VEC_index (tree, fnargs, p);
          var = VEC_index (tree, fnargs, p);
 
 
          if (TREE_CODE (var) == NON_LVALUE_EXPR)
          if (TREE_CODE (var) == NON_LVALUE_EXPR)
            var = TREE_OPERAND (var, 0);
            var = TREE_OPERAND (var, 0);
 
 
          if (TREE_CODE (var) == ERROR_MARK)
          if (TREE_CODE (var) == ERROR_MARK)
            return NULL_TREE;   /* Let somebody else deal with the problem. */
            return NULL_TREE;   /* Let somebody else deal with the problem. */
 
 
          arg_type = TREE_TYPE (var);
          arg_type = TREE_TYPE (var);
 
 
          /* The intrinsics spec does not specify precisely how to
          /* The intrinsics spec does not specify precisely how to
             resolve generic intrinsics.  We require an exact match
             resolve generic intrinsics.  We require an exact match
             for vector types and let C do it's usual parameter type
             for vector types and let C do it's usual parameter type
             checking/promotions for scalar arguments, except for the
             checking/promotions for scalar arguments, except for the
             first argument of intrinsics which don't have a vector
             first argument of intrinsics which don't have a vector
             parameter. */
             parameter. */
          if ((!SCALAR_TYPE_P (param_type)
          if ((!SCALAR_TYPE_P (param_type)
               || !SCALAR_TYPE_P (arg_type)
               || !SCALAR_TYPE_P (arg_type)
               || (all_scalar && p == 0))
               || (all_scalar && p == 0))
              && !lang_hooks.types_compatible_p (param_type, arg_type))
              && !lang_hooks.types_compatible_p (param_type, arg_type))
            break;
            break;
        }
        }
      if (param == void_list_node)
      if (param == void_list_node)
        {
        {
          if (p != nargs)
          if (p != nargs)
            {
            {
              error ("too many arguments to overloaded function %s",
              error ("too many arguments to overloaded function %s",
                     desc->name);
                     desc->name);
              return error_mark_node;
              return error_mark_node;
            }
            }
 
 
          match = decl;
          match = decl;
          break;
          break;
        }
        }
    }
    }
 
 
  if (match == NULL_TREE)
  if (match == NULL_TREE)
    {
    {
      error ("parameter list does not match a valid signature for %s()",
      error ("parameter list does not match a valid signature for %s()",
             desc->name);
             desc->name);
      return error_mark_node;
      return error_mark_node;
    }
    }
 
 
  return build_function_call_vec (loc, match, fnargs, NULL);
  return build_function_call_vec (loc, match, fnargs, NULL);
#undef SCALAR_TYPE_P
#undef SCALAR_TYPE_P
}
}
 
 
 
 
void
void
spu_cpu_cpp_builtins (struct cpp_reader *pfile)
spu_cpu_cpp_builtins (struct cpp_reader *pfile)
{
{
  builtin_define_std ("__SPU__");
  builtin_define_std ("__SPU__");
  cpp_assert (pfile, "cpu=spu");
  cpp_assert (pfile, "cpu=spu");
  cpp_assert (pfile, "machine=spu");
  cpp_assert (pfile, "machine=spu");
  if (spu_arch == PROCESSOR_CELLEDP)
  if (spu_arch == PROCESSOR_CELLEDP)
    builtin_define_std ("__SPU_EDP__");
    builtin_define_std ("__SPU_EDP__");
  builtin_define_std ("__vector=__attribute__((__spu_vector__))");
  builtin_define_std ("__vector=__attribute__((__spu_vector__))");
  switch (spu_ea_model)
  switch (spu_ea_model)
    {
    {
    case 32:
    case 32:
      builtin_define_std ("__EA32__");
      builtin_define_std ("__EA32__");
      break;
      break;
    case 64:
    case 64:
      builtin_define_std ("__EA64__");
      builtin_define_std ("__EA64__");
      break;
      break;
    default:
    default:
       gcc_unreachable ();
       gcc_unreachable ();
    }
    }
 
 
  if (!flag_iso)
  if (!flag_iso)
    {
    {
      /* Define this when supporting context-sensitive keywords.  */
      /* Define this when supporting context-sensitive keywords.  */
      cpp_define (pfile, "__VECTOR_KEYWORD_SUPPORTED__");
      cpp_define (pfile, "__VECTOR_KEYWORD_SUPPORTED__");
      cpp_define (pfile, "vector=vector");
      cpp_define (pfile, "vector=vector");
 
 
      /* Initialize vector keywords.  */
      /* Initialize vector keywords.  */
      __vector_keyword = get_identifier ("__vector");
      __vector_keyword = get_identifier ("__vector");
      C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
      C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
      vector_keyword = get_identifier ("vector");
      vector_keyword = get_identifier ("vector");
      C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
      C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
 
 
      /* Enable context-sensitive macros.  */
      /* Enable context-sensitive macros.  */
      cpp_get_callbacks (pfile)->macro_to_expand = spu_macro_to_expand;
      cpp_get_callbacks (pfile)->macro_to_expand = spu_macro_to_expand;
    }
    }
}
}
 
 
void
void
spu_c_common_override_options (void)
spu_c_common_override_options (void)
{
{
  if (!TARGET_STD_MAIN)
  if (!TARGET_STD_MAIN)
    {
    {
      /* Don't give warnings about the main() function.  */
      /* Don't give warnings about the main() function.  */
      warn_main = 0;
      warn_main = 0;
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.