3

gcc provides numerous builtin routines. Where can I find the source code of the builtin routines? I understand that sometimes they might be direct opcodes. This was shown e.g. in Implementation of __builtin_clz.

I tried the following four functions

int leading_zeroes(int x){ return __builtin_ctz(x); }

double cpsgn(double x, double y){ return __builtin_copysign(x,y); }

int exponent(double x) { return __builtin_ilogb(x); }

double loadexp(double x, int y){ return __builtin_ldexp(x,y); }

Finally, I'm interested in the assembler code. With https://godbolt.org/ I got this assembler code

leading_zeroes:
  xor eax, eax
  rep bsf eax, edi
  ret
cpsgn:
  andpd xmm0, XMMWORD PTR .LC0[rip]
  movapd xmm2, xmm1
  andpd xmm2, XMMWORD PTR .LC1[rip]
  orpd xmm0, xmm2
  ret
exponent:
  jmp ilogb
loadexp:
  jmp ldexp
.LC0:
  .long 4294967295
  .long 2147483647
  .long 0
  .long 0
.LC1:
  .long 0
  .long -2147483648
  .long 0
  .long 0

So __builtin_ctz becomes bsf. copysign is resolved, too. However, ilogb and ldexp, which is often slow, result in a jmp instruction. How can I resolve the jmp (or call)?

  • 4
    It's unclear what you are asking. The actual builtins are generated by the compiler, they probably don't have a single source. Likely just a function to emit the code (but I haven't checked). If you mean where `ilogb` and `ldexp` are, those are standard C functions from the math library. You are seeing them because the compiler doesn't have an optimized versions for the architecture and/or arguments and/or settings that you are using. – Jester Dec 31 '19 at 00:23
  • If the built-ins are optimised to a single instruction, do they really have source code? At least you'd have to specify a platform, and then it's probably better to see what GCC generates in practice, ie, after optimisation in your real program context. You can try checking the GCC source though, it's freely available. – Useless Dec 31 '19 at 00:24
  • 1
    So you say `__builtins__ilogb` goes back to `ilogb` from math.c, so may one like this https://fossies.org/linux/musl/src/math/ilogb.c? So how can I trace back, which code was used for compilation? And what is the asm behind `jmp`? – Friedrich -- Слава Україні Dec 31 '19 at 00:40
  • 2
    `jmp ilogb` is a tail call to the `ilogb` library function. The point of having a GNU C builtin is to allow constant-propagation through the function when the inputs are constants instead of runtime variables. Otherwise we'd only need the libc definition. – Peter Cordes Dec 31 '19 at 04:32
  • 2
    Look in the subdirectory `gcc/config` - you will find `.md` files. These are **m**achine **d**escription files. These provide the translations of an intrinsic (including, I think, undocumented intrinsics / patterns useful to the compiler) to a set of (micro-architecture specific) instructions. e.g. `i386/i386.md` – Brett Hale Dec 31 '19 at 10:19
  • I found it online: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/i386.md. But on a linux machine I could not find gcc/config/, instead /usr/lib64/gcc/x86_64-suse-linux/4.6/ which has no config directory, but some *.so and *.o files (e.g. libquadmath.so), which seems to provide some `ilogb` function (https://github.com/gcc-mirror/gcc/blob/master/libquadmath/math/ilogbq.c), – Friedrich -- Слава Україні Dec 31 '19 at 17:56
  • @Friedrich - it's part of the compiler's *source* code. Once the compiler is built, targeting a particular host platform, that information is built into the "executables". – Brett Hale Jan 01 '20 at 07:46

0 Answers0