3

The MSP430 series microcontrollers provide fast bit set / bit clear machine instructions.

These bit manipulation comamnds are useful for some register or I/O manipulations that have side effects or need atomic access to prevent glitches or race conditions.

However, beside many intrinsics for almost all other special features of the MSP430 core, GCC does not provide intrinsics to the bit manipulation instructions.

Why is that? Does GCC still issue those instructions, and what C code would be neccessary to issue them?

dronus
  • 10,774
  • 8
  • 54
  • 80

1 Answers1

2

The C language already allows to express bit manipulations:

$ cat bits.c
#include <msp430.h>
void main(void)
{
        P1IFG &= ~BIT1;
        P1IE |= BIT1;
}
$ msp430-gcc -mmcu=msp430f2013 -Os -S bits.c
$ cat bits.s 
...
        ; end of prologue
        BIC.B   #2, &0x0023
        BIS.B   #2, &0x0025
        ; start of epilogue
...
CL.
  • 173,858
  • 17
  • 217
  • 259
  • 1
    Ok cool, so the "most likely style" of bit manipulation via bitwise operators and a one-bit-mask is optimized into the apropriate hardware commands. Is this for granted? What if the bit mask would be a variable? – dronus Jul 14 '16 at 19:19
  • 1
    That would be a different question. But I'd suggest you ask a third question, "How can I check what machine instructions gcc generates?" – CL. Jul 14 '16 at 19:22
  • Well it would be better to tell C to the bit set instead doing some plain C and check the build result if it fits every time... – dronus Jul 14 '16 at 19:23
  • @dronus: if you want to write in assembly language, do that. (but [don't use inline-asm for this](https://gcc.gnu.org/wiki/DontUseInlineAsm); that would be shooting yourself in the foot.) If you want to write in C, you have to either trust the compiler, or check its output. Most of the time for most platforms, gcc will do a good job of using the instruction set. After checking a few times, you'll probably become confident that it's doing a good job and not need to check every time. – Peter Cordes Jul 15 '16 at 01:33
  • 1
    @dronus: If you want the compiler to be able to optimize your code (which is part of the point of using C instead of asm), an intrinsic for setting a bit would have to mean "set this bit in whatever way is most efficient", not "I require a BIS.B instruction here with these operands". The former is very well expressed by `P1IE |= BIT1`. Compilers understand that, and know what it means, and how to emit efficient code for it. – Peter Cordes Jul 15 '16 at 01:35
  • @dronus: Actually, I missed the part of the question where you want guarantees like atomicity when accessing i/o registers. C11 atomics do include [`atomic_fetch_or`](http://en.cppreference.com/w/c/atomic/atomic_fetch_or). Hopefully the load of the old value would get optimized away. (But it might not if you use pointer-to-`volatile` for your `atomic_int *port`). So hrm, it's a bit less clear-cut, and you might want to use inline asm to guarantee which instruction actually modified the port. – Peter Cordes Jul 15 '16 at 01:41
  • As we see in the disassembly above, the apropriate machine instructions are actually used for the given C source. So if this holds reliable, all atomicity and other side effect relevant things would hold. – dronus Jul 15 '16 at 09:32
  • I redone your test and it takes a minimum of `-O2` or `-Os` as you tried to get the atomic instructions. Otherwise `BIS` is used, but on a temporary register. So no guarantee for the side effects, but the optimized version seems stable enough to rely on. – dronus Jul 15 '16 at 19:14