[patch] Two Intel ADX instructions
Robert Smith <[email protected]> Sun, 1 Mar 2026 14:09:04 -0500
| Newsgroups | gmane.lisp.steel-bank.devel |
|---|---|
| Message-ID | <CAPbE8xAS_atXbYq4CY8d0eyU2UE+72udwjpwGZ3s=p0A-mNoGQ@mail.gmail.com> |
Hello SBCL friends: Attached is a patch to add ADCX and ADOX to SBCL's assembler. It doesn't change any VOPs. It's a very small patch, but I'm not sure if I got a few things right. Some points: - The ADX extension isn't supported by all processors. Support began on AMD Ryzen and Intel Broadwell (both ~10 years ago, plus or minus). Since this is "recent", I decided to put these instruction definitions next to their closest cousin, MULX, in the AVX2 file. (Technically MULX is from the BMI2, too.) - There is a CPUID way to determine support, but I felt getting into the weeds of config and build for this granular addition was too much, so I instead rely on AVX2 "implying" ADX. - The tests are just a couple smoke tests, nothing too serious. - I'm not an expert at x86 instruction encodings, so I did a little bit of mimicry + referencing section 10.5 of [1]. - I've tested these instructions in an "actual" application that uses these paths billions of times in a tedious arithmetic calculation with verified intermediate and final results. This patch allows me to write faster code for extremely high-precision arithmetic beyond SBCL BIGNUM and GMP, specifically for add-mul-carry chains that occur in large integer multiplication and a few other places. While it's a welcome improvement in many regards, it's not critical, so I will not be offended in the slightest if this patch is turned away. :) Robert [1] https://web.archive.org/web/20130929035331/http://download-software.intel.com/sites/default/files/319433-015.pdf _______________________________________________ Sbcl-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/sbcl-devel
0001-Add-ADCX-and-ADOX-instruction-definitions.patch
(application/x-patch, 2.4 KB)
From 2555e1e4b6fa7a891b8359e49ea8a2389fe710e7 Mon Sep 17 00:00:00 2001 From: Robert Smith <[email protected]> Date: Sun, 1 Mar 2026 17:39:43 +0000 Subject: [PATCH] Add ADCX and ADOX instruction definitions --- src/compiler/x86-64/avx2-insts.lisp | 18 ++++++++++++++++++ tests/assembler.pure.lisp | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/compiler/x86-64/avx2-insts.lisp b/src/compiler/x86-64/avx2-insts.lisp index c2b41363b..99256691c 100644 --- a/src/compiler/x86-64/avx2-insts.lisp +++ b/src/compiler/x86-64/avx2-insts.lisp @@ -1271,3 +1271,21 @@ . #.(avx2-inst-printer-list 'vex-gpr #xF2 #xF6 :nds t :opcode-prefix #x0f38)) + +(define-instruction adcx (segment &prefix prefix dst src) + (:printer ext-2byte-prefix-reg-reg/mem + ((prefix #x66) (op1 #x38) (op2 #xf6))) + (:emitter + (let ((size (pick-operand-size prefix dst src))) + (aver (memq size '(:dword :qword))) + (emit-sse-inst-2byte segment dst src #x66 #x38 #xf6 + :operand-size size)))) + +(define-instruction adox (segment &prefix prefix dst src) + (:printer ext-2byte-prefix-reg-reg/mem + ((prefix #xf3) (op1 #x38) (op2 #xf6))) + (:emitter + (let ((size (pick-operand-size prefix dst src))) + (aver (memq size '(:dword :qword))) + (emit-sse-inst-2byte segment dst src #xf3 #x38 #xf6 + :operand-size size)))) diff --git a/tests/assembler.pure.lisp b/tests/assembler.pure.lisp index d73e496af..2177952ea 100644 --- a/tests/assembler.pure.lisp +++ b/tests/assembler.pure.lisp @@ -107,6 +107,18 @@ (test-assemble `(crc32 :qword ,r9-tn ,(ea r14-tn r15-tn)) "F24F0F38F10C3E CRC32 R9, QWORD PTR [R14+R15]")) +(test-util:with-test (:name :assemble-adcx-adox :skipped-on (not :x86-64)) + ;; ADCX: 66 [REX.W] 0F 38 F6 ModRM + (test-assemble `(adcx ,eax ,ebx) + "660F38F6C3 ADCX EAX, EBX") + (test-assemble `(adcx ,rax-tn ,rbx-tn) + "66480F38F6C3 ADCX RAX, RBX") + ;; ADOX: F3 [REX.W] 0F 38 F6 ModRM + (test-assemble `(adox ,eax ,ebx) + "F30F38F6C3 ADOX EAX, EBX") + (test-assemble `(adox ,rax-tn ,rbx-tn) + "F3480F38F6C3 ADOX RAX, RBX")) + (test-util:with-test (:name :assemble-unsigned-qword-imm-to-mem :skipped-on (not :x86-64)) ;; unsigned bits cast as signed bits (let ((const #xffffffff801234BB)) -- 2.43.0