>I can currently not verify this, but anyways: I think that union's were >and possibly are implicitly
>treated as volatile by SDCC and/or the PIC backend(s) due to problems in >maintaining correct >potential alias sets. This might explain the bad code that is generated >for the a+=b operation >you see, as your code does use unions. To test this, you could x+=y two >global uint16_t variables >and see what happens. For structs, I would expect the same code as for >globals. > It might also be interesting to see what happens if the right operand is >simple > (say, just a global variable or even a function argument): Thanks for the suggestions, it looks you are right, see below. Adding two globals produces indeed is best with no unnecessary temp vars. Unfortunately this brings back the unnecessary BANKSEL problem. I'd be happy to use globals, the unions were only introduced to get rid of the extra BANSELs. The right hand operator type (struct or union) does not seem to make a difference. _bar: ; .line 225; stepperirq.c void bar() MOVFF FSR2L, POSTDEC1 MOVFF FSR1L, FSR2L MOVFF r0x00, POSTDEC1 MOVFF r0x01, POSTDEC1 BANKSEL _y ; .line 227; stepperirq.c x += y; MOVF _y, W, B BANKSEL _x ADDWF _x, F, B BANKSEL (_y + 1) MOVF (_y + 1), W, B BANKSEL (_x + 1) ADDWFC (_x + 1), F, B BANKSEL _y ; .line 228; stepperirq.c s.v += y; MOVF _y, W, B BANKSEL _s ADDWF _s, W, B MOVWF r0x00 BANKSEL (_y + 1) MOVF (_y + 1), W, B BANKSEL (_s + 1) ADDWFC (_s + 1), W, B MOVWF r0x01 MOVF r0x00, W ; removed redundant BANKSEL MOVWF _s, B MOVF r0x01, W ; removed redundant BANKSEL MOVWF (_s + 1), B BANKSEL _y ; .line 229; stepperirq.c u.a += y; MOVF _y, W, B BANKSEL _u ADDWF _u, W, B MOVWF r0x00 BANKSEL (_y + 1) MOVF (_y + 1), W, B BANKSEL (_u + 1) ADDWFC (_u + 1), W, B MOVWF r0x01 MOVF r0x00, W ; removed redundant BANKSEL MOVWF _u, B MOVF r0x01, W ; removed redundant BANKSEL MOVWF (_u + 1), B MOVFF PREINC1, r0x01 MOVFF PREINC1, r0x00 MOVFF PREINC1, FSR2L RETURN ; ; Starting pCode block S_stepperirq__foo code _foo: ; .line 218; stepperirq.c void foo() MOVFF FSR2L, POSTDEC1 MOVFF FSR1L, FSR2L MOVFF r0x00, POSTDEC1 MOVFF r0x01, POSTDEC1 BANKSEL _y ; .line 220; stepperirq.c x += y; MOVF _y, W, B BANKSEL _x ADDWF _x, F, B BANKSEL (_y + 1) MOVF (_y + 1), W, B BANKSEL (_x + 1) ADDWFC (_x + 1), F, B BANKSEL (_s + 2) ; .line 221; stepperirq.c s.v += s.w; MOVF (_s + 2), W, B ; removed redundant BANKSEL ADDWF _s, W, B MOVWF r0x00 ; removed redundant BANKSEL MOVF (_s + 3), W, B ; removed redundant BANKSEL ADDWFC (_s + 1), W, B MOVWF r0x01 MOVF r0x00, W ; removed redundant BANKSEL MOVWF _s, B MOVF r0x01, W ; removed redundant BANKSEL MOVWF (_s + 1), B BANKSEL _u ; .line 222; stepperirq.c u.a += u.b; MOVF _u, W, B MOVWF r0x00 ADDWF r0x00, F ; removed redundant BANKSEL RLCF (_u + 1), W, B MOVWF r0x01 MOVF r0x00, W ; removed redundant BANKSEL MOVWF _u, B MOVF r0x01, W ; removed redundant BANKSEL MOVWF (_u + 1), B MOVFF PREINC1, r0x01 MOVFF PREINC1, r0x00 MOVFF PREINC1, FSR2L RETURN Making the second operator function parameter does change things a bit, but that is not an option for me as moving the global state to a local would defeat the saving I get in the addition: ; .line 225; stepperirq.c void bar(uint16_t y) MOVFF FSR2L, POSTDEC1 MOVFF FSR1L, FSR2L MOVFF r0x00, POSTDEC1 MOVFF r0x01, POSTDEC1 MOVFF r0x02, POSTDEC1 MOVFF r0x03, POSTDEC1 MOVLW 0x02 MOVFF PLUSW2, r0x00 MOVLW 0x03 MOVFF PLUSW2, r0x01 ; .line 227; stepperirq.c x += y; MOVF r0x00, W BANKSEL _x ADDWF _x, F, B MOVF r0x01, W ; removed redundant BANKSEL ADDWFC (_x + 1), F, B ; .line 228; stepperirq.c s.v += y; MOVF r0x00, W BANKSEL _s ADDWF _s, W, B MOVWF r0x02 MOVF r0x01, W ; removed redundant BANKSEL ADDWFC (_s + 1), W, B MOVWF r0x03 MOVF r0x02, W ; removed redundant BANKSEL MOVWF _s, B MOVF r0x03, W ; removed redundant BANKSEL MOVWF (_s + 1), B BANKSEL _u ; .line 229; stepperirq.c u.a += y; MOVF _u, W, B ADDWF r0x00, F ; removed redundant BANKSEL MOVF (_u + 1), W, B ADDWFC r0x01, F MOVF r0x00, W ; removed redundant BANKSEL MOVWF _u, B MOVF r0x01, W ; removed redundant BANKSEL MOVWF (_u + 1), B MOVFF PREINC1, r0x03 MOVFF PREINC1, r0x02 MOVFF PREINC1, r0x01 MOVFF PREINC1, r0x00 MOVFF PREINC1, FSR2L RETURN So I'm in a bit of 22 unless I can somehow tell the compiler to not use so many BANKSELs in which case I could use straight forward globals. The contorted union/structs were only introduced to force the compiler to generate faster code and indeed they do, except for this addition. About the only thing I would need to use the union is to check the high bit of the nco accumulator, the union really makes checking the high bit fast! Any ideas how to get forward? ...and of course, many thanks for the support and SDCC in the first place. br Kusti This e-mail may contain confidential or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. We will not be liable for direct, indirect, special or consequential damages arising from alteration of the contents of this message by a third party or as a result of any virus being passed on or as of transmission of this e-mail in general. ------------------------------------------------------------------------------ Open source business process management suite built on Java and Eclipse Turn processes into business applications with Bonita BPM Community Edition Quickly connect people, data, and systems into organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards http://p.sf.net/sfu/Bonitasoft _______________________________________________ Sdcc-user mailing list Sdcc-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sdcc-user