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

Reply via email to