←back to thread

420 points gnabgib | 2 comments | | HN request time: 0.519s | source
Show context
npendleton ◴[] No.44003801[source]
This is so cool!

Terrible nitpick, but this is actually 3 operations, not instructions. On x86 you get 4:

  is_leap_year_fast:
        imul    eax, edi, 1073750999
        and     eax, -1073614833
        cmp     eax, 126977
        setb    al
        ret
On ARM you get a bit more due to instruction encoding:

  is_leap_year_fast:
        ldr     r1, .LCPI0_0
        mul     r0, r0, r1
        ldr     r1, .LCPI0_1
        and     r1, r0, r1
        mov     r0, #0
        cmp     r1, #126976
        movwls  r0, #1
        bx      lr
  .LCPI0_0:
        .long   1073750999
  .LCPI0_1:
        .long   3221352463
Compiler explorer reference: https://godbolt.org/z/7ajYqbT9z
replies(1): >>44004256 #
1. gpderetta ◴[] No.44004256[source]
You could argue that the setb and ret are not part of the leap year check itself. For example if the compiled inlined the call into a caller doing:

    if(is_leap_year_fast()) {...}
Then the ret would obviously go away and the setb wouldn't be necessary as it could generate directly a conditional jmp from the result of the cmp.
replies(1): >>44004560 #
2. npendleton ◴[] No.44004560[source]
Hah, great point!