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