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.