Skip to content

Instantly share code, notes, and snippets.

@matu3ba
Last active February 15, 2022 13:11
Show Gist options
  • Save matu3ba/771e91bdca43bbdf98405c727212874f to your computer and use it in GitHub Desktop.
Save matu3ba/771e91bdca43bbdf98405c727212874f to your computer and use it in GitHub Desktop.
wip docs compier_rt

If hardware lacks basic or specialized functionality, compiler-rt adds such functionality. One such example is 64-bit integer multiplication on 32-bit x86.

Open question about scope (tracking libgcc):

  • Integer library routines => implemented
  • Soft float library routines => mostly implemented
  • Decimal float library routines => ~120 functions
  • Fixed-point fractional library routines => ~300 functions
  • Exception handling routines? => 32 functions not including undocumented ones
  • Miscellaneous routines => cache control and stack function

This library is automatically built as-needed for the compilation target and then statically linked and therefore is a transparent dependency for the programmer. For details see ../compiler_rt.zig.

This folder contains routines annotated as type source routine, with routine being the name used in aforementioned compiler_rt.zig. dev means deviating from compiler_rt, port ported, source is the information source for the implementation. In the following a brief overview of is given:

  • dev source name_routine, name_routine2 various implementations for performance, simplicity etc
  • port llvm ported compiler-rt library routines from LLVM
    • LLVM emits library calls to compiler-rt, if the hardware lacks functionality
  • port softfloat floating point routines from berkeley-softfloat
  • port musl libc routines from musl If the library or information source is uncommon, use the entry other for source. Please do not break the search by inserting entries in another format than impl space source.

Bugs should be solved by trying to duplicate the bug upstream, if possible.

  • If the bug exists upstream, get it fixed upstream and port the fix downstream to Zig.
  • If the bug only exists in Zig, use the corresponding C code and debug both implementations side by side to figure out what is wrong.

impl source routine(s) description

Integer library routines

Bit operations

dev HackersDelight __clzsi2 // count leading zeros dev HackersDelight __clzdi2 // count leading zeros dev HackersDelight __clzti2 // count leading zeros dev HackersDelight __ctzsi2 // count trailing zeros dev HackersDelight __ctzdi2 // count trailing zeros dev HackersDelight __ctzti2 // count trailing zeros dev __ctzsi2 __ffssi2 // find least significant 1 bit dev __ctzsi2 __ffsdi2 // find least significant 1 bit dev __ctzsi2 __ffsti2 // find least significant 1 bit dev BitTwiddlingHacks __paritysi2 // bit parity dev BitTwiddlingHacks __paritydi2 // bit parity dev BitTwiddlingHacks __parityti2 // bit parity dev TAOCP __popcountsi2 // bit population dev TAOCP __popcountdi2 // bit population dev TAOCP __popcountti2 // bit population dev other __bswapsi2 // a byteswapped dev other __bswapdi2 // a byteswapped dev other __bswapti2 // a byteswapped

Comparison: (a<b=>0,a==b->1,a>b=>2)

port llvm __cmpsi2 port llvm __cmpdi2 port llvm __cmpti2 port llvm __ucmpsi2 port llvm __ucmpdi2 port llvm __ucmpti2

Arithmetic

none none __ashlsi3 // a << b missing port llvm __ashldi3 // a << b port llvm __ashlti3 // a << b port llvm __ashrsi3 // a >> b arithmetic (sign fill) missing port llvm __ashrdi3 // a >> b arithmetic (sign fill) port llvm __ashrti3 // a >> b arithmetic (sign fill) none none __lshrsi3 // a >> b logical (zero fill) missing port llvm __lshrdi3 // a >> b logical (zero fill) port llvm __lshrti3 // a >> b logical (zero fill) port llvm __negdi2 // -a port llvm __negti2 // -a none none __mulsi3 // a * b missing signed port llvm __muldi3 // a * b signed port llvm __multi3 // a * b signed port llvm __divsi3 // a / b signed port llvm __divdi3 // a / b signed port llvm __divti3 // a / b signed port llvm __udivsi3 // a / b unsigned port llvm __udivdi3 // a / b unsigned port llvm __udivti3 // a / b unsigned port llvm __modsi3 // a % b signed port llvm __moddi3 // a % b signed port llvm __modti3 // a % b signed port llvm __umodsi3 // a % b unsigned port llvm __umoddi3 // a % b unsigned port llvm __umodti3 // a % b unsigned port llvm __udivmoddi4 // a / b, rem.* = a % b unsigned port llvm __udivmodti4 // a / b, rem.* = a % b unsigned port llvm __udivmodsi4 // a / b, rem.* = a % b unsigned port llvm __divmodsi4 // a / b, rem.* = a % b signed, ARM

Arithmetic with trapping overflow

dev BitTwiddlingHacks __absvsi2 // abs(a) dev BitTwiddlingHacks __absvdi2 // abs(a) dev BitTwiddlingHacks __absvti2 // abs(a) port llvm __negvsi2 // -a port llvm __negvdi2 // -a port llvm __negvti2 // -a TODO upstreaming __addvsi3..__mulvti3 after testing panics works dev HackersDelight __addvsi3 // a + b dev HackersDelight __addvdi3 // a + b dev HackersDelight __addvti3 // a + b dev HackersDelight __subvsi3 // a - b dev HackersDelight __subvdi3 // a - b dev HackersDelight __subvti3 // a - b dev HackersDelight __mulvsi3 // a * b dev HackersDelight __mulvdi3 // a * b dev HackersDelight __mulvti3 // a * b

Arithmetic which returns if overflow (would be faster without pointer)

dev HackersDelight __addosi4 // a * b, overflow=>ov.=1 else 0 dev HackersDelight __addodi4 // a * b, overflow=>ov.=1 else 0 dev HackersDelight __addoti4 // a * b, overflow=>ov.=1 else 0 dev HackersDelight __subosi4 // a * b, overflow=>ov.=1 else 0 dev HackersDelight __subodi4 // a * b, overflow=>ov.=1 else 0 dev HackersDelight __suboti4 // a * b, overflow=>ov.=1 else 0 dev HackersDelight __mulosi4 // a * b, overflow=>ov.=1 else 0 (required by llvm) dev HackersDelight __mulodi4 // a * b, overflow=>ov.=1 else 0 (required by llvm) dev HackersDelight __muloti4 // a * b, overflow=>ov.*=1 else 0 (required by llvm)

Soft float library routines

Integral / floating point conversion

__fixsfsi // convert a to i32, rounding towards zero __fixdfsi // __fixtfsi // __fixxfsi // missing __fixsfdi // convert a to i64, rounding towards zero __fixdfdi // __fixtfdi // __fixxfdi // missing __fixsfti // convert a to i128, rounding towards zero __fixdfti // __fixtfdi // __fixxfti // missing

__fixunssfsi // convert to u32, rounding towards zero. negative values become 0. __fixunsdfsi // __fixunstfsi // __fixunsxfsi // missing __fixunssfdi // convert to u64, rounding towards zero. negative values become 0. __fixunsdfdi // __fixunstfdi // __fixunsxfdi // missing __fixunssfti // convert to u128, rounding towards zero. negative values become 0. __fixunsdfti // __fixunstfdi // __fixunsxfti // missing

__floatsisf // convert i32 to floating point __floatsidf // __floatsitf // missing __floatsixf // __floatdisf // convert i64 to floating point __floatdidf // __floatditf // __floatdixf // missing __floattisf // convert i128 to floating point __floattidf // __floattixf //

__floatunsisf // convert i32 to floating point __floatunsidf // __floatunsitf // __floatunsixf // missing __floatundisf // convert i64 to floating point __floatundidf // __floatunditf // __floatundixf // missing __floatuntisf // convert i128 to floating point __floatuntidf // __floatuntitf // __floatuntixf // missing

Floating point raised to integer power

__powisf2 // a ^ b // missing __powidf2 // a ^ b // missing __powitf2 // a ^ b // missing __powixf2 // a ^ b // missing

Routines for floating point emulation

__addsf3 // a + b f32 __adddf3 // a + b f64 __addtf3 // a + b f128 __addxf3 // a + b f80 __aeabi_fadd // a + b f64 ARM: AAPCS __aeabi_dadd // a + b f64 ARM: AAPCS __subsf3 // a - b __subdf3 // a - b __subtf3 // a - b __subxf3 // a - b f80 __aeabi_fsub // a - b f64 ARM: AAPCS __aeabi_dsub // a - b f64 ARM: AAPCS __mulsf3 // a * b __muldf3 // a * b __multf3 // a * b __mulxf3 // a * b missing __divsf3 // a / b __divdf3 // a / b __divtf3 // a / b __divxf3 // a / b missing __negsf2 // -a __negdf2 // __negtf2 // missing __negxf2 // missing

__extendsfdf2 // conversion functions __truncxfdf2 // truncate a to narrower mode of return type, rounding towards zero __trunctfdf2 // __truncxfsf2 // __trunctfsf2 // __truncdfsf2 //

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment