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 read the descriptions of (high:m exp) and (lo_sum:m x y) in the gcc internal manuls (Section 10.7 and 10.9). The last line of their descriptions confused me because they wrote "m should be Pmode". Is it really a strict rule? The RTX "(set (reg:SI xx) (high:m yy))" seems to let m to be an integer mode. Doesn't it lead to some undefined behaviors in the back-end passes?

Reply via email to