jwt27 / build-gcc

Shell scripts to build various gcc cross-compilers (primarily djgpp)
https://jw.h4ck.me/debian/
GNU General Public License v3.0
41 stars 9 forks source link

undefined reference to `__sync_bool_compare_and_swap_4' #37

Open stsp opened 11 months ago

stsp commented 11 months ago

Using __sync intrinsics by default results into an error. Changing -march solves the problem, but things should work by default.

jwt27 commented 11 months ago

386 doesn't have cmpxchg, you'll need -march=i486 at minimum. I do want the debian/ubuntu packages to produce 386 code by default, so won't fix.

stsp commented 11 months ago

Undefined reference is not an answer. If you want to support i386, then you need to update libgcc to include the replacements.

jwt27 commented 11 months ago

I think those are in libatomic. Have you considered other solutions? For atomic flags you generally only need __atomic_test_and_set() (which is just regular xchg).

stsp commented 11 months ago

Have you considered other solutions?

Tried just now: undefined reference to `__atomic_fetch_sub_4'

generally only need __atomic_test_and_set() (which is just regular xchg).

How so?

stsp commented 11 months ago

I think those are in libatomic

Its probably unavailable in your build. -latomic doesn't seem to work.

stsp commented 11 months ago

386 doesn't have cmpxchg, you'll need -march=i486 at minimum. I do want the debian/ubuntu packages to produce 386 code by default, so won't fix.

How far does 486 go besides atomics? If atomics is the only extension, then, as they are probably not emitted by the compiler on his own (unless the user explicitly used the intrinsic), you are safe? I know gcc can emit cmov, but that one is far ahead of i486. So why i486 by default is unsafe?

jwt27 commented 11 months ago

I think those are in libatomic

Its probably unavailable in your build. -latomic doesn't seem to work.

It hasn't been ported to djgpp yet, I guess no one ever needed it.

386 doesn't have cmpxchg, you'll need -march=i486 at minimum. I do want the debian/ubuntu packages to produce 386 code by default, so won't fix.

How far does 486 go besides atomics? If atomics is the only extension, then, as they are probably not emitted by the compiler on his own (unless the user explicitly used the intrinsic), you are safe? I know gcc can emit cmov, but that one is far ahead of i486. So why i486 by default is unsafe?

bswap is 486+, and that is fairly common.

stsp commented 11 months ago

Maybe if you use -mtune=i386 then it won't use anything of 486 unless explicitly asked? Just a guess.

jwt27 commented 11 months ago

Maybe if you use -mtune=i386 then it won't use anything of 486 unless explicitly asked? Just a guess.

-mtune only affects instruction timings, so that doesn't help:

$ cat test.c
unsigned test(unsigned x)
{
  return (x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24);
}

$ i386-pc-msdosdjgpp-gcc -S -O3 -masm=intel -march=i486 -mtune=i386 test.c -o -
        .file   "test.c"
        .intel_syntax noprefix
        .section .text
        .p2align 2
        .globl  _test
_test:
        push    ebp
        mov     ebp, esp
        mov     eax, DWORD PTR [ebp+8]
        bswap   eax
        pop     ebp
        ret
        .ident  "GCC: (GNU) 12.2.0"
stsp commented 11 months ago

I was hoping it to deduce that the timing of bswap on 386 is veeery poor. :)