summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-14 10:00:56 +0000
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-14 10:00:56 +0000
commitfa0431fadad26c96f0b895eaf974ffea34e1f20f (patch)
treeda23e4e79b412c8171d2375bf3121ad99e702e08 /libgcc
parentb03f58fac017e8ad5640d9b80ac9a23b52cffba2 (diff)
downloadgcc-fa0431fadad26c96f0b895eaf974ffea34e1f20f.tar.gz
libgcc/
PR target/50931 * config/avr/t-avr (LIB1ASMSRC): Add _mulpsi3, _mulsqipsi3. * config/avr/lib1funcs.S (__mulpsi3, __mulsqipsi3): New functions. gcc/ PR target/50931 * config/avr/avr.md (mulpsi3): New expander. (*umulqihipsi3, *umulhiqipsi3): New insns. (*mulsqipsi3.libgcc, *mulpsi3.libgcc): New insns. (mulsqipsi3, *mulpsi3): New insn-and-splits. (ashlpsi3): Turn to expander. Move insn code to... (*ashlpsi3): ...this new insn. testsuite/ PR target/50931 * gcc.target/avr/torture/int24-mul.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182328 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/config/avr/lib1funcs.S149
-rw-r--r--libgcc/config/avr/t-avr1
3 files changed, 155 insertions, 1 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 5122e9f1af4..ce2df4acd32 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-12-14 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/49313
+ * config/avr/t-avr (LIB1ASMSRC): Add _mulpsi3, _mulsqipsi3.
+ * config/avr/lib1funcs.S (__mulpsi3, __mulsqipsi3): New functions.
+
2011-12-11 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sol2-unwind.h: Use #ifdef directive consistently.
diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S
index 07490fbb20a..bc16cf28207 100644
--- a/libgcc/config/avr/lib1funcs.S
+++ b/libgcc/config/avr/lib1funcs.S
@@ -466,6 +466,153 @@ ENDF __mulsi3
#endif /* __AVR_HAVE_MUL__ */
/*******************************************************
+ Multiplication 24 x 24
+*******************************************************/
+
+#if defined (L_mulpsi3)
+
+;; A[0..2]: In: Multiplicand; Out: Product
+#define A0 22
+#define A1 A0+1
+#define A2 A0+2
+
+;; B[0..2]: In: Multiplier
+#define B0 18
+#define B1 B0+1
+#define B2 B0+2
+
+#if defined (__AVR_HAVE_MUL__)
+
+;; C[0..2]: Expand Result
+#define C0 22
+#define C1 C0+1
+#define C2 C0+2
+
+;; R24:R22 *= R20:R18
+;; Clobbers: r21, r25, r26, r27, __tmp_reg__
+
+#define AA0 26
+#define AA2 21
+
+DEFUN __mulpsi3
+ wmov AA0, A0
+ mov AA2, A2
+ XCALL __umulhisi3
+ mul AA2, B0 $ add C2, r0
+ mul AA0, B2 $ add C2, r0
+ clr __zero_reg__
+ ret
+ENDF __mulpsi3
+
+#undef AA2
+#undef AA0
+
+#undef C2
+#undef C1
+#undef C0
+
+#else /* !HAVE_MUL */
+
+;; C[0..2]: Expand Result
+#define C0 0
+#define C1 C0+1
+#define C2 21
+
+;; R24:R22 *= R20:R18
+;; Clobbers: __tmp_reg__, R18, R19, R20, R21
+
+DEFUN __mulpsi3
+
+ ;; C[] = 0
+ clr __tmp_reg__
+ clr C2
+
+0: ;; Shift N-th Bit of B[] into Carry. N = 24 - Loop
+ LSR B2 $ ror B1 $ ror B0
+
+ ;; If the N-th Bit of B[] was set...
+ brcc 1f
+
+ ;; ...then add A[] * 2^N to the Result C[]
+ ADD C0,A0 $ adc C1,A1 $ adc C2,A2
+
+1: ;; Multiply A[] by 2
+ LSL A0 $ rol A1 $ rol A2
+
+ ;; Loop until B[] is 0
+ subi B0,0 $ sbci B1,0 $ sbci B2,0
+ brne 0b
+
+ ;; Copy C[] to the return Register A[]
+ wmov A0, C0
+ mov A2, C2
+
+ clr __zero_reg__
+ ret
+ENDF __mulpsi3
+
+#undef C2
+#undef C1
+#undef C0
+
+#endif /* HAVE_MUL */
+
+#undef B2
+#undef B1
+#undef B0
+
+#undef A2
+#undef A1
+#undef A0
+
+#endif /* L_mulpsi3 */
+
+#if defined (L_mulsqipsi3) && defined (__AVR_HAVE_MUL__)
+
+;; A[0..2]: In: Multiplicand
+#define A0 22
+#define A1 A0+1
+#define A2 A0+2
+
+;; BB: In: Multiplier
+#define BB 25
+
+;; C[0..2]: Result
+#define C0 18
+#define C1 C0+1
+#define C2 C0+2
+
+;; C[] = A[] * sign_extend (BB)
+DEFUN __mulsqipsi3
+ mul A0, BB
+ movw C0, r0
+ mul A2, BB
+ mov C2, r0
+ mul A1, BB
+ add C1, r0
+ adc C2, r1
+ clr __zero_reg__
+ sbrs BB, 7
+ ret
+ ;; One-extend BB
+ sub C1, A0
+ sbc C2, A1
+ ret
+ENDF __mulsqipsi3
+
+#undef C2
+#undef C1
+#undef C0
+
+#undef BB
+
+#undef A2
+#undef A1
+#undef A0
+
+#endif /* L_mulsqipsi3 && HAVE_MUL */
+
+/*******************************************************
Multiplication 64 x 64
*******************************************************/
@@ -1342,7 +1489,7 @@ DEFUN __divdi3_moddi3
#endif /* SPEED_DIV */
0: ;; The Prologue
- ;; Save Z = 12 Registers: Y, 17...8
+ ;; Save 12 Registers: Y, 17...8
;; No Frame needed (X = 0)
clr r26
clr r27
diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr
index c6806dc0ece..7d7dc9ef33b 100644
--- a/libgcc/config/avr/t-avr
+++ b/libgcc/config/avr/t-avr
@@ -2,6 +2,7 @@ LIB1ASMSRC = avr/lib1funcs.S
LIB1ASMFUNCS = \
_mulqi3 \
_mulhi3 \
+ _mulpsi3 _mulsqipsi3 \
_mulhisi3 \
_umulhisi3 \
_usmulhisi3 \