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