Electronics & Programming

develissimo

Open Source electronics development and programming

  • You are not logged in.
  • Root
  • » MSPGCC
  • » [Mspgcc-users] intrinsic function __even_in_range [RSS Feed]

#1 June 14, 2010 10:50:23

Paul F.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


I wrote an assembly routine to emulate the intrinsic function__even_in_range, and although it might work I doubt that it accomplishesanything significant. Take a look (below) at the only place where thefunctions is used, in adc12.c. It is a simple switch statement withonly one valid case statement. Seems like it would be just as efficientto use a single "IF __value = 6..." statement. Maybe I just don'tunderstand the significance of the intrinsic function _in this specificcase_, but I don't believe it is worthwhile to spend any more time on it(except that I could use the assembler experience).

switch(__even_in_range(ADC12IV,34))
{
case 0: break; // Vector 0: No interrupt
case 2: break; // Vector 2: ADC overflowcase 4: break; // Vector 4: ADC timingoverflowcase 6: // Vector 6: ADC12IFG0adc12_result = ADC12MEM0; // Moveresults, IFG is clearedadc12_data_ready = 1;_BIC_SR_IRQ(LPM3_bits); // Exitactive CPUbreak;
case 8: break; // Vector 8: ADC12IFG1
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: break; // Vector 14: ADC12IFG4
case 16: break; // Vector 16: ADC12IFG5
case 18: break; // Vector 18: ADC12IFG6
case 20: break; // Vector 20: ADC12IFG7
case 22: break; // Vector 22: ADC12IFG8
case 24: break; // Vector 24: ADC12IFG9
case 26: break; // Vector 26: ADC12IFG10
case 28: break; // Vector 28: ADC12IFG11
case 30: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}


--
Paul


Sehorne owned or managed Web Sites

* Airport Homes <http://airporthomes.org/>
* Female Body Building <http://bodybuilding.sehorne.net/>
* Credit Repair <http://creditrepair.sehorne.net/>
* Personal Loans <http://personalloans.sehorne.net/>
* Shopping <http://shop.sehorne.net/>
* Hidden Valley Airpark <http://hiddenvalleyairpark.org/>

Offline

#2 June 14, 2010 18:03:00

Sergey A.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


On 14.06.2010 5:50, Paul F. Sehorne wrote:I wrote an assembly routine to emulate the intrinsic function
__even_in_range, and although it might work I doubt that it accomplishes
anything significant.This function ensures the compiler that it's first argument is always even andalways in range . So compiler allowed to generate case asefficient table jump without additional checking of switch() statement.And nothing more. You can just replace
switch(__even_in_range(ADC12IV,34))
to
switch(ADC12IV).

--
Regards,
Sergey A. Borshch mailto: sb...@sourceforge.net
SB ELDI ltd. Riga, Latvia

Offline

#3 June 14, 2010 19:20:26

J.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


Having something like this on the mspgcc would be nice. Currently, I have to
use inline assembly for all these vector-register-driven ISRs (Timer, USART,
NMI etc.)
It works and once made, you can forget it, but doing so in 'plain' C would be
nicer.
OTOH, IAR and CCE require something liek that as they don't offer reliable
inline assembly. The GCC is superior here.

JMGross



----- Ursprüngliche Nachricht -----
Von: Sergey A. Borshch
An: GCC for MSP430 -http://mspgcc.sf.netGesendet am: 14 Jun 2010 11:38:01
Betreff: Re: intrinsic function __even_in_range

On 14.06.2010 5:50, Paul F. Sehorne wrote:
> I wrote an assembly routine to emulate the intrinsic function
> __even_in_range, and although it might work I doubt that it accomplishes
> anything significant.
This function ensures the compiler that it's first argument is always even and
always in range . So compiler allowed to generate case as
efficient table jump without additional checking of switch() statement.
And nothing more. You can just replace
switch(__even_in_range(ADC12IV,34))
to
switch(ADC12IV).

Offline

#4 June 14, 2010 23:32:03

Paul F.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


Sergey, thanks for your explanation.I understand the goal of __even_in_range. I saw in the IAR disassembledcode what it accomplishes. And I understand the need if the switchstatement actually had 34 case statements, but in this code there isonly one case statement. So, other than for educational reasons, Idon't see the value of spending my time trying to figure out how towrite the equivalent routine.I did write a routine that confirms (at runtime) that the passed invalue is in range and is even (lsb is 0); in which case the value isjust passed back to the program, and if it does not meet these criterionzero is passed back (again, at runtime). I could further improve thisroutine by moving the code in the one lone case statement into theassembler routine. And I would like to revisit this function at a laterdate, for educational reasons and to eventually have an __even_in_rangefunction when needed for multiple case statements. But for the timebeing I am content to move on to other more pressing issues that areholding up the completion of my port of the eZChronos firmware to mspgcc4.If I am making a mistake by passing on this for the moment, please pointit out to me.Paul


On 6/14/2010 4:38 AM, Sergey A. Borshch wrote:On 14.06.2010 5:50, Paul F. Sehorne wrote:I wrote an assembly routine to emulate the intrinsic function
__even_in_range, and although it might work I doubt that it accomplishes
anything significant.This function ensures the compiler that it's first argument is always even and
always in range . So compiler allowed to generate case as
efficient table jump without additional checking of switch() statement.
And nothing more. You can just replace
switch(__even_in_range(ADC12IV,34))
to
switch(ADC12IV).--
Paul


Sehorne owned or managed Web Sites

* Airport Homes <http://airporthomes.org/>
* Female Body Building <http://bodybuilding.sehorne.net/>
* Credit Repair <http://creditrepair.sehorne.net/>
* Personal Loans <http://personalloans.sehorne.net/>
* Shopping <http://shop.sehorne.net/>
* Hidden Valley Airpark <http://hiddenvalleyairpark.org/>

Offline

#5 June 15, 2010 03:08:59

Anthony A.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


ADC12IV is only 1 example of the usage of the interrupt vecor table.For the msp43054xx cases, every single interrupt has a similar interruptvector register often with numerous subconditions (valid casestatements). Adding support for effeiciently producing these interruptvector tables would be very useful in C would be very useful.For example on the DMA interrupt, the DMAIV is set based on whichchannel is triggered:from slau208e.pdf (msp4305xx Family Guide)


7.3.10 DMA Interrupt Vector Register (DMAIV)
DMAIV Bits 15-0 DMA interrupt vector value
DMAIV Interrupt Source Interrupt Flag Interrupt Contents Priority
00h No interrupt pending
02h DMA channel 0 DMA0IFG Highest
04h DMA channel 1 DMA1IFG
06h DMA channel 2 DMA2IFG
08h DMA channel 3 DMA3IFG
0Ah DMA channel 4 DMA4IFG
0Ch DMA channel 5 DMA5IFG
0Eh DMA channel 6 DMA6IFG
10h DMA channel 7 DMA7IFG LowestThe example usage taken from msp430x54x_dma_04.c in the code examplesshows an interrupt handler like this:#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
switch(__even_in_range(DMAIV,16))
{
case 0: break;
case 2: // DMA0IFG = DMA Channel 0
P1OUT ^= BIT0; // Toggle P1.0
break;
case 4: break; // DMA1IFG = DMA Channel 1
case 6: break; // DMA2IFG = DMA Channel 2
case 8: break; // DMA3IFG = DMA Channel 3
case 10: break; // DMA4IFG = DMA Channel 4
case 12: break; // DMA5IFG = DMA Channel 5
case 14: break; // DMA6IFG = DMA Channel 6
case 16: break; // DMA7IFG = DMA Channel 7
default: break;
}Obviously if more than 1 DMA channel is used, then more then 1 casestatement is required.Paul F. Sehorne wrote:Sergey, thanks for your explanation.I understand the goal of __even_in_range. I saw in the IARdisassembled code what it accomplishes. And I understand the need ifthe switch statement actually had 34 case statements, but in this codethere is only one case statement. So, other than for educationalreasons, I don't see the value of spending my time trying to figureout how to write the equivalent routine.I did write a routine that confirms (at runtime) that the passed invalue is in range and is even (lsb is 0); in which case the value isjust passed back to the program, and if it does not meet thesecriterion zero is passed back (again, at runtime). I could furtherimprove this routine by moving the code in the one lone case statementinto the assembler routine. And I would like to revisit this functionat a later date, for educational reasons and to eventually have an__even_in_range function when needed for multiple case statements.But for the time being I am content to move on to other more pressingissues that are holding up the completion of my port of the eZChronosfirmware to mspgcc4.If I am making a mistake by passing on this for the moment, pleasepoint it out to me.Paul


On 6/14/2010 4:38 AM, Sergey A. Borshch wrote:On 14.06.2010 5:50, Paul F. Sehorne wrote:I wrote an assembly routine to emulate the intrinsic function__even_in_range, and although it might work I doubt that itaccomplishesanything significant.This function ensures the compiler that it's first argument is alwayseven andalways in range . So compiler allowed togenerate case asefficient table jump without additional checking of switch() statement.
And nothing more. You can just replace
switch(__even_in_range(ADC12IV,34))
toswitch(ADC12IV).------------------------------------------------------------------------


Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.nethttps://lists.sourceforge.net/lists/listinfo/mspgcc-users

Offline

#6 June 15, 2010 05:04:48

Anthony A.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


oops, looking back over the context of that thread, I realize that mymessage was slightly off topic.It would be nice for the GCC to support the interrupt vector tablethrough a switch statement.....however for your TI code development I would suggest you remove theintrinsic or define it as a pass through macro. The intention of thisintrinsic in IAR is not to run time check the data, but to assert to thecompiler that the input data has certain properties that can be used tooptimize the assembler code. I think this is more commonly referred toas a "pragma" but IAR implemented it as a intrinsic.a*


Anthony Asterisk wrote:ADC12IV is only 1 example of the usage of the interrupt vecor table.For the msp43054xx cases, every single interrupt has a similarinterrupt vector register often with numerous subconditions (validcase statements). Adding support for effeiciently producing theseinterrupt vector tables would be very useful in C would be very useful.For example on the DMA interrupt, the DMAIV is set based on whichchannel is triggered:from slau208e.pdf (msp4305xx Family Guide)


7.3.10 DMA Interrupt Vector Register (DMAIV)
DMAIV Bits 15-0 DMA interrupt vector value
DMAIV Interrupt Source Interrupt Flag Interrupt Contents Priority
00h No interrupt pending
02h DMA channel 0 DMA0IFG Highest
04h DMA channel 1 DMA1IFG
06h DMA channel 2 DMA2IFG
08h DMA channel 3 DMA3IFG
0Ah DMA channel 4 DMA4IFG
0Ch DMA channel 5 DMA5IFG
0Eh DMA channel 6 DMA6IFG
10h DMA channel 7 DMA7IFG LowestThe example usage taken from msp430x54x_dma_04.c in the code examplesshows an interrupt handler like this:#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
switch(__even_in_range(DMAIV,16))
{
case 0: break;
case 2: // DMA0IFG = DMA Channel 0
P1OUT ^= BIT0; // Toggle P1.0
break;
case 4: break; // DMA1IFG = DMA Channel 1
case 6: break; // DMA2IFG = DMA Channel 2
case 8: break; // DMA3IFG = DMA Channel 3
case 10: break; // DMA4IFG = DMA Channel 4
case 12: break; // DMA5IFG = DMA Channel 5
case 14: break; // DMA6IFG = DMA Channel 6
case 16: break; // DMA7IFG = DMA Channel 7
default: break;
}Obviously if more than 1 DMA channel is used, then more then 1 casestatement is required.Paul F. Sehorne wrote:Sergey, thanks for your explanation.I understand the goal of __even_in_range. I saw in the IARdisassembled code what it accomplishes. And I understand the need ifthe switch statement actually had 34 case statements, but in thiscode there is only one case statement. So, other than foreducational reasons, I don't see the value of spending my time tryingto figure out how to write the equivalent routine.I did write a routine that confirms (at runtime) that the passed invalue is in range and is even (lsb is 0); in which case the value isjust passed back to the program, and if it does not meet thesecriterion zero is passed back (again, at runtime). I could furtherimprove this routine by moving the code in the one lone casestatement into the assembler routine. And I would like to revisitthis function at a later date, for educational reasons and toeventually have an __even_in_range function when needed for multiplecase statements. But for the time being I am content to move on toother more pressing issues that are holding up the completion of myport of the eZChronos firmware to mspgcc4.If I am making a mistake by passing on this for the moment, pleasepoint it out to me.Paul


On 6/14/2010 4:38 AM, Sergey A. Borshch wrote:On 14.06.2010 5:50, Paul F. Sehorne wrote:I wrote an assembly routine to emulate the intrinsic function__even_in_range, and although it might work I doubt that itaccomplishesanything significant.This function ensures the compiler that it's first argument isalways even andalways in range . So compiler allowed togenerate case asefficient table jump without additional checking of switch() statement.
And nothing more. You can just replace
switch(__even_in_range(ADC12IV,34))
toswitch(ADC12IV).------------------------------------------------------------------------


Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.nethttps://lists.sourceforge.net/lists/listinfo/mspgcc-users

Offline

#7 June 15, 2010 08:19:52

Shigenobu K.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


> It would be nice for the GCC to support the interrupt vector table through a
> switch statement.

Here is an example how to implement switch (__even_in_range()) in gcc.

interrupt (UART0TX_VECTOR) i2c_tx()
{
#define __even_in_range(x,y) x
switch (__even_in_range(I2CIV, 0x10)) // Use calculated branching
{
case I2CIV_RXRDY :
I2CBuffer = I2CDRB; // Store RX data in buffer
break;
case I2CIV_TXRDY :
I2CDRB = I2CBuffer;
if (I2CTxPtr-- == 0) // TX finished?
I2CIE &= ~TXRDYIE; // Disable TX ready interrupt
break;
}
}

#if 0
i2c_tx_jump_table()
{
static void *jump_table = {
&&l_else, /* 00 : NONE */
&&l_else, /* 02 : AL */
&&l_else, /* 04 : NACK */
&&l_else, /* 06 : OA */
&&l_else, /* 08 : ARDY */
&&l_RXRDY, /* 0A : RXRDY */
&&l_TXRDY, /* 0C : TXRDY */
&&l_else, /* 0E : GC */
&&l_else, /* 10 : STT */
};
goto *jump_table;
l_TXRDY:
I2CDRB = I2CBuffer;
if (I2CTxPtr-- == 0) // TX finished?
I2CIE &= ~TXRDYIE; // Disable TX ready interrupt
goto l_else;
l_RXRDY:
I2CBuffer = I2CDRB; // Store RX data in buffer
l_else: ;
}

/* switch
mov &0x011C, r15
cmp #llo(10), r15
jeq .L65
cmp #llo(12), r15
jeq .L66
jmp .L63


jump_table
mov &0x011C, r15
bic #llo(1),r15
br jump_table.0(r15)
.L73:

*/
#endif

Offline

#8 June 15, 2010 19:31:43

J.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[Mspgcc-users] intrinsic function __even_in_range


Of course you're right, if you only have one case, even a normal switch
statement makes no sense at all. A simple IF does it as well.


Anyway, this intrinsic has its advantages. For all these ISRs with a vector
register (and on the 54xx, almost ALL ISRs have one, including the reset), I
use an ISR of the following form:

interrupt(TIMER1_A1_VECTOR) timera1x_handler(void){
__asm__ __volatile__("add % ,r0 ":: "m" (TA1IV));
__asm__ __volatile__("reti "::); // NO INT
__asm__ __volatile__("jmp timera1_cc1_handler "::); // CC1
__asm__ __volatile__("jmp timera1_cc2_handler "::); // CC2
__asm__ __volatile__("reti "::); // RESERVED
__asm__ __volatile__("reti "::); // RESERVED
__asm__ __volatile__("reti "::); // RESERVED
__asm__ __volatile__("reti "::); // RESERVED
__asm__ __volatile__("jmp timera1_ifg_handler "::); // IFG
}
interrupt(NOVECTOR) timera1_cc1_handler(void){}
interrupt(NOVECTOR) timera1_cc2_handler(void){}
interrupt(NOVECTOR) timera1_ifg_handler(void){}


Doing so with a case statement that results in the same efficience would be
great, but this can only be done with direct compiler support.
Just a function that checks (at runtime) whether the result is even and in a
given range is useless if no code is generated to take advantage from this
information.
I don't think the original intrinsic will do any runtime checking. (I've never
seen an IAR or CCE assembly output) But I guess It just generates a jumptable
like above, filling the 'gaps' where no case exists with a dummy
jump behind the case statement. Any function call would be counterproductive.
It is, however, not advised to use an IV register as parameter to a normal
switch statement. It's possible that you'll read the register once for every
case statement, which of course won't work since the register is
cleared with the first read.

JMGross

----- Ursprüngliche Nachricht -----
Von: Paul F. Sehorne
An: GCC for MSP430 -http://mspgcc.sf.netGesendet am: 14 Jun 2010 17:31:55
Betreff: Re: intrinsic function __even_in_range


I understand the goal of __even_in_range. I saw in the IAR disassembled
code what it accomplishes. And I understand the need if the switch
statement actually had 34 case statements, but in this code there is
only one case statement. So, other than for educational reasons, I
don't see the value of spending my time trying to figure out how to
write the equivalent routine.

I did write a routine that confirms (at runtime) that the passed in
value is in range and is even (lsb is 0); in which case the value is
just passed back to the program, and if it does not meet these criterion
zero is passed back (again, at runtime). I could further improve this
routine by moving the code in the one lone case statement into the
assembler routine. And I would like to revisit this function at a later
date, for educational reasons and to eventually have an __even_in_range
function when needed for multiple case statements. But for the time
being I am content to move on to other more pressing issues that are
holding up the completion of my port of the eZChronos firmware to mspgcc4.

If I am making a mistake by passing on this for the moment, please point
it out to me.

Paul

Offline

  • Root
  • » MSPGCC
  • » [Mspgcc-users] intrinsic function __even_in_range [RSS Feed]

Board footer

Moderator control

Enjoy the 16th of December
PoweredBy

The Forums are managed by develissimo stuff members, if you find any issues or misplaced content please help us to fix it. Thank you! Tell us via Contact Options
Leave a Message
Welcome to Develissimo Live Support