Jump to content
43oh

New intrinsics, how to ?


Recommended Posts

Moving from AVR and GCC compiler to MSP430 and CCS, I wish 2 new intrinsics like my old:

 

static inline void PUSH (uint16_t u)
{
asm volatile (
	"push %B0" "\n\t"
	"push %A0" "\n\t"
	:
	: "r" (u)
);
}
static inline uint16_t POP ()
{
uint16_t result;
asm volatile (
	"pop %A0" "\n\t"
	"pop %B0" "\n\t"
	: "=r" (result)
);
return result;
}

 

At moment, I've solved with:

inline void PUSH (uint16_t u)
{
_set_R4_register(u);
asm(" PUSH.W R4");
}
inline uint16_t POP ()
{
asm(" POP.W R4");
return _get_R4_register();
}

 

I think it's inelegant because I need to use the register R4.

 

Any idea with CCS 4.2 ?

 

jmP

Link to post
Share on other sites

Corth, that sounds fun.

 

You might want to look at the C compiler that CCS V4 uses. I think it is Version 3. The

calling convention with CCS 'C' is that the first 4 integer arguments to a c function are

passed in R12-R15. Arg1 is R12 and arg4 is R15 ( at least for integer arguments)

Seems like you should be able to push R12 instead of using R4.

 

More info here:

 

http://www.ti.com/lit/ug/slau132c/slau132c.pdf#page=101

 

-rick

Link to post
Share on other sites

Why are there two push/pop in your code?

 

With CCS this should work for inline asm push/pop...

 

uint16_t foo;

__asm(" push &foo");

__asm(" pop &foo");

 

Or as functions...

inline void push(uint16_t x) { __asm(" push R12"); }

inline uint16_t pop(void) { __asm(" pop R12"); }

 

Look at the disassembly to see if it does what you want.

Link to post
Share on other sites

Hi oPossum,

 

Simplified inline functions push and pop as your propose are unfortunately not a good solution because the compiler doesn't follow the mormal rules of calling parameters and returns. The compiler (CCS 4.2) inserts the source of the inline function and makes a global optimization of the code, so doesn't systematically use R12 calling arguments and return, neither put CALL and RET.

 

Your first solution which is to place a single asm("...") referring an external variable is interesting. In practice it's a little waste of codes because the foo referred variable must be a global variable. But this is a good solution if the regisgter R4 (or R5) isn't free. Thanks.

 

jmP

Link to post
Share on other sites
Simplified inline functions push and pop as your propose are unfortunately not a good solution because the compiler doesn't follow the mormal rules of calling parameters and returns. The compiler (CCS 4.2) inserts the source of the inline function and makes a global optimization of the code, so doesn't systematically use R12 calling arguments and return, neither put CALL and RET.

Technically, the term "intrinsic" with compilers normally means exactly that: something that looks like a function, but for which the behavior is internally defined by the compiler which is allowed to optimize it in whatever way is consistent with the semantics. There's no requirement that it follow calling conventions, because it's not really a function.

 

For gcc, it's a bad idea to reference specific registers in the output template (e.g., asm("push r15")) because gcc isn't aware that r15 is being referenced. In particular, if that appears in an inline function, the fact that r15 is normally used for a parameter might cause the parameter to be eliminated entirely, if there's no other reference to it.

 

I'm not entirely clear what you're trying to do, but for mspgcc what you originally had for AVR is probably pretty close (an output template that does not specify a particular register, and an operand string that ensures whatever you pass in gets placed into a register before the asm is executed). But put it in a #define instead of an inline function, in case the compiler choses not to inline the function and you end up pushing something onto a call frame that gets discarded. Something like the following:

#include 

#define PUSHW(v) __asm__ __volatile__ ("push\t%0" :: "r"(v))
#define POP() ({ uint16_t v; __asm__ __volatile__ ("pop\t%0" : "=r"(v)); v;})

int function (int v)
{
 PUSHW(1234);
 v += POP();
 return v;
}

Link to post
Share on other sites
Is it difficult to switch from the internal CCS compiler to MSPGCC? And preserve CCS environment!

 

Do you mean you're using the Code Composer Studio development environment (which I think is now Eclipse-based) and want to replace the underlying compiler with mspgcc?

 

I have no idea how to do that: I only use mspgcc under Linux at the command line. I would expect the debugger would stop working, though, since mspgcc almost certainly won't generate the same format of object file debug entries as CCS-the-compiler.

 

Peter

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...