Skip to content
  • Rasmus Villemoes's avatar
    lib/vsprintf.c: eliminate some branches · 51be17df
    Rasmus Villemoes authored
    
    
    Since FORMAT_TYPE_INT is simply 1 more than FORMAT_TYPE_UINT, and
    similarly for BYTE/UBYTE, SHORT/USHORT, LONG/ULONG, we can eliminate a few
    instructions by making SIGN have the value 1 instead of 2, and then use
    arithmetic instead of branches for computing the right spec->type.  It's a
    little hacky, but certainly in the same spirit as SMALL needing to have
    the value 0x20.  For example for the spec->qualifier == 'l' case, gcc now
    generates
    
         75e:       0f b6 53 01             movzbl 0x1(%rbx),%edx
         762:       83 e2 01                and    $0x1,%edx
         765:       83 c2 09                add    $0x9,%edx
         768:       88 13                   mov    %dl,(%rbx)
    
    instead of
    
         763:       0f b6 53 01             movzbl 0x1(%rbx),%edx
         767:       83 e2 02                and    $0x2,%edx
         76a:       80 fa 01                cmp    $0x1,%dl
         76d:       19 d2                   sbb    %edx,%edx
         76f:       83 c2 0a                add    $0xa,%edx
         772:       88 13                   mov    %dl,(%rbx)
    
    Signed-off-by: default avatarRasmus Villemoes <linux@rasmusvillemoes.dk>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Tejun Heo <tj@kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    51be17df