This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

Blackfin mulsi_highpart patterns


This provides the {s,u}mulsi3_highpart patterns for the Blackfin which are necessary to turn divide by constant into a multiplication at compile time. Since the sequences get rather long (synthesizing a 32x32->64 multiplication out of several 16x16->32 ones) and register allocation is tricky for some of the involved multiplication patterns, I made the compiler emit library calls instead of emitting them in-line.

Committed as 122379.


Bernd -- This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, Vincent Roche, Joseph E. McDonough
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 122377)
+++ ChangeLog	(working copy)
@@ -48,6 +48,13 @@
 
 	* config/bfin/bfin.md (rotl16, rotlsi3, rotrsi3): New patterns.
 
+	* config/bfin/t-bfin-elf (LIB1ASMFUNCS): Add _umulsi3_highpart and
+	_smulsi3_highpart.
+	* config/bfin/lib1funcs.asm (___umulsi3_highpart, ___smulsi3_highpart):
+	New functions.
+	* config/bfin/bfin.md (smulsi3_highpart, umulsi3_highpart): New
+	patterns.
+
 2007-02-27  Andreas Schwab  <schwab@suse.de>
 
 	* Makefile.in (TEXI_GCCINSTALL_FILES): Add gcc-common.texi.
Index: config/bfin/lib1funcs.asm
===================================================================
--- config/bfin/lib1funcs.asm	(revision 122331)
+++ config/bfin/lib1funcs.asm	(working copy)
@@ -117,3 +117,50 @@ ___umodsi3:
 	RTS;
 #endif
 
+#ifdef L_umulsi3_highpart
+.align 2
+.global ___umulsi3_highpart;
+.type ___umulsi3_highpart, STT_FUNC;
+
+___umulsi3_highpart:
+	R2 = R1.H * R0.H, R3 = R1.L * R0.H (FU);
+	R0 = R1.L * R0.L, R1 = R1.H * R0.L (FU);
+	R0 >>= 16;
+	/* Unsigned multiplication has the nice property that we can
+	   ignore carry on this first addition.  */
+	R0 = R0 + R3;
+	R0 = R0 + R1;
+	cc = ac0;
+	R1 = cc;
+	R1 = PACK(R1.l,R0.h);
+	R0 = R1 + R2;
+	RTS;
+#endif
+
+#ifdef L_smulsi3_highpart
+.align 2
+.global ___smulsi3_highpart;
+.type ___smulsi3_highpart, STT_FUNC;
+
+___smulsi3_highpart:
+	R2 = R1.L * R0.L (FU);
+	R3 = R1.H * R0.L (IS,M);
+	R0 = R0.H * R1.H, R1 = R0.H * R1.L (IS,M);
+
+	R1.L = R2.H + R1.L;
+	cc = ac0;
+	R2 = cc;
+
+	R1.L = R1.L + R3.L;
+	cc = ac0;
+	R1 >>>= 16;
+	R3 >>>= 16;
+	R1 = R1 + R3;
+	R1 = R1 + R2;
+	R2 = cc;
+	R1 = R1 + R2;
+
+	R0 = R0 + R1;
+	RTS;
+#endif
+
Index: config/bfin/bfin.md
===================================================================
--- config/bfin/bfin.md	(revision 122377)
+++ config/bfin/bfin.md	(working copy)
@@ -1436,6 +1436,46 @@ (define_insn "mulsi3"
   "%0 *= %2;"
   [(set_attr "type" "mult")])
 
+(define_expand "umulsi3_highpart"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (truncate:SI
+        (lshiftrt:DI
+         (mult:DI (zero_extend:DI
+                   (match_operand:SI 1 "nonimmediate_operand" ""))
+                  (zero_extend:DI
+                   (match_operand:SI 2 "register_operand" "")))
+         (const_int 32))))]
+  ""
+{
+  rtx umulsi3_highpart_libfunc
+    = init_one_libfunc ("__umulsi3_highpart");
+
+  emit_library_call_value (umulsi3_highpart_libfunc,
+			   operands[0], LCT_NORMAL, SImode,
+			   2, operands[1], SImode, operands[2], SImode);
+  DONE;
+})
+
+(define_expand "smulsi3_highpart"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (truncate:SI
+        (lshiftrt:DI
+         (mult:DI (sign_extend:DI
+                   (match_operand:SI 1 "nonimmediate_operand" ""))
+                  (sign_extend:DI
+                   (match_operand:SI 2 "register_operand" "")))
+         (const_int 32))))]
+  ""
+{
+  rtx smulsi3_highpart_libfunc
+    = init_one_libfunc ("__smulsi3_highpart");
+
+  emit_library_call_value (smulsi3_highpart_libfunc,
+			   operands[0], LCT_NORMAL, SImode,
+			   2, operands[1], SImode, operands[2], SImode);
+  DONE;
+})
+
 (define_expand "ashlsi3"
   [(set (match_operand:SI 0 "register_operand" "")
         (ashift:SI (match_operand:SI 1 "register_operand" "")
Index: config/bfin/t-bfin-elf
===================================================================
--- config/bfin/t-bfin-elf	(revision 122331)
+++ config/bfin/t-bfin-elf	(working copy)
@@ -1,7 +1,8 @@
 ## Target part of the Makefile
 
 LIB1ASMSRC = bfin/lib1funcs.asm
-LIB1ASMFUNCS = _divsi3 _udivsi3 _umodsi3 _modsi3
+LIB1ASMFUNCS = _divsi3 _udivsi3 _umodsi3 _modsi3 _umulsi3_highpart
+LIB1ASMFUNCS += _smulsi3_highpart
 
 EXTRA_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o crtlibid.o
 

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