0

I wonder if it is possible to turn on 1st bit in multiple registers using one sentence in C. I got an inspiration here. I would normally turn on 1st bit in 2 registers registers like this:

#define REG_NAME1 (*((volatile unsigned int *) 0x130031D4))
#define REG_NAME1 (*((volatile unsigned int *) 0x130031D4))
#define BIT1 0x1

REG_NAME1 |= 0x1;
REG_NAME2 |= 0x1;

But here I use 2 sentences. How do i do this in 1? I am just being curious.

Best Regards!

Community
  • 1
  • 1
71GA
  • 1,132
  • 6
  • 36
  • 69
  • Totally unrelated, but you may wanna read these before using volatile: **[compiler optimization messes up with volatile](http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf)** and [this bit on linux doc](http://www.mjmwired.net/kernel/Documentation/volatile-considered-harmful.txt) – Shahbaz Nov 19 '11 at 10:42
  • 1
    The term "sentence" has no specific meaning in C. Perhaps you mean "statement". – Clifford Nov 20 '11 at 11:36
  • 1
    You have two identical definitions for REG_NAME1 and no definition for REG_NAME2. And the definition of BIT1 is unused. – Clifford Nov 20 '11 at 11:43
  • If these are two different registers (as Clifford pointed out, you evidently made a mistake when you wrote your question), then there will be two write instructions under the hood anyway. What do you hope to achieve by using two instructions? (Note: what you call “sentence” is in fact called a *statement* or an *instruction*.) – Gilles 'SO- stop being evil' Nov 21 '11 at 00:15
  • @Shahbaz: Interesting, but the not using `volatile` would be wrong in any case. The article tests 13 compilers, but 9 of them were in fact GCC, and 8 of them targeted IA32. Seems somewhat narrow to me. [Dan Saks on volatile](http://www.eetimes.com/discussion/programming-pointers/4025609/Place-volatile-accurately), and [also](http://www.eetimes.com/discussion/beginner-s-corner/4023801/Introduction-to-the-Volatile-Keyword). The chances are the chip vendor or compiler's device header defines them that way in any case. – Clifford Nov 21 '11 at 15:22
  • @Clifford, anyway, volatiles were created for memory mapped IO and in that case, of course they can be used. I just posted those for people to know how volatile could be dangerous. One common misuse of volatile is between threads, which like I said if the compiler is buggy, is disaster. Proper way of doing it there would be using mutexes, that inside they have something called a memory barrier or something – Shahbaz Nov 21 '11 at 15:40

3 Answers3

3

This is code obfuscation annoyance but:

REG_NAME1 |= (REG_NAME2 |= BIT1) & BIT1;  
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
  • 2
    @BlackBear: Not cool at all if you end up being the poor person who has to maintain such code. Ahmed even said as much. Code such as this could be hazardous to the health of your business. – Clifford Nov 21 '11 at 22:00
  • @Clifford: I've no such problem because I'm still at school, I just upvoted because I'm amazed by these things. Thanks for pointing it out though :) – BlackBear Nov 22 '11 at 18:13
  • @BlackBear: Fair enough, but be aware that if you choose a career in software development, such code could also be hazardous to your career. Always bear in mind [this](http://nedbatchelder.com/blog/200310/kernighan_on_debugging_clever_code.html) from [Brian Kernhigan](http://en.wikipedia.org/wiki/Brian_Kernighan) – Clifford Nov 22 '11 at 20:01
1

How about the comma-operator:

REG_NAME1 |= 0x1, REG_NAME2 |= 0x1;

Still two expression (which you can't escape from) but only one statement.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Oh so it is impossible to write 1 statement to do it all? Oh well thats too bad :) – 71GA Nov 19 '11 at 10:56
  • 2
    @71GA: No it is not impossible, Joachim's suggestion *is* one statement. The comma in this case is an operator, so the statement is semantically a single *expression* too, contrary to Joachim's opinion. However it will most probably result in identical code in translation. There probably is no real benefit in doing this, it will not result in a single machine instruction however your write it. – Clifford Nov 20 '11 at 11:39
1

If the registers are adjacent you can have a single register of a type twice the size and write it in one statement.

Assuming unsigned int is 32-bit and unsigned long long is 64-bit:

#define REG_NAME1_NAME2 (*((volatile unsigned long long*) 0x130031D4))
REG_NAME1_NAME2 |= 0x0000000100000001ULL ;

Of course if these type sizes are not as stated, the bit mask must be different. I strongly suggest that you use C99 types such as uint32_t and uint64_t in any case.

Clifford
  • 88,407
  • 13
  • 85
  • 165