Hi List,
I'm in a bit of a tight spot, having an interrupt running at 24 kHz so I need
to squeeze out
every cycle I can to make this work.
While I'm fluent in numerous processor assembly languages, unfortunately I'm
not too
familiar with PIC code and details of SDCC code generation, so tips would be
welcome.
I would rather tweak my C code to let SDCC produce fast enough code than resort
to
assembly language but I could throw in one or two lines of inline asm if it
necessary.
I've peeked at the generated code and a few things make me wonder if these could
be improved by giving the compiler some hints or using custom peep hole
optimization.
1) Even with the --obanksel=3 there are quite a lot of BANKSEL statements
apart from a few bigger arrays most explicit variables should fit on one page,
so
could this fact be used to speed things up?
2) Arrays not spanning multiple pages
I've got a one or two 'char' arrays that the interrupt needs to use that I can
guarantee
not to span multiple pages. Looking at the generated code I see things like:
05531 ; .line 172; stepper.c OPCODE =
PCODE[CFRONT];
1CC8 C000 F000 05532 MOVFF r0x00, r0x01
1CCC 6A00 05533 CLRF r0x02
1CCE 0E00 05534 MOVLW LOW(_pcodes + 768)
1CD0 2600 05535 ADDWF r0x01, F
1CD2 0E00 05536 MOVLW HIGH(_pcodes + 768)
1CD4 2200 05537 ADDWFC r0x02, F
this suggest to me that hi byte of the address is unnecessary (in this case)
used in
the indexing calculations.
3) BANSEL for variables on the same page
again looking at the code I see:
1CB4 05519 _00612_DS_:
1CB4 0000 05520 BANKSEL _g_RoundCntr
05521 ; .line 154; stepper.c g_RoundCntr=0;
1CB6 6B00 05522 CLRF _g_RoundCntr, B
05523 ; .line 170; stepper.c if (CREAR!=CFRONT) {
1CB8 C000 F000 05524 MOVFF (_engines + 162), r0x00
1CBC 0000 05525 BANKSEL (_engines + 161)
1CBE 5100 05526 MOVF (_engines + 161), W, B
here again I know that the variables '_g_RoundCntr' and 'engines' both reside on
the same page so the BANKSELs seem redundant (they are even defined in the same
file).
4) The interrupt entry/exit stuff
The interrupt entry/exit save a lot of r0xNN registers, I do claim to really
understand
the details but are these not just some ram locations that I could dedicate to
the
the interrupt so that they do not need to be saved?
2482 CFE4 F000 06615 MOVFF PREINC1, r0x05
2486 CFE4 F000 06616 MOVFF PREINC1, r0x04
248A CFE4 F000 06617 MOVFF PREINC1, r0x03
248E CFE4 F000 06618 MOVFF PREINC1, r0x02
2492 CFE4 F000 06619 MOVFF PREINC1, r0x01
2496 CFE4 F000 06620 MOVFF PREINC1, r0x00
249A CFE4 FFD9 06621 MOVFF PREINC1, FSR2L
249E CFE4 FFFB 06622 MOVFF PREINC1, PCLATU
24A2 CFE4 FFFA 06623 MOVFF PREINC1, PCLATH
24A6 CFE4 FFEA 06624 MOVFF PREINC1, FSR0H
24AA CFE4 FFE9 06625 MOVFF PREINC1, FSR0L
24AE CFE4 FFF4 06626 MOVFF PREINC1, PRODH
24B2 CFE4 FFF3 06627 MOVFF PREINC1, PRODL
24B6 CFE4 FFE0 06628 MOVFF PREINC1, BSR
24BA CFE4 FFD8 06629 MOVFF PREINC1, STATUS
24BE CFE4 FFE8 06630 MOVFF PREINC1, WREG
24C2 0010 06631 RETFIE
5) I've got a macro
#define POPD(X) do {X=DSTACK[0]; DSTACK[0]=DSTACK[1]; DSTACK[1]=DSTACK[2];
DSTACK[2]=DSTACK[3];} while(0)
that compiles to
06229 ; .line 272; stepper.c POPD(ACCU);
21FE C000 F000 06230 MOVFF (_engines + 131), _ACCU
2202 C000 F000 06231 MOVFF (_engines + 132), (_ACCU + 1)
2206 C000 F000 06232 MOVFF (_engines + 133), r0x00
220A C000 F000 06233 MOVFF (_engines + 134), r0x01
220E 5000 06234 MOVF r0x00, W
06235 ; removed redundant BANKSEL
2210 6F00 06236 MOVWF (_engines + 131), B
2212 5000 06237 MOVF r0x01, W
06238 ; removed redundant BANKSEL
2214 6F00 06239 MOVWF (_engines + 132), B
2216 C000 F000 06240 MOVFF (_engines + 135), r0x00
221A C000 F000 06241 MOVFF (_engines + 136), r0x01
221E 5000 06242 MOVF r0x00, W
06243 ; removed redundant BANKSEL
2220 6F00 06244 MOVWF (_engines + 133), B
2222 5000 06245 MOVF r0x01, W
06246 ; removed redundant BANKSEL
2224 6F00 06247 MOVWF (_engines + 134), B
2226 C000 F000 06248 MOVFF (_engines + 137), r0x00
222A C000 F000 06249 MOVFF (_engines + 138), r0x01
222E 5000 06250 MOVF r0x00, W
06251 ; removed redundant BANKSEL
2230 6F00 06252 MOVWF (_engines + 135), B
2232 5000 06253 MOVF r0x01, W
06254 ; removed redundant BANKSEL
2234 6F00 06255 MOVWF (_engines + 136), B
2236 0000 06256 BANKSEL _ACCU
which is not a bad optimization by the compiler but I was wondering if there
there
could be a better way to accomplish this, after all this is just moving 4 words
around...
thank you for your attention!
br Kusti
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user