https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89063
Bug ID: 89063 Summary: [x86] lack of support for BEXTR from BMI extension Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: wojciech_mula at poczta dot onet.pl Target Milestone: --- Instruction BEXTR extracts an arbitrary unsigned bit field from 32- or 64-bit value. As I see in `config/i386.md`, there's support for the immediate variant available in AMD's TBM (TARGET_TBM). Intel's variant gets parameters from a register. Although this variant won't be profitable in all cases -- as we need an extra move to setup the bit-field parameters in a register -- I bet bit-field-intensive code might benefit from BEXTR. ---bextr.c--- #include <immintrin.h> #include <stdint.h> uint64_t test(uint64_t x) { const uint64_t a0 = (x & 0x3f); const uint64_t a1 = (x >> 11) & 0x3f; const uint64_t a2 = (x >> 22) & 0x3f; return a0 + a1 + a2; } uint64_t test_intrinsics(uint64_t x) { const uint64_t a0 = (x & 0x3f); const uint64_t a1 = _bextr_u64(x, 11, 6); const uint64_t a2 = _bextr_u64(x, 22, 6); return a0 + a1 + a2; } ---eof--- $ gcc --version gcc (GCC) 9.0.0 20190117 (experimental) $ gcc -O3 -mbmi -march=skylake bextr.c -c && objdump -d bextr.o 0000000000000000 <test>: 0: 48 89 fa mov %rdi,%rdx 3: 48 c1 ea 0b shr $0xb,%rdx 7: 48 89 f8 mov %rdi,%rax a: 48 89 d1 mov %rdx,%rcx d: 48 c1 e8 16 shr $0x16,%rax 11: 83 e0 3f and $0x3f,%eax 14: 83 e1 3f and $0x3f,%ecx 17: 48 8d 14 01 lea (%rcx,%rax,1),%rdx 1b: 83 e7 3f and $0x3f,%edi 1e: 48 8d 04 3a lea (%rdx,%rdi,1),%rax 22: c3 retq 0000000000000030 <test_intrinsics>: 30: b8 0b 06 00 00 mov $0x60b,%eax 35: c4 e2 f8 f7 d7 bextr %rax,%rdi,%rdx 3a: b8 16 06 00 00 mov $0x616,%eax 3f: c4 e2 f8 f7 c7 bextr %rax,%rdi,%rax 44: 83 e7 3f and $0x3f,%edi 47: 48 01 d0 add %rdx,%rax 4a: 48 01 f8 add %rdi,%rax 4d: c3 retq