Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: Example of C and inline ASM in a file?

2006-04-15 by John Heenan

--- In lpc2000@yahoogroups.com, "jayasooriah" <jayasooriah@...> wrote:
>
> John,
> 
> Hope this spoilt child will not be grounded for critiquing on dad's
> work :)
 
Don't want to understand.

> It certainly dismisses the myth that one can disable interrupts 
while
> in 16-bit mode without interworking!

I was not aware of any such myths. I have simply submitted some 
industry standard core code using techniques adapted from numerous 
sources to fit a simple idea. I noted there is no MSR or MSR 
instruction in Thumb and have not noted any code for the equivalent 
in Thumb. The core of the code is firmly based on well documented 
examples given by ARM and Philips.

Interrupts can be disabled without interworking on the LPC2xxx 
through the VIC registers while in Thumb mode. I have brief notes in 
preperation to be submitted as a file to the group.

> 
> I hope you will not mind if I critique your design with the view of
> improving it becomes a file.  I do not wish to kill your efforts by
> coming up with yet another interface design.
> 
> I do apologise before hand if in aiming to be complete I appear to 
be
> nit picking.  It is occupational hazard that I have learnt to live 
with :)
> 
> I feel your design can be made more compiler friendly in relation to
> optimisation if you had used inline functions.

I agreed it would give more freedom to the compiler to do its thing. 
I have made comments about inline code below. 

> I trust my comments will be received in a constructive mode.

As I said it is just standard code adapted to fit a simple idea, 
namely force industry standard ARM assembler code into a form 
suitable for Thumb through functions compiled for interworking.

More comments below.

John Heenan

> 
> Regards,
> 
> Jaya
> 
> --- In lpc2000@yahoogroups.com, "John Heenan" <l10@> wrote:
> >
> > I have extended and tidied up the examples I have just posted to 
the 
> > thread. I will probably post the code to the file section soon.
> > 
> > John Heenan
> > 
> > //header file interwork.h
> > #ifndef INTERWORK_H_
> > #define INTERWORK_H_
> 
> Probably your intention was to demonstrate interworking.  When you
> make it a file, perhaps you could reflect on the purpose of this
> interface, which is not interworking.

Yes.

> 
> > //MAKE SURE A DEFAULT ISR HANDLER IS ASSIGNED TO VICDefVectAddr
> > //THE DEFAULT ISR HANDLER CAN BE EMPTY BUT MUST BE PRESENT
> 
> I do feel this comment is out of place.  Certainly it applies to LPC
> but is not something generic that I think warrants such a comment if
> we look at the portability requirement some here appear preoccupied 
with.

I disagree. It is a practical issue. Both ARM and Philips state a 
default handler must be assigned using the standard examples they 
provide that has been incorparated into the code.

> 
> > 
> > #ifdef THUMB_INTERWORK
> 
> Appears to violate a rule in my KISS book that says:
> 
>   "Avoid defining a new conditional for one that exists."
> 
> Why not use the __thumb__ token that is already defined by GCC when
> you invoke it with -mthumb option to produce 16-bit code?

Point accepted. Saw THUMB_INTERWORK in another example and took a 
punt it was standard. I was wrong.

> 
> >  #define INTDISABLE cpsr_if_disable()
> >  #define INTENABLE  cpsr_if_enable()
> >  #define SLOWINTDISABLE cpsr_i_disable()
> >  #define SLOWINTENABLE  cpsr_i_enable()
> >  //volatile definition forces stack storage and is not required
> >  //as optimisation sees variable is used by a function and so 
keeps
> 
> I think the comment is not clear.  I do not understand what you are
> getting here.  Perhaps you can rephrase it to make it clearer.
> 
> >  #define INTVAR int cpsr_prior
> 
> Appears to violate two rules in my KISS book:
> 
>   "Avoid defining a new interface for one that exists."
> 
> and
> 
>   "Avoid using macros to alters syntax or semantics."


It reflects my attitudes to macros and functions. I tend to make 
function names reflect what is really going on at the lower level and 
make them lower case. I tend to make macros names closer to the real 
intention of the macro is and in upper case. It is a practice that 
serves me well personally. I get a marriage of intention (macro name) 
with implementation (function name), all in a single line definition! 

However it is a practice I can be divorced from if is the democratic 
will!

> 
> In relation to the latter rule I am assuming we are taking about a
> fresh design, not retrofitting header to existing code.

> 
> >  #define INTGETDISABLE cpsr_prior=cpsr_ifget_disable()
> >  #define INTRESTORE cpsr_c_restore(cpsr_prior)
> > 
> >  void cpsr_if_disable(void); //works with thumb
> >  void cpsr_if_enable(void);
> >  void cpsr_i_disable(void);
> >  void cpsr_i_enable(void);
> >  int cpsr_ifget_disable(void);
> >  void cpsr_c_restore(int cpsr_prior);
> > #else
> >  #define INTDISABLE INTIF_DISABLE
> >  #define INTENABLE  INTIF_ENABLE
> >  #define SLOWINTDISABLE INTI_DISABLE
> >  #define SLOWINTENABLE  INTI_ENABLE
> >  #define INTVAR volatile int cpsr_prior
> >  #define INTGETDISABLE INTIFGET_DISABLE(cpsr_prior)
> >  #define INTRESTORE INTIF_RESTORE(cpsr_prior)
> > #endif
> > 
> > /*
> > Usage example
> >   INTDISABLE
> >   
> >   INTENABLE
> > 
> > 
> >   INTVAR;
> >   INTGETDISABLE;
> >   
> >   
> >   INTRESTORE;
> >   
> >   INTGETDISABLE;
> >   
> >   
> >   INTRESTORE;
> > */
> > 
> > //not OK for thumb code
> > #define INTIF_ENABLE   asm volatile ( \
> >    "mrs r3,cpsr     \n\t" \
> >    "bic r3,r3,#0xC0 \n\t" \
> >    "msr cpsr_c,r3   \n\t" \
> >    :                      \
> >    :                      \
> >    : "r3"                 \
> > )
> 
> I prefer to avoid having to name registers explicitly so as not to
> impose additional constraints on register optimisation.
 
I only named one register, r3, and specified it was clobbered. Since 
the register cannot be attached to an input or output variable and 
since I did not to troll through the horrific GAS assembler 
documentation to see if there was a qualifier to specify working 
registers r0-r3 or r12 only, I took the easy way out.

> Although not naming a register appears to adds one extra instruction
> (which can be avoided if we were to design the interface 
differently),
> it can save two move instructions where it is instantiated inline.

Inline code CANNOT get rid of the call and return bx instructions 
(bxl for Thumb also) as these instructions are the mode change 
instructions. Inline code expands TOTAL code size but does have the 
advantage of not refilling the fetch/decode/execute pipeline.


> > 
> > #define INTIF_DISABLE  asm volatile ( \
> >    "mrs r3,cpsr		\n\t" \
> >    "orr r3,r3,#0x80 \n\t" /* I bit. separate disablement: see 
user 
> > manual */ \
> >    "msr cpsr_c,r3   \n\t" \
> >    "orr r3,r3,#0x40 \n\t" /* F bit */ \
> >    "msr cpsr_c,r3   \n\t" \
> >    :                      \
> >    :                      \
> >    : "r3"                 \
> > )
> 
> Same issue here with naming register.  More such examples below.
> 
> > 
> > #define INTI_ENABLE   asm volatile ( \
> >    "mrs r3,cpsr     \n\t" \
> >    "bic r3,r3,#0x80 \n\t" \
> >    "msr cpsr_c,r3   \n\t" \
> >    :                      \
> >    :                      \
> >    : "r3"                 \
> > )
> > 
> > #define INTI_DISABLE  asm volatile ( \
> >    "mrs r3,cpsr     \n\t" \
> >    "orr r3,r3,#0x80 \n\t" \
> >    "msr cpsr_c,r3   \n\t" \
> >    :                      \
> >    :                      \
> >    : "r3"                 \
> > )
> >                 	
> >                 
> > #define INTIFGET_DISABLE(A) asm volatile ( \
> >    "mrs %0, cpsr       \n\t" \
> >    "orr r3, %0, #0x80  \n\t"  /* I bit. separate disablement: see 
> > user manual */ \
> >    "msr cpsr_c, r3     \n\t" \
> >    "orr r3, r3, #0x40  \n\t"  /* F bit */ \
> >    "msr cpsr_c, r3     \n\t" \
> >     : "=r"(A)                \
> >     :                        \
> >     : "r3"                   \
> > )                                         
> > 
> > #define INTIF_RESTORE(A) asm volatile ( \
> >    "msr cpsr_c, %0 \n\t" \
> >     :                    \
> >     : "r"(A)             \
> > )
> > 
> > #endif // INTERWORK_H_
> > 
> > //##########################
> > 
> > //module file interwork.c compiled as ARM assembler
> 
> I recommend naming the interworking options needed if compiled code 
is
> to work when called from 16-bit mode -- caller or callee 
interworking?

Agreed.

> 
> > #include "interwork.h"
> > void cpsr_if_disable(void)
> > {
> >  INTIF_DISABLE;
> > }
> > 
> > void cpsr_if_enable(void)
> > {
> >   INTIF_ENABLE;
> > }
> > 
> > void cpsr_i_disable(void)
> > {
> >   INTI_DISABLE;
> > }
> > 
> > void cpsr_i_enable(void)
> > {
> >   INTI_ENABLE;
> > }
> > 
> > int cpsr_ifget_disable(void)
> > {
> >   unsigned int cpsr_prior;
> >   INTIFGET_DISABLE(cpsr_prior);
> >   return cpsr_prior;  
> > //assembler generated
> > // mrs r0, cpsr       
> > // orr r3, r0, #0x80  
> > // msr cpsr_c, r3     
> > // orr r3, r3, #0x40  
> > // msr cpsr_c, r3     
> > // bx	lr
> > }
> > 
> > void cpsr_c_restore(int cpsr_prior)
> > {
> >   INTIF_RESTORE(cpsr_prior);	
> > //assembler generated
> > // msr cpsr_c, r0  
> > // bx	lr
> > }
> > 
> > --- In lpc2000@yahoogroups.com, "John Heenan" <l10@> wrote:
> > >
> > > Despised by the 'beautiful people' but practical, macros make 
it is 
> > > easy to retarget ARM inline assembler to work with C code 
compiled 
> > as 
> > > Thumb assembler.
> 
> The macro feature is powerful, so powerful that it can be used to
> obfuscate code as much as to make it clearer.
> 
> Macros in themselves are not ugly, but it certainly can be used in
> very ugly ways.  Thus I do not despise the macro feature itself.
> 
> The most powerful use of macro is in retrofitting through making
> minimal yet effective changes in the header.
> 
> > > 
> > > Following are expamples for interrupt disable/enable for GCC. 
The 
> > > intention is simply to force the macros through functions 
compiled 
> > as 
> > > ARM code so as the compiler will force correct usage of bx to 
> > switch 
> > > between ARM and Thumb modes, when compiling Thumb code. The 
beauty 
> > of 
> > > the macro system is that all ARM generated code can use pure 
inline 
> > > assembler through
> >
>

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.