aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.6/gcc/config/arc/lib1funcs.asm
diff options
context:
space:
mode:
authorJing Yu <jingyu@google.com>2011-12-19 16:56:54 -0800
committerJing Yu <jingyu@google.com>2011-12-19 16:56:54 -0800
commit40d7cd0fd78fe2004e2a53c4618c148339b02733 (patch)
tree5874557a6c86a1f564a03e5f28b266e31bc3759c /gcc-4.6/gcc/config/arc/lib1funcs.asm
parentfe2afdf3f3701489c05d2a7509752d6f0c7616f7 (diff)
downloadtoolchain_gcc-40d7cd0fd78fe2004e2a53c4618c148339b02733.tar.gz
toolchain_gcc-40d7cd0fd78fe2004e2a53c4618c148339b02733.tar.bz2
toolchain_gcc-40d7cd0fd78fe2004e2a53c4618c148339b02733.zip
Add gcc-4.6. Synced to @180989
Change-Id: Ie3676586e1d8e3c8cd9f07d022f450d05fa08439 svn://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6-mobile
Diffstat (limited to 'gcc-4.6/gcc/config/arc/lib1funcs.asm')
-rw-r--r--gcc-4.6/gcc/config/arc/lib1funcs.asm266
1 files changed, 266 insertions, 0 deletions
diff --git a/gcc-4.6/gcc/config/arc/lib1funcs.asm b/gcc-4.6/gcc/config/arc/lib1funcs.asm
new file mode 100644
index 000000000..c61f39a5c
--- /dev/null
+++ b/gcc-4.6/gcc/config/arc/lib1funcs.asm
@@ -0,0 +1,266 @@
+; libgcc routines for ARC cpu.
+
+/* Copyright (C) 1995, 1997,2004, 2009 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#ifdef L_mulsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___mulsi3
+___mulsi3:
+
+/* This the simple version.
+
+ while (a)
+ {
+ if (a & 1)
+ r += b;
+ a >>= 1;
+ b <<= 1;
+ }
+*/
+ mov r2,0 ; Accumulate result here.
+.Lloop:
+ sub.f 0,r0,0 ; while (a)
+ nop
+ beq.nd .Ldone
+ and.f 0,r0,1 ; if (a & 1)
+ add.nz r2,r2,r1 ; r += b
+ lsr r0,r0 ; a >>= 1
+ b.d .Lloop
+ lsl r1,r1 ; b <<= 1
+.Ldone:
+ j.d blink
+ mov r0,r2
+#endif
+
+#endif /* L_mulsi3 */
+
+#ifdef L_umulsidi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___umulsidi3
+___umulsidi3:
+
+/* This the simple version.
+
+ while (a)
+ {
+ if (a & 1)
+ r += b;
+ a >>= 1;
+ b <<= 1;
+ }
+*/
+ mov r2,0 ; Top part of b.
+ mov r3,0 ; Accumulate result here.
+ mov r4,0
+.Lloop:
+ sub.f 0,r0,0 ; while (a)
+ nop
+ beq.nd .Ldone
+ and.f 0,r0,1 ; if (a & 1)
+ sub.f 0,r0,0
+ nop
+ beq .Ldontadd
+ add.f r4,r4,r1 ; r += b
+ adc r3,r3,r2
+.Ldontadd:
+ lsr r0,r0 ; a >>= 1
+ lsl.f r1,r1 ; b <<= 1
+ b.d .Lloop
+ rlc r2,r2
+.Ldone:
+#ifdef __big_endian__
+ mov r1,r4
+ j.d blink
+ mov r0,r3
+#else
+ mov r0,r4
+ j.d blink
+ mov r1,r3
+#endif
+#endif
+
+#endif /* L_umulsidi3 */
+
+#ifdef L_divmod_tools
+
+; Utilities used by all routines.
+
+ .section .text
+ .align 4
+
+; inputs: r0 = numerator, r1 = denominator
+; outputs: positive r0/r1,
+; r6.bit1 = sign of numerator, r6.bit0 = sign of result
+
+ .global ___divnorm
+___divnorm:
+ mov r6,0 ; keep sign in r6
+ sub.f 0,r0,0 ; is numerator -ve?
+ sub.lt r0,0,r0 ; negate numerator
+ mov.lt r6,3 ; sign is -ve
+ sub.f 0,r1,0 ; is denominator -ve?
+ sub.lt r1,0,r1 ; negate denominator
+ xor.lt r6,r6,1 ; toggle sign
+ j.nd blink
+
+/*
+unsigned long
+udivmodsi4(int modwanted, unsigned long num, unsigned long den)
+{
+ unsigned long bit = 1;
+ unsigned long res = 0;
+
+ while (den < num && bit && !(den & (1L<<31)))
+ {
+ den <<=1;
+ bit <<=1;
+ }
+ while (bit)
+ {
+ if (num >= den)
+ {
+ num -= den;
+ res |= bit;
+ }
+ bit >>=1;
+ den >>=1;
+ }
+ if (modwanted) return num;
+ return res;
+}
+*/
+
+; inputs: r0 = numerator, r1 = denominator
+; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed
+
+ .global ___udivmodsi4
+___udivmodsi4:
+ mov r2,1 ; bit = 1
+ mov r3,0 ; res = 0
+.Lloop1:
+ sub.f 0,r1,r0 ; while (den < num
+ nop
+ bnc.nd .Lloop2
+ sub.f 0,r2,0 ; && bit
+ nop
+ bz.nd .Lloop2
+ lsl.f 0,r1 ; && !(den & (1<<31))
+ nop
+ bc.nd .Lloop2
+ lsl r1,r1 ; den <<= 1
+ b.d .Lloop1
+ lsl r2,r2 ; bit <<= 1
+.Lloop2:
+ sub.f 0,r2,0 ; while (bit)
+ nop
+ bz.nd .Ldivmodend
+ sub.f 0,r0,r1 ; if (num >= den)
+ nop
+ bc.nd .Lshiftdown
+ sub r0,r0,r1 ; num -= den
+ or r3,r3,r2 ; res |= bit
+.Lshiftdown:
+ lsr r2,r2 ; bit >>= 1
+ b.d .Lloop2
+ lsr r1,r1 ; den >>= 1
+.Ldivmodend:
+ mov r1,r0 ; r1 = mod
+ j.d blink
+ mov r0,r3 ; r0 = res
+
+#endif
+
+#ifdef L_udivsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___udivsi3
+___udivsi3:
+ mov r7,blink
+ bl.nd ___udivmodsi4
+ j.nd r7
+#endif
+
+#endif /* L_udivsi3 */
+
+#ifdef L_divsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___divsi3
+___divsi3:
+ mov r7,blink
+ bl.nd ___divnorm
+ bl.nd ___udivmodsi4
+ and.f 0,r6,1
+ sub.nz r0,0,r0 ; cannot go in delay slot, has limm value
+ j.nd r7
+#endif
+
+#endif /* L_divsi3 */
+
+#ifdef L_umodsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___umodsi3
+___umodsi3:
+ mov r7,blink
+ bl.nd ___udivmodsi4
+ j.d r7
+ mov r0,r1
+#endif
+
+#endif /* L_umodsi3 */
+
+#ifdef L_modsi3
+ .section .text
+ .align 4
+
+#ifdef __base__
+ .cpu base
+ .global ___modsi3
+___modsi3:
+ mov r7,blink
+ bl.nd ___divnorm
+ bl.nd ___udivmodsi4
+ and.f 0,r6,2
+ sub.nz r1,0,r1
+ j.d r7
+ mov r0,r1
+#endif
+
+#endif /* L_modsi3 */