Home | History | Annotate | Line # | Download | only in spu
spu-c.c revision 1.1.1.1.4.2
      1  1.1.1.1.4.2  yamt /* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
      2  1.1.1.1.4.2  yamt 
      3  1.1.1.1.4.2  yamt    This file is free software; you can redistribute it and/or modify it under
      4  1.1.1.1.4.2  yamt    the terms of the GNU General Public License as published by the Free
      5  1.1.1.1.4.2  yamt    Software Foundation; either version 3 of the License, or (at your option)
      6  1.1.1.1.4.2  yamt    any later version.
      7  1.1.1.1.4.2  yamt 
      8  1.1.1.1.4.2  yamt    This file is distributed in the hope that it will be useful, but WITHOUT
      9  1.1.1.1.4.2  yamt    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     10  1.1.1.1.4.2  yamt    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     11  1.1.1.1.4.2  yamt    for more details.
     12  1.1.1.1.4.2  yamt 
     13  1.1.1.1.4.2  yamt    You should have received a copy of the GNU General Public License
     14  1.1.1.1.4.2  yamt    along with GCC; see the file COPYING3.  If not see
     15  1.1.1.1.4.2  yamt    <http://www.gnu.org/licenses/>.  */
     16  1.1.1.1.4.2  yamt 
     17  1.1.1.1.4.2  yamt #include "config.h"
     18  1.1.1.1.4.2  yamt #include "system.h"
     19  1.1.1.1.4.2  yamt #include "coretypes.h"
     20  1.1.1.1.4.2  yamt #include "tm.h"
     21  1.1.1.1.4.2  yamt #include "cpplib.h"
     22  1.1.1.1.4.2  yamt #include "tree.h"
     23  1.1.1.1.4.2  yamt #include "c-tree.h"
     24  1.1.1.1.4.2  yamt #include "c-pragma.h"
     25  1.1.1.1.4.2  yamt #include "function.h"
     26  1.1.1.1.4.2  yamt #include "rtl.h"
     27  1.1.1.1.4.2  yamt #include "expr.h"
     28  1.1.1.1.4.2  yamt #include "tm_p.h"
     29  1.1.1.1.4.2  yamt #include "langhooks.h"
     30  1.1.1.1.4.2  yamt #include "insn-config.h"
     31  1.1.1.1.4.2  yamt #include "insn-codes.h"
     32  1.1.1.1.4.2  yamt #include "recog.h"
     33  1.1.1.1.4.2  yamt #include "optabs.h"
     34  1.1.1.1.4.2  yamt 
     35  1.1.1.1.4.2  yamt 
     37  1.1.1.1.4.2  yamt /* Keep the vector keywords handy for fast comparisons.  */
     38  1.1.1.1.4.2  yamt static GTY(()) tree __vector_keyword;
     39  1.1.1.1.4.2  yamt static GTY(()) tree vector_keyword;
     40  1.1.1.1.4.2  yamt 
     41  1.1.1.1.4.2  yamt static cpp_hashnode *
     42  1.1.1.1.4.2  yamt spu_categorize_keyword (const cpp_token *tok)
     43  1.1.1.1.4.2  yamt {
     44  1.1.1.1.4.2  yamt   if (tok->type == CPP_NAME)
     45  1.1.1.1.4.2  yamt     {
     46  1.1.1.1.4.2  yamt       cpp_hashnode *ident = tok->val.node.node;
     47  1.1.1.1.4.2  yamt 
     48  1.1.1.1.4.2  yamt       if (ident == C_CPP_HASHNODE (vector_keyword)
     49  1.1.1.1.4.2  yamt 	  || ident == C_CPP_HASHNODE (__vector_keyword))
     50  1.1.1.1.4.2  yamt 	return C_CPP_HASHNODE (__vector_keyword);
     51  1.1.1.1.4.2  yamt       else
     52  1.1.1.1.4.2  yamt 	return ident;
     53  1.1.1.1.4.2  yamt     }
     54  1.1.1.1.4.2  yamt   return 0;
     55  1.1.1.1.4.2  yamt }
     56  1.1.1.1.4.2  yamt 
     57  1.1.1.1.4.2  yamt /* Called to decide whether a conditional macro should be expanded.
     58  1.1.1.1.4.2  yamt    Since we have exactly one such macro (i.e, 'vector'), we do not
     59  1.1.1.1.4.2  yamt    need to examine the 'tok' parameter.  */
     60  1.1.1.1.4.2  yamt 
     61  1.1.1.1.4.2  yamt static cpp_hashnode *
     62  1.1.1.1.4.2  yamt spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
     63  1.1.1.1.4.2  yamt {
     64  1.1.1.1.4.2  yamt   cpp_hashnode *expand_this = tok->val.node.node;
     65  1.1.1.1.4.2  yamt   cpp_hashnode *ident;
     66  1.1.1.1.4.2  yamt 
     67  1.1.1.1.4.2  yamt   ident = spu_categorize_keyword (tok);
     68  1.1.1.1.4.2  yamt   if (ident == C_CPP_HASHNODE (__vector_keyword))
     69  1.1.1.1.4.2  yamt     {
     70  1.1.1.1.4.2  yamt       tok = cpp_peek_token (pfile, 0);
     71  1.1.1.1.4.2  yamt       ident = spu_categorize_keyword (tok);
     72  1.1.1.1.4.2  yamt 
     73  1.1.1.1.4.2  yamt       if (ident)
     74  1.1.1.1.4.2  yamt 	{
     75  1.1.1.1.4.2  yamt 	  enum rid rid_code = (enum rid)(ident->rid_code);
     76  1.1.1.1.4.2  yamt 	  if (ident->type == NT_MACRO)
     77  1.1.1.1.4.2  yamt 	    {
     78  1.1.1.1.4.2  yamt 	      (void) cpp_get_token (pfile);
     79  1.1.1.1.4.2  yamt 	      tok = cpp_peek_token (pfile, 0);
     80  1.1.1.1.4.2  yamt 	      ident = spu_categorize_keyword (tok);
     81  1.1.1.1.4.2  yamt 	      if (ident)
     82  1.1.1.1.4.2  yamt 		rid_code = (enum rid)(ident->rid_code);
     83  1.1.1.1.4.2  yamt 	    }
     84  1.1.1.1.4.2  yamt 
     85  1.1.1.1.4.2  yamt 	  if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
     86  1.1.1.1.4.2  yamt 	      || rid_code == RID_SHORT || rid_code == RID_SIGNED
     87  1.1.1.1.4.2  yamt 	      || rid_code == RID_INT || rid_code == RID_CHAR
     88  1.1.1.1.4.2  yamt 	      || rid_code == RID_FLOAT || rid_code == RID_DOUBLE)
     89  1.1.1.1.4.2  yamt 	    expand_this = C_CPP_HASHNODE (__vector_keyword);
     90  1.1.1.1.4.2  yamt 	}
     91  1.1.1.1.4.2  yamt     }
     92  1.1.1.1.4.2  yamt   return expand_this;
     93  1.1.1.1.4.2  yamt }
     94  1.1.1.1.4.2  yamt 
     95  1.1.1.1.4.2  yamt /* target hook for resolve_overloaded_builtin(). Returns a function call
     96  1.1.1.1.4.2  yamt    RTX if we can resolve the overloaded builtin */
     97  1.1.1.1.4.2  yamt tree
     98  1.1.1.1.4.2  yamt spu_resolve_overloaded_builtin (location_t loc, tree fndecl, void *passed_args)
     99  1.1.1.1.4.2  yamt {
    100  1.1.1.1.4.2  yamt #define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
    101  1.1.1.1.4.2  yamt 			  || SCALAR_FLOAT_TYPE_P (t) \
    102  1.1.1.1.4.2  yamt 			  || POINTER_TYPE_P (t))
    103  1.1.1.1.4.2  yamt   VEC(tree,gc) *fnargs = (VEC(tree,gc) *) passed_args;
    104  1.1.1.1.4.2  yamt   unsigned int nargs = VEC_length (tree, fnargs);
    105  1.1.1.1.4.2  yamt   int new_fcode, fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
    106  1.1.1.1.4.2  yamt   struct spu_builtin_description *desc;
    107  1.1.1.1.4.2  yamt   tree match = NULL_TREE;
    108  1.1.1.1.4.2  yamt 
    109  1.1.1.1.4.2  yamt   /* The vector types are not available if the backend is not initialized.  */
    110  1.1.1.1.4.2  yamt   gcc_assert (!flag_preprocess_only);
    111  1.1.1.1.4.2  yamt 
    112  1.1.1.1.4.2  yamt   desc = &spu_builtins[fcode];
    113  1.1.1.1.4.2  yamt   if (desc->type != B_OVERLOAD)
    114  1.1.1.1.4.2  yamt     return NULL_TREE;
    115  1.1.1.1.4.2  yamt 
    116  1.1.1.1.4.2  yamt   /* Compare the signature of each internal builtin function with the
    117  1.1.1.1.4.2  yamt      function arguments until a match is found. */
    118  1.1.1.1.4.2  yamt 
    119  1.1.1.1.4.2  yamt   for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
    120  1.1.1.1.4.2  yamt        new_fcode++)
    121  1.1.1.1.4.2  yamt     {
    122  1.1.1.1.4.2  yamt       tree decl = spu_builtins[new_fcode].fndecl;
    123  1.1.1.1.4.2  yamt       tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
    124  1.1.1.1.4.2  yamt       tree param;
    125  1.1.1.1.4.2  yamt       bool all_scalar;
    126  1.1.1.1.4.2  yamt       unsigned int p;
    127  1.1.1.1.4.2  yamt 
    128  1.1.1.1.4.2  yamt       /* Check whether all parameters are scalar.  */
    129  1.1.1.1.4.2  yamt       all_scalar = true;
    130  1.1.1.1.4.2  yamt       for (param = params; param != void_list_node; param = TREE_CHAIN (param))
    131  1.1.1.1.4.2  yamt       if (!SCALAR_TYPE_P (TREE_VALUE (param)))
    132  1.1.1.1.4.2  yamt 	all_scalar = false;
    133  1.1.1.1.4.2  yamt 
    134  1.1.1.1.4.2  yamt       for (param = params, p = 0;
    135  1.1.1.1.4.2  yamt 	   param != void_list_node;
    136  1.1.1.1.4.2  yamt 	   param = TREE_CHAIN (param), p++)
    137  1.1.1.1.4.2  yamt 	{
    138  1.1.1.1.4.2  yamt 	  tree var, arg_type, param_type = TREE_VALUE (param);
    139  1.1.1.1.4.2  yamt 
    140  1.1.1.1.4.2  yamt 	  if (p >= nargs)
    141  1.1.1.1.4.2  yamt 	    {
    142  1.1.1.1.4.2  yamt 	      error ("insufficient arguments to overloaded function %s",
    143  1.1.1.1.4.2  yamt 		     desc->name);
    144  1.1.1.1.4.2  yamt 	      return error_mark_node;
    145  1.1.1.1.4.2  yamt 	    }
    146  1.1.1.1.4.2  yamt 
    147  1.1.1.1.4.2  yamt 	  var = VEC_index (tree, fnargs, p);
    148  1.1.1.1.4.2  yamt 
    149  1.1.1.1.4.2  yamt 	  if (TREE_CODE (var) == NON_LVALUE_EXPR)
    150  1.1.1.1.4.2  yamt 	    var = TREE_OPERAND (var, 0);
    151  1.1.1.1.4.2  yamt 
    152  1.1.1.1.4.2  yamt 	  if (TREE_CODE (var) == ERROR_MARK)
    153  1.1.1.1.4.2  yamt 	    return NULL_TREE;	/* Let somebody else deal with the problem. */
    154  1.1.1.1.4.2  yamt 
    155  1.1.1.1.4.2  yamt 	  arg_type = TREE_TYPE (var);
    156  1.1.1.1.4.2  yamt 
    157  1.1.1.1.4.2  yamt 	  /* The intrinsics spec does not specify precisely how to
    158  1.1.1.1.4.2  yamt 	     resolve generic intrinsics.  We require an exact match
    159  1.1.1.1.4.2  yamt 	     for vector types and let C do it's usual parameter type
    160  1.1.1.1.4.2  yamt 	     checking/promotions for scalar arguments, except for the
    161  1.1.1.1.4.2  yamt 	     first argument of intrinsics which don't have a vector
    162  1.1.1.1.4.2  yamt 	     parameter. */
    163  1.1.1.1.4.2  yamt 	  if ((!SCALAR_TYPE_P (param_type)
    164  1.1.1.1.4.2  yamt 	       || !SCALAR_TYPE_P (arg_type)
    165  1.1.1.1.4.2  yamt 	       || (all_scalar && p == 0))
    166  1.1.1.1.4.2  yamt 	      && !lang_hooks.types_compatible_p (param_type, arg_type))
    167  1.1.1.1.4.2  yamt 	    break;
    168  1.1.1.1.4.2  yamt 	}
    169  1.1.1.1.4.2  yamt       if (param == void_list_node)
    170  1.1.1.1.4.2  yamt 	{
    171  1.1.1.1.4.2  yamt 	  if (p != nargs)
    172  1.1.1.1.4.2  yamt 	    {
    173  1.1.1.1.4.2  yamt 	      error ("too many arguments to overloaded function %s",
    174  1.1.1.1.4.2  yamt 		     desc->name);
    175  1.1.1.1.4.2  yamt 	      return error_mark_node;
    176  1.1.1.1.4.2  yamt 	    }
    177  1.1.1.1.4.2  yamt 
    178  1.1.1.1.4.2  yamt 	  match = decl;
    179  1.1.1.1.4.2  yamt 	  break;
    180  1.1.1.1.4.2  yamt 	}
    181  1.1.1.1.4.2  yamt     }
    182  1.1.1.1.4.2  yamt 
    183  1.1.1.1.4.2  yamt   if (match == NULL_TREE)
    184  1.1.1.1.4.2  yamt     {
    185  1.1.1.1.4.2  yamt       error ("parameter list does not match a valid signature for %s()",
    186  1.1.1.1.4.2  yamt 	     desc->name);
    187  1.1.1.1.4.2  yamt       return error_mark_node;
    188  1.1.1.1.4.2  yamt     }
    189  1.1.1.1.4.2  yamt 
    190  1.1.1.1.4.2  yamt   return build_function_call_vec (loc, match, fnargs, NULL);
    191  1.1.1.1.4.2  yamt #undef SCALAR_TYPE_P
    192  1.1.1.1.4.2  yamt }
    193  1.1.1.1.4.2  yamt 
    194  1.1.1.1.4.2  yamt 
    195  1.1.1.1.4.2  yamt void
    196  1.1.1.1.4.2  yamt spu_cpu_cpp_builtins (struct cpp_reader *pfile)
    197  1.1.1.1.4.2  yamt {
    198  1.1.1.1.4.2  yamt   builtin_define_std ("__SPU__");
    199  1.1.1.1.4.2  yamt   cpp_assert (pfile, "cpu=spu");
    200  1.1.1.1.4.2  yamt   cpp_assert (pfile, "machine=spu");
    201  1.1.1.1.4.2  yamt   if (spu_arch == PROCESSOR_CELLEDP)
    202  1.1.1.1.4.2  yamt     builtin_define_std ("__SPU_EDP__");
    203  1.1.1.1.4.2  yamt   builtin_define_std ("__vector=__attribute__((__spu_vector__))");
    204  1.1.1.1.4.2  yamt   switch (spu_ea_model)
    205  1.1.1.1.4.2  yamt     {
    206  1.1.1.1.4.2  yamt     case 32:
    207  1.1.1.1.4.2  yamt       builtin_define_std ("__EA32__");
    208  1.1.1.1.4.2  yamt       break;
    209  1.1.1.1.4.2  yamt     case 64:
    210  1.1.1.1.4.2  yamt       builtin_define_std ("__EA64__");
    211  1.1.1.1.4.2  yamt       break;
    212  1.1.1.1.4.2  yamt     default:
    213  1.1.1.1.4.2  yamt        gcc_unreachable ();
    214  1.1.1.1.4.2  yamt     }
    215  1.1.1.1.4.2  yamt 
    216  1.1.1.1.4.2  yamt   if (!flag_iso)
    217  1.1.1.1.4.2  yamt     {
    218  1.1.1.1.4.2  yamt       /* Define this when supporting context-sensitive keywords.  */
    219  1.1.1.1.4.2  yamt       cpp_define (pfile, "__VECTOR_KEYWORD_SUPPORTED__");
    220  1.1.1.1.4.2  yamt       cpp_define (pfile, "vector=vector");
    221  1.1.1.1.4.2  yamt 
    222  1.1.1.1.4.2  yamt       /* Initialize vector keywords.  */
    223  1.1.1.1.4.2  yamt       __vector_keyword = get_identifier ("__vector");
    224  1.1.1.1.4.2  yamt       C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
    225  1.1.1.1.4.2  yamt       vector_keyword = get_identifier ("vector");
    226  1.1.1.1.4.2  yamt       C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
    227  1.1.1.1.4.2  yamt 
    228  1.1.1.1.4.2  yamt       /* Enable context-sensitive macros.  */
    229  1.1.1.1.4.2  yamt       cpp_get_callbacks (pfile)->macro_to_expand = spu_macro_to_expand;
    230  1.1.1.1.4.2  yamt     }
    231  1.1.1.1.4.2  yamt }
    232  1.1.1.1.4.2  yamt 
    233  1.1.1.1.4.2  yamt void
    234  1.1.1.1.4.2  yamt spu_c_common_override_options (void)
    235  1.1.1.1.4.2  yamt {
    236  1.1.1.1.4.2  yamt   if (!TARGET_STD_MAIN)
    237  1.1.1.1.4.2  yamt     {
    238  1.1.1.1.4.2  yamt       /* Don't give warnings about the main() function.  */
    239  1.1.1.1.4.2  yamt       warn_main = 0;
    240  1.1.1.1.4.2  yamt     }
    241                    }
    242