On 20/05/2020 05:30, Sebastian Riedel wrote:
It’s integer promotion.
Ah, yes, I see it now. Some sort of sign-extension. But it still doesn't
make any sense to me.
I tried compiling with --no-peep, to see if the optimiser was removing
anything that would put the extraneous code in context, but I'm still
unsure as to the full intent of the resulting assembly code:
_bar:
ldw x, (0x03, sp)
jrne 00110$
jp 00103$
00110$:
ldw x, (0x03, sp)
pushw x
call _foo
addw sp, #2
inc a
push a
rlc a
clr a
sbc a, #0x00
ld xl, a
pop a
jp 00104$
00103$:
clr a
clrw x
00104$:
00101$:
ret
Surely if it was trying to promote the return value from the call to
foo() to a 16-bit signed int, it would be doing a "ld xh, a"? (Ignoring
the fact X reg essentially goes unused from that point.)
On 20/05/2020 12:52, Philipp Klaus Krause wrote:
And using --i-code-in-asm --fverbose-asm shows that for some reason,
foo(vlaue) + 1 is calculated as a signed char, then cast to signed int.
Clearly, this shouldn't happen.
Fortunately, when the return value of bar is changed to uint16_t that
weird signed char stuff goes away (otherwise there would be a real bug
here resulting in wrong return values).
I'd suggest to file a feature request in the tracker, so this
inefficiency won't be forgotten.
If I change the code of bar() to use unsigned constants:
uint8_t bar(uint16_t value) {
return (value ? foo(value) + 1U : 0U);
}
Then the extraneous assembly code does not appear, presumably because
there is no casting and/or signed arithmetic going on in the first place.
Do you want me to file a feature request? I don't feel I am best placed
to do so, as I would not be sure how to properly describe this issue,
because I don't really fully understand it. I tried compiling myself
with the aforementioned options, but the output in the listing file is
just gibberish to me. :)
Regards,
Basil
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user