diff options
Diffstat (limited to 'libgcc/config')
-rw-r--r-- | libgcc/config/avr/lib1funcs-fixed.S | 224 | ||||
-rw-r--r-- | libgcc/config/avr/lib1funcs.S | 41 | ||||
-rw-r--r-- | libgcc/config/avr/t-avr | 24 |
3 files changed, 273 insertions, 16 deletions
diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S index c1aff53d5fd..ddcd02e197c 100644 --- a/libgcc/config/avr/lib1funcs-fixed.S +++ b/libgcc/config/avr/lib1funcs-fixed.S @@ -808,8 +808,8 @@ DEFUN __divsa3 XCALL __udivusa3 sbrs r0, 7 ; negate result if needed ret - NEG4 r_quoL - ret + ;; negate r_quoL + XJMP __negsi2 ENDF __divsa3 #endif /* defined (L_divsa3) */ @@ -872,3 +872,223 @@ ENDF __udivusa3 #undef r_divHL #undef r_divHH #undef r_cnt + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Saturation, 2 Bytes +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; First Argument and Return Register +#define A0 24 +#define A1 A0+1 + +#if defined (L_ssneg_2) +DEFUN __ssneg_2 + NEG2 A0 + brvc 0f + sbiw A0, 1 +0: ret +ENDF __ssneg_2 +#endif /* L_ssneg_2 */ + +#if defined (L_ssabs_2) +DEFUN __ssabs_2 + sbrs A1, 7 + ret + XJMP __ssneg_2 +ENDF __ssabs_2 +#endif /* L_ssabs_2 */ + +#undef A0 +#undef A1 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Saturation, 4 Bytes +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; First Argument and Return Register +#define A0 22 +#define A1 A0+1 +#define A2 A0+2 +#define A3 A0+3 + +#if defined (L_ssneg_4) +DEFUN __ssneg_4 + XCALL __negsi2 + brvc 0f + ldi A3, 0x7f + ldi A2, 0xff + ldi A1, 0xff + ldi A0, 0xff +0: ret +ENDF __ssneg_4 +#endif /* L_ssneg_4 */ + +#if defined (L_ssabs_4) +DEFUN __ssabs_4 + sbrs A3, 7 + ret + XJMP __ssneg_4 +ENDF __ssabs_4 +#endif /* L_ssabs_4 */ + +#undef A0 +#undef A1 +#undef A2 +#undef A3 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Saturation, 8 Bytes +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; First Argument and Return Register +#define A0 18 +#define A1 A0+1 +#define A2 A0+2 +#define A3 A0+3 +#define A4 A0+4 +#define A5 A0+5 +#define A6 A0+6 +#define A7 A0+7 + +#if defined (L_clr_8) +FALIAS __usneguta2 +FALIAS __usneguda2 +FALIAS __usnegudq2 + +;; Clear Carry and all Bytes +DEFUN __clr_8 + ;; Clear Carry and set Z + sub A7, A7 + ;; FALLTHRU +ENDF __clr_8 +;; Propagate Carry to all Bytes, Carry unaltered +DEFUN __sbc_8 + sbc A7, A7 + sbc A6, A6 + wmov A4, A6 + wmov A2, A6 + wmov A0, A6 + ret +ENDF __sbc_8 +#endif /* L_clr_8 */ + +#if defined (L_ssneg_8) +FALIAS __ssnegta2 +FALIAS __ssnegda2 +FALIAS __ssnegdq2 + +DEFUN __ssneg_8 + XCALL __negdi2 + brvc 0f + ;; A[] = 0x7fffffff + sec + XCALL __sbc_8 + ldi A7, 0x7f +0: ret +ENDF __ssneg_8 +#endif /* L_ssneg_8 */ + +#if defined (L_ssabs_8) +FALIAS __ssabsta2 +FALIAS __ssabsda2 +FALIAS __ssabsdq2 + +DEFUN __ssabs_8 + sbrs A7, 7 + ret + XJMP __ssneg_8 +ENDF __ssabs_8 +#endif /* L_ssabs_8 */ + +;; Second Argument +#define B0 10 +#define B1 B0+1 +#define B2 B0+2 +#define B3 B0+3 +#define B4 B0+4 +#define B5 B0+5 +#define B6 B0+6 +#define B7 B0+7 + +#if defined (L_usadd_8) +FALIAS __usadduta3 +FALIAS __usadduda3 +FALIAS __usaddudq3 + +DEFUN __usadd_8 + XCALL __adddi3 + brcs 0f + ret + ;; A[] = 0xffffffff +0: XJMP __sbc_8 +ENDF __usadd_8 +#endif /* L_usadd_8 */ + +#if defined (L_ussub_8) +FALIAS __ussubuta3 +FALIAS __ussubuda3 +FALIAS __ussubudq3 + +DEFUN __ussub_8 + XCALL __subdi3 + brcs 0f + ret + ;; A[] = 0 +0: XJMP __clr_8 +ENDF __ussub_8 +#endif /* L_ussub_8 */ + +#if defined (L_ssadd_8) +FALIAS __ssaddta3 +FALIAS __ssaddda3 +FALIAS __ssadddq3 + +DEFUN __ssadd_8 + ;; A = (B >= 0) ? INT64_MAX : INT64_MIN + XCALL __adddi3 + brvc 0f + cpi B7, 0x80 + XCALL __sbc_8 + subi A7, 0x80 +0: ret +ENDF __ssadd_8 +#endif /* L_ssadd_8 */ + +#if defined (L_sssub_8) +FALIAS __sssubta3 +FALIAS __sssubda3 +FALIAS __sssubdq3 + +DEFUN __sssub_8 + XCALL __subdi3 + brvc 0f + ;; A = (B < 0) ? INT64_MAX : INT64_MIN + ldi A7, 0x7f + cp A7, B7 + XCALL __sbc_8 + subi A7, 0x80 +0: ret +ENDF __sssub_8 +#endif /* L_sssub_8 */ + +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef A4 +#undef A5 +#undef A6 +#undef A7 +#undef B0 +#undef B1 +#undef B2 +#undef B3 +#undef B4 +#undef B5 +#undef B6 +#undef B7 diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S index 6b9879ee7d7..ad979189306 100644 --- a/libgcc/config/avr/lib1funcs.S +++ b/libgcc/config/avr/lib1funcs.S @@ -91,6 +91,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see .endfunc .endm +.macro FALIAS name +.global \name +.func \name +\name: +.size \name, .-\name +.endfunc +.endm + ;; Negate a 2-byte value held in consecutive registers .macro NEG2 reg com \reg+1 @@ -99,6 +107,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see .endm ;; Negate a 4-byte value held in consecutive registers +;; Sets the V flag for signed overflow tests if REG >= 16 .macro NEG4 reg com \reg+3 com \reg+2 @@ -1325,7 +1334,7 @@ DEFUN __divmodsi4 bst r_arg1HH,7 ; store sign of dividend brtc 0f com __tmp_reg__ ; r0.7 is sign of result - rcall __divmodsi4_neg1 ; dividend negative: negate + XCALL __negsi2 ; dividend negative: negate 0: sbrc r_arg2HH,7 rcall __divmodsi4_neg2 ; divisor negative: negate @@ -1333,16 +1342,7 @@ DEFUN __divmodsi4 sbrc __tmp_reg__, 7 ; correct quotient sign rcall __divmodsi4_neg2 brtc __divmodsi4_exit ; correct remainder sign -__divmodsi4_neg1: - ;; correct dividend/remainder sign - com r_arg1HH - com r_arg1HL - com r_arg1H - neg r_arg1L - sbci r_arg1H, 0xff - sbci r_arg1HL,0xff - sbci r_arg1HH,0xff - ret + XJMP __negsi2 __divmodsi4_neg2: ;; correct divisor/quotient sign com r_arg2HH @@ -1357,6 +1357,16 @@ __divmodsi4_exit: ENDF __divmodsi4 #endif /* defined (L_divmodsi4) */ +#if defined (L_negsi2) +;; (set (reg:SI 22) +;; (neg:SI (reg:SI 22))) +;; Sets the V flag for signed overflow tests +DEFUN __negsi2 + NEG4 22 + ret +ENDF __negsi2 +#endif /* L_negsi2 */ + #undef r_remHH #undef r_remHL #undef r_remH @@ -1689,6 +1699,8 @@ ENDF __divdi3_moddi3 ;; (set (reg:DI 18) ;; (plus:DI (reg:DI 18) ;; (reg:DI 10))) +;; Sets the V flag for signed overflow tests +;; Sets the C flag for unsigned overflow tests DEFUN __adddi3 ADD A0,B0 $ adc A1,B1 $ adc A2,B2 $ adc A3,B3 adc A4,B4 $ adc A5,B5 $ adc A6,B6 $ adc A7,B7 @@ -1700,6 +1712,8 @@ ENDF __adddi3 ;; (set (reg:DI 18) ;; (plus:DI (reg:DI 18) ;; (sign_extend:SI (reg:QI 26)))) +;; Sets the V flag for signed overflow tests +;; Sets the C flag for unsigned overflow tests provided 0 <= R26 < 128 DEFUN __adddi3_s8 clr TT sbrc r26, 7 @@ -1714,6 +1728,8 @@ ENDF __adddi3_s8 ;; (set (reg:DI 18) ;; (minus:DI (reg:DI 18) ;; (reg:DI 10))) +;; Sets the V flag for signed overflow tests +;; Sets the C flag for unsigned overflow tests DEFUN __subdi3 SUB A0,B0 $ sbc A1,B1 $ sbc A2,B2 $ sbc A3,B3 sbc A4,B4 $ sbc A5,B5 $ sbc A6,B6 $ sbc A7,B7 @@ -1747,6 +1763,9 @@ ENDF __cmpdi2_s8 #endif /* L_cmpdi2_s8 */ #if defined (L_negdi2) +;; (set (reg:DI 18) +;; (neg:DI (reg:DI 18))) +;; Sets the V flag for signed overflow tests DEFUN __negdi2 com A4 $ com A5 $ com A6 $ com A7 diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index 749613376b3..d1f55e408d3 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -20,7 +20,7 @@ LIB1ASMFUNCS = \ _divdi3 _udivdi3 \ _muldi3 \ _udivmod64 \ - _negdi2 \ + _negsi2 _negdi2 \ _prologue \ _epilogue \ _exit \ @@ -72,7 +72,12 @@ LIB1ASMFUNCS += \ _divqq3 _udivuqq3 \ _divhq3 _udivuhq3 \ _divha3 _udivuha3 \ - _divsa3 _udivusa3 + _divsa3 _udivusa3 \ + _clr_8 \ + _ssneg_2 _ssneg_4 _ssneg_8 \ + _ssabs_2 _ssabs_4 _ssabs_8 \ + _ssadd_8 _sssub_8 \ + _usadd_8 _ussub_8 LIB2FUNCS_EXCLUDE = \ _moddi3 _umoddi3 \ @@ -103,6 +108,7 @@ endif # Filter out supported conversions from fixed-bit.c +# Also filter out TQ and UTQ. conv_XY=$(conv)$(mode1)$(mode2) func_X=$(func)$(mode) @@ -141,8 +147,20 @@ allfix_modes = QQ UQQ HQ UHQ HA UHA SQ USQ SA USA DA UDA DQ UDQ TQ UTQ TA UTA LIB2FUNCS_EXCLUDE += \ $(foreach func,_add _sub,\ - $(foreach mode,$(allfix_modes),$(func_X)3)) + $(foreach mode,$(allfix_modes),$(func_X))) LIB2FUNCS_EXCLUDE += \ $(foreach func,_lshr _ashl _ashr _cmp,\ $(foreach mode,$(allfix_modes),$(func_X))) + + +usat_modes = UQQ UHQ UHA USQ USA UDQ UDA UTQ UTA +ssat_modes = QQ HQ HA SQ SA DQ DA TQ TA + +LIB2FUNCS_EXCLUDE += \ + $(foreach func,_ssadd _sssub _ssneg _ssabs,\ + $(foreach mode,$(ssat_modes),$(func_X))) + +LIB2FUNCS_EXCLUDE += \ + $(foreach func,_usadd _ussub _usneg,\ + $(foreach mode,$(usat_modes),$(func_X))) |