aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2007-02-27 16:29:10 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2007-02-27 16:29:10 +0000
commit01e7cd6e292e62d5b21500deb06cc11843ec4be0 (patch)
treed7942867a7a528c2779000682e2dc22e64edd183 /gcc/config
parentf6fc5c864bf5b85e668042d2e7bdd3f9a496fde5 (diff)
downloadgcc-01e7cd6e292e62d5b21500deb06cc11843ec4be0.zip
gcc-01e7cd6e292e62d5b21500deb06cc11843ec4be0.tar.gz
gcc-01e7cd6e292e62d5b21500deb06cc11843ec4be0.tar.bz2
t-bfin-elf (LIB1ASMFUNCS): Add _umulsi3_highpart and _smulsi3_highpart.
* 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. From-SVN: r122379
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/bfin/bfin.md40
-rw-r--r--gcc/config/bfin/lib1funcs.asm47
-rw-r--r--gcc/config/bfin/t-bfin-elf3
3 files changed, 89 insertions, 1 deletions
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index b65e8dd..fd55f4f 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -1436,6 +1436,46 @@
"%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" "")
diff --git a/gcc/config/bfin/lib1funcs.asm b/gcc/config/bfin/lib1funcs.asm
index 77d4fff..1d2db9b 100644
--- a/gcc/config/bfin/lib1funcs.asm
+++ b/gcc/config/bfin/lib1funcs.asm
@@ -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
+
diff --git a/gcc/config/bfin/t-bfin-elf b/gcc/config/bfin/t-bfin-elf
index 06aa0ae..1d9fce6 100644
--- a/gcc/config/bfin/t-bfin-elf
+++ b/gcc/config/bfin/t-bfin-elf
@@ -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