#include #include #include bool is_zero_or(const uint8_t * addr) { return ((addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]) == 0); } bool is_bcast_and(const uint8_t * addr) { return ((addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff); } bool is_zero_add(const uint8_t * addr) { return ((addr[0] + addr[1] + addr[2] + addr[3] + addr[4] + addr[5]) == 0); } bool is_bcast_add(const uint8_t * addr) { return ((addr[0] + addr[1] + addr[2] + addr[3] + addr[4] + addr[5]) == (6*0xff)); } ======================================================================================== Clang 8.0.0, -O3: // Add variants are much the same as the inline versions, but OR/AND get SIMD'd (obviously unhelpful for kernel) 0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 66 0f 6e 07 movd (%rdi),%xmm0 8: 66 0f 60 c0 punpcklbw %xmm0,%xmm0 c: 66 0f 61 c0 punpcklwd %xmm0,%xmm0 10: 66 0f 70 c8 4e pshufd $0x4e,%xmm0,%xmm1 15: 66 0f eb c8 por %xmm0,%xmm1 19: 66 0f 70 c1 e5 pshufd $0xe5,%xmm1,%xmm0 1e: 66 0f eb c1 por %xmm1,%xmm0 22: 66 0f 7e c0 movd %xmm0,%eax 26: 0a 47 04 or 0x4(%rdi),%al 29: 0a 47 05 or 0x5(%rdi),%al 2c: 0f 94 c0 sete %al 2f: 5d pop %rbp 30: c3 retq 0000000000000040 : 40: 55 push %rbp 41: 48 89 e5 mov %rsp,%rbp 44: 66 0f 6e 07 movd (%rdi),%xmm0 48: 66 0f 60 c0 punpcklbw %xmm0,%xmm0 4c: 66 0f 61 c0 punpcklwd %xmm0,%xmm0 50: 66 0f 70 c8 4e pshufd $0x4e,%xmm0,%xmm1 55: 66 0f db c8 pand %xmm0,%xmm1 59: 66 0f 70 c1 e5 pshufd $0xe5,%xmm1,%xmm0 5e: 66 0f db c1 pand %xmm1,%xmm0 62: 66 0f 7e c0 movd %xmm0,%eax 66: 22 47 04 and 0x4(%rdi),%al 69: 22 47 05 and 0x5(%rdi),%al 6c: 3c ff cmp $0xff,%al 6e: 0f 94 c0 sete %al 71: 5d pop %rbp 72: c3 retq 0000000000000080 : 80: 55 push %rbp 81: 48 89 e5 mov %rsp,%rbp 84: 0f b6 07 movzbl (%rdi),%eax 87: 0f b6 4f 01 movzbl 0x1(%rdi),%ecx 8b: 01 c1 add %eax,%ecx 8d: 0f b6 47 02 movzbl 0x2(%rdi),%eax 91: 01 c8 add %ecx,%eax 93: 0f b6 4f 03 movzbl 0x3(%rdi),%ecx 97: 01 c1 add %eax,%ecx 99: 0f b6 47 04 movzbl 0x4(%rdi),%eax 9d: 01 c8 add %ecx,%eax 9f: 0f b6 4f 05 movzbl 0x5(%rdi),%ecx a3: 01 c1 add %eax,%ecx a5: 0f 94 c0 sete %al a8: 5d pop %rbp a9: c3 retq 00000000000000b0 : b0: 55 push %rbp b1: 48 89 e5 mov %rsp,%rbp b4: 0f b6 07 movzbl (%rdi),%eax b7: 0f b6 4f 01 movzbl 0x1(%rdi),%ecx bb: 01 c1 add %eax,%ecx bd: 0f b6 47 02 movzbl 0x2(%rdi),%eax c1: 01 c8 add %ecx,%eax c3: 0f b6 4f 03 movzbl 0x3(%rdi),%ecx c7: 01 c1 add %eax,%ecx c9: 0f b6 47 04 movzbl 0x4(%rdi),%eax cd: 01 c8 add %ecx,%eax cf: 0f b6 4f 05 movzbl 0x5(%rdi),%ecx d3: 01 c1 add %eax,%ecx d5: 81 f9 fa 05 00 00 cmp $0x5fa,%ecx db: 0f 94 c0 sete %al de: 5d pop %rbp df: c3 retq ======================================================================================== GCC 8.3.0, -O3: // Add variants are the same, but AND/OR variants generate shorter code by fusing load + and/or into a single OP. 0000000000000000 : 0: 0f b6 07 movzbl (%rdi),%eax 3: 0a 47 01 or 0x1(%rdi),%al 6: 0a 47 02 or 0x2(%rdi),%al 9: 0a 47 03 or 0x3(%rdi),%al c: 0a 47 04 or 0x4(%rdi),%al f: 0a 47 05 or 0x5(%rdi),%al 12: 0f 94 c0 sete %al 15: c3 retq 0000000000000020 : 20: 0f b6 07 movzbl (%rdi),%eax 23: 22 47 01 and 0x1(%rdi),%al 26: 22 47 02 and 0x2(%rdi),%al 29: 22 47 03 and 0x3(%rdi),%al 2c: 22 47 04 and 0x4(%rdi),%al 2f: 22 47 05 and 0x5(%rdi),%al 32: 3c ff cmp $0xff,%al 34: 0f 94 c0 sete %al 37: c3 retq