Folks,
I'm trying to read the status register to see if the cpu is off while
inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and
the compiler doesn't recognize SR or R2. I'm sure this is simple.
What am I missing? MSP430F5438 chip...
Thanks,
Mike Raines
Reading status register
Started by ●August 4, 2009
Reply by ●August 4, 20092009-08-04
You do not mean the current content of SR. Do you?
If you use the CPU to read the current content of SR, I can guarantee that the CPUOFF bit is 0.
The content of SR before the interrupt is saved in the stack.
--- In m..., "Mike Raines" wrote:
>
> Folks,
>
> I'm trying to read the status register to see if the cpu is off while inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and the compiler doesn't recognize SR or R2. I'm sure this is simple. What am I missing? MSP430F5438 chip...
> Thanks,
> Mike Raines
>
If you use the CPU to read the current content of SR, I can guarantee that the CPUOFF bit is 0.
The content of SR before the interrupt is saved in the stack.
--- In m..., "Mike Raines" wrote:
>
> Folks,
>
> I'm trying to read the status register to see if the cpu is off while inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and the compiler doesn't recognize SR or R2. I'm sure this is simple. What am I missing? MSP430F5438 chip...
> Thanks,
> Mike Raines
>
Reply by ●August 4, 20092009-08-04
On Tue, 04 Aug 2009 15:02:14 +0100, Mike Raines
wrote:
> Folks,
>
> I'm trying to read the status register to see if the cpu is off while
> inside the SYSNMI ISR.
If you are executing, then the CPU cannot be "off". Or else it wouldn't
run. Am I being totally thick here? No, I don't think so.
> I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and the compiler
> doesn't recognize SR or R2.
Of course it doesn't.
> I'm sure this is simple. What am I missing? MSP430F5438 chip...
Try looking at the intrinsic functions for your compiler. I do not
believe you wish to read R2 directly because, if you're executing, the CPU
CANNOT BE OFF!
-- Paul.
wrote:
> Folks,
>
> I'm trying to read the status register to see if the cpu is off while
> inside the SYSNMI ISR.
If you are executing, then the CPU cannot be "off". Or else it wouldn't
run. Am I being totally thick here? No, I don't think so.
> I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and the compiler
> doesn't recognize SR or R2.
Of course it doesn't.
> I'm sure this is simple. What am I missing? MSP430F5438 chip...
Try looking at the intrinsic functions for your compiler. I do not
believe you wish to read R2 directly because, if you're executing, the CPU
CANNOT BE OFF!
-- Paul.
Reply by ●August 4, 20092009-08-04
Mike Raines wrote:
> Folks,
>
> I'm trying to read the status register to see if the cpu is off while inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and the compiler doesn't recognize SR or R2. I'm sure this is simple. What am I missing? MSP430F5438 chip...
>
As pointed out, the cpu is running in the interrupt. The condition of
LPM is on the stack and gets popped back at the interrupt exit. I don't
know about your compiler but for mspgcc there is READ_SP. It assembles to:
mov r1, r15;
So you can:
if( READ_SP & CPUOFF)
to see if you will be in LPM.
Best, Dan.
> Folks,
>
> I'm trying to read the status register to see if the cpu is off while inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF) and the compiler doesn't recognize SR or R2. I'm sure this is simple. What am I missing? MSP430F5438 chip...
>
As pointed out, the cpu is running in the interrupt. The condition of
LPM is on the stack and gets popped back at the interrupt exit. I don't
know about your compiler but for mspgcc there is READ_SP. It assembles to:
mov r1, r15;
So you can:
if( READ_SP & CPUOFF)
to see if you will be in LPM.
Best, Dan.
Reply by ●August 4, 20092009-08-04
Hi,
> Mike Raines wrote:
> > Folks,
> >
> > I'm trying to read the status register to see if the cpu is off while
> inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF)
> and the compiler doesn't recognize SR or R2. I'm sure this is simple.
> What am I missing? MSP430F5438 chip...
> >
>
> As pointed out, the cpu is running in the interrupt. The condition of
> LPM is on the stack and gets popped back at the interrupt exit. I don't
> know about your compiler but for mspgcc there is READ_SP. It assembles to:
> mov r1, r15;
>
> So you can:
> if( READ_SP & CPUOFF)
I think you're just testing a bit in the stack pointer. That's not what you
want to do. You need to read a value offset from the stack pointer--doing
so is inherently non-portable. There are intrinsic functions to do this for
you which will account for the current stack pointer and the stack pointer
on entry to the ISR.
--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!
> Mike Raines wrote:
> > Folks,
> >
> > I'm trying to read the status register to see if the cpu is off while
> inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF)
> and the compiler doesn't recognize SR or R2. I'm sure this is simple.
> What am I missing? MSP430F5438 chip...
> >
>
> As pointed out, the cpu is running in the interrupt. The condition of
> LPM is on the stack and gets popped back at the interrupt exit. I don't
> know about your compiler but for mspgcc there is READ_SP. It assembles to:
> mov r1, r15;
>
> So you can:
> if( READ_SP & CPUOFF)
I think you're just testing a bit in the stack pointer. That's not what you
want to do. You need to read a value offset from the stack pointer--doing
so is inherently non-portable. There are intrinsic functions to do this for
you which will account for the current stack pointer and the stack pointer
on entry to the ISR.
--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!
Reply by ●August 4, 20092009-08-04
Paul Curtis wrote:
> Hi,
>
>
>> Mike Raines wrote:
>>
>>> Folks,
>>>
>>> I'm trying to read the status register to see if the cpu is off while
>>>
>> inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF)
>> and the compiler doesn't recognize SR or R2. I'm sure this is simple.
>> What am I missing? MSP430F5438 chip...
>>
>> As pointed out, the cpu is running in the interrupt. The condition of
>> LPM is on the stack and gets popped back at the interrupt exit. I don't
>> know about your compiler but for mspgcc there is READ_SP. It assembles to:
>> mov r1, r15;
>>
>> So you can:
>> if( READ_SP & CPUOFF)
>>
>
> I think you're just testing a bit in the stack pointer. That's not what you
> want to do. You need to read a value offset from the stack pointer--doing
> so is inherently non-portable. There are intrinsic functions to do this for
> you which will account for the current stack pointer and the stack pointer
> on entry to the ISR.
>
Hi Paul,
Thanks. And it occurred to me after posting. I don't know what that
function is in mspgcc so I would end up hacking one. But I'm not sure
about the rest. I take it the offset is about using an extended memory
device like the MSP430F543x? Is that what the .L__FrameOffset_ is for?
(I have not used a device past 64k yet).
But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work fine?
And yes! by declaring my int pointer unsigned I get clrc, rrc!
It just doesn't feel right that whatever was sitting in the carry flag
gets shifted in for a signed int.
Best, Dan.
> Hi,
>
>
>> Mike Raines wrote:
>>
>>> Folks,
>>>
>>> I'm trying to read the status register to see if the cpu is off while
>>>
>> inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF)
>> and the compiler doesn't recognize SR or R2. I'm sure this is simple.
>> What am I missing? MSP430F5438 chip...
>>
>> As pointed out, the cpu is running in the interrupt. The condition of
>> LPM is on the stack and gets popped back at the interrupt exit. I don't
>> know about your compiler but for mspgcc there is READ_SP. It assembles to:
>> mov r1, r15;
>>
>> So you can:
>> if( READ_SP & CPUOFF)
>>
>
> I think you're just testing a bit in the stack pointer. That's not what you
> want to do. You need to read a value offset from the stack pointer--doing
> so is inherently non-portable. There are intrinsic functions to do this for
> you which will account for the current stack pointer and the stack pointer
> on entry to the ISR.
>
Hi Paul,
Thanks. And it occurred to me after posting. I don't know what that
function is in mspgcc so I would end up hacking one. But I'm not sure
about the rest. I take it the offset is about using an extended memory
device like the MSP430F543x? Is that what the .L__FrameOffset_ is for?
(I have not used a device past 64k yet).
But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work fine?
And yes! by declaring my int pointer unsigned I get clrc, rrc!
It just doesn't feel right that whatever was sitting in the carry flag
gets shifted in for a signed int.
Best, Dan.
Reply by ●August 4, 20092009-08-04
On Tue, 04 Aug 2009 18:31:20 +0100, Dan Bloomquist
wrote:
>>> So you can:
>>> if( READ_SP & CPUOFF)
>>
>> I think you're just testing a bit in the stack pointer. That's not
>> what you
>> want to do. You need to read a value offset from the stack
>> pointer--doing
>> so is inherently non-portable. There are intrinsic functions to do
>> this for you which will account for the current stack pointer and the
>> stack pointer on entry to the ISR.
>> Hi Paul,
> Thanks. And it occurred to me after posting. I don't know what that
> function is in mspgcc so I would end up hacking one. But I'm not sure
> about the rest. I take it the offset is about using an extended memory
> device like the MSP430F543x? Is that what the .L__FrameOffset_ is for?
Who knows? I've no interest in MSPGCC. ;-)
> (I have not used a device past 64k yet).
>
> But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work
> fine?
No. Consider a function with a local that is addressed--SP will (usually)
be decremented by two on entry to the function to make a stack frame,
hence *SP or 2(SP) does not get you the saved SR and return address, it
would now be 2(SP) and 4(SP). Even worse, if in your C code you needed to
call a function which requires arguments on the stack *and* you want to
read what's in the stack frame, then those 2(SP) and 4(SP) refrences have
to change (depending on how much is currently pushed on to the stack, aka
the stack adjustment).
> And yes! by declaring my int pointer unsigned I get clrc, rrc!
That's fine. And shifting an int is (in fact) inherently non-portable.
> It just doesn't feel right that whatever was sitting in the carry flag
> gets shifted in for a signed int.
If you read the C standard you will find that shifting a signed integer
can result in an aritmetic shift (shift sign bit in) *or* a logical shift
(shift a zero bit in).
How portable is that? Is it any wonder that there are brittle programs in
this world when users assume a specific type of shift?
-- Paul.
wrote:
>>> So you can:
>>> if( READ_SP & CPUOFF)
>>
>> I think you're just testing a bit in the stack pointer. That's not
>> what you
>> want to do. You need to read a value offset from the stack
>> pointer--doing
>> so is inherently non-portable. There are intrinsic functions to do
>> this for you which will account for the current stack pointer and the
>> stack pointer on entry to the ISR.
>> Hi Paul,
> Thanks. And it occurred to me after posting. I don't know what that
> function is in mspgcc so I would end up hacking one. But I'm not sure
> about the rest. I take it the offset is about using an extended memory
> device like the MSP430F543x? Is that what the .L__FrameOffset_ is for?
Who knows? I've no interest in MSPGCC. ;-)
> (I have not used a device past 64k yet).
>
> But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work
> fine?
No. Consider a function with a local that is addressed--SP will (usually)
be decremented by two on entry to the function to make a stack frame,
hence *SP or 2(SP) does not get you the saved SR and return address, it
would now be 2(SP) and 4(SP). Even worse, if in your C code you needed to
call a function which requires arguments on the stack *and* you want to
read what's in the stack frame, then those 2(SP) and 4(SP) refrences have
to change (depending on how much is currently pushed on to the stack, aka
the stack adjustment).
> And yes! by declaring my int pointer unsigned I get clrc, rrc!
That's fine. And shifting an int is (in fact) inherently non-portable.
> It just doesn't feel right that whatever was sitting in the carry flag
> gets shifted in for a signed int.
If you read the C standard you will find that shifting a signed integer
can result in an aritmetic shift (shift sign bit in) *or* a logical shift
(shift a zero bit in).
How portable is that? Is it any wonder that there are brittle programs in
this world when users assume a specific type of shift?
-- Paul.
Reply by ●August 4, 20092009-08-04
Thanks to all who replied and either pointed out the faults in my algorithm or
pointed to a better way.
I checked the intrinsic functions for IAR (full) and am using "if (__get_SR_register_on_exit() & CPUOFF) "
to determine if I will be asleep when exiting the ISR.
Thanks again. Great bunch of Guys,
Mike Raines
________________________________
From: m... [mailto:m...] On Behalf Of Dan Bloomquist
Sent: Tuesday, August 04, 2009 1:31 PM
To: m...
Subject: Re: [msp430] Reading status register
Paul Curtis wrote:
> Hi,
>> Mike Raines wrote:
>>
>>> Folks,
>>>
>>> I'm trying to read the status register to see if the cpu is off while
>>>
>> inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF)
>> and the compiler doesn't recognize SR or R2. I'm sure this is simple.
>> What am I missing? MSP430F5438 chip...
>>
>> As pointed out, the cpu is running in the interrupt. The condition of
>> LPM is on the stack and gets popped back at the interrupt exit. I don't
>> know about your compiler but for mspgcc there is READ_SP. It assembles to:
>> mov r1, r15;
>>
>> So you can:
>> if( READ_SP & CPUOFF)
>> I think you're just testing a bit in the stack pointer. That's not what you
> want to do. You need to read a value offset from the stack pointer--doing
> so is inherently non-portable. There are intrinsic functions to do this for
> you which will account for the current stack pointer and the stack pointer
> on entry to the ISR.
>
Hi Paul,
Thanks. And it occurred to me after posting. I don't know what that
function is in mspgcc so I would end up hacking one. But I'm not sure
about the rest. I take it the offset is about using an extended memory
device like the MSP430F543x? Is that what the .L__FrameOffset_ is for?
(I have not used a device past 64k yet).
But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work fine?
And yes! by declaring my int pointer unsigned I get clrc, rrc!
It just doesn't feel right that whatever was sitting in the carry flag
gets shifted in for a signed int.
Best, Dan.
I checked the intrinsic functions for IAR (full) and am using "if (__get_SR_register_on_exit() & CPUOFF) "
to determine if I will be asleep when exiting the ISR.
Thanks again. Great bunch of Guys,
Mike Raines
________________________________
From: m... [mailto:m...] On Behalf Of Dan Bloomquist
Sent: Tuesday, August 04, 2009 1:31 PM
To: m...
Subject: Re: [msp430] Reading status register
Paul Curtis wrote:
> Hi,
>> Mike Raines wrote:
>>
>>> Folks,
>>>
>>> I'm trying to read the status register to see if the cpu is off while
>>>
>> inside the SYSNMI ISR. I have tried if (SR & CPUOFF) and if (R2 & CPUOFF)
>> and the compiler doesn't recognize SR or R2. I'm sure this is simple.
>> What am I missing? MSP430F5438 chip...
>>
>> As pointed out, the cpu is running in the interrupt. The condition of
>> LPM is on the stack and gets popped back at the interrupt exit. I don't
>> know about your compiler but for mspgcc there is READ_SP. It assembles to:
>> mov r1, r15;
>>
>> So you can:
>> if( READ_SP & CPUOFF)
>> I think you're just testing a bit in the stack pointer. That's not what you
> want to do. You need to read a value offset from the stack pointer--doing
> so is inherently non-portable. There are intrinsic functions to do this for
> you which will account for the current stack pointer and the stack pointer
> on entry to the ISR.
>
Hi Paul,
Thanks. And it occurred to me after posting. I don't know what that
function is in mspgcc so I would end up hacking one. But I'm not sure
about the rest. I take it the offset is about using an extended memory
device like the MSP430F543x? Is that what the .L__FrameOffset_ is for?
(I have not used a device past 64k yet).
But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work fine?
And yes! by declaring my int pointer unsigned I get clrc, rrc!
It just doesn't feel right that whatever was sitting in the carry flag
gets shifted in for a signed int.
Best, Dan.
Reply by ●August 4, 20092009-08-04
Paul Curtis wrote:
> On Tue, 04 Aug 2009 18:31:20 +0100, Dan Bloomquist
> wrote:
>
>
>> (I have not used a device past 64k yet).
>>
>> But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work
>> fine?
>>
>
> No. Consider a function with a local that is addressed--SP will (usually)
> be decremented by two on entry to the function to make a stack frame,
> hence *SP or 2(SP) does not get you the saved SR and return address, it
> would now be 2(SP) and 4(SP). Even worse, if in your C code you needed to
> call a function which requires arguments on the stack *and* you want to
> read what's in the stack frame, then those 2(SP) and 4(SP) refrences have
> to change (depending on how much is currently pushed on to the stack, aka
> the stack adjustment).
>
So I did a test, the lights came on. .L__FrameOffset_ is an assembler
directive to offset the SP according to what is pushed on the stack in a
call. In one interrupt, no pushes I get:
LPM3_EXIT;
279a: b1 c0 d0 00 bic #208, 0(r1) ;#0x00d0
And with an r15 push I get:
LPM3_EXIT;
2758: b1 c0 d0 00 bic #208, 2(r1) ;#0x00d0
275c: 02 00
I could not find a __get_SR_register_on_exit but it would look like:
#define GET_SR_ON_EXIT \
({ \
uint16_t __x; \
__asm__ __volatile__( \
"mov .L__FrameOffset_" __FUNCTION__ "(r1), r15" \
: "=r" ((uint16_t) __x) \
:); \
__x; \
})
It compiles:
GET_SR_ON_EXIT;
2790: 1f 41 02 00 mov 2(r1), r15 ;
Thanks, Dan.
> On Tue, 04 Aug 2009 18:31:20 +0100, Dan Bloomquist
> wrote:
>
>
>> (I have not used a device past 64k yet).
>>
>> But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work
>> fine?
>>
>
> No. Consider a function with a local that is addressed--SP will (usually)
> be decremented by two on entry to the function to make a stack frame,
> hence *SP or 2(SP) does not get you the saved SR and return address, it
> would now be 2(SP) and 4(SP). Even worse, if in your C code you needed to
> call a function which requires arguments on the stack *and* you want to
> read what's in the stack frame, then those 2(SP) and 4(SP) refrences have
> to change (depending on how much is currently pushed on to the stack, aka
> the stack adjustment).
>
So I did a test, the lights came on. .L__FrameOffset_ is an assembler
directive to offset the SP according to what is pushed on the stack in a
call. In one interrupt, no pushes I get:
LPM3_EXIT;
279a: b1 c0 d0 00 bic #208, 0(r1) ;#0x00d0
And with an r15 push I get:
LPM3_EXIT;
2758: b1 c0 d0 00 bic #208, 2(r1) ;#0x00d0
275c: 02 00
I could not find a __get_SR_register_on_exit but it would look like:
#define GET_SR_ON_EXIT \
({ \
uint16_t __x; \
__asm__ __volatile__( \
"mov .L__FrameOffset_" __FUNCTION__ "(r1), r15" \
: "=r" ((uint16_t) __x) \
:); \
__x; \
})
It compiles:
GET_SR_ON_EXIT;
2790: 1f 41 02 00 mov 2(r1), r15 ;
Thanks, Dan.
Reply by ●August 4, 20092009-08-04
On Tue, 04 Aug 2009 20:13:46 +0100, Dan Bloomquist
wrote:
> Paul Curtis wrote:
>> On Tue, 04 Aug 2009 18:31:20 +0100, Dan Bloomquist
>> wrote:
>>> (I have not used a device past 64k yet).
>>>
>>> But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work
>>> fine?
>>> No. Consider a function with a local that is addressed--SP will
>> (usually)
>> be decremented by two on entry to the function to make a stack frame,
>> hence *SP or 2(SP) does not get you the saved SR and return address, it
>> would now be 2(SP) and 4(SP). Even worse, if in your C code you needed
>> to
>> call a function which requires arguments on the stack *and* you want to
>> read what's in the stack frame, then those 2(SP) and 4(SP) refrences
>> have
>> to change (depending on how much is currently pushed on to the stack,
>> aka
>> the stack adjustment).
>> So I did a test, the lights came on. .L__FrameOffset_ is an assembler
> directive to offset the SP according to what is pushed on the stack in a
> call. In one interrupt, no pushes I get:
> LPM3_EXIT;
> 279a: b1 c0 d0 00 bic #208, 0(r1) ;#0x00d0
>
> And with an r15 push I get:
> LPM3_EXIT;
> 2758: b1 c0 d0 00 bic #208, 2(r1) ;#0x00d0
> 275c: 02 00
This only works if the stack pointer is not adjusted after the stack frame
is created during execution of the function--a big ask.
> I could not find a __get_SR_register_on_exit but it would look like:
>
> #define GET_SR_ON_EXIT \
> ({ \
> uint16_t __x; \
> __asm__ __volatile__( \
> "mov .L__FrameOffset_" __FUNCTION__ "(r1), r15" \
> : "=r" ((uint16_t) __x) \
> :); \
> __x; \
> })
I don't believe this definition is correct; for a start, the =r constraint
assigns x to *some* register, might be r15, might not. It might work out
for some functions, but won't for others. (Why use the =r constraint if
there is no constraint in the assembly template text?)
> It compiles:
> GET_SR_ON_EXIT;
> 2790: 1f 41 02 00 mov 2(r1), r15 ;
Like I said, lucky. This time.
You are not alone in getting this wrong--even Luminary (now owned by TI)
got this stuff wrong with GCC and shipped it. I'm not sure anybody
bothered to test their broken code on GCC because Michael has spent a few
days correcting the "canned examples that just work!" that don't.
-- Paul.
wrote:
> Paul Curtis wrote:
>> On Tue, 04 Aug 2009 18:31:20 +0100, Dan Bloomquist
>> wrote:
>>> (I have not used a device past 64k yet).
>>>
>>> But for a <64k device shouldn't 'if( *(int*)READ_SP & CPUOFF )' work
>>> fine?
>>> No. Consider a function with a local that is addressed--SP will
>> (usually)
>> be decremented by two on entry to the function to make a stack frame,
>> hence *SP or 2(SP) does not get you the saved SR and return address, it
>> would now be 2(SP) and 4(SP). Even worse, if in your C code you needed
>> to
>> call a function which requires arguments on the stack *and* you want to
>> read what's in the stack frame, then those 2(SP) and 4(SP) refrences
>> have
>> to change (depending on how much is currently pushed on to the stack,
>> aka
>> the stack adjustment).
>> So I did a test, the lights came on. .L__FrameOffset_ is an assembler
> directive to offset the SP according to what is pushed on the stack in a
> call. In one interrupt, no pushes I get:
> LPM3_EXIT;
> 279a: b1 c0 d0 00 bic #208, 0(r1) ;#0x00d0
>
> And with an r15 push I get:
> LPM3_EXIT;
> 2758: b1 c0 d0 00 bic #208, 2(r1) ;#0x00d0
> 275c: 02 00
This only works if the stack pointer is not adjusted after the stack frame
is created during execution of the function--a big ask.
> I could not find a __get_SR_register_on_exit but it would look like:
>
> #define GET_SR_ON_EXIT \
> ({ \
> uint16_t __x; \
> __asm__ __volatile__( \
> "mov .L__FrameOffset_" __FUNCTION__ "(r1), r15" \
> : "=r" ((uint16_t) __x) \
> :); \
> __x; \
> })
I don't believe this definition is correct; for a start, the =r constraint
assigns x to *some* register, might be r15, might not. It might work out
for some functions, but won't for others. (Why use the =r constraint if
there is no constraint in the assembly template text?)
> It compiles:
> GET_SR_ON_EXIT;
> 2790: 1f 41 02 00 mov 2(r1), r15 ;
Like I said, lucky. This time.
You are not alone in getting this wrong--even Luminary (now owned by TI)
got this stuff wrong with GCC and shipped it. I'm not sure anybody
bothered to test their broken code on GCC because Michael has spent a few
days correcting the "canned examples that just work!" that don't.
-- Paul.