diff options
Diffstat (limited to 'libgcc/config/avr')
-rw-r--r-- | libgcc/config/avr/lib1funcs-fixed.S | 66 | ||||
-rw-r--r-- | libgcc/config/avr/lib1funcs.S | 45 | ||||
-rw-r--r-- | libgcc/config/avr/t-avr | 32 |
3 files changed, 91 insertions, 52 deletions
diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S index 278ee1b..4115589 100644 --- a/libgcc/config/avr/lib1funcs-fixed.S +++ b/libgcc/config/avr/lib1funcs-fixed.S @@ -31,14 +31,6 @@ ;; Fixed point library routines for AVR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -#if defined __AVR_TINY__ -#define __zero_reg__ r17 -#define __tmp_reg__ r16 -#else -#define __zero_reg__ r1 -#define __tmp_reg__ r0 -#endif - .section .text.libgcc.fixed, "ax", @progbits #ifndef __AVR_TINY__ @@ -251,6 +243,7 @@ DEFUN __fractsfusa ENDF __fractsfusa #endif /* L_fractsfusa */ +#endif /* ! AVR_TINY */ ;; For multiplication the functions here are called directly from ;; avr-fixed.md instead of using the standard libcall mechanisms. @@ -295,8 +288,14 @@ DEFUN __mulhq3 rol r25 brvs 1f ;; Round +#ifndef __AVR_TINY__ sbrc r23, 7 adiw r24, 1 +#else + lsl r23 + adc r24, __zero_reg__ + adc r25, __zero_reg__ +#endif /* AVR_TINY? */ ret 1: ;; Overflow. TR 18037 requires (-1)^2 not to overflow ldi r24, lo8 (0x7fff) @@ -315,8 +314,14 @@ ENDF __mulhq3 DEFUN __muluhq3 XCALL __umulhisi3 ;; Round +#ifndef __AVR_TINY__ sbrc r23, 7 adiw r24, 1 +#else + lsl r23 + adc r24, __zero_reg__ + adc r25, __zero_reg__ +#endif /* AVR_TINY? */ ret ENDF __muluhq3 #endif /* L_muluhq3 */ @@ -361,8 +366,14 @@ DEFUN __muluha3_round mov r25, r24 mov r24, r23 ;; Round +#ifndef __AVR_TINY__ sbrc r22, 7 adiw r24, 1 +#else + lsl r22 + adc r24, __zero_reg__ + adc r25, __zero_reg__ +#endif /* AVR_TINY? */ ret ENDF __muluha3_round #endif /* L_muluha3_round */ @@ -372,6 +383,8 @@ ENDF __muluha3_round Fixed Multiplication 16.16 x 16.16 *******************************************************/ +#ifndef __AVR_TINY__ + ;; Bits outside the result (below LSB), used in the signed version #define GUARD __tmp_reg__ @@ -679,6 +692,8 @@ ENDF __mulusa3_round #undef GUARD +#endif /* ! AVR_TINY */ + /*********************************************************** Fixed unsigned saturated Multiplication 8.8 x 8.8 ***********************************************************/ @@ -762,8 +777,14 @@ DEFUN __ssmulha3 ;; SS = 0 --> 0x7fff ldi C3, 0x7f ldi C2, 0xff +#ifndef __AVR_TINY__ sbrc SS, 7 adiw C2, 1 +#else + lsl SS + adc C2, __zero_reg__ + adc C3, __zero_reg__ +#endif /* AVR_TINY? */ ret ENDF __ssmulha3 #endif /* L_ssmulha3 */ @@ -778,6 +799,8 @@ ENDF __ssmulha3 Fixed unsigned saturated Multiplication 16.16 x 16.16 ***********************************************************/ +#ifndef __AVR_TINY__ + #define C0 18 #define C1 C0+1 #define C2 C0+2 @@ -883,6 +906,8 @@ ENDF __ssmulsa3 #undef C7 #undef SS +#endif /* ! AVR_TINY */ + /******************************************************* Fractional Division 8 / 8 *******************************************************/ @@ -962,8 +987,8 @@ ENDF __divqq_helper #if defined (L_divhq3) DEFUN __divhq3 - mov r0, r_divdH - eor r0, r_divH + mov __tmp_reg__, r_divdH + eor __tmp_reg__, r_divH sbrs r_divH, 7 rjmp 1f NEG2 r_divL @@ -1027,8 +1052,8 @@ ENDF __udivuha3_common *******************************************************/ #if defined (L_divha3) DEFUN __divha3 - mov r0, r_divdH - eor r0, r_divH + mov __tmp_reg__, r_divdH + eor __tmp_reg__, r_divH sbrs r_divH, 7 rjmp 1f NEG2 r_divL @@ -1040,7 +1065,7 @@ DEFUN __divha3 XCALL __udivuha3 lsr r_quoH ; adjust to 7 fractional bits ror r_quoL - sbrs r0, 7 ; negate result if needed + sbrs __tmp_reg__, 7 ; negate result if needed ret NEG2 r_quoL ret @@ -1069,6 +1094,8 @@ ENDF __udivuha3 Fixed Division 16.16 / 16.16 *******************************************************/ +#ifndef __AVR_TINY__ + #define r_arg1L 24 /* arg1 gets passed already in place */ #define r_arg1H 25 #define r_arg1HL 26 @@ -1171,6 +1198,8 @@ ENDF __udivusa3 #undef r_divHH #undef r_cnt +#endif /* ! AVR_TINY */ + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Saturation, 1 Byte @@ -1206,7 +1235,7 @@ ENDF __ssabs_1 DEFUN __ssneg_2 NEG2 A0 brvc 0f - sbiw A0, 1 + wsubi A0, 1 0: ret ENDF __ssneg_2 #endif /* L_ssneg_2 */ @@ -1228,6 +1257,8 @@ ENDF __ssabs_2 ;; Saturation, 4 Bytes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#ifndef __AVR_TINY__ + ;; First Argument and Return Register #define A0 22 #define A1 A0+1 @@ -1413,6 +1444,8 @@ ENDF __sssub_8 #undef B6 #undef B7 +#endif /* ! AVR_TINY */ + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Rounding Helpers @@ -1613,6 +1646,8 @@ ENDF __round_u2_const ;; Rounding, 4 Bytes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#ifndef __AVR_TINY__ + #define A0 18 #define A1 A0 + 1 #define A2 A0 + 2 @@ -1915,6 +1950,7 @@ ENDF __round_x8 #undef RP #undef FBITm1 +#endif /* ! AVR_TINY */ ;; Supply implementations / symbols for the bit-banging functions ;; __builtin_avr_bitsfx and __builtin_avr_fxbits @@ -1923,5 +1959,3 @@ DEFUN __ret ret ENDF __ret #endif /* L_ret */ - -#endif /* if not __AVR_TINY__ */ diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S index 96f20ca..dfe99b1 100644 --- a/libgcc/config/avr/lib1funcs.S +++ b/libgcc/config/avr/lib1funcs.S @@ -395,45 +395,57 @@ ENDF __mulhi3 #if defined (L_umulhisi3) DEFUN __umulhisi3 +#ifdef __AVR_TINY__ + ;; Save callee saved regs. + push B0 + push B1 +#endif /* AVR_TINY */ wmov B0, 24 ;; Zero-extend B clr B2 clr B3 ;; Zero-extend A wmov A2, B2 +#ifdef __AVR_TINY__ + ;; Clear hi16 of the result so we can use __mulsi3_helper. + wmov CC2, B2 + XJMP __mulsi3_helper +#else XJMP __mulsi3 +#endif /* AVR_TINY? */ ENDF __umulhisi3 #endif /* L_umulhisi3 */ #if defined (L_mulhisi3) DEFUN __mulhisi3 +#ifdef __AVR_TINY__ + ;; Save callee saved regs. + push B0 + push B1 +#endif /* AVR_TINY */ wmov B0, 24 ;; Sign-extend B lsl r25 sbc B2, B2 mov B3, B2 -#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ - ;; Sign-extend A - clr A2 - sbrc A1, 7 - com A2 - mov A3, A2 - XJMP __mulsi3 -#else /* no __AVR_ERRATA_SKIP_JMP_CALL__ */ ;; Zero-extend A and __mulsi3 will run at least twice as fast ;; compared to a sign-extended A. clr A2 clr A3 + ;; Clear hi16 of the result so we can use __mulsi3_helper. + wmov CC2, A2 sbrs A1, 7 - XJMP __mulsi3 +#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ + rjmp 1f +#else + XJMP __mulsi3_helper +#endif /* ERRATA_SKIP */ ;; If A < 0 then perform the B * 0xffff.... before the ;; very multiplication by initializing the high part of the ;; result CC with -B. - wmov CC2, A2 sub CC2, B0 sbc CC3, B1 - XJMP __mulsi3_helper -#endif /* __AVR_ERRATA_SKIP_JMP_CALL__ */ +1: XJMP __mulsi3_helper ENDF __mulhisi3 #endif /* L_mulhisi3 */ @@ -581,19 +593,12 @@ DEFUN __umulhisi3 mul A1, B1 movw C2, r0 mul A0, B1 -#ifdef __AVR_HAVE_JMP_CALL__ - ;; This function is used by many other routines, often multiple times. - ;; Therefore, if the flash size is not too limited, avoid the RCALL - ;; and inverst 6 Bytes to speed things up. add C1, r0 adc C2, r1 clr __zero_reg__ adc C3, __zero_reg__ -#else - rcall 1f -#endif mul A1, B0 -1: add C1, r0 + add C1, r0 adc C2, r1 clr __zero_reg__ adc C3, __zero_reg__ diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index b10542c..d181784 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -4,6 +4,7 @@ LIB1ASMFUNCS = \ _mulhi3 \ _mulqihi3 _umulqihi3 \ _mulpsi3 \ + _mulhisi3 _umulhisi3 \ _mulsi3 \ _udivmodqi4 \ _divmodqi4 \ @@ -33,12 +34,23 @@ LIB1ASMFUNCS = \ _popcountsi2 \ _popcountqi2 \ _bswapsi2 \ - _fmul _fmuls _fmulsu + _fmul _fmuls _fmulsu \ + _mulqq3 \ + _mulhq3 _muluhq3 \ + _mulha3 _muluha3 _muluha3_round \ + _usmuluha3 _ssmulha3 \ + _divqq3 _udivuqq3 _divqq_helper \ + _divhq3 _udivuhq3 \ + _divha3 _udivuha3 \ + _ssneg_2 \ + _ssabs_1 _ssabs_2 \ + _mask1 _ret \ + _roundqq3 _rounduqq3 \ + _round_s2 _round_u2 _round_2_const _addmask_2 \ # The below functions either use registers that are not present # in tiny core, or use a different register convention (don't save # callee saved regs, for example) -# _mulhisi3 and variations - clobber R18, R19 # All *di funcs - use regs < R16 or expect args in regs < R20 # _prologue and _epilogue save registers < R16 # _load, __fload and _xload variations - expect lpm and elpm support @@ -46,8 +58,6 @@ LIB1ASMFUNCS = \ FUNCS_notiny = \ _mulsqipsi3 \ - _mulhisi3 \ - _umulhisi3 \ _usmulhisi3 \ _muluhisi3 \ _mulshisi3 \ @@ -81,24 +91,14 @@ FUNCS_notiny += \ _fractsfqq _fractsfuqq \ _fractsfhq _fractsfuhq _fractsfha _fractsfuha \ _fractsfsq _fractsfusq _fractsfsa _fractsfusa \ - _mulqq3 \ - _mulhq3 _muluhq3 \ - _mulha3 _muluha3 _muluha3_round \ _mulsa3 _mulusa3 \ - _usmuluha3 _ssmulha3 \ _usmulusa3 _ssmulsa3 \ - _divqq3 _udivuqq3 _divqq_helper \ - _divhq3 _udivuhq3 \ - _divha3 _udivuha3 \ _divsa3 _udivusa3 \ _clr_8 \ - _ssneg_2 _ssneg_4 _ssneg_8 \ - _ssabs_1 _ssabs_2 _ssabs_4 _ssabs_8 \ + _ssneg_4 _ssneg_8 \ + _ssabs_4 _ssabs_8 \ _ssadd_8 _sssub_8 \ _usadd_8 _ussub_8 \ - _mask1 _ret \ - _roundqq3 _rounduqq3 \ - _round_s2 _round_u2 _round_2_const _addmask_2 \ _round_s4 _round_u4 _round_4_const _addmask_4 \ _round_x8 \ _rounddq3 _roundudq3 \ |