[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] 16Bit arg in assembl. macro

From: Dave Hansen
Subject: Re: [avr-gcc-list] 16Bit arg in assembl. macro
Date: Wed, 17 Sep 2003 09:59:19 -0400

I'm not a gcc inline assembly expert.  But I'll try to help anyway...

From: Torsten Hahn <address@hidden>
i wanted to write an assembler macro, wich takes an uint16_t sized Argument (two bytes) and returns two bytes (again an uint16_t) which are computed by the macro.

i defined the macro like this:

#define randLCG(_seed_) ({              \
        uint16_t __t;                                   \
        __asm__ __volatile__ (                  \
                        "; some assembler code"               \
                : "=r" (__t)  /* out */                       \
                : "r" ((uint16_t)(_seed_)) /* in */   \
                :  /* clobber */                                \
                );                                                      \
                __t;                                                    \

where __t is the return value and the 16 bit _seed_ should go into 2 registers (selected by the compiler).

My question is now, is it possible to assign an 2 byte var like i have done it to the register(s) and how do i reference them (%1 and %2 for low/higbyte doesnt work)? Or do i have to break it into two one byte vars manually ?

Consider the code in ...include/avr/delay.h:

  static inline void
  _delay_loop_2(unsigned int __count)
     asm volatile (
        "1: sbiw %0,1" "\n\t"
        "brne 1b"
        : "=w" (__count)
        : "0" (__count)

__count is unisgned int, but is passed in as a 16-bit value using "w" for the constraint rather than "r". But it is also manipulated solely as a 16 bit value. If you are doing something similar, this is the way to do it.

If you need to access the individual bytes of your 16-bit values, I have seen an example "swap bytes" macro that looks something like this:

  asm volatile (
     "mov __tmp_reg__, %A0 \n\t"
     "mov %A0, %B0   \n\t"
     "mov %B0, __tmp_reg__  \n\t"
     : "=r" (value)
     : "0"

where the "r" constraint is used, but the individual bytes are accessed with the "A" and "B" prefixes (e.g., %A0 rather than %0). I haven't tried this myself, but you might want to look into it. For 32-bit values, you can use "C" and "D" prefixes as well.

And than a second question. If i use code in my assembler macros which clobbers registers r0 and r1 (multiplications), is it save if i only add the two registers to the clobber-list or is there extra work to do?

I don't think you have to do even that. R0 is designated as a temporary, and can be clobbered with impunity. R1 is the zero register, and if you clobber it, you should make sure it gets cleared. That's all.


Use custom emotions -- try MSN Messenger 6.0! http://www.msnmessenger-download.com/tracking/reach_emoticon

reply via email to

[Prev in Thread] Current Thread [Next in Thread]