[committed] Fix FR-V __MDPACKH() builtin

Richard Sandiford rsandifo@redhat.com
Fri Jan 28 14:01:00 GMT 2005


As extend.texi says:

    GCC provides many FR-V-specific built-in functions.  In general,
    these functions are intended to be compatible with those described
    by @cite{FR-V Family, Softune C/C++ Compiler Manual (V6), Fujitsu
    Semiconductor}.  The two exceptions are @code{__MDUNPACKH} and
    @code{__MBTOHE}, the gcc forms of which pass 128-bit values by
    pointer rather than by value.

Unfortunately, there was another, unintentional, exception: gcc's
__MDPACKH() took two 64-bit arguments (which mapped directly to the two
64-bit input registers) whereas Fujitsu's version took the four individual
halfwords as separate arguments.

The patch below brings gcc into line with the Fujitsu definition.
Regression tested on frv-elf, approved by Aldy off-line & applied to head.

Richard


	* config/frv/frv.c (bdesc_2arg): Remove __MDPACKH.
	(frv_init_builtins): Change its prototype to take 4 uhalf arguments.
	(frv_expand_mdpackh_builtin): New function.
	(frv_expand_builtin): Use it to expand __MDPACKH.
	* doc/extend.texi (__MDPACKH): Update documentation.

testsuite/
	* gcc.target/frv/all-mdpackh-1.c: New test.

Index: config/frv/frv.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/frv/frv.c,v
retrieving revision 1.78
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.78 frv.c
*** config/frv/frv.c	30 Dec 2004 03:07:46 -0000	1.78
--- config/frv/frv.c	13 Jan 2005 12:51:44 -0000
*************** static struct builtin_description bdesc_
*** 9109,9115 ****
    { CODE_FOR_mqsubhss, "__MQSUBHSS", FRV_BUILTIN_MQSUBHSS, 0, 0 },
    { CODE_FOR_mqsubhus, "__MQSUBHUS", FRV_BUILTIN_MQSUBHUS, 0, 0 },
    { CODE_FOR_mpackh, "__MPACKH", FRV_BUILTIN_MPACKH, 0, 0 },
-   { CODE_FOR_mdpackh, "__MDPACKH", FRV_BUILTIN_MDPACKH, 0, 0 },
    { CODE_FOR_mcop1, "__Mcop1", FRV_BUILTIN_MCOP1, 0, 0 },
    { CODE_FOR_mcop2, "__Mcop2", FRV_BUILTIN_MCOP2, 0, 0 },
    { CODE_FOR_mwcut, "__MWCUT", FRV_BUILTIN_MWCUT, 0, 0 },
--- 9109,9114 ----
*************** #define TRINARY(RET, T1, T2, T3) \
*** 9254,9259 ****
--- 9253,9264 ----
  			    tree_cons (NULL_TREE, T2, \
  			    tree_cons (NULL_TREE, T3, endlink))))
  
+ #define QUAD(RET, T1, T2, T3, T4) \
+   build_function_type (RET, tree_cons (NULL_TREE, T1, \
+ 			    tree_cons (NULL_TREE, T2, \
+ 			    tree_cons (NULL_TREE, T3, \
+ 			    tree_cons (NULL_TREE, T4, endlink)))))
+ 
    tree void_ftype_void = build_function_type (voidt, endlink);
  
    tree void_ftype_acc = UNARY (voidt, accumulator);
*************** #define TRINARY(RET, T1, T2, T3) \
*** 9287,9292 ****
--- 9292,9298 ----
    tree uw2_ftype_uw2_uw2 = BINARY (uword2, uword2, uword2);
    tree uw2_ftype_uw2_int = BINARY (uword2, uword2, integer);
    tree uw2_ftype_acc_int = BINARY (uword2, accumulator, integer);
+   tree uw2_ftype_uh_uh_uh_uh = QUAD (uword2, uhalf, uhalf, uhalf, uhalf);
  
    tree sw2_ftype_sw2_sw2 = BINARY (sword2, sword2, sword2);
    tree sw2_ftype_sw2_int   = BINARY (sword2, sword2, integer);
*************** #define TRINARY(RET, T1, T2, T3) \
*** 9349,9355 ****
    def_builtin ("__MEXPDHD", uw2_ftype_uw1_int, FRV_BUILTIN_MEXPDHD);
    def_builtin ("__MPACKH", uw1_ftype_uh_uh, FRV_BUILTIN_MPACKH);
    def_builtin ("__MUNPACKH", uw2_ftype_uw1, FRV_BUILTIN_MUNPACKH);
!   def_builtin ("__MDPACKH", uw2_ftype_uw2_uw2, FRV_BUILTIN_MDPACKH);
    def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
    def_builtin ("__MBTOH", uw2_ftype_uw1, FRV_BUILTIN_MBTOH);
    def_builtin ("__MHTOB", uw1_ftype_uw2, FRV_BUILTIN_MHTOB);
--- 9355,9361 ----
    def_builtin ("__MEXPDHD", uw2_ftype_uw1_int, FRV_BUILTIN_MEXPDHD);
    def_builtin ("__MPACKH", uw1_ftype_uh_uh, FRV_BUILTIN_MPACKH);
    def_builtin ("__MUNPACKH", uw2_ftype_uw1, FRV_BUILTIN_MUNPACKH);
!   def_builtin ("__MDPACKH", uw2_ftype_uh_uh_uh_uh, FRV_BUILTIN_MDPACKH);
    def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
    def_builtin ("__MBTOH", uw2_ftype_uw1, FRV_BUILTIN_MBTOH);
    def_builtin ("__MHTOB", uw1_ftype_uw2, FRV_BUILTIN_MHTOB);
*************** #define TRINARY(RET, T1, T2, T3) \
*** 9408,9413 ****
--- 9414,9420 ----
  #undef UNARY
  #undef BINARY
  #undef TRINARY
+ #undef QUAD
  }
  
  /* Set the names for various arithmetic operations according to the
*************** frv_expand_voidaccop_builtin (enum insn_
*** 9876,9881 ****
--- 9883,9926 ----
    return NULL_RTX;
  }
  
+ /* Expand the MDPACKH builtin.  It takes four unsigned short arguments and
+    each argument forms one word of the two double-word input registers.
+    ARGLIST is a TREE_LIST of the arguments and TARGET, if nonnull,
+    suggests a good place to put the return value.  */
+ 
+ static rtx
+ frv_expand_mdpackh_builtin (tree arglist, rtx target)
+ {
+   enum insn_code icode = CODE_FOR_mdpackh;
+   rtx pat, op0, op1;
+   rtx arg1 = frv_read_argument (&arglist);
+   rtx arg2 = frv_read_argument (&arglist);
+   rtx arg3 = frv_read_argument (&arglist);
+   rtx arg4 = frv_read_argument (&arglist);
+ 
+   target = frv_legitimize_target (icode, target);
+   op0 = gen_reg_rtx (DImode);
+   op1 = gen_reg_rtx (DImode);
+ 
+   /* The high half of each word is not explicitly initialised, so indicate
+      that the input operands are not live before this point.  */
+   emit_insn (gen_rtx_CLOBBER (DImode, op0));
+   emit_insn (gen_rtx_CLOBBER (DImode, op1));
+ 
+   /* Move each argument into the low half of its associated input word.  */
+   emit_move_insn (simplify_gen_subreg (HImode, op0, DImode, 2), arg1);
+   emit_move_insn (simplify_gen_subreg (HImode, op0, DImode, 6), arg2);
+   emit_move_insn (simplify_gen_subreg (HImode, op1, DImode, 2), arg3);
+   emit_move_insn (simplify_gen_subreg (HImode, op1, DImode, 6), arg4);
+ 
+   pat = GEN_FCN (icode) (target, op0, op1);
+   if (! pat)
+     return NULL_RTX;
+ 
+   emit_insn (pat);
+   return target;
+ }
+ 
  /* Expand the MCLRACC builtin.  This builtin takes a single accumulator
     number as argument.  */
  
*************** frv_expand_builtin (tree exp,
*** 10103,10108 ****
--- 10148,10156 ----
      case FRV_BUILTIN_MWTACCG:
        return frv_expand_mwtacc_builtin (CODE_FOR_mwtaccg, arglist);
  
+     case FRV_BUILTIN_MDPACKH:
+       return frv_expand_mdpackh_builtin (arglist, target);
+ 
      case FRV_BUILTIN_IACCreadll:
        {
  	rtx src = frv_read_iacc_argument (DImode, &arglist);
diff -c /dev/null testsuite/gcc.target/frv/all-mdpackh-1.c
*** /dev/null	2004-02-18 15:26:44.000000000 +0000
--- testsuite/gcc.target/frv/all-mdpackh-1.c	2005-01-10 14:08:50.000000000 +0000
***************
*** 0 ****
--- 1,16 ----
+ /* Test the new (Fujitsu-compatible) __MDPACKH() interface.  */
+ /* { dg-do run } */
+ extern void exit (int);
+ extern void abort (void);
+ 
+ unsigned short x[] = { 0x8765, 0x1234, 0x2222, 0xeeee };
+ 
+ int
+ main ()
+ {
+   if (__MDPACKH (x[0], x[1], x[2], x[3]) != 0x876522221234eeeeULL)
+     abort ();
+   if (__MDPACKH (0x1111, 0x8001, 0xeeee, 0x7002) != 0x1111eeee80017002ULL)
+     abort ();
+   exit (0);
+ }
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.235
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.235 extend.texi
--- doc/extend.texi	3 Dec 2004 17:37:09 -0000	1.235
+++ doc/extend.texi	28 Jan 2005 13:49:05 -0000
@@ -5793,8 +5793,8 @@ The functions listed below map directly 
 @item @code{uw2 __MDCUTSSI (acc, const)}
 @tab @code{@var{c} = __MDCUTSSI (@var{a}, @var{b})}
 @tab @code{MDCUTSSI @var{a},#@var{b},@var{c}}
-@item @code{uw2 __MDPACKH (uw2, uw2)}
-@tab @code{@var{c} = __MDPACKH (@var{a}, @var{b})}
+@item @code{uw2 __MDPACKH (uh, uh, uh, uh)}
+@tab @code{@var{c} = __MDPACKH (@var{a1}, @var{a2}, @var{b1}, @var{b2})}
 @tab @code{MDPACKH @var{a},@var{b},@var{c}}
 @item @code{uw2 __MDROTLI (uw2, const)}
 @tab @code{@var{c} = __MDROTLI (@var{a}, @var{b})}



More information about the Gcc-patches mailing list