• AVR Freaks

Is there a way to force C30 generate a Jump Table for a simple switch() statement?

Page: 123 > Showing page 1 of 3
Author
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
2017/10/29 12:36:29 (permalink)
0

Is there a way to force C30 generate a Jump Table for a simple switch() statement?

[some sunday question, again Smile
 
I have a simple switch() with some 8 cases, based upon an enum hence all consecutive: but the compiler still generates a bunch of Comparisons/Branch... no matter what optimization in use.
 
I am (for a change!) pushing the limits of speed in an interrupt so... well, it would be nice.
 
Maybe XC16 does it better?

GENOVA :D :D ! GODO
#1

44 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 12:38:21 (permalink)
    0
    DarioG
    ...
    Maybe XC16 does it better?

    Certainly XC8 does some deep analysis of the best approach for each switch() statement, so you'd expect that to have moved into XC16.
    #2
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 12:51:45 (permalink)
    0
    Let me try then Smile

    GENOVA :D :D ! GODO
    #3
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 13:25:54 (permalink)
    0
    Ufff, no I can't test it right now - I'm using some library functions and of course XC does not have them...
     
    If anyone wants to try, this is the simple snippet of code:

    void __attribute__ (( interrupt, shadow,  no_auto_psv )) _T3Interrupt(void) {
        static BYTE sampleCnt;
        static const WORD *ptr=samplesTable;
      static WORD lfsr = 0xACE1u;
        BYTE b;
    //uso ptr per velocizzare!
    // potremmo essere sulle 13-15 istruzioni in tutto...300nS

    //    mLED_1_Toggle();

        switch(tipoOnda) {
            case NESSUNA:
                break;
            case QUADRA:
                break;
            case TRIANGOLARE:
                sampleCnt++;
    //          OC1RS   = samplesTable /*TRIANGLE_WAVE_TABLE*/[sampleCnt++];
              OC1RS   = *ptr++;
                break;
            case SAWTOOTH:
                sampleCnt++;
    //          OC1RS   = samplesTable /*SAWTOOTH_WAVE_TABLE*/[sampleCnt++];
              OC1RS   = *ptr++;
                break;
            case SINUSOIDALE:
                sampleCnt++;
    //          OC1RS   = samplesTable /*SINE_WAVE_TABLE*/[sampleCnt++];
              OC1RS   = *ptr++;
                break;
            case IMPULSI:
                break;
            case RUMORE_BIANCO:
    //          OC1RS   = (FCY/1000000L*rand())/RAND_MAX;
            b  = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
            lfsr =  (lfsr >> 1) | (b << 15);
                OC1RS = lfsr >> 10;        // basato su 64
                break;
            case RUMORE_ROSA:            // filtrare...
    //          OC1RS   = (FCY/1000000L*rand())/RAND_MAX;
            b  = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
            lfsr =  (lfsr >> 1) | (b << 15);
                OC1RS = lfsr >> 10;        // basato su 64
                break;
            }

    //    sampleCnt &= NUM_SAMPLES-1;
    //    if(sampleCnt >= NUM_SAMPLES) {
        if(sampleCnt & 0x10) {
            sampleCnt=0;
            ptr=samplesTable;
            }    

        IFS0bits.T3IF = 0;             //Clear the Timer2 interrupt status flag
        // non lo trova @#£$% T2_Clear_Intr_Status_Bit;     
        }

     
    with this enum:

    enum TIPO_ONDA {
        NESSUNA,
        QUADRA,
        TRIANGOLARE,
        SAWTOOTH,
        SINUSOIDALE,
        IMPULSI,
        RUMORE_BIANCO,
        RUMORE_ROSA
        };

     
    PIC is a PIC24EP512GU810

    GENOVA :D :D ! GODO
    #4
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 13:54:02 (permalink)
    0
    put functions in an array and call them indirectly.
    or create a jump table in asm.
     
    void func(int j);
     
    .globl _func
     
    .equ arg_Index,w0
     
    _func:
    ;*** sl arg_Index,arg_Index if gotos ***
    bra     arg_Index
    bra     _NESSUNA
    bra     _QUADRA
    bra     _TRIANGOLARE
     
     
     
    post edited by Gort2015 - 2017/10/29 14:05:05

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #5
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 14:03:58 (permalink)
    0
    Hmmm, thanks for the array suggestion Smile even if at the interrupt level that may trigger more saving.
     
    And writing a Jump Table in ASM in there is something I never did but... I can learn!

    GENOVA :D :D ! GODO
    #6
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 14:13:43 (permalink)
    +1 (1)
    More effective.
    Indexing is always faster that way.
     
     
    I watched a tv program the other night and it was dubbed in Russian.
    They had 2 people doing all the voices and there was no emotion in their voices.
     
    There was always that joke about Russia finding out that John Lennon was dead because they were so behind.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #7
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 14:36:31 (permalink)
    0
    Yep.
     
    And yes, I was in Poland long ago and they used to the same! On the other hand, I watched a movie with Will Smith and Gene Hackman, some time ago, and not only it was well dubbed, the screens (TV, PC) were translated... but even Gene was eating a Bretzel grin !!!
    (no, maybe it was like that in original too.)
     
    BTW, I have a version of Terminator Salvation with russian subtitles.

    GENOVA :D :D ! GODO
    #8
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 15:02:31 (permalink)
    0
    You ever seen Monkey? (Journey to the West)
    It must be over 30yrs old.
     
    The English dubbing is good on that.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #9
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 15:20:05 (permalink)
    0
    Gort2015
    You ever seen Monkey? (Journey to the West)
    It must be over 30yrs old.
     
    The English dubbing is good on that.

    There's a remake in the works, but it could never be the same...
    https://en.wikipedia.org/wiki/The_Legend_of_Monkey
     
    #10
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/29 15:53:07 (permalink)
    0
    No, I don't know that... let me check

    GENOVA :D :D ! GODO
    #11
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/10/30 12:07:48 (permalink)
    +1 (1)
    Can't believe you have not seen the original Monkey.
    There was another series about 5yrs ago.  That was Japanese, subs in English.
     
    Didn't know about the Legend of Monkey.  See if I can get a preview on youtube.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #12
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 08:32:23 (permalink)
    +1 (1)
    I came up with this code (inside ISR) and it's good enough Smile

    __asm__ (

    "mov   #0,w0\n"
    "mov.b   _configParms+2,wreg\n"
    "bra     w0\n"
    "bra     label_NESSUNA\n"
    "bra     label_QUADRA\n"
    "bra     label_TRIANGOLARE\n"
    "bra     label_SAWTOOTH\n"
    "bra     label_SINUSOIDALE\n"
    "bra     label_IMPULSI\n"
    "bra     label_RUMORE_BIANCO\n"
    "bra     label_RUMORE_ROSA\n"
    );

        switch(configParms.tipoOnda) {
            case NESSUNA:
    __asm__ ("label_NESSUNA:");
                break;
            case QUADRA:
    __asm__ ("label_QUADRA:");
                break;
            case TRIANGOLARE:
    __asm__ ("label_TRIANGOLARE:");
                sampleCnt++;
              OC1R   = *ptr++;
                break;
            case SAWTOOTH:
    __asm__ ("label_SAWTOOTH:");
                sampleCnt++;
              OC1R   = *ptr++;
                break;
            case SINUSOIDALE:
    __asm__ ("label_SINUSOIDALE:");
                sampleCnt++;
              OC1R   = *ptr++;
                break;
            case IMPULSI:
    __asm__ ("label_IMPULSI:");
                break;
            case RUMORE_BIANCO:
    __asm__ ("label_RUMORE_BIANCO:");
            b  = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
            lfsr =  (lfsr >> 1) | (b << 15);
                OC1R = lfsr >> 10;        // basato su 64
                break;
            case RUMORE_ROSA:            // filtrare...
    __asm__ ("label_RUMORE_ROSA:");
            b  = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
            lfsr =  (lfsr >> 1) | (b << 15);
                OC1R = lfsr >> 10;        // basato su 64
                break;
            }

        if(sampleCnt & 0x10) {
            sampleCnt=0;
            ptr=samplesTable;
            }   

     
    I could even leave switch in place! (for debugging or in case I change my mind)
    But I could not use C labels... strange.
     
    A pity you can't move a byte to a Wreg clearing upper byte. Of course I could make my "switch" label a 16bits one but... will think later.
     
    An average of 11cycles. => 150nSec... this means 600KHz sinewave synthesized with 8 samples Smile good enough for my multi-waveform functions generator.
     
    Oh, of course we can also overclock (!)

    GENOVA :D :D ! GODO
    #13
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 09:33:39 (permalink)
    0
    "A pity you can't move a byte to a Wreg clearing upper byte."
    Or
    bra.b

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #14
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 10:11:28 (permalink)
    0
    Acc, really?! I did not see that in the docs...

    GENOVA :D :D ! GODO
    #15
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 10:12:01 (permalink)
    0
    No, C30 assembler-inline does not like bra.b ...
     

    GENOVA :D :D ! GODO
    #16
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 11:38:24 (permalink)
    0
    It does not exist but it would have been nice.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #17
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 11:44:13 (permalink)
    0
    ah-ah, you're ... "£$%@#! grin
     
    I was wodering if a SL could act in place of a MOV, sign-extending to the high byte... (my Cases are < 10)

    GENOVA :D :D ! GODO
    #18
    malaugh
    Super Member
    • Total Posts : 400
    • Reward points : 0
    • Joined: 2011/03/31 14:04:42
    • Location: San Diego
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 13:05:52 (permalink)
    0
    you could make your own jump table
     

    int func;
    int index = 0;
     
    void func1(void) { func = 1; }
    void func2(void) { func = 2; }
    void func3(void) { func = 3; }
     
    typedef   void (*NULLFUNC)(void);
    NULLFUNC JumpTable[] = { func1,    func2,    func3 };
     
    void main(void)
    {
        JumpTable[index]();
    }

    #19
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3366
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Is there a way to force C30 generate a Jump Table for a simple switch() statement? 2017/11/01 14:51:26 (permalink)
    0
    Asm is just quicker for interrupt coding.
     
    "SL inplace of move"
    You can "SL" then "SE" sign extend or "ZE" zero extend.
     
    ;0100,1001
    sl w0,w0
    ;1001,0010
    se w0,w0
    1111,1111,1001,0010
     
    The high destination byte is always wiped.
    post edited by Gort2015 - 2017/11/01 14:59:23

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #20
    Page: 123 > Showing page 1 of 3
    Jump to:
    © 2019 APG vNext Commercial Version 4.5