public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4724] LibF7: Implement mul_mant for devices without MUL instruction.
@ 2023-10-18 17:00 Georg-Johann Lay
  0 siblings, 0 replies; only message in thread
From: Georg-Johann Lay @ 2023-10-18 17:00 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:67f7bf78ba3bea2c4efe87589714d57ccb1d8f93

commit r14-4724-g67f7bf78ba3bea2c4efe87589714d57ccb1d8f93
Author: Georg-Johann Lay <avr@gjlay.de>
Date:   Wed Oct 18 18:59:17 2023 +0200

    LibF7: Implement mul_mant for devices without MUL instruction.
    
    libgcc/config/avr/libf7/
            * libf7-asm.sx (mul_mant): Implement for devices without MUL.
            * asm-defs.h (wmov) [!HAVE_MUL]: Fix regno computation.
            * t-libf7 (F7_ASM_FLAGS): Add -g0.

Diff:
---
 libgcc/config/avr/libf7/asm-defs.h   |  6 +--
 libgcc/config/avr/libf7/libf7-asm.sx | 94 ++++++++++++++++++++++++++++++++++++
 libgcc/config/avr/libf7/t-libf7      |  2 +-
 3 files changed, 98 insertions(+), 4 deletions(-)

diff --git a/libgcc/config/avr/libf7/asm-defs.h b/libgcc/config/avr/libf7/asm-defs.h
index 4cfd3e61cbb8..a50260a162f2 100644
--- a/libgcc/config/avr/libf7/asm-defs.h
+++ b/libgcc/config/avr/libf7/asm-defs.h
@@ -134,14 +134,14 @@
     ..regno = 0
 
     .irp    reg,                        \
-            X, x, XL, xl, Xl, xL, x, x  \
+            X, x, XL, xl, Xl, xL, x, x, \
             Y, y, YL, yl, Yl, yL, y, y, \
             Z, z, ZL, zl, Zl, zL, z, z
         .ifc  \reg,\dst
-            ..dst = (..regno / 8) + 26
+            ..dst = 2 * (..regno / 8) + 26
         .endif
         .ifc  \reg,\src
-            ..src = (..regno / 8) + 26
+            ..src = 2 * (..regno / 8) + 26
         .endif
         ..regno = ..regno + 1
     .endr
diff --git a/libgcc/config/avr/libf7/libf7-asm.sx b/libgcc/config/avr/libf7/libf7-asm.sx
index 5df167fe73cc..4505764c1263 100644
--- a/libgcc/config/avr/libf7/libf7-asm.sx
+++ b/libgcc/config/avr/libf7/libf7-asm.sx
@@ -1067,6 +1067,100 @@ DEFUN mul_mant
 ENDF mul_mant
 #endif /* F7MOD_mul_mant_ && MUL */
 
+#if defined F7MOD_mul_mant_ && ! defined (__AVR_HAVE_MUL__)
+    #define     AA      TMP
+    #define     A0      13
+    #define     A1      A0+1
+    #define     A2      A0+2
+    #define     A3      A0+3
+    #define     A4      A0+4
+    #define     A5      r26
+    #define     A6      r27
+    #define     BB      ZERO
+    #define     Bits    r29
+    #define     Bytes   r28
+
+DEFUN mul_mant
+    do_prologue_saves 7
+    bst     r18,    0           ; T = 1: Don't round.
+    ;; Save result address for later.
+    push    r25
+    push    r24
+    ;; Load 1st operand mantissa.
+    wmov    r30,    r22
+    clr     AA
+    LDD     A0,     Z+0+Off
+    LDD     A1,     Z+1+Off
+    LDD     A2,     Z+2+Off
+    LDD     A3,     Z+3+Off
+    LDD     A4,     Z+4+Off
+    LDD     A5,     Z+5+Off
+    LDD     A6,     Z+6+Off
+    ;; Let Z point one past .mant of the 2nd input operand.
+    wmov    r30,    r20
+    adiw    r30,    Expo
+
+    ;; Clear the result mantissa.
+    .global __clr_8
+    XCALL   __clr_8
+
+    ;; Loop over the bytes of B's mantissa from highest to lowest.
+    ;; "+1" because we jump into the loop.
+    ldi     Bytes,  1 + F7_MANT_BYTES
+
+    ;; Divide one operand by 2 so that the result mantissa won't overflow.
+    ;; This is accounted for by "Carry = 1" below.
+    ldi     Bits,   1
+    rjmp    .Loop_entry
+
+.Loop_bytes:
+    ld      BB,     -Z
+    ;;  Loop over the bits of B's mantissa from highest to lowest.
+    ldi     Bits,   8
+.Loop_bits:
+    lsl     BB
+    brcc    .Lnext_bit
+
+    ADD     CA,     AA
+    adc     C0,     A0
+    adc     C1,     A1
+    adc     C2,     A2
+    adc     C3,     A3
+    adc     C4,     A4
+    adc     C5,     A5
+    adc     C6,     A6
+
+.Lnext_bit:
+.Loop_entry:
+    LSR     A6
+    ror     A5
+    ror     A4
+    ror     A3
+    ror     A2
+    ror     A1
+    ror     A0
+    ror     AA
+
+    dec     Bits
+    brne    .Loop_bits
+
+    dec     Bytes
+    brne    .Loop_bytes
+
+    ;; Finally...
+
+    pop     ZL
+    pop     ZH
+
+    ;; The result has to be left-shifted by one (multiplied by 2) in order
+    ;; to undo the division by 2 of the 1st operand.
+    ldi     Carry,  1
+    F7call  normalize.maybe_round.store_with_flags
+
+    do_epilogue_restores 7
+ENDF mul_mant
+#endif /* F7MOD_mul_mant_ && ! MUL */
+
 
 #if defined (F7MOD_div_)
 
diff --git a/libgcc/config/avr/libf7/t-libf7 b/libgcc/config/avr/libf7/t-libf7
index 30aa280d11e3..f17e67e8523a 100644
--- a/libgcc/config/avr/libf7/t-libf7
+++ b/libgcc/config/avr/libf7/t-libf7
@@ -86,7 +86,7 @@ F7_C_FLAGS +=   $(F7_FLAGS) \
 		-fno-tree-loop-optimize \
 		-fno-tree-loop-im -fno-move-loop-invariants
 
-F7_ASM_FLAGS +=	$(F7_FLAGS)
+F7_ASM_FLAGS +=	$(F7_FLAGS) -g0
 
 $(patsubst %, f7_c_%.o, $(CALL_PROLOGUES)) \
 	: F7_C_FLAGS += -mcall-prologues

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-10-18 17:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-18 17:00 [gcc r14-4724] LibF7: Implement mul_mant for devices without MUL instruction Georg-Johann Lay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).