The subreg question
Ling-hua Tseng
uranus@it.muds.net
Sat Apr 23 16:33:00 GMT 2005
James E Wilson wrote:
> Ling-hua Tseng wrote:
>> It's obvious that `movil' and `movim' are only access the partial
>> 16-bit of the 32-bit register. How can I use RTL expression to
>> represent the operations?
>
> As you noticed, within a register, subreg can only be used for low
> parts. You can't ask for the high part of a single register. If you
> have an item that spans multiple registers, e.g. a 64-bit value that is
> contained in a register pair, then you can ask for the SImode highpart
> of a DImode reg and get valid RTL. This works because the high part is
> an entire register. This isn't useful to you.
>
> Otherwise, you can access subparts via bitfield insert/extract
> operations, or logicals operations (ior/and), though this is likely to
> be tedious, and may confuse optimizers.
>
> There are high/lo_sum RTL operators that may be useful to you. You can use
> (set (reg:SI) (high: ...))
> (set (reg:SI) (lo_sum (reg:SI) (...)))
> where the first pattern corresponds to movims, and the second one to
> movil. You could just as well use ior instead of lo_sum for the second
> pattern, this is probably better as movil does not do an add.
>
> You may want to emit normal rtl for an SImode move, and then split it
> into its two 16-bit parts after reload. This will avoid confusing RTL
> optimizers before reload.
>
> We have vector modes which might be useful to you. If you say a
> register is holding a V4QI mode value, then there are natural ways to
> get at the individual elements of the vector via vector operations.
I implemented my 4 `movi' cases in the following forms.
The result of them sould be a 32-bit integer because the `movi' is in order to generate SImode immediate.
The case 4 is special. It's also used to generate HImode and QImode immediates.
Would you like to help me confirm them? (RTX semantics and the usage of `HI' mode)
1. set MSB 16-bit and clear LSB 16-bit to zero
[(set (match_operand:SI 0 "register_operand" "=r")
(high:SI (match_operand:SI 1 "immediate_operand" "i")))]
(Does (high:SI ...) have the semantic of clearing LSB 16-bit ? )
2. set MSB 16-bit and unchange/keep LSB 16-bit
[(parallel
[(set (high:SI (match_operand:SI 0 "register_operand" "=r"))
(high:SI (match_operand:SI 1 "immediate_operand" "i")))
(set (strict_lowpart (subreg:HI (match_dup 0) 0))
(match_operand:HI "immediate_operand" "i"))])]
(I know it's incorrect if the semantic of (high:SI ...) will change LSB 16-bit.)
3. set LSB 16-bit and clear MSB 16-bit to zero
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:HI 1 "immediate_operand" "i"))]
4. set LSB 16-bit and unchange/keep LSB 16-bit
[(set (strict_lowpart (subreg:HI (match_operand:SI 0 "register_operand" "=r") 0))
(match_operand:HI "immediate_operand" "i"))]
(Would it better than use (lo_sum:SI ...) ? )
Thanks.
More information about the Gcc
mailing list