Inline asm for ARM
Pavel Pavlov
pavel@summit-tech.ca
Wed Jun 16 20:44:00 GMT 2010
> -----Original Message-----
> Behalf Of Andrew Haley
> Sent: Wednesday, June 16, 2010 13:00
> To: gcc-help@gcc.gnu.org
> Subject: Re: Inline asm for ARM
>
> On 06/16/2010 05:57 PM, Pavel Pavlov wrote:
> >
> >
> >> -----Original Message-----
> >> From: gcc-help-owner@gcc.gnu.org [mailto:gcc-help-owner@gcc.gnu.org]
> >> On Behalf Of Andrew Haley
> >> Sent: Wednesday, June 16, 2010 12:52
> >> To: gcc-help@gcc.gnu.org
> >> Subject: Re: Inline asm for ARM
> >>
> >> On 06/16/2010 05:40 PM, Pavel Pavlov wrote:
> >>>> -----Original Message-----
> >>>> From: Andrew Haley [mailto:aph@redhat.com] On 06/16/2010 05:11 PM,
> >>>> Pavel Pavlov wrote:
> >>>>>> -----Original Message-----
> >>>>>> On 06/16/2010 01:15 PM, Andrew Haley wrote:
> >>>>>>> On 06/16/2010 11:23 AM, Pavel Pavlov wrote:
> >>>>> ...
> >>>>>> inline uint64_t smlalbb(uint64_t acc, unsigned int lo, unsigned int hi) {
> >>>>>> union
> >>>>>> {
> >>>>>> uint64_t ll;
> >>>>>> struct
> >>>>>> {
> >>>>>> unsigned int l;
> >>>>>> unsigned int h;
> >>>>>> } s;
> >>>>>> } retval;
> >>>>>>
> >>>>>> retval.ll = acc;
> >>>>>>
> >>>>>> __asm__("smlalbb %0, %1, %2, %3"
> >>>>>> : "+r"(retval.s.l), "+r"(retval.s.h)
> >>>>>> : "r"(lo), "r"(hi));
> >>>>>>
> >>>>>> return retval.ll;
> >>>>>> }
> >>>>>>
> >>>>>
> >>>>> [Pavel Pavlov]
> >>>>> Later on I found out that I had to use +r constraint, but then,
> >>>>> when I use that
> >>>> function for example like that:
> >>>>> int64_t rsmlalbb64(int64_t i, int x, int y) {
> >>>>> return smlalbb64(i, x, y);
> >>>>> }
> >>>>>
> >>>>> Gcc generates this asm:
> >>>>> <rsmlalbb64>:
> >>>>> push {r4, r5}
> >>>>> mov r4, r0
> >>>>> mov ip, r1
> >>>>> smlalbb r4, ip, r2, r3
> >>>>> mov r5, ip
> >>>>> mov r0, r4
> >>>>> mov r1, ip
> >>>>> pop {r4, r5}
> >>>>> bx lr
> >>>>>
> >>>>> It's bizarre what gcc is doing in that function, I understand if
> >>>>> it can't optimize and correctly use r0 and r1 directly, but from
> >>>>> that listing it looks as if gcc got drunk and decided to touch r5
> >>>>> for absolutely no reason!
> >>>>>
> >>>>> the expected out should have been like that:
> >>>>> <rsmlalbb64>:
> >>>>> smlalbb r0, r1, r2, r3
> >>>>> bx lr
> >>>>>
> >>>>> I'm using cegcc 4.1.0 and I compile with
> >>>>> arm-mingw32ce-g++ -O3 -mcpu=arm1136j-s -c ARM_TEST.cpp -o
> >>>>> arm-mingw32ce-g++ ARM_TEST_GCC.obj
> >>>>>
> >>>>> Is there a way to access individual parts of that 64-bit input
> >>>>> integer or, is there a way to specify that two 32-bit integers
> >>>>> should be treated as a Hi:Lo parts of 64 bit variable. It's
> >>>>> commonly done with a temporary, but the result is that gcc generates to
> much junk.
> >>>>
> >>>> Why don't you just use the function I sent above? It generates
> >>>>
> >>>> smlalbb:
> >>>> smlalbb r0, r1, r2, r3
> >>>> mov pc, lr
> >>>>
> >>>> smlalXX64:
> >>>> smlalbb r0, r1, r2, r3
> >>>> smlalbt r0, r1, r2, r3
> >>>> smlaltb r0, r1, r2, r3
> >>>> smlaltt r0, r1, r2, r3
> >>>> mov pc, lr
> >>>>
> >>>
> >>> [Pavel Pavlov]
> >>> What's your gcc -v? The output I posted comes from your function.
> >>
> >> 4.3.0
> >>
> >> Perhaps your compiler options were wrong? Dunno.
> >>
> >
> >
> > [Pavel Pavlov]
> > It's kind of difficult ot get that part wrong :)
>
> It's not. Trust me, I have been on gcc-help for _long_ while...
>
> I've even seen complains about poor code when optimization is disabled.
>
> Andrew.
>
>
> Andrew.
>
>
>
> I saw that there are some changes between 4.1.0 and 4.3.0 in arm code,
> optimizer code might have been improved between the two versions as well. So,
> I'm building 4.4.0 now to see if it fixes the problem.
[Pavel Pavlov]
Well, off course I enable optimization. -O3 I suppose is enough for this simple case. That's why I said that it's difficult to get that wrong. Without optimizations it would generate something quite different (without inlining etc)
More information about the Gcc-help
mailing list