Я проверял исходный код целочисленного GMP, чтобы понять, как внешний primops может быть реализован с точки зрения cmm, как зарегистрировано на странице GHC Primops. Я знаю о методах для реализации их использующий llvm взлом или fvia-C/gcc - это - больше полезного опыта для меня для понимания этого третьего подхода та библиотека interger-gmp использование.
Так, я искал учебное руководство CMM на странице MSFT (ссылка PDF), прошел страницу GHC CMM, и все еще существуют некоторые оставшиеся без ответа вопросы (трудно для хранения всех тех понятий в голове, не роя в CMM, который является тем, что я делаю теперь). Существует этот фрагмент кода от целого-числа-bmp cmm файл:
integer_cmm_int2Integerzh (W_ val)
{
W_ s, p; /* to avoid aliasing */
ALLOC_PRIM_N (SIZEOF_StgArrWords + WDS(1), integer_cmm_int2Integerzh, val);
p = Hp - SIZEOF_StgArrWords;
SET_HDR(p, stg_ARR_WORDS_info, CCCS);
StgArrWords_bytes(p) = SIZEOF_W;
/* mpz_set_si is inlined here, makes things simpler */
if (%lt(val,0)) {
s = -1;
Hp(0) = -val;
} else {
if (%gt(val,0)) {
s = 1;
Hp(0) = val;
} else {
s = 0;
}
}
/* returns (# size :: Int#,
data :: ByteArray#
#)
*/
return (s,p);
}
Как определено в ghc cmm заголовок:
W_ is alias for word.
ALLOC_PRIM_N is a function for allocating memory on the heap for primitive object.
Sp(n) and Hp(n) are defined as below (comments are mine):
#define WDS(n) ((n)*SIZEOF_W) //WDS(n) calculates n*sizeof(Word)
#define Sp(n) W_[Sp + WDS(n)]//Sp(n) points to Stackpointer + n word offset?
#define Hp(n) W_[Hp + WDS(n)]//Hp(n) points to Heap pointer + n word offset?
Я не понимаю строки 5-9 (строка 1 является запуском в случае, если у Вас есть 1/0 беспорядок). Более конкретно:
Функция насколько я понимаю (от рассмотрения функциональной подписи в Prim.hs) берет интервал и возвращается (интервал, массив байтов) (сохраненный в s
,p
соответственно в коде).
Для любого, кто задается вопросом о встроенном, призывают if block
, это - cmm реализация GMP mpz_init_si функция. Мое предположение - то, при вызове функции, определяемой в объектном файле через ccall это не может быть встроено (который имеет смысл, так как это - объектный код, не промежуточный код - подход LLVM кажется более подходящим для встраивания через LLVM IR). Так, оптимизация должна была определить cmm представление функции, которая будет встроена. Исправьте меня, если это предположение является неправильным.
Объяснение строк 5-9 будет очень цениться. У меня есть больше вопросов о других макросах, определенных в файле целочисленного GMP, но это могло бы быть слишком много для выяснения в одном сообщении. Если можно ответить на вопрос со страницей Wiki Haskell или блогом (можно отправить ссылку как ответ), который очень ценился бы (и если бы Вы делаете, я также ценил бы пошаговую пошаговую демонстрацию целочисленного GMP cmm макрос такой как GMP_TAKE2_RET1
).