mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
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.
This commit is contained in:
parent
ff05a3e91d
commit
67f7bf78ba
@ -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
|
||||
|
@ -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_)
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user