aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2012-09-15 15:52:28 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2012-09-15 15:52:28 +0000
commit51526856a1ca4a9434919d012a2bed07c8395ee0 (patch)
tree89382cc27ddcd6714736d847af8f8dc0b6289abc /libgcc
parentfc2655fb3082182075b288b58c93ac563ef661a0 (diff)
downloadgcc-51526856a1ca4a9434919d012a2bed07c8395ee0.zip
gcc-51526856a1ca4a9434919d012a2bed07c8395ee0.tar.gz
gcc-51526856a1ca4a9434919d012a2bed07c8395ee0.tar.bz2
re PR target/54222 ([avr] Implement fixed-point support)
gcc/ PR target/54222 * config/avr/avr-fixed.md (ALL2S, ALL4S, ALL24S, ALL124S, ALL124U): New mode iterators. (<code_stdname><mode>3): New insns for SS_PLUS, SS_MINUS. (<code_stdname><mode>3): New insns for US_PLUS, US_MINUS. (usneg<mode>2): New insns. (<code_stdname><mode>2): New expanders for SS_NEG, SS_ABS. (*<code_stdname><mode>2): New insns for SS_NEG, SS_ABS. * config/avr/avr-dimode.md (ALL8U, ALL8S): New mode iterators. (avr_out_plus64, avr_out_minus64): Use avr_out_plus instead. (<code_stdname><mode>3): New expanders for SS_PLUS, SS_MINUS. (<code_stdname><mode>3): New expanders for US_PLUS, US_MINUS. (<code_stdname><mode>3_insn): New insns. (<code_stdname><mode>3_const_insn): New insns. * config/avr/avr.md (cc): Add: plus. Remove: out_plus, out_plus_noclobber, minus. (length): Add: plus. Remove: out_plus, out_plus_noclobber, plus64, minus, minus64. (abelian): New code_attr. (code_stdname): Handle: ss_plus, ss_minus, ss_neg, ss_abs, us_plus, us_minus, us_neg. (*add<mode>3, add<mode>3_clobber, add<mode>3, addpsi3, sub<mode>3): Use avr_out_plus to output. * config/avr/avr-protos.h (avr_out_plus): Change prototype. (avr_out_plus_noclobber, avr_out_minus): Remove. (avr_out_plus64, avr_out_minus64): Remove. * config/avr/avr.c (avr_out_plus_1): Add new default arguments code_sat, sign. Saturate after operation if code_sat != UNKNOWN. (avr_out_plus_symbol): New static function. (avr_out_plus): Rewrite. (adjust_insn_length): Handle: ADJUST_LEN_PLUS. Remove handling of: ADJUST_LEN_OUT_PLUS, ADJUST_LEN_PLUS64, ADJUST_LEN_MINUS, ADJUST_LEN_MINUS64, ADJUST_LEN_OUT_PLUS_NOCLOBBER. (notice_update_cc): Handle: CC_PLUS. Remove handling of: CC_MINUS, CC_OUT_PLUS, CC_OUT_PLUS_NOCLOBBER (avr_out_plus_noclobber, avr_out_minus): Remove. (avr_out_plus64, avr_out_minus64): Remove. (avr_print_operand): Print raw REGNO if 'r' is used with REG. libgcc/ PR target/54222 * config/avr/lib1funcs-fixed.S (__ssneg_2, __ssabs_2, __ssneg_4, __ssabs_4, __clr_8, __ssneg_8, __ssabs_8, __usadd_8, __ussub_8, __ssadd_8, __sssub_8): New functions. (__divsa3): Use __negsi2 to negate r_quoL. * config/avr/lib1funcs.S (FALIAS): New macro. (__divmodsi4): Break out and use __divmodsi4_neg1 as... (__negsi2): ...this new function. * config/avr/t-avr (LIB1ASMFUNCS): Add _negsi2, _clr_8, _ssneg_2, _ssneg_4, _ssneg_8, _ssabs_2, _ssabs_4, _ssabs_8, _ssadd_8, _sssub_8, _usadd_8, _ussub_8. (LIB2FUNCS_EXCLUDE): Fix typo for _add _sub. Add: _ssadd*, _sssub*, _ssneg*, _ssabs* for signed fixed modes. Add: _usadd*, _ussub*, _usneg* for unsigned fixed modes. gcc/testsuite/ PR target/54222 * gcc.target/avr/torture/fix-types.h: New. * gcc.target/avr/torture/vals-hr.def: New. * gcc.target/avr/torture/vals-r.def: New. * gcc.target/avr/torture/vals-k.def: New. * gcc.target/avr/torture/vals-ur.def: New. * gcc.target/avr/torture/vals-uk.def: New. * gcc.target/avr/torture/vals-uhr.def: New. * gcc.target/avr/torture/vals-llk.def: New. * gcc.target/avr/torture/vals-ullk.def: New. * gcc.target/avr/torture/sat-hr-plus-minus.c: New. * gcc.target/avr/torture/sat-r-plus-minus.c: New. * gcc.target/avr/torture/sat-k-plus-minus.c: New. * gcc.target/avr/torture/sat-ur-plus-minus.c: New. * gcc.target/avr/torture/sat-uk-plus-minus.c: New. * gcc.target/avr/torture/sat-uhr-plus-minus.c: New. * gcc.target/avr/torture/sat-llk-plus-minus.c: New. * gcc.target/avr/torture/sat-ullk-plus-minus.c: New. From-SVN: r191345
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog17
-rw-r--r--libgcc/config/avr/lib1funcs-fixed.S224
-rw-r--r--libgcc/config/avr/lib1funcs.S41
-rw-r--r--libgcc/config/avr/t-avr24
4 files changed, 290 insertions, 16 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index a225e58..2045aac 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,20 @@
+2012-09-15 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/54222
+ * config/avr/lib1funcs-fixed.S (__ssneg_2, __ssabs_2, __ssneg_4,
+ __ssabs_4, __clr_8, __ssneg_8, __ssabs_8,
+ __usadd_8, __ussub_8, __ssadd_8, __sssub_8): New functions.
+ (__divsa3): Use __negsi2 to negate r_quoL.
+ * config/avr/lib1funcs.S (FALIAS): New macro.
+ (__divmodsi4): Break out and use __divmodsi4_neg1 as...
+ (__negsi2): ...this new function.
+ * config/avr/t-avr (LIB1ASMFUNCS): Add _negsi2, _clr_8,
+ _ssneg_2, _ssneg_4, _ssneg_8, _ssabs_2, _ssabs_4,
+ _ssabs_8, _ssadd_8, _sssub_8, _usadd_8, _ussub_8.
+ (LIB2FUNCS_EXCLUDE): Fix typo for _add _sub.
+ Add: _ssadd*, _sssub*, _ssneg*, _ssabs* for signed fixed modes.
+ Add: _usadd*, _ussub*, _usneg* for unsigned fixed modes.
+
2012-09-10 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54089
diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S
index c1aff53..ddcd02e 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 6b9879e..ad97918 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 7496133..d1f55e4 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)))