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.

Reply via email to