Re: In-line Assembler Code

Georg-Johann Lay <[email protected]>
Newsgroups gmane.comp.hardware.avr.gcc
Message-ID <[email protected]>
Alistair Gadd schrieb:
> Hi Guys,
> 
> I'm trying to use GCC-AVR to set up the clock prescale on an ATmega32U4, 
> using the clock_prescale_set() function as outlined in the "avr/power.h 
> " header file.
> 
> If I call:
>     clock_prescale_set(clock_div_1)
> or
>     clock_prescale_set(0);
> where clock_prescale_set is defined in "avr/power.h" as follows:
> 
> typedef enum
> {
>     clock_div_1 = 0,
>     clock_div_2 = 1,
>     clock_div_4 = 2,
>     clock_div_8 = 3,
>     clock_div_16 = 4,
>     clock_div_32 = 5,
>     clock_div_64 = 6,
>     clock_div_128 = 7,
>     clock_div_256 = 8
> #if defined(__AVR_ATmega128RFA1__) \
> || defined(__AVR_ATmega256RFR2__) \
> || defined(__AVR_ATmega2564RFR2__) \
> || defined(__AVR_ATmega128RFR2__) \
> || defined(__AVR_ATmega1284RFR2__) \
> || defined(__AVR_ATmega64RFR2__) \
> || defined(__AVR_ATmega644RFR2__)
>     , clock_div_1_rc = 15
> #endif
> } clock_div_t;
> 
> void clock_prescale_set(clock_div_t __x)
> {
>     uint8_t __tmp = _BV(CLKPCE);
>     __asm__ __volatile__ (
>         "in __tmp_reg__,__SREG__" "\n\t"
>         "cli" "\n\t"
>         "sts %1, %0" "\n\t"
>         "sts %1, %2" "\n\t"
>         "out __SREG__, __tmp_reg__"
>         : /* no outputs */
>         : "d" (__tmp),
>           "M" (_SFR_MEM_ADDR(CLKPR)),
>           "d" (__x)
>         : "r0");
> }
> 
> I get the following in-line assembler generated (.lss file extract):
> 
> void clock_prescale_set(clock_div_t __x)
> {
>     uint8_t __tmp = _BV(CLKPCE);
>     __asm__ __volatile__ (
>      12a:    90 e0           ldi    r25, 0x00    ; 0
>      12c:    80 e8           ldi    r24, 0x80    ; 128
>      12e:    0f b6           in    r0, 0x3f    ; 63
>      130:    f8 94           cli
>      132:    80 93 61 00     sts    0x0061, r24
>      136:    90 93 61 00     sts    0x0061, r25
>      13a:    0f be           out    0x3f, r0    ; 63

This is obviously not the code as generated by the cited inline 
assembler sequence.  Hence either the dump is basing on a wrong or 
outdated file, or the dump is just sloppy and misleading (LDI is not 
part of the inline asm for example).

Apart from being suboptimal, that inline assembler sequence is not fully 
correct.

> which I can understand, but if I call:
>     clock_prescale_set(clock_div_4);
> or:
>     clock_prescale_set(2);
> I get exactly the same code generated, in other words:
> 
> void clock_prescale_set(clock_div_t __x)
> {
>     uint8_t __tmp = _BV(CLKPCE);
>     __asm__ __volatile__ (
>      12a:    90 e0           ldi    r25, *0x00*    ; 0
>      12c:    80 e8           ldi    r24, 0x80    ; 128
>      12e:    0f b6           in    r0, 0x3f    ; 63
>      130:    f8 94           cli
>      132:    80 93 61 00     sts    0x0061, r24
>      136:    90 93 61 00     sts    0x0061, r25
>      13a:    0f be           out    0x3f, r0    ; 63
> 
> where I would expect to get this:

If you want to see the exact assembler sequence, add -save-temps to the 
command options and inspect the assembler (.s) file.

If you want to see the exact preprocessed code, i.e. the input to the 
compiler proper, add -save-temps to the command options and inspect the 
preprocessed code (.i or .ii) file.

> void clock_prescale_set(clock_div_t __x)
> {
>     uint8_t __tmp = _BV(CLKPCE);
>     __asm__ __volatile__ (
>      12a:    90 e0           ldi    r25, *0x02*    ; 0
>      12c:    80 e8           ldi    r24, 0x80    ; 128
>      12e:    0f b6           in    r0, 0x3f    ; 63
>      130:    f8 94           cli
>      132:    80 93 61 00     sts    0x0061, r24
>      136:    90 93 61 00     sts    0x0061, r25
>      13a:    0f be           out    0x3f, r0    ; 63
> 
> I don't get any compilation errors, so I think it sees the enum okay and 
> the assembly listing is fresh each time I try. I'm sure I must be doing 
> something simplisticly crazy, but I think I need help, because this is 

You snipped out / left out any information that would enable one to 
reproduce what you did...

Johann
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.