Ich befinde mich in der folgenden Situation:
- Ich schreibe Code für einen Kernel, der keine SSE-Befehle zulässt
- Ich muss Gleitkomma-Arithmetik betreiben
- Ich kompiliere für eine x86_64-Plattform
Hier ist ein Codebeispiel, das das Problem veranschaulicht:
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;
}
Und hier ist die entsprechende Zeile aus dem 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
Wenn ich einen Build ausführe, erhalte ich diesen Fehler:
SSE register return with SSE disabled
(Der Fehler zeigt auf die Zeile, die d und base_value multipliziert)
Haben Sie eine Idee, was ich tun kann, um das Problem zu beheben? Entfernen -mno-sse ist keine Option, aber es scheint, wie der Compiler sollte in der Lage sein, nicht-se Code zu generieren, um die Multiplikation zu tun.
Danke Nathan
1 Stimmen
Es ist möglich, dass gcc mit diesem Fall nicht umgehen kann, weil er davon ausgeht, dass alle x86-64-Prozessoren SSE haben.
1 Stimmen
Bedeutet das, dass niemand jemals etwas innerhalb des FreeBSD-Kernels auf 64-Bit-Builds multipliziert?
0 Stimmen
Jeder Kernel, an dem ich gearbeitet habe, neigt dazu, Fließkommazahlen so weit wie möglich zu vermeiden.
0 Stimmen
Carl, ich frage mich, warum das so ist. Werden die FP-Register bei einem Moduswechsel normalerweise nicht gespeichert?
3 Stimmen
Ja, ja. Die Kernel-Leute hassen es, wenn sie mehr Register speichern und wiederherstellen müssen.
3 Stimmen
Gcc kann x87-Mathematik sehr gut ausführen (wenn Sie dem Kernel sagen, dass er den x87-FPU-Status im Benutzerbereich speichern und wiederherstellen soll). Das Problem ist die Übergabe
double
als Funktionsarg, da Sie für eine Aufrufkonvention kompilieren, diedouble
args in XMM-Registern. Wenn Sie dieprintf("d = %f, dbase = %f\n", d, dbase);
können Sie Funktionen schreiben, die FP-Mathematik verwenden, sogar mit-mno-sse
: siehe z.B. godbolt.org/g/oIM1rS für die asm-Ausgabe einer einfachen Funktion.