Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inline assembly in Haskell

Can I somehow use inline assembly in Haskell (similar to what GCC does for C)?

I want to compare my Haskell code to the reference implementation (ASM) and this seems the most straightforward way. I guess I could just call Haskell from C and use GCC inline assembly, but I'm still interested if I can do it the other way around.

(I'm on Linux/x86)

like image 893
akosch Avatar asked Jun 05 '11 22:06

akosch


1 Answers

There are two ways:

  • Call C via the FFI, and use inline assembly on the C side.
  • Write a CMM fragment that calls C (without the FFI), and uses inlined assembly.

Both solutions use inline assembly on the C side. The former is the most idiomatic. Here's an example, from the rdtsc package:

cycles.h:

static __inline__ ticks getticks(void)
{
     unsigned int tbl, tbu0, tbu1;

     do {
      __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0));
      __asm__ __volatile__ ("mftb %0" : "=r"(tbl));
      __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1));
     } while (tbu0 != tbu1);

     return (((unsigned long long)tbu0) << 32) | tbl;
}

rdtsc.c:

unsigned long long rdtsc(void)
{    
  return getticks();
}

rdtsc.h:

unsigned long long rdtsc(void);

rdtsc.hs:

foreign import ccall unsafe "rdtsc.h" rdtsc :: IO Word64

Finally:

  • A slightly non-obvious solution is to use the LLVM or Harpy packages to call some generated assembly.
like image 62
Don Stewart Avatar answered Nov 14 '22 04:11

Don Stewart