This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

new __builtin_choose_type (patch)


hi guys.

for the altivec enhancements, we need a way to overload functions in C.

for example:

	vec_add(foo, bar)

where foo and bar can be of a variety of vector types.  so if foo and
bar are of V4SF something happens, and if they are of type V2SI
something else happens.

it was suggested to have a builtin analogous to the ?: operator that
will work as follows:

	__builtin_choose_type (exp0, type, exp1, exp2);

if <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.

i have a patch for this feature and i'd like some comments.

in the example below, b=10 gets evaluated because float != double, and
the entire builtin's value is 10.

    int b;
    double a;
    float float_type;
    
    foo(){
            __builtin_choose_type(a, float_type, b=8, b=10);
    }
    
one problem i have with the patch below, is that if the first argument
is of type "char" it gets promoted to an "int" so there's no way to use
this builtin with a <char>.  it really doesn't matter since what i
really want is vector types, but i'd really like to get it working
across all types-- perhaps we can rewrite that <tgmath.h> crap with this
builtin ;-).

comment away.

-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a Motorcycle
Red Hat, Inc.


2001-10-01  Aldy Hernandez  <aldyh@redhat.com>

        * builtins.c (expand_builtin_choose_type): New.
        (expand_builtin): Add case for BUILT_IN_CHOOSE_TYPE.

        * builtins.def (BUILT_IN_CHOOSE_TYPE): New.

Index: builtins.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/builtins.def,v
retrieving revision 1.22
diff -c -r1.22 builtins.def
*** builtins.def	2001/08/22 14:34:42	1.22
--- builtins.def	2001/10/02 18:34:22
***************
*** 336,341 ****
--- 336,344 ----
  DEF_GCC_BUILTIN(BUILT_IN_TRAP,
  		"__builtin_trap",
  		BT_FN_VOID)
+ DEF_GCC_BUILTIN(BUILT_IN_CHOOSE_TYPE,
+ 		"__builtin_choose_type", 
+ 		BT_FN_PTR_VAR)
  
  /* Stdio builtins.  */
  DEF_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR,
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/builtins.c,v
retrieving revision 1.121
diff -c -r1.121 builtins.c
*** builtins.c	2001/09/22 08:42:00	1.121
--- builtins.c	2001/10/02 18:34:33
***************
*** 95,100 ****
--- 95,101 ----
  static rtx expand_builtin_classify_type	PARAMS ((tree));
  static rtx expand_builtin_mathfn	PARAMS ((tree, rtx, rtx));
  static rtx expand_builtin_constant_p	PARAMS ((tree));
+ static rtx expand_builtin_choose_type	PARAMS ((tree, rtx));
  static rtx expand_builtin_args_info	PARAMS ((tree));
  static rtx expand_builtin_next_arg	PARAMS ((tree));
  static rtx expand_builtin_va_start	PARAMS ((int, tree));
***************
*** 1316,1321 ****
--- 1317,1384 ----
    return tmp;
  }
  
+ /* Expand expression EXP, which is a call to __builtin_choose_type.
+ 
+    __builtin_type_choose (<exp0>, <type>, <exp1>, <exp2>)
+ 
+    If <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.
+ */
+ 
+ static rtx
+ expand_builtin_choose_type (exp, target)
+      tree exp;
+      rtx target;
+ {
+   tree arg = TREE_OPERAND (exp, 1);
+   tree chain;
+   enum machine_mode exp0_mode, desired_mode;
+ 
+   if (arg == 0)
+     return const0_rtx;
+ 
+   chain = TREE_CHAIN (arg);
+   arg = TREE_VALUE (arg);
+ 
+   /* Strip off all NOPs.  */
+   while (TREE_CODE (arg) == NOP_EXPR
+ 	 || TREE_CODE (arg) == CONVERT_EXPR
+ 	 || TREE_CODE (arg) == NON_LVALUE_EXPR
+ 	 || TREE_CODE (arg) == INDIRECT_REF)
+     arg = TREE_OPERAND (arg, 0);
+ 
+   /* Get <exp0> type.  */
+   exp0_mode = TYPE_MODE (TREE_TYPE (arg));
+ 
+   /* Get <type> type.  */
+   arg = TREE_VALUE (chain);
+   if (!arg)
+     return const0_rtx;
+   /* Strip off all NOPs.  */
+   while (TREE_CODE (arg) == NOP_EXPR
+ 	 || TREE_CODE (arg) == CONVERT_EXPR
+ 	 || TREE_CODE (arg) == NON_LVALUE_EXPR
+ 	 || TREE_CODE (arg) == INDIRECT_REF)
+     arg = TREE_OPERAND (arg, 0);
+   desired_mode = TYPE_MODE (TREE_TYPE (arg));
+ 
+   /* Get exp1.  */
+   chain = TREE_CHAIN (chain);
+   if (!chain)
+     error ("missing argument in `__builtin_choose_type'");
+ 
+   if (exp0_mode == desired_mode)
+     /* Evaluate exp1.  */
+     return expand_expr (TREE_VALUE (chain), target, VOIDmode, EXPAND_NORMAL);
+   
+   /* Get exp2.  */
+   chain = TREE_CHAIN (chain);
+   if (!chain)
+     error ("missing argument in `__builtin_choose_type'");
+ 
+   /* Evaluate exp2.  */
+   return expand_expr (TREE_VALUE (chain), target, VOIDmode, EXPAND_NORMAL);
+ }
+ 
  /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
     Return 0 if a normal call should be emitted rather than expanding the
     function in-line.  EXP is the expression that is a call to the builtin
***************
*** 3512,3517 ****
--- 3575,3583 ----
  
      case BUILT_IN_CONSTANT_P:
        return expand_builtin_constant_p (exp);
+ 
+     case BUILT_IN_CHOOSE_TYPE:
+       return expand_builtin_choose_type (exp, target);
  
      case BUILT_IN_FRAME_ADDRESS:
      case BUILT_IN_RETURN_ADDRESS:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]