In certain scenarios, separate parts of SDCC code generation for the STM8 can emit differently-formatted assembly code for the same instruction. This causes difficulty when attempting to write peephole optimiser rules, because duplicate rules with subtly different match patterns have to be created to account for the differences.
An example of this is when testing a single-bit field of a static/global struct variable - e.g. if(somevar.flag). In some scenarios, code for such a test is generated like so:
ldw x, #_somevar+0
ld a, (x)
swap a
and a, #0x01
jreq 00116$
And in others, the code is like so:
ldw x, #(_somevar + 0)
ld a, (x)
swap a
and a, #0x01
jreq 00121$
Note the difference in the formatting of the second operand to the ldw instruction. One has parentheses and spacing, one does not.
Some cursory digging in the SDCC source (stm8/gen.c, as of [r11995]) for instances of var+offset pattern found the following:
Line 456: SNPRINTF (buffer, sizeof(buffer), "#((%s + %d) >> %d)", aop->aopu.immd, aop->aopu.immd_off, offset * 8);
Line 500: SNPRINTF (buffer, sizeof(buffer), "#((%s + %d) >> %d)", aop->aopu.immd, aop->aopu.immd_off, offset * 8);
Line 502: SNPRINTF (buffer, sizeof(buffer), "#(%s + %d)", aop->aopu.immd, aop->aopu.immd_off);
Line 7969: emit2 ("ldw", "y, #%s+%ld", sym->rname, (long)(operandLitValue (right)));
Line 7993: emit2 ("ldw", "x, #%s+%ld", sym->rname, (long)(operandLitValue (right)));
The first is in aopGet(), the next two in aopGet2() and the last two in genAddrOf().