Hi,

Attached is a patch based on gcc-4.6.1 that wires-up missing ARM
iwmmxt intrinsics. Without it, gcc is completely useless when it comes
to using a large portion of the intrinsics documented on this page:
http://gcc.gnu.org/onlinedocs/gcc/ARM-iWMMXt-Built_002din-Functions.html

The patch is based on the work of <ser...@yandex.ru> in bug 35294.

I do not know why the check_opsmode hack is necessary. Perhaps serowk
can help with that. I also do not know if this wires up all the
missing intrinsics, but it is sufficient to build a working
iwmmxt-optimized pixman:
http://cgit.freedesktop.org/~mattst88/pixman/log/?h=iwmmxt-optimizations

I have seen much more extensive patches from Xinyu Qi, but I do not
suppose that they will be available in gcc 4.6.

Thanks,
Matt Turner
--- arm.c.orig	2011-08-19 00:03:06.163195724 -0400
+++ arm.c	2011-08-19 00:03:10.872195933 -0400
@@ -157,7 +157,7 @@
 static void arm_init_builtins (void);
 static void arm_init_iwmmxt_builtins (void);
 static rtx safe_vector_operand (rtx, enum machine_mode);
-static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx, bool);
 static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
 static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 static void emit_constant_insn (rtx cond, rtx pattern);
@@ -19197,7 +19197,7 @@
 
 static rtx
 arm_expand_binop_builtin (enum insn_code icode,
-			  tree exp, rtx target)
+			  tree exp, rtx target, bool check_opsmode)
 {
   rtx pat;
   tree arg0 = CALL_EXPR_ARG (exp, 0);
@@ -19218,7 +19218,8 @@
       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
     target = gen_reg_rtx (tmode);
 
-  gcc_assert (GET_MODE (op0) == mode0 && GET_MODE (op1) == mode1);
+  if (check_opsmode)
+    gcc_assert (GET_MODE (op0) == mode0 && GET_MODE (op1) == mode1);
 
   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
     op0 = copy_to_mode_reg (mode0, op0);
@@ -19760,13 +19761,13 @@
       return target;
 
     case ARM_BUILTIN_WSADB:
-      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, exp, target);
+      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, exp, target, true);
     case ARM_BUILTIN_WSADH:
-      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, exp, target);
+      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, exp, target, true);
     case ARM_BUILTIN_WSADBZ:
-      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
+      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target, true);
     case ARM_BUILTIN_WSADHZ:
-      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
+      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target, true);
 
       /* Several three-argument builtins.  */
     case ARM_BUILTIN_WMACS:
@@ -19814,6 +19815,65 @@
       emit_insn (pat);
       return target;
 
+    case ARM_BUILTIN_WSLLH:
+    case ARM_BUILTIN_WSLLHI:
+    case ARM_BUILTIN_WSLLW:
+    case ARM_BUILTIN_WSLLWI:
+    case ARM_BUILTIN_WSLLD:
+    case ARM_BUILTIN_WSLLDI:
+    case ARM_BUILTIN_WSRAH:
+    case ARM_BUILTIN_WSRAHI:
+    case ARM_BUILTIN_WSRAW:
+    case ARM_BUILTIN_WSRAWI:
+    case ARM_BUILTIN_WSRAD:
+    case ARM_BUILTIN_WSRADI:
+    case ARM_BUILTIN_WSRLH:
+    case ARM_BUILTIN_WSRLHI:
+    case ARM_BUILTIN_WSRLW:
+    case ARM_BUILTIN_WSRLWI:
+    case ARM_BUILTIN_WSRLD:
+    case ARM_BUILTIN_WSRLDI:
+    case ARM_BUILTIN_WRORH:
+    case ARM_BUILTIN_WRORHI:
+    case ARM_BUILTIN_WRORW:
+    case ARM_BUILTIN_WRORWI:
+    case ARM_BUILTIN_WRORD:
+    case ARM_BUILTIN_WRORDI:
+    case ARM_BUILTIN_WAND:
+    case ARM_BUILTIN_WANDN:
+    case ARM_BUILTIN_WOR:
+    case ARM_BUILTIN_WXOR:
+      icode = (fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
+	       : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSLLW  ? CODE_FOR_ashlv2si3_di
+	       : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSLLD  ? CODE_FOR_ashldi3_di
+	       : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSRAH  ? CODE_FOR_ashrv4hi3_di
+	       : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSRAW  ? CODE_FOR_ashrv2si3_di
+	       : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSRAD  ? CODE_FOR_ashrdi3_di
+	       : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSRLH  ? CODE_FOR_lshrv4hi3_di
+	       : fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSRLW  ? CODE_FOR_lshrv2si3_di
+	       : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
+	       : fcode == ARM_BUILTIN_WSRLD  ? CODE_FOR_lshrdi3_di
+	       : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
+	       : fcode == ARM_BUILTIN_WRORH  ? CODE_FOR_rorv4hi3_di
+	       : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
+	       : fcode == ARM_BUILTIN_WRORW  ? CODE_FOR_rorv2si3_di
+	       : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
+	       : fcode == ARM_BUILTIN_WRORD  ? CODE_FOR_rordi3_di
+	       : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
+	       : fcode == ARM_BUILTIN_WAND   ? CODE_FOR_iwmmxt_anddi3
+	       : fcode == ARM_BUILTIN_WANDN  ? CODE_FOR_iwmmxt_nanddi3
+	       : fcode == ARM_BUILTIN_WOR    ? CODE_FOR_iwmmxt_iordi3
+	       : fcode == ARM_BUILTIN_WXOR   ? CODE_FOR_iwmmxt_xordi3
+	       : CODE_FOR_rordi3);
+      return arm_expand_binop_builtin (icode, exp, target, false);
+
     case ARM_BUILTIN_WZERO:
       target = gen_reg_rtx (DImode);
       emit_insn (gen_iwmmxt_clrdi (target));
@@ -19828,7 +19888,7 @@
 
   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
     if (d->code == (const enum arm_builtins) fcode)
-      return arm_expand_binop_builtin (d->icode, exp, target);
+      return arm_expand_binop_builtin (d->icode, exp, target, true);
 
   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
     if (d->code == (const enum arm_builtins) fcode)

Reply via email to