2011/11/2 Georg-Johann Lay <a...@gjlay.de>:
> Georg-Johann Lay wrote:
>> To support the upcoming named address space support in avr, a 24-bit pointer
>> type is needed. This patch adds respective support of a 24-bit integer mode
>> called PSI.
>>
>> The patch supports more than is actually needed for a pointer-only
>> implementation: is supplies almost all needed insns to render the new mode
>> efficient for use in arithmetic.
>>
>> The impact on already existing code for non-PSI part of the backend is very
>> small and just a handfull of lines:
>>
>> - avr_out_plus_1, output_reload_in_const and avr_simplify_comparison_p
>>   can handle 3-byte types now.
>>
>> - avr_libcall_value: 3-byte values will be passed in even registers.
>>
>> - TARGET_SCALAR_MODE_SUPPORTED_P reports PSI as supported scalar
>>
>> - avr_init_builtins exposes the new mode to user land as new
>>   build-in types __int24_t and __uint24_t.
>>
>> - avr_cpu_cpp_builtins adds build-in macros
>>   __INT24_MAX__, __INT24_MIN__ and __UINT24_MAX__ so that user can test
>>   if the new mode is available for arithmetic.
>>
>> The rest of the patch is PSI-specific:
>>
>> Routines for comparison, addition, rotation, and, or, xor were already 
>> generic
>> enough to support the new type without effort.
>>
>> Shifts and load/store/move are a bit lengthy routines as it is the case with
>> SI, too.
>>
>> There are some parts missing and are planned to supply them in separate 
>> patches:
>>
>> - Documentation
>> - Test cases
>> - libgcc support of __[u]divmodpsi4
>> - Perhaps more efficient MUL. At the moment, multiplication is extended to
>>   32 bits. This leads to suboptimal code because of 32-bit arithmetic and
>>   more SUBREGs than with a native mulpsi3 support.
>>
>> Patch is lightly tested and passes the test suites.
>>
>> Ok for trunk?
>>
>> Johann
>>       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.
>>       (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): 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_int24): New static function.
>>       (avr_init_builtins): Use it.
>
> This patch is the div/mod support for libgcc.
>
> With this patch, 24-bit integers are fully supported for integer arithmetic.
>
> During the implementation it turned out that the register footprint is smaller
> than that of SImode: PSI need 3 registers less so that the representation in
> avr.md needs adjustment like so:
>
>
> @@ -2199,6 +2294,66 @@ (define_insn "*udivmodhi4_call"
>   [(set_attr "type" "xcall")
>    (set_attr "cc" "clobber")])
>
> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +
> +(define_insn_and_split "divmodpsi4"
> +  [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
> +                   (div:PSI (match_operand:PSI 1 "pseudo_register_operand" 
> "")
> +                            (match_operand:PSI 2 "pseudo_register_operand" 
> "")))
> +              (set (match_operand:PSI 3 "pseudo_register_operand" "")
> +                   (mod:PSI (match_dup 1) (match_dup 2)))
> +              (clobber (reg:DI 18))
> +              (clobber (reg:QI 26))])]
> +  ""
> +  { gcc_unreachable(); }
> +  ""
> +  [(set (reg:PSI 22) (match_dup 1))
> +   (set (reg:PSI 18) (match_dup 2))
> +   (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
> +              (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
> +              (clobber (reg:QI 26))])
> +   (set (match_dup 0) (reg:PSI 22))
> +   (set (match_dup 3) (reg:PSI 18))])
> +
> +(define_insn "*divmodpsi4_call"
> +  [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
> +   (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
> +   (clobber (reg:QI 26))]
> +  ""
> +  "%~call __divmodpsi4"
> +  [(set_attr "type" "xcall")
> +   (set_attr "cc" "clobber")])
> +
> +(define_insn_and_split "udivmodpsi4"
> +  [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
> +                   (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" 
> "")
> +                             (match_operand:PSI 2 "pseudo_register_operand" 
> "")))
> +              (set (match_operand:PSI 3 "pseudo_register_operand" "")
> +                   (umod:PSI (match_dup 1) (match_dup 2)))
> +              (clobber (reg:DI 18))
> +              (clobber (reg:QI 26))])]
> +  ""
> +  { gcc_unreachable(); }
> +  ""
> +  [(set (reg:PSI 22) (match_dup 1))
> +   (set (reg:PSI 18) (match_dup 2))
> +   (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
> +              (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
> +              (clobber (reg:QI 26))])
> +   (set (match_dup 0) (reg:PSI 22))
> +   (set (match_dup 3) (reg:PSI 18))])
> +
> +(define_insn "*udivmodpsi4_call"
> +  [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
> +   (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
> +   (clobber (reg:QI 26))]
> +  ""
> +  "%~call __udivmodpsi4"
> +  [(set_attr "type" "xcall")
> +   (set_attr "cc" "clobber")])
> +
> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +
>
> The division routines are tested against the 32-bit division functions for 
> lots
> of (pseudo) random values and special values like 0, 1, -1, 0x7f..., 0x80...
> etc. libgcc builds fine and assembles for the new objects.
>
> Ok for trunk?
>
> Johann
>
>        PR target/50931
>        * config/avr/t-avr (LIB1ASMFUNCS): Add _divmodpsi4, _udivmodpsi4.
>        * config/avr/libgcc.S (__udivmodpsi4, __divmodpsi4): New functions.
>

Please commit both patches.

Denis.

Reply via email to