diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2012-09-15 15:52:28 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2012-09-15 15:52:28 +0000 |
commit | 51526856a1ca4a9434919d012a2bed07c8395ee0 (patch) | |
tree | 89382cc27ddcd6714736d847af8f8dc0b6289abc /libgcc/config/avr/lib1funcs-fixed.S | |
parent | fc2655fb3082182075b288b58c93ac563ef661a0 (diff) | |
download | gcc-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/config/avr/lib1funcs-fixed.S')
-rw-r--r-- | libgcc/config/avr/lib1funcs-fixed.S | 224 |
1 files changed, 222 insertions, 2 deletions
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 |