0

I was trying to compile ODE(Open Dynamics Engine) physics C++ library for Android Native application on Android Studio.

When i tried to build it, it gave me some error telling that some inline ASM code is not correct as they are written for INTEL processor syntax. This are mostly to get CPU clock frequency for physics simulation purpose.


(Editor's note: this x86 GNU C inline asm is inefficient and not even safe or portable. See How to get the CPU cycle count in x86_64 from C++? for correct ways to use i386 / x86-64 rdtsc.)

static inline void getClockCount (unsigned long cc[2])
{
#ifndef X86_64_SYSTEM   
    asm volatile (
        "rdtsc\n"
        "movl %%eax,(%%esi)\n"
        "movl %%edx,4(%%esi)\n"
        : : "S" (cc) : "%eax","%edx","cc","memory");
#else
    asm volatile (
        "rdtsc\n"
        "movl %%eax,(%%rsi)\n"
        "movl %%edx,4(%%rsi)\n"
        : : "S" (cc) : "%eax","%edx","cc","memory");
#endif  
}


static inline void serialize()
{
#ifndef X86_64_SYSTEM
    asm volatile (
        "mov $0,%%eax\n"
        "push %%ebx\n"
        "cpuid\n"
        "pop %%ebx\n"
        : : : "%eax","%ecx","%edx","cc","memory");
#else
    asm volatile (
        "mov $0,%%rax\n"
        "push %%rbx\n"
        "cpuid\n"
        "pop %%rbx\n"
        : : : "%rax","%rcx","%rdx","cc","memory");
#endif
}


static inline double loadClockCount (unsigned long a[2])
{
    double ret;
#ifndef X86_64_SYSTEM
    asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) :
    "cc","memory");
#else
    asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) :
    "cc","memory");
#endif  
    return ret;
}

I don't know how to do same for ARM? Any help?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • That x86 GNU C inline asm is pretty nasty anyway! `long` is a 64-bit type in x86-64 System V (Linux) but 32-bit on Windows. So `long cc[2]` holds either the low and high halves of a single 64-bit integer, or `cc[0]` is a single 64-bit integer. Also there's no need to store to memory. Also, GCC more recent than some 4.x version can declare a clobber on EBX instead of having to push/pop. And x86-64 can always declare a clobber on RBX, but push/pop is specifically unsafe (steps on the red zone). – Peter Cordes Jun 11 '20 at 20:52
  • 2
    [The logic for reading the hardware counter on ARM is quite different](https://stackoverflow.com/questions/40454157/is-there-an-equivalent-instruction-to-rdtsc-in-arm/40455065). There's no RDTSC command. Also, "if not x86_64 then, I guess, x86" is completely inapplicable to Android. – Seva Alekseyev Jun 11 '20 at 20:59
  • @SevaAlekseyev: re: the `#ifdef` logic: better-designed inline asm doesn't need an `ifdef` around RDTSC; it would just produce two `unsigned long` outputs and leave it to C to shift/OR them. Like [How to get the CPU cycle count in x86\_64 from C++?](https://stackoverflow.com/q/13772567) showed before the answer was updated to recommend the now-portable intrinsic. All the details of this inline asm implementation are overcomplicated, inefficient, or even just plain buggy. – Peter Cordes Jun 12 '20 at 00:44
  • @PeterCordes I believe Seva's point was that since OP is compiling for ARM, it would use the `#ifndef X86_64_SYSTEM` code, but that's not going to work on ARM because `rdtsc` isn't a valid ARM instruction. While this code might look like it's designed for crossplatform (with the #if and all), there is no branch here that is appropriate for ARM. It's not clear to me why you keep linking to x86 solutions. Perhaps you missed OP's intent? – David Wohlferd Jun 12 '20 at 03:39
  • @DavidWohlferd: No, I do understand the big picture. The point I intended to make was that when adding `#ifdef __arm__` and `__aarch64__` checks, the ifdef branch for x86 could cover x86 and x86-64, instead of adding to this crap. But apparently this code offended my sensibilities so much that I got bogged down in its details >. – Peter Cordes Jun 12 '20 at 04:07
  • 1
    @PeterCordes "offended my sensibilities" and there we agree. One of the (many) downsides of inline asm is that once someone writes something, it never dies. It just gets copy/pasted over and over again into new projects. So many people don't really understand how it works and refuse to touch it, even when a much better solution (like the intrinsic you referenced) becomes available. Indeed, while Seva's link seems to have a plausible answer, the linked code doesn't use `__arm_mcr` (which I *think* would be appropriate here). – David Wohlferd Jun 12 '20 at 04:32
  • @DavidWohlferd The Open Dynamics Physics engine is platform independent as Wikipedia, But the developer of that library only configured it for Windows and Linux Operating System. Everything was fine until this point. They did't thought about ARM. And most of the Physics library needs to query CPU clock frequency for accurate physics simulation. For me i'm kinda very average guy who knows very few about Assembly(Basic Arithmetic). Your points are true. Its easy to learn the exact from elders then study a tons of doc. – Almahmudrony Jun 12 '20 at 06:30
  • Can you suggest me valid ARM instructions that can do the same like above? – Almahmudrony Jun 12 '20 at 06:34
  • Did you look at Seva's link above? – David Wohlferd Jun 12 '20 at 06:53
  • @DavidWohlferd Oh! Sorry missed it. – Almahmudrony Jun 12 '20 at 08:09
  • BTW, you can't say both "platform independent" and "did't thought about ARM." If you must "think" about the platform, then you aren't platform independent. Indeed, by definition using inline asm instantly makes you platform *dependent*. That's one of the [many](https://gcc.gnu.org/wiki/DontUseInlineAsm) reasons you generally shouldn't use it. I'm not familiar with ODPE, but I wonder about the assertion that you need to "query the CPU clock frequency." That's not always as simple (or as useful) as one might think, depending on the hw. But that's beyond the scope of this question. – David Wohlferd Jun 12 '20 at 09:05

0 Answers0