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