Mark Butcher

Coldfire register access, best practice and compiler dependency

Discussion created by Mark Butcher on Feb 4, 2010
Latest reply on Feb 5, 2010 by Mark Butcher

Hi All

Consider the following code:

ADC_CTRL1 |= 0x2000; // start an ADC conversion (address is 0x40190000 and is defined as a short word)

Now consider this code

ADC_CTRL1 = (ADC_CTRL | 0x2000); // start an ADC conversion (address is 0x40190000 and is defined as a short word)

Is there a difference?








Assembler gives, in the two cases,

0x0000000E  0x207C40190000           movea.l  #1075380224,a0        ; '@...'
0x00000014  0x08D00005               bset     #5,(a0)


0x00000018  0x7000                   moveq    #0,d0
0x0000001A  0x303940190000           move.w   0x40190000,d0
0x00000020  0x08C0000D               bset     #13,d0
0x00000024  0x33C040190000           move.w   d0,0x40190000

The first fails and the second works....(the reason being that the access to the register in the first case is performed as a bit set acting on the first byte in the register whereas the second manipulates the value in a data register and performs a short word destination write - presumably this register doesn't like to be addresses as a byte.)

This leads to a question as to best practice in these situations? The problem can be solved by:
a) disabling optimisation
b) ensuring that the register is declared as volatile (although the volatile declaration is not explicitly causing the register to be handled as a volatile but does avoid the use of bset directed to a single byte).
c) use CW 6.4 rather than CW 7.2 (CW6.4 tends to use ori rather than bset when setting bits)


Maybe a bit of a theoretical topic but still interesting in some way....