I have a simple CPU architecture with just SI registers / operations. The only 
place bytes and words and used is during loads / stores.

I'm trying to understand how a QI/HI load to an SI register works. I have this 
to expand moves --

(define_expand "mov<mode>"
        [(set (match_operand:ALLMODES 0 "nonimmediate_operand" "")
                (match_operand:ALLMODES 1 "general_operand" ""))]
        ""
        {
                if (ghost_expand_move (operands[0], operands[1])) DONE;
                FAIL;
        })

Where ALLMODES is QI,HI,SI. I have PROMOTE_MODE setup to promote anything 
smaller than SI to SI (as RISCV etc).

With a simple function of "unsigned int fn(type *ptr) { return *ptr; }" I am 
getting a tree of --

type = unsigned int :

(insn 7 4 8 2 (set (reg:SI 28)
        (mem:SI (reg/v/f:SI 25 [ ptr ]) [0  S4 A32])) "test.c":3:9 discrim 1 -1
     (nil))
(insn 8 7 12 2 (set (reg:SI 24 [ <retval> ])
        (reg:SI 28)) "test.c":3:9 discrim 1 -1
     (nil))

(expected, works fine)

type = unsigned char :

(insn 7 4 8 2 (set (reg:QI 29)
        (mem:QI (reg/v/f:SI 26 [ ptr ]) [0  S1 A8])) "test.c":3:9 -1
     (nil))
(insn 8 7 9 2 (set (reg:SI 28 [ _4 ])
        (ashift:SI (subreg:SI (reg:QI 29) 0)
            (const_int 24 [0x18]))) "test.c":3:9 -1
     (nil))
(insn 9 8 10 2 (set (reg:SI 28 [ _4 ])
        (ashift:SI (reg:SI 28 [ _4 ])
            (const_int 24 [0x18]))) "test.c":3:9 -1
     (nil))
(insn 10 9 14 2 (set (reg:SI 25 [ <retval> ])
        (reg:SI 28 [ _4 ])) "test.c":3:9 discrim 1 -1
     (nil))

It looks like it's doing a shift left 24 / right 24 to sign extend the top 24 
bits (which is odd in itself as all vars are unsigned), but this ends up 
generating incorrect code as I assume the shift subreg pattern isn't being 
matched (I just have SI). I've also tried setting LOAD_EXTEND_OP to ZERO_EXTEND 
but this makes no difference.

What am I missing to be able to match specific --

        [(set (match_operand:SI 0 "register_operand" "=da")
                (zero_extend:SI (mem:QI (match_operand:SI 1 "register_operand" 
"a"))))]

Type patterns to directly load a byte into a 32bit register?

Any pointers appreciated, I assume I'm missing something fundamental.

Reply via email to