Thank you for your advice. Compared RICE (my processor name) RTL and
MIPS RTL,  I found the problem. Because of the subreg operations which
I missed to add support in my RTL. I noticed the mips rtl code which
will convert the QImode and HI mode to SImode operations. Like the
following:

(insn 28 26 29 2 (set (reg:QI 198)
        (mem:QI (reg/v/f:SI 193 [ data ]) [0 S1 A8])) -1 (nil)
    (nil))

(insn 29 28 30 2 (set (reg:SI 191 [ D.1099 ])
        (zero_extend:SI (reg:QI 198))) -1 (nil)
    (nil))

(insn 30 29 31 2 (set (reg:SI 199)
        (lshiftrt:SI (reg:SI 191 [ D.1099 ])
            (const_int 4 [0x4]))) -1 (nil)
    (nil))

But in my port, the rtl code is like this:

(insn 25 23 26 2 (set (reg:QI 45 [ D.1059 ])
        (mem:QI (reg/v/f:SI 47 [ data ]) [0 S1 A8])) -1 (nil)
    (nil))

(insn 26 25 27 2 (set (reg:QI 50)
        (lshiftrt:QI (reg:QI 45 [ D.1059 ])
            (const_int 4 [0x4]))) -1 (nil)
    (nil))

If I extend the QI operands, then do the shift operations,  the logic
will be right.
But the question is how I make the gcc know to extend every smaller
mode to SImode. Now I check the MIPS port, maybe I can find some clue.

Thank you for your guys.


daniel.tian


2009/3/27 Ian Lance Taylor <i...@google.com>:
> daniel tian <daniel.xnt...@gmail.com> writes:
>
>>       I am porting gcc to a 32bit RISC chip, and  I met a logical
>> error with 16bit arithmetic operations in generating assemble code.
>> the error is between two 16bit data movement(unsigned short).
>> While like A = B,  A, and B are all unsigned short type.  B is a
>> result of a series of computation, which may have value in high 16bit.
>> Because A , B are both HImode, so the move insn doesn't take zero
>> extend operation, so A will have value in high 16bit which will caused
>> a wrong result in computation.
>
> The relevant types in your code are "unsigned short".  I assume that on
> your processor that is a 16 bit type.  An variable of an unsigned 16 bit
> type can hold values from 0 to 0xffff, inclusive.  There is nothing
> wrong with having the high bit be set in such a variable.  It just means
> that the value is between 0x8000 and 0xffff.
>
>
>> ;;      1--> 23   R5=R6 0>>0xc                       :nothing
>>              //R5 and R6 are both unsigned short type. But R6 will
>> have it's value in high 16bit because of series of logical operations
>> (AND, OR, XOR and so on). Doing it like this way will cause R5 also
>> being valued in high 16bit. This will cause a wrong value. The correct
>> one is : R5 = R2 0 >> 0xC. because R2 did zero extend in former insn
>>>From R6. But How I let gcc know it.
>
> No.  0>> means a logical right shift, not an arithmetic right shift
> (LSHIFTRT rathre than ASHIFTRT).  When doing a logical right shift, the
> sign bit is moved right also; it is not sticky.  This instruction is
> fine.  Perhaps there is a problem in your implementation of LSHIFTRT.
>
> Ian
>

Reply via email to