Встроенная сборка в Haskell

Можно ли каким-либо образом использовать встроенную сборку в Haskell (аналогично тому, что GCC делает для C)?

Я хочу сравнить свой код Haskell с эталонной реализацией (ASM), и это кажется самым простым способом. Думаю, я мог бы просто вызвать Haskell с C и использовать встроенную сборку GCC, но мне все равно интересно, могу ли я сделать это наоборот.

(я на Linux/x86)

Ответ 1

Существует два способа:

  • Вызовите C через FFI и используйте встроенную сборку на стороне C.
  • Напишите фрагмент CMM, который вызывает C (без FFI), и использует встроенную сборку.

Оба решения используют встроенную сборку на стороне C. Первый - самый идиоматический. Вот пример из пакета rdtsc:

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

Наконец:

  • Несколько неочевидным решением является использование LLVM или Harpy для вызова некоторой сгенерированной сборки.