bug-gplusplus
[Top][All Lists]
Advanced

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

Re: inline assembler register allocation for H8S/2357


From: Chris Torek
Subject: Re: inline assembler register allocation for H8S/2357
Date: Sun, 10 Dec 2000 05:19:08 -0800 (PST)

I sent a rather longer version of this as a reply, but in case it
might be useful to someone else, here is a short version...

In article <address@hidden>
Carlos Manhaeghe <address@hidden> wrote:
>my program needs to convert 32-bit values from little-endian to big-endian.
>This conversion is done by the following routine:
>
>static __inline__ unsigned long DDT32P(unsigned long *pulData)
>{      register unsigned long ulResult asm("er3");
>       asm("mov.b\t@(3,%1),r3h"
>       "\n\tmov.b\t@(2,%1),r3l"
>       "\n\tmov.w\tr3,e3"
>       "\n\tmov.b\t@(1,%1),r3h"
>       "address@hidden,r3l"
>               : "=&r" (ulResult)
>               : "r" (pulData));
>       return ulResult;
>}
>
>The converted value is put into er3, which should correspond to the ulResult
>local variable. However, one of the expansions of this routine [runs with
 the input variable "pulData" allocated to register er3 anyway]:
>; #APP
>       mov.b   @(3,er3),r3h
>       mov.b   @(2,er3),r3l
>       mov.w   r3,e3
>       mov.b   @(1,er3),r3h
>       mov.b   @er3,r3l
>; #NO_APP
>       mov.l   er2,er3

I do not believe this is a compiler bug, but rather an incorrect
asm specification.

I am not familiar with the CPU in question, but after a quick scan
through gcc/config/h8300/h8300.c, I would attempt this version of
the whole thing:

        /* the name "htonl" really means "host byte order to
           big-endian order, for 32-bit quantity"; the name is
           a concession to 4.xBSD history and TCP/IP on the VAX */

        static __inline__ unsigned long htonl(unsigned long x) {
                unsigned long r;

                __asm__("mov.b %w1,%z0\n\t"
                        "mov.b %x1,%y0\n\t"
                        "mov.b %y1,%x0\n\t"
                        "mov.b %z1,%w0" : "=&r"(r) : "r"(x));
                return r;
        }

        #define DDT32P(ptr) htonl(*(ptr))

The documentation in h8300.c claims that the %{w,x,y,z} constraints
refer to low (least significant) byte, 2nd, 3rd, and high (ms) byte
of a 32-bit (register or constant) value, respectively.

An obvious improvement (that was not in my email reply) would be
to allow constants for "x", by replacing "r"(x) with "rn"(x).  Of
course htonl(some_constant) might be better done by shifting and
masking anyway:

                if (__builtin_constant_p(x))
                        r = ((x << 24) & 0xff000000) |
                            ((x << 8)  & 0x00ff0000) |
                            ((x >> 8)  & 0x0000ff00) |
                            ((x >> 24) & 0x000000ff);
                else
                        __asm__ ... as before
                return r;
-- 
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA, USA     Domain: address@hidden  +1 510 234 3167
http://claw.bsdi.com/torek/  (not always up)    I report spam to address@hidden



reply via email to

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