Denis Chertykov wrote:
> 2011/11/2 Georg-Johann Lay <x...@yyy.zz>:
>> 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.


Committed with the following changes:

* The new 24-bit types are named __int24 and __uint24 (instead of
  __[u]int24_t) similar to __int128 that is supported by some targets.

* PSI is also element of QISI and QIDI iterators.  The insns that use
  these iterators are general enough to handle PSI without extension.

* __[u]divmodpsi4 call clobbers R21, R25 and R26, not only R26

* There is a combine pattern *addpsi3.lt0 similar to *addsi3.lt0.

http://gcc.gnu.org/viewcvs?view=revision&revision=180962

Johann



Reply via email to