Fix building with gcc 8 and later
Describe the bug
As mentioned in #68 (closed), gcc 8.1.1 can't build a working lisp. Verified again that gcc 9.3.1 can't either.
To Reproduce
Steps to reproduce the behavior:
- Modify
Config.x86_linux
to use-O2
- Build lisp
- See error as mentioned in #68 (closed).
Expected behavior
gcc 8.1.1 should be able to build a working lisp.
Desktop (please complete the following information):
- OS: Linux, possible others
- Version 21d
- gcc 9.3.1
Additional context
Did some debugging and determined that everything works if gencgc.c
is compiled with -O2
but the alloc function is compiled with -O1
(using #pragma optimize ("-O1")
). When compiled with -O2
, we see the following disassembly of alloc:
alloc:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $532, %esp
movl gc_assert_level, %eax
movl 8(%ebp), %ebx
testl %eax, %eax
jle .L2073
testb $7, 671089780
jne .L2074
testb $7, %bl
jne .L2089
.L2076:
movl 671089180, %edx
testl %edx, %edx
je .L2090
.L2073:
movq bytes_allocated_sum, %xmm1
movl %ebx, %eax
movd %ebx, %xmm0
cltd
movd %edx, %xmm2
punpckldq %xmm2, %xmm0
paddq %xmm1, %xmm0
movq %xmm0, bytes_allocated_sum
So in computing bytes_allocated_sum
, gcc uses xmm registers. And this happens before we can save the FPU state. Thus xmm0-xmm2 are trashed and Lisp doesn't know about it.
Saving the state on entry and restoring it on exit seems to make this work. But maybe we should revisit option 1 mentioned in #68 (closed).