aboutsummaryrefslogtreecommitdiff
path: root/libgcc/config/avr
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2023-10-18 18:59:17 +0200
committerGeorg-Johann Lay <avr@gjlay.de>2023-10-18 19:00:09 +0200
commit67f7bf78ba3bea2c4efe87589714d57ccb1d8f93 (patch)
treeb46ef4056fcbed937d1332b8d1e6ad5a8be456b9 /libgcc/config/avr
parentff05a3e91ddac56acd23db107a9a44f246aeb8b1 (diff)
downloadgcc-67f7bf78ba3bea2c4efe87589714d57ccb1d8f93.zip
gcc-67f7bf78ba3bea2c4efe87589714d57ccb1d8f93.tar.gz
gcc-67f7bf78ba3bea2c4efe87589714d57ccb1d8f93.tar.bz2
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.
Diffstat (limited to 'libgcc/config/avr')
-rw-r--r--libgcc/config/avr/libf7/asm-defs.h6
-rw-r--r--libgcc/config/avr/libf7/libf7-asm.sx94
-rw-r--r--libgcc/config/avr/libf7/t-libf72
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 4cfd3e6..a50260a 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 5df167f..4505764 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 30aa280..f17e67e8 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