This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Help needed with zero/sign extension
- From: Anthony Green <green at moxielogic dot com>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 02 Apr 2014 08:08:38 -0400
- Subject: Help needed with zero/sign extension
- Authentication-results: sourceware.org; auth=none
One embarrassing feature of the moxie compiler port is that it really
doesn't understand how to promote integral types. Moxie cores
zero-extend all loads, but the compiler still shifts loaded values back
and forth to zero out the upper bits.
So...
unsigned int foo (unsigned char *c)
{
return *c;
}
..results in...
foo:
ldi.l $r1, 24
ld.b $r0, ($r0)
ashl $r0, $r1
lshr $r0, $r1
ret
I though the answer was to simply add something like this...
(define_insn "zero_extendqisi"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
""
"; ZERO EXTEND (comment for debugging)")
But nothing changes in the example above.
However, the following code...
unsigned int p;
void foo (unsigned char *c)
{
p = *c;
}
...does result in the correct output...
foo:
ld.b $r0, ($r0)
; ZERO EXTEND (comment for debugging)
sta.l p, $r0
ret
Any advice? I'd really like to take care of this because the compiler
output is pretty bloated right now.
Here's what I've been testing with. I'm not sure what I'm missing...
(define_insn "zero_extendqisi"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
""
"; ZERO EXTEND (comment for debugging)")
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
(match_operand:QI 1 "general_operand" ""))]
""
"
{
/* If this is a store, force the value into a register. */
if (MEM_P (operands[0]))
operands[1] = force_reg (QImode, operands[1]);
}")
(define_insn "*movqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r")
(match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
"register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode)"
"@
xor %0, %0
mov %0, %1
ldi.b %0, %1
st.b %0, %1
sta.b %0, %1
ld.b %0, %1
lda.b %0, %1
sto.b %0, %1
ldo.b %0, %1"
[(set_attr "length" "2,2,6,2,6,2,6,6,6")])
Thanks!
AG