• Maciej W. Rozycki's avatar
    MIPS: Rewrite `csum_tcpudp_nofold' in plain C · 84aa8510
    Maciej W. Rozycki authored
    Recent commit 198688ed ("MIPS: Fix inline asm input/output type
    mismatch in checksum.h used with Clang") introduced a code size and
    performance regression with 64-bit code emitted for `csum_tcpudp_nofold'
    by GCC, caused by a redundant truncation operation produced due to a
    data type change made to the variable associated with the inline
    assembly's output operand.
    
    The intent previously expressed here with operands and constraints for
    optimal code was to have the output operand share a register with one
    inputs, both of a different integer type each.  This is perfectly valid
    with the MIPS psABI where a register can hold integer data of different
    types and the assembly code used here makes data stored in the output
    register match the data type used with the output operand, however it
    has turned out impossible to express this arrangement in source code
    such as to satisfy LLVM, apparently due to the compiler's internal
    limitations.
    
    There is nothing peculiar about the inline assembly `csum_tcpudp_nofold'
    includes however, though it does choose assembly instructions carefully.
    
    Rewrite this piece of assembly in plain C then, using corresponding C
    language operations, making GCC produce the same assembly instructions,
    possibly shuffled, in the general case and sometimes actually fewer of
    them where an input is constant, because the compiler does not have to
    reload it to a register (operand constraints could be adjusted for that,
    but the plain C approach is cleaner anyway).
    
    Example code size changes are as follows, for a 32-bit configuration:
    
          text       data        bss      total filename
       5920480    1347236     126592    7394308 vmlinux-old
       5920480    1347236     126592    7394308 vmlinux-now
       5919728    1347236     126592    7393556 vmlinux-c
    
    and for a 64-bit configuration:
    
          text       data        bss      total filename
       6024112    1790828     225728    8040668 vmlinux-old
       6024128    1790828     225728    8040684 vmlinux-now
       6023760    1790828     225728    8040316 vmlinux-c
    
    respectively, where "old" is with the commit referred reverted, "now" is
    with no change, and "c" is with this change applied.
    Signed-off-by: default avatarMaciej W. Rozycki <macro@orcam.me.uk>
    Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
    84aa8510
checksum.h 5.64 KB