Commit e4fe948a by Georg-Johann Lay

re PR target/50931 ([avr] Support a 24-bit scalar integer mode)

gcc/
	PR target/50931
	* config/avr/avr-modes.def: New file defining PSImode.
	* config/avr/avr-c.c (__INT24_MAX__, __INT24_MIN__,
	__UINT24_MAX__): New built-in defines.
	* config/avr/avr.md (adjust_len): Add tstpsi, mov24,  reload_in24,
	ashlpsi, ashrpsi, lshrpsi.
	(QISO, QIDI, HISI, HIDI, MPUSH, rotx, rotsmode): Add PSI.
	(MOVMODE): New mode iterator.
	(movpsi): New expander.
	(movqi, movhi, movsi, movsf, movpsi): Write as one using MOVMODE.
	(*reload_inpsi, *movpsi): New insns.
	(*reload_inpsi): New RTL peephole.
	(addpsi3, *addpsi3_zero_extend.qi, *addpsi3_zero_extend.hi,
	*addpsi3_sign_extend.hi): New insns.
	(subpsi3, *subpsi3_zero_extend.qi, *subpsi3_zero_extend.hi,
	*subpsi3_sign_extend.hi): New insns.
	(divmodpsi4, udivmodpsi4): New define insn-and-split.
	(*divmodpsi4_call, *udivmodpsi4_call): New insns.
	(andpsi3, iorpsi3, xorpsi3): New insns.
	(*rotlpsi2.1, *rotlpsi2.23): New insns.
	(*rotw<mode>): Insn condition only allow even-sized modes.
	(*rotb<mode>): Insn condition allows odd-sized modes.
	(ashlpsi3, ashrpsi3, lshrpsi3, *addpsi3.lt0): New insns.
	(negpsi2, one_cmplpsi2): New insns.
	(extendqipsi2, extendhipsi2, extendpsisi2): New insns.
	(zero_extendqipsi2, zero_extendhipsi2, zero_extendpsisi2): New
	insn-and-splits.
	(*cmppsi, *negated_tstpsi, *reversed_tstpsi): New insns.
	(cbranchpsi4): New expander.
	* config/avr/constraints.md (Ca3, Co3, Cx3): New constraints.
	* config/avr/avr-protos.h (avr_out_tstpsi, avr_out_movpsi,
	avr_out_ashlpsi3, avr_out_ashrpsi3, avr_out_lshrpsi3,
	avr_out_reload_inpsi): New prototypes.

	* config/avr/avr.c (TARGET_SCALAR_MODE_SUPPORTED_P): Define to...
	(avr_scalar_mode_supported_p): ...this new static function.
	(avr_asm_len): Always return "".
	(avr_out_load_psi, avr_out_store_psi): New static functions.
	(avr_out_movpsi, avr_out_reload_inpsi): New functions.
	(avr_out_tstpsi): New function.
	(avr_out_ashlpsi3, avr_out_ashrpsi3, avr_out_lshrpsi3): New functions.
	(avr_out_plus_1, output_reload_in_const): Handle 3-byte types.
	(avr_simplify_comparison_p): Ditto.
	(adjust_insn_length): Handle ADJUST_LEN_RELOAD_IN24,
	ADJUST_LEN_MOV24, ADJUST_LEN_TSTPSI, ADJUST_LEN_ASHLPSI,
	ADJUST_LEN_ASHRPSI, ADJUST_LEN_LSHRPSI.
	(avr_rtx_costs_1): Report PSI costs.
	(avr_libcall_value): Handle odd-sized parameters.
	(avr_init_builtin_int24): New static function to define built-in
	24-bit types __int24 and __uint24.
	(avr_init_builtins): Use it.

libgcc/
	PR target/50931
	* config/t-avr (LIB1ASMFUNCS): Add _divmodpsi4, _udivmodpsi4.
	* config/lib1funcs.S (__udivmodpsi4, __divmodpsi4): New functions.

From-SVN: r180962
parent 2fcc5e64
2011-11-04 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
2011-11-04 Georg-Johann Lay <avr@gjlay.de>
PR target/50931
* config/avr/avr-modes.def: New file defining PSImode.
* config/avr/avr-c.c (__INT24_MAX__, __INT24_MIN__,
__UINT24_MAX__): New built-in defines.
* config/avr/avr.md (adjust_len): Add tstpsi, mov24, reload_in24,
ashlpsi, ashrpsi, lshrpsi.
(QISO, QIDI, HISI, HIDI, MPUSH, rotx, rotsmode): Add PSI.
(MOVMODE): New mode iterator.
(movpsi): New expander.
(movqi, movhi, movsi, movsf, movpsi): Write as one using MOVMODE.
(*reload_inpsi, *movpsi): New insns.
(*reload_inpsi): New RTL peephole.
(addpsi3, *addpsi3_zero_extend.qi, *addpsi3_zero_extend.hi,
*addpsi3_sign_extend.hi): New insns.
(subpsi3, *subpsi3_zero_extend.qi, *subpsi3_zero_extend.hi,
*subpsi3_sign_extend.hi): New insns.
(divmodpsi4, udivmodpsi4): New define insn-and-split.
(*divmodpsi4_call, *udivmodpsi4_call): New insns.
(andpsi3, iorpsi3, xorpsi3): New insns.
(*rotlpsi2.1, *rotlpsi2.23): New insns.
(*rotw<mode>): Insn condition only allow even-sized modes.
(*rotb<mode>): Insn condition allows odd-sized modes.
(ashlpsi3, ashrpsi3, lshrpsi3, *addpsi3.lt0): New insns.
(negpsi2, one_cmplpsi2): New insns.
(extendqipsi2, extendhipsi2, extendpsisi2): New insns.
(zero_extendqipsi2, zero_extendhipsi2, zero_extendpsisi2): New
insn-and-splits.
(*cmppsi, *negated_tstpsi, *reversed_tstpsi): New insns.
(cbranchpsi4): New expander.
* config/avr/constraints.md (Ca3, Co3, Cx3): New constraints.
* config/avr/avr-protos.h (avr_out_tstpsi, avr_out_movpsi,
avr_out_ashlpsi3, avr_out_ashrpsi3, avr_out_lshrpsi3,
avr_out_reload_inpsi): New prototypes.
* config/avr/avr.c (TARGET_SCALAR_MODE_SUPPORTED_P): Define to...
(avr_scalar_mode_supported_p): ...this new static function.
(avr_asm_len): Always return "".
(avr_out_load_psi, avr_out_store_psi): New static functions.
(avr_out_movpsi, avr_out_reload_inpsi): New functions.
(avr_out_tstpsi): New function.
(avr_out_ashlpsi3, avr_out_ashrpsi3, avr_out_lshrpsi3): New functions.
(avr_out_plus_1, output_reload_in_const): Handle 3-byte types.
(avr_simplify_comparison_p): Ditto.
(adjust_insn_length): Handle ADJUST_LEN_RELOAD_IN24,
ADJUST_LEN_MOV24, ADJUST_LEN_TSTPSI, ADJUST_LEN_ASHLPSI,
ADJUST_LEN_ASHRPSI, ADJUST_LEN_LSHRPSI.
(avr_rtx_costs_1): Report PSI costs.
(avr_libcall_value): Handle odd-sized parameters.
(avr_init_builtin_int24): New static function to define built-in
24-bit types __int24 and __uint24.
(avr_init_builtins): Use it.
2011-11-04 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
PR target/50989
* config/arm/rtems-elf.h, config/arm/t-rtems: Add optional
......@@ -105,4 +105,8 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
cpp_define (pfile, "__BUILTIN_AVR_FMUL");
cpp_define (pfile, "__BUILTIN_AVR_FMULS");
cpp_define (pfile, "__BUILTIN_AVR_FMULSU");
cpp_define (pfile, "__INT24_MAX__=8388607L");
cpp_define (pfile, "__INT24_MIN__=(-__INT24_MAX__-1)");
cpp_define (pfile, "__UINT24_MAX__=16777215UL");
}
FRACTIONAL_INT_MODE (PSI, 24, 3);
......@@ -59,8 +59,10 @@ extern const char *out_movsi_mr_r (rtx insn, rtx op[], int *l);
extern const char *output_movsisf (rtx insn, rtx operands[], int *l);
extern const char *avr_out_tstsi (rtx, rtx*, int*);
extern const char *avr_out_tsthi (rtx, rtx*, int*);
extern const char *avr_out_tstpsi (rtx, rtx*, int*);
extern const char *avr_out_compare (rtx, rtx*, int*);
extern const char *ret_cond_branch (rtx x, int len, int reverse);
extern const char *avr_out_movpsi (rtx, rtx*, int*);
extern const char *ashlqi3_out (rtx insn, rtx operands[], int *len);
extern const char *ashlhi3_out (rtx insn, rtx operands[], int *len);
......@@ -73,6 +75,11 @@ extern const char *ashrsi3_out (rtx insn, rtx operands[], int *len);
extern const char *lshrqi3_out (rtx insn, rtx operands[], int *len);
extern const char *lshrhi3_out (rtx insn, rtx operands[], int *len);
extern const char *lshrsi3_out (rtx insn, rtx operands[], int *len);
extern const char *avr_out_ashlpsi3 (rtx, rtx*, int*);
extern const char *avr_out_ashrpsi3 (rtx, rtx*, int*);
extern const char *avr_out_lshrpsi3 (rtx, rtx*, int*);
extern bool avr_rotate_bytes (rtx operands[]);
extern void expand_prologue (void);
......@@ -93,6 +100,7 @@ extern int extra_constraint_Q (rtx x);
extern int adjust_insn_length (rtx insn, int len);
extern const char* output_reload_inhi (rtx*, rtx, int*);
extern const char* output_reload_insisf (rtx*, rtx, int*);
extern const char* avr_out_reload_inpsi (rtx*, rtx, int*);
extern void notice_update_cc (rtx body, rtx insn);
extern void print_operand (FILE *file, rtx x, int code);
extern void print_operand_address (FILE *file, rtx addr);
......
......@@ -133,6 +133,11 @@
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 2, (1<<0) | (1<<7) | (1<<8))")))
(define_constraint "Ca3"
"Constant 3-byte integer that allows AND without clobber register."
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 3, (1<<0) | (1<<7) | (1<<8))")))
(define_constraint "Ca4"
"Constant 4-byte integer that allows AND without clobber register."
(and (match_code "const_int")
......@@ -143,6 +148,11 @@
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 2, (1<<0) | (1<<1) | (1<<8))")))
(define_constraint "Co3"
"Constant 3-byte integer that allows OR without clobber register."
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 3, (1<<0) | (1<<1) | (1<<8))")))
(define_constraint "Co4"
"Constant 4-byte integer that allows OR without clobber register."
(and (match_code "const_int")
......@@ -153,6 +163,11 @@
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 2, (1<<0) | (1<<8))")))
(define_constraint "Cx3"
"Constant 3-byte integer that allows XOR without clobber register."
(and (match_code "const_int")
(match_test "avr_popcount_each_byte (op, 3, (1<<0) | (1<<8))")))
(define_constraint "Cx4"
"Constant 4-byte integer that allows XOR without clobber register."
(and (match_code "const_int")
......
2011-11-04 Georg-Johann Lay <avr@gjlay.de>
PR target/50931
* config/t-avr (LIB1ASMFUNCS): Add _divmodpsi4, _udivmodpsi4.
* config/lib1funcs.S (__udivmodpsi4, __divmodpsi4): New functions.
2011-11-04 Joel Sherrill <joel.sherrill@oarcorp.com>
PR target/50989
......
......@@ -599,7 +599,142 @@ ENDF __divmodhi4
#undef r_arg2L
#undef r_cnt
/*******************************************************
Division 24 / 24 => (result + remainder)
*******************************************************/
;; A[0..2]: In: Dividend; Out: Quotient
#define A0 22
#define A1 A0+1
#define A2 A0+2
;; B[0..2]: In: Divisor; Out: Remainder
#define B0 18
#define B1 B0+1
#define B2 B0+2
;; C[0..2]: Expand remainder
#define C0 __zero_reg__
#define C1 26
#define C2 25
;; Loop counter
#define r_cnt 21
#if defined (L_udivmodpsi4)
;; R24:R22 = R24:R22 udiv R20:R18
;; R20:R18 = R24:R22 umod R20:R18
;; Clobbers: R21, R25, R26
DEFUN __udivmodpsi4
; init loop counter
ldi r_cnt, 24+1
; Clear remainder and carry. C0 is already 0
clr C1
sub C2, C2
; jump to entry point
rjmp __udivmodpsi4_start
__udivmodpsi4_loop:
; shift dividend into remainder
rol C0
rol C1
rol C2
; compare remainder & divisor
cp C0, B0
cpc C1, B1
cpc C2, B2
brcs __udivmodpsi4_start ; remainder <= divisor
sub C0, B0 ; restore remainder
sbc C1, B1
sbc C2, B2
__udivmodpsi4_start:
; shift dividend (with CARRY)
rol A0
rol A1
rol A2
; decrement loop counter
dec r_cnt
brne __udivmodpsi4_loop
com A0
com A1
com A2
; div/mod results to return registers
; remainder
mov B0, C0
mov B1, C1
mov B2, C2
clr __zero_reg__ ; C0
ret
ENDF __udivmodpsi4
#endif /* defined (L_udivmodpsi4) */
#if defined (L_divmodpsi4)
;; R24:R22 = R24:R22 div R20:R18
;; R20:R18 = R24:R22 mod R20:R18
;; Clobbers: T, __tmp_reg__, R21, R25, R26
DEFUN __divmodpsi4
; R0.7 will contain the sign of the result:
; R0.7 = A.sign ^ B.sign
mov __tmp_reg__, B2
; T-flag = sign of dividend
bst A2, 7
brtc 0f
com __tmp_reg__
; Adjust dividend's sign
rcall __divmodpsi4_negA
0:
; Adjust divisor's sign
sbrc B2, 7
rcall __divmodpsi4_negB
; Do the unsigned div/mod
XCALL __udivmodpsi4
; Adjust quotient's sign
sbrc __tmp_reg__, 7
rcall __divmodpsi4_negA
; Adjust remainder's sign
brtc __divmodpsi4_end
__divmodpsi4_negB:
; Correct divisor/remainder sign
com B2
com B1
neg B0
sbci B1, -1
sbci B2, -1
ret
; Correct dividend/quotient sign
__divmodpsi4_negA:
com A2
com A1
neg A0
sbci A1, -1
sbci A2, -1
__divmodpsi4_end:
ret
ENDF __divmodpsi4
#endif /* defined (L_divmodpsi4) */
#undef A0
#undef A1
#undef A2
#undef B0
#undef B1
#undef B2
#undef C0
#undef C1
#undef C2
#undef r_cnt
/*******************************************************
Division 32 / 32 => (result + remainder)
*******************************************************/
......
......@@ -12,6 +12,7 @@ LIB1ASMFUNCS = \
_divmodqi4 \
_udivmodhi4 \
_divmodhi4 \
_divmodpsi4 _udivmodpsi4 \
_udivmodsi4 \
_divmodsi4 \
_prologue \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment