Для каждой константы набор команд определяется на основании их "весовых коэффициентов" и количества тактов процессора, необходимых для их выполнения. В качестве примера приведена вот такая табличка оптимизации умножения с 2 до 32. Ее всегда можно посмотреть и в самом мануале, но лучше пусть будет под рукой.
; Умножение на 2
add reg1, reg1 ; 1 такт процессора
; Умножение на 3
lea reg1, [reg1+reg1*2] ; 2 такта процессора
; Умножение на 4
shl reg1, 2 ; 1 такт процессора
; Умножение на 5
lea reg1, [reg1+reg1*4] ; 2 такта процессора
; Умножение на 6
lea reg1, [reg1+reg1*2] ; 3 такта процессора
add reg1, reg1
; Умножение на 7:
mov reg2, reg1 ; 2 такта процессора
shl reg1, 3
sub reg1, reg2
; Умножение на 8:
shl reg1, 3 ; 1 такт процессора
; Умножение на 9:
lea reg1, [reg1+reg1*8] ; 2 такта процессора
; Умножение на 10:
lea reg1, [reg1+reg1*4] ; 3 такта процессора
add reg1, reg1
; Умножение на 11:
lea reg2, [reg1+reg1*8] ; 3 такта процессора
add reg1, reg1
add reg1, reg2
; Умножение на 12:
lea reg1, [reg1+reg1*2] ; 3 такта процессора
shl reg1, 2
; Умножение на 13:
lea reg2, [reg1+reg1*2] ; 3 такта процессора
shl reg1, 4
sub reg1, reg2
; Умножение на 14:
lea reg2, [reg1+reg1] ; 3 такта процессора
shl reg1, 4
sub reg1, reg2
; Умножение на 15:
lea reg1, [reg1+reg1*2] ; 4 такта процессора
lea reg1, [reg1+reg1*4]
; Умножение на 16:
shl reg1, 4 ; 1 такт процессора
; Умножение на 17:
mov reg2, reg1 ; 2 такта процессора
shl reg1, 4
add reg1, reg2
; Умножение на 18:
lea reg1, [reg1+reg1*8] ; 3 такта процессора
add reg1, reg1
; Умножение на 19:
lea reg2, [reg1+reg1*2] ; 3 такта процессора
shl reg1, 4
add reg1, reg2
; Умножение на 20:
lea reg1, [reg1+reg1*4] ; 3 такта процессора
shl reg1, 2
; Умножение на 21:
lea reg2, [reg1+reg1*4] ; 3 такта процессора
shl reg1, 4
add reg1, reg2
; Умножение на 22:
lea reg2, [reg1+reg1*4] ; 4 такта процессора
add reg1, reg1
lea reg1, [reg1+reg2*4]
; Умножение на 23:
lea reg2, [reg1+reg1*8] ; 3 такта процессора
shl reg1, 5
sub reg1, reg2
; Умножение на 24:
lea reg1, [reg1+reg1*2] ; 3 такта процессора
shl reg1, 3
; Умножение на 25:
lea reg1, [reg1+reg1*4] ; 4 такта процессора
lea reg1, [reg1+reg1*4]
; Умножение на 26:
lea reg2, [reg1+reg1*2] ; 4 такта процессора
add reg1, reg1
lea reg1, [reg1+reg2*8]
; Умножение на 27:
lea reg1, [reg1+reg1*2] ; 4 такта процессора
lea reg1, [reg1+reg1*8]
; Умножение на 28:
lea reg2, [reg1*4] ; 3 такта процессора
shl reg1, 5
sub reg1, reg2
; Умножение на 29:
lea reg2, [reg1+reg1*2] ; 3 такта процессора
shl reg1, 5
sub reg1, reg2
; Умножение на 30:
lea reg2, [reg1+reg1] ; 3 такта процессора
shl reg1, 5
sub reg1, reg2
; Умножение на 31:
mov reg2, reg1 ; 2 такта процессора
shl reg1, 5
sub reg1, reg2
; Умножение на 32:
shl reg1, 5 ; 1 такт процессора
В разделе мануала, посвященном оптимизации целочисленного умножения, упоминается программа "FINDMUL", которая находится на "AMD Documentation CD-ROM". Как написано в мануале, эта программа должна рассчитывать оптимальный алгоритм умножения на константу. К сожалению, ни саму программу, ни этот диск в интернетах мне найти не удалось, поэтому больше ничего про нее сказать не могу. Неизвестны ни алгоритм ее работы, ни диапазон констант, которые она в состоянии оптимизировать. Если кто-то знает где его взять, то, пожалуйста, напишите. Буду очень благодарен.
Но в процессе поисков информации я наткнулся на интересную статью "
Integer multiplying by constants" на сайте программиста Paul Hsieh. Там приведена расширенная
таблица оптимизированного умножения на константу. Кроме самой таблицы выложены исходники программы "MULTOPP5", которая ищет оптимальный алгоритм умножения. Из-за особенностей работы, максимальное значение константы, которое сможет оптимизировать эта программа, немногим превышает 2000. Я не силен в C, но может быть как-нибудь можно ее модифицировать, чтобы расширить диапазон поиска.