سؤال

أنا في الموقف التالي:

  • أنا أكتب رمزًا للحصول على نواة لا تسمح بتعليمات SSE
  • أنا بحاجة إلى القيام بحساب النقطة العائمة
  • أقوم بتجميع منصة x86_64

فيما يلي عينة رمز توضح المشكلة:

int
main(int argc, char** argv)
{
    double d = 0.0, dbase;
    uint64_t base_value = 300;

    d = (2200.0 - 1000.0)/(1000.0);
    dbase = d * base_value;
    printf("d = %f, dbase = %f\n", d, dbase);
    base_value = dbase;
    printf("base_value = %llu\n", (long long unsigned)base_value);
    return 0;
}

وهنا هو الخط ذي الصلة من Makefile:

CFLAGS +=   -mcmodel=kernel -mno-red-zone -mfpmath=387 -mno-sse -mno-sse2 -mno-mmx -mno-3dnow \
            -msoft-float -fno-asynchronous-unwind-tables -fno-omit-frame-pointer

عندما أقوم بتشغيل بناء أحصل على هذا الخطأ:

SSE register return with SSE disabled

(يشير الخطأ إلى السطر الذي يضاعف D و Base_Value)

أي فكرة عما يمكنني فعله لإصلاح هذا؟ إن إزالة -mno-SSE ليس خيارًا ، ولكن يبدو أن المترجم يجب أن يكون قادرًا على إنشاء رمز غير SSE للقيام بالضرب.

شكرا ناثان

هل كانت مفيدة؟

المحلول

يبدو أن المترجم ينبعث منه مكالمة إلى روتين مكتبة للقيام بالنقطة العائمة تتكاثر لك (من المفترض دون استخدام SSE) ، لكنه يحاول استخدام ABI للمكالمة التي تم تمرير قيمة الإرجاع في SSE. من الواضح أن هذا لا يعمل.

إذا كان من الممكن على الإطلاق استخدام النقطة العائمة على الإطلاق في kernel ، فيجب أن تكون هناك مكتبة وقت تشغيل خاص للقيام بعمليات طينية لا تستخدم الوسيطة المعتادة (Userland) التي تم نقلها وإرجاعها. ومع ذلك ، على حد علمي ، لا يوجد أي دعم للنقطة العائمة في kernel BSD. كان هذا هو الحال بالتأكيد قبل بضع سنوات.

من المحتمل أن تسأل فقط قائمة البريد الإلكتروني لـ BSD kernel dev ما إذا كان من الممكن استخدام نقطة العائمة أم لا ؛ أظن أنه سيعطيك إجابة أسرع أكثر من ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top