This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
The subreg question
- From: "Ling-hua Tseng" <uranus at it dot muds dot net>
- To: <gcc at gcc dot gnu dot org>
- Date: Sun, 17 Apr 2005 17:01:32 +0800
- Subject: The subreg question
I have a chip which is developed by other lab.
It's VLIW architecture and it contains 2 RISCs and 8 DSPs.
The size of all registers are 32 bits.
There is a special instruction in the RISC which is called `movi' (move immediate).
Its syntax and semantic are:
movil r1, #<const> (moves #<const> to LSB 16-bit, without changes MSB 16-bit)
movils r1, #<const> (moves #<const> to LSB 16-bit, and sets the MSB 16-bit to zero)
movim r1, #<const> (moves #<const> to MSB 16-bit, without changes LSB 16-bit)
movims r1, #<const> (moves #<const> to MSB 16-bit, and sets the LSB 16-bit to zero)
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?
(I should implement the standard pattern `movsi' in the machine description,
and I tried to design an define_split to generate a 32-bit immediate value)
It's the define_split RTX in the machine description:
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "immediate_operand" ""))]
"!valid_10bit_immediate(INTVAL(operands[1]))"
<new patterns>
{
<prepare stmts>
})
First, I tried to write the <new patterns> in the following form:
[(set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 2))
(set (subreg:HI (match_dup 0) 2)) (match_dup 3))] <------- (*1)
And I wrote the <prepare stmts> in the following form:
operands[2] = GEN_INT(INTVAL(operands[1]) & 0x0000ffff);
operands[3] = GEN_INT((INTVAL(operands[2]) & 0xffff0000) >> 16); ....... (*2)
The expression (*1) is in want of a RTX `(strict_high_part x)' but it's not existing.
So I just writing it without `strict' semantic.
But the subreg RTX is not accepted by the gcc.
The emit-rtl.c: validate_subreg( ) will return false at the line 692 (gcc 4.0 20050416).
(BTW, the gen_highpart( ) is also failed when I trying to generate the MSB 16-bit operand.)
After some studying, I know that the `subreg' RTX is only able to represent the LSB n-bit.
Instead, I wrote the following form to solve it temporarily:
[(set (match_dup 0)
(ior:SI (match_dup 0) (match_dup 2)))
(set (match_dup 0)
(ior:SI (match_dup 0) (match_dup 3)))]
{
operands[2] = GEN_INT(INTVAL(operands[1]) & 0x0000ffff);
operands[3] = GEN_INT(INTVAL(operands[1]) & 0xffff0000);
})
Unfortunately, I need to face this problem eventually.
The DSP function unit provides `packing' and SIMD operations.
We can pack four 8-bit integer values into one 32-bit register,
and then do an arithmetic operation by one instruction.
So I need to treat one 32-bit register as four 8-bit sub-registers.
But I couldn't represent them by:
(subreg:QI (reg:SI xx) 0), (subreg:QI (reg:SI xx) 1), (subreg:QI (reg:SI xx) 2), and (subreg:QI (reg:SI xx) 3).
Would anyone teach me how to use RTL expression to represent these sub-registers?
Thanks a lot.