|
Packit |
5c3484 |
divert(-1)
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl m4 macros for amd64 assembler.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Copyright 1999-2005, 2008, 2009, 2011-2013 Free Software Foundation, Inc.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl This file is part of the GNU MP Library.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl The GNU MP Library is free software; you can redistribute it and/or modify
|
|
Packit |
5c3484 |
dnl it under the terms of either:
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl * the GNU Lesser General Public License as published by the Free
|
|
Packit |
5c3484 |
dnl Software Foundation; either version 3 of the License, or (at your
|
|
Packit |
5c3484 |
dnl option) any later version.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl or
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl * the GNU General Public License as published by the Free Software
|
|
Packit |
5c3484 |
dnl Foundation; either version 2 of the License, or (at your option) any
|
|
Packit |
5c3484 |
dnl later version.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl or both in parallel, as here.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl The GNU MP Library is distributed in the hope that it will be useful, but
|
|
Packit |
5c3484 |
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
Packit |
5c3484 |
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
Packit |
5c3484 |
dnl for more details.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl You should have received copies of the GNU General Public License and the
|
|
Packit |
5c3484 |
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
|
|
Packit |
5c3484 |
dnl see https://www.gnu.org/licenses/.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: CPUVEC_FUNCS_LIST
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl A list of the functions from gmp-impl.h x86 struct cpuvec_t, in the
|
|
Packit |
5c3484 |
dnl order they appear in that structure.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(CPUVEC_FUNCS_LIST,
|
|
Packit |
5c3484 |
``add_n',
|
|
Packit |
5c3484 |
`addlsh1_n',
|
|
Packit |
5c3484 |
`addlsh2_n',
|
|
Packit |
5c3484 |
`addmul_1',
|
|
Packit |
5c3484 |
`addmul_2',
|
|
Packit |
5c3484 |
`bdiv_dbm1c',
|
|
Packit |
5c3484 |
`cnd_add_n',
|
|
Packit |
5c3484 |
`cnd_sub_n',
|
|
Packit |
5c3484 |
`com',
|
|
Packit |
5c3484 |
`copyd',
|
|
Packit |
5c3484 |
`copyi',
|
|
Packit |
5c3484 |
`divexact_1',
|
|
Packit |
5c3484 |
`divrem_1',
|
|
Packit |
5c3484 |
`gcd_1',
|
|
Packit |
5c3484 |
`lshift',
|
|
Packit |
5c3484 |
`lshiftc',
|
|
Packit |
5c3484 |
`mod_1',
|
|
Packit |
5c3484 |
`mod_1_1p',
|
|
Packit |
5c3484 |
`mod_1_1p_cps',
|
|
Packit |
5c3484 |
`mod_1s_2p',
|
|
Packit |
5c3484 |
`mod_1s_2p_cps',
|
|
Packit |
5c3484 |
`mod_1s_4p',
|
|
Packit |
5c3484 |
`mod_1s_4p_cps',
|
|
Packit |
5c3484 |
`mod_34lsub1',
|
|
Packit |
5c3484 |
`modexact_1c_odd',
|
|
Packit |
5c3484 |
`mul_1',
|
|
Packit |
5c3484 |
`mul_basecase',
|
|
Packit |
5c3484 |
`mullo_basecase',
|
|
Packit |
5c3484 |
`preinv_divrem_1',
|
|
Packit |
5c3484 |
`preinv_mod_1',
|
|
Packit |
5c3484 |
`redc_1',
|
|
Packit |
5c3484 |
`redc_2',
|
|
Packit |
5c3484 |
`rshift',
|
|
Packit |
5c3484 |
`sqr_basecase',
|
|
Packit |
5c3484 |
`sub_n',
|
|
Packit |
5c3484 |
`sublsh1_n',
|
|
Packit |
5c3484 |
`submul_1'')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl In the amd64 code we use explicit TEXT and ALIGN() calls in the code,
|
|
Packit |
5c3484 |
dnl since different alignments are wanted in various circumstances. So for
|
|
Packit |
5c3484 |
dnl instance,
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl TEXT
|
|
Packit |
5c3484 |
dnl ALIGN(16)
|
|
Packit |
5c3484 |
dnl PROLOGUE(mpn_add_n)
|
|
Packit |
5c3484 |
dnl ...
|
|
Packit |
5c3484 |
dnl EPILOGUE()
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`PROLOGUE_cpu',
|
|
Packit |
5c3484 |
m4_assert_numargs(1)
|
|
Packit |
5c3484 |
` GLOBL $1
|
|
Packit |
5c3484 |
TYPE($1,`function')
|
|
Packit |
5c3484 |
$1:
|
|
rpm-build |
c3cd4f |
CFPROT_ENDBR
|
|
Packit |
5c3484 |
')
|
|
Packit |
5c3484 |
|
|
rpm-build |
c3cd4f |
dnl Generates the endbr64 instructions
|
|
rpm-build |
c3cd4f |
dnl Using macro, so it can be easily extended to use some arch specific conditional defines
|
|
rpm-build |
c3cd4f |
define(`CFPROT_ENDBR',
|
|
rpm-build |
c3cd4f |
``
|
|
rpm-build |
c3cd4f |
endbr64''
|
|
rpm-build |
c3cd4f |
)
|
|
rpm-build |
c3cd4f |
|
|
rpm-build |
c3cd4f |
dnl Append the .gnu-property to the end of files
|
|
rpm-build |
c3cd4f |
dnl This is needed for a -fcf-protection
|
|
rpm-build |
c3cd4f |
dnl Again, using macro for easy arch specific defines
|
|
rpm-build |
c3cd4f |
dnl
|
|
rpm-build |
c3cd4f |
define(`CF_PROT',``
|
|
rpm-build |
c3cd4f |
.section .note.gnu.property,"a"
|
|
rpm-build |
c3cd4f |
.align 8
|
|
rpm-build |
c3cd4f |
.long 1f - 0f
|
|
rpm-build |
c3cd4f |
.long 4f - 1f
|
|
rpm-build |
c3cd4f |
.long 5
|
|
rpm-build |
c3cd4f |
0:
|
|
rpm-build |
c3cd4f |
.string "GNU"
|
|
rpm-build |
c3cd4f |
1:
|
|
rpm-build |
c3cd4f |
.align 8
|
|
rpm-build |
c3cd4f |
.long 0xc0000002
|
|
rpm-build |
c3cd4f |
.long 3f - 2f
|
|
rpm-build |
c3cd4f |
2:
|
|
rpm-build |
c3cd4f |
.long 0x3
|
|
rpm-build |
c3cd4f |
3:
|
|
rpm-build |
c3cd4f |
.align 8
|
|
rpm-build |
c3cd4f |
4:
|
|
rpm-build |
c3cd4f |
'')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: ASSERT([cond][,instructions])
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl If WANT_ASSERT is 1, output the given instructions and expect the given
|
|
Packit |
5c3484 |
dnl flags condition to then be satisfied. For example,
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl ASSERT(ne, `cmpq %rax, %rbx')
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl The instructions can be omitted to just assert a flags condition with
|
|
Packit |
5c3484 |
dnl no extra calculation. For example,
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl ASSERT(nc)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl When `instructions' is not empty, a pushfq/popfq is added for
|
|
Packit |
5c3484 |
dnl convenience to preserve the flags, but the instructions themselves must
|
|
Packit |
5c3484 |
dnl preserve any registers that matter.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl The condition can be omitted to just output the given instructions when
|
|
Packit |
5c3484 |
dnl assertion checking is wanted. In this case the pushf/popf is omitted.
|
|
Packit |
5c3484 |
dnl For example,
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl ASSERT(, `movq %rax, VAR_KEEPVAL')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(ASSERT,
|
|
Packit |
5c3484 |
m4_assert_numargs_range(1,2)
|
|
Packit |
5c3484 |
m4_assert_defined(`WANT_ASSERT')
|
|
Packit |
5c3484 |
`ifelse(WANT_ASSERT,1,
|
|
Packit |
5c3484 |
`ifelse(`$1',,
|
|
Packit |
5c3484 |
` $2',
|
|
Packit |
5c3484 |
`ifelse(`$2',,,
|
|
Packit |
5c3484 |
` pushfq')
|
|
Packit |
5c3484 |
$2
|
|
Packit |
5c3484 |
`j$1' L(ASSERT_ok`'ASSERT_counter)
|
|
Packit |
5c3484 |
ud2 C assertion failed
|
|
Packit |
5c3484 |
L(ASSERT_ok`'ASSERT_counter):
|
|
Packit |
5c3484 |
ifelse(`$2',,,` popfq')
|
|
Packit |
5c3484 |
define(`ASSERT_counter',incr(ASSERT_counter))')')')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(ASSERT_counter,1)
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`LEA',`dnl
|
|
Packit |
5c3484 |
ifdef(`PIC',
|
|
Packit |
5c3484 |
`mov $1@GOTPCREL(%rip), $2'
|
|
Packit |
5c3484 |
,
|
|
Packit |
5c3484 |
`movabs `$'$1, $2')
|
|
Packit |
5c3484 |
')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`DEF_OBJECT',
|
|
Packit |
5c3484 |
m4_assert_numargs_range(1,2)
|
|
Packit |
5c3484 |
` RODATA
|
|
Packit |
5c3484 |
ALIGN(ifelse($#,1,2,$2))
|
|
Packit |
5c3484 |
$1:
|
|
Packit |
5c3484 |
')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`END_OBJECT',
|
|
Packit |
5c3484 |
m4_assert_numargs(1)
|
|
Packit |
5c3484 |
` SIZE(`$1',.-`$1')')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`R32',
|
|
Packit |
5c3484 |
`ifelse($1,`%rax',`%eax',
|
|
Packit |
5c3484 |
$1,`%rbx',`%ebx',
|
|
Packit |
5c3484 |
$1,`%rcx',`%ecx',
|
|
Packit |
5c3484 |
$1,`%rdx',`%edx',
|
|
Packit |
5c3484 |
$1,`%rsi',`%esi',
|
|
Packit |
5c3484 |
$1,`%rdi',`%edi',
|
|
Packit |
5c3484 |
$1,`%rbp',`%ebp',
|
|
Packit |
5c3484 |
$1,`%r8',`%r8d',
|
|
Packit |
5c3484 |
$1,`%r9',`%r9d',
|
|
Packit |
5c3484 |
$1,`%r10',`%r10d',
|
|
Packit |
5c3484 |
$1,`%r11',`%r11d',
|
|
Packit |
5c3484 |
$1,`%r12',`%r12d',
|
|
Packit |
5c3484 |
$1,`%r13',`%r13d',
|
|
Packit |
5c3484 |
$1,`%r14',`%r14d',
|
|
Packit |
5c3484 |
$1,`%r15',`%r15d')')
|
|
Packit |
5c3484 |
define(`R8',
|
|
Packit |
5c3484 |
`ifelse($1,`%rax',`%al',
|
|
Packit |
5c3484 |
$1,`%rbx',`%bl',
|
|
Packit |
5c3484 |
$1,`%rcx',`%cl',
|
|
Packit |
5c3484 |
$1,`%rdx',`%dl',
|
|
Packit |
5c3484 |
$1,`%rsi',`%sil',
|
|
Packit |
5c3484 |
$1,`%rdi',`%dil',
|
|
Packit |
5c3484 |
$1,`%rbp',`%bpl',
|
|
Packit |
5c3484 |
$1,`%r8',`%r8b',
|
|
Packit |
5c3484 |
$1,`%r9',`%r9b',
|
|
Packit |
5c3484 |
$1,`%r10',`%r10b',
|
|
Packit |
5c3484 |
$1,`%r11',`%r11b',
|
|
Packit |
5c3484 |
$1,`%r12',`%r12b',
|
|
Packit |
5c3484 |
$1,`%r13',`%r13b',
|
|
Packit |
5c3484 |
$1,`%r14',`%r14b',
|
|
Packit |
5c3484 |
$1,`%r15',`%r15b')')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: CALL(funcname)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`CALL',`dnl
|
|
Packit |
5c3484 |
ifdef(`PIC',
|
|
Packit |
5c3484 |
`call GSYM_PREFIX`'$1@PLT'
|
|
Packit |
5c3484 |
,
|
|
Packit |
5c3484 |
`call GSYM_PREFIX`'$1'
|
|
Packit |
5c3484 |
)')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`JUMPTABSECT', `.section .data.rel.ro.local,"aw",@progbits')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: JMPENT(targlabel,tablabel)
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`JMPENT',`dnl
|
|
Packit |
5c3484 |
ifdef(`PIC',
|
|
Packit |
5c3484 |
`.long $1-$2'dnl
|
|
Packit |
5c3484 |
,
|
|
Packit |
5c3484 |
`.quad $1'dnl
|
|
Packit |
5c3484 |
)')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl These macros are defined just for DOS64, where they provide calling
|
|
Packit |
5c3484 |
dnl sequence glue code.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`FUNC_ENTRY',`')
|
|
Packit |
5c3484 |
define(`FUNC_EXIT',`')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Target ABI macros.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`IFDOS', `')
|
|
Packit |
5c3484 |
define(`IFSTD', `$1')
|
|
Packit |
5c3484 |
define(`IFELF', `$1')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: PROTECT(symbol)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl Used for private GMP symbols that should never be overridden by users.
|
|
Packit |
5c3484 |
dnl This can save reloc entries and improve shlib sharing as well as
|
|
Packit |
5c3484 |
dnl application startup times
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`PROTECT', `.hidden $1')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: x86_lookup(target, key,value, key,value, ...)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl Look for `target' among the `key' parameters.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl x86_lookup expands to the corresponding `value', or generates an error
|
|
Packit |
5c3484 |
dnl if `target' isn't found.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(x86_lookup,
|
|
Packit |
5c3484 |
m4_assert_numargs_range(1,999)
|
|
Packit |
5c3484 |
`ifelse(eval($#<3),1,
|
|
Packit |
5c3484 |
`m4_error(`unrecognised part of x86 instruction: $1
|
|
Packit |
5c3484 |
')',
|
|
Packit |
5c3484 |
`ifelse(`$1',`$2', `$3',
|
|
Packit |
5c3484 |
`x86_lookup(`$1',shift(shift(shift($@))))')')')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: x86_opcode_regxmm(reg)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl Validate the given xmm register, and return its number, 0 to 7.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(x86_opcode_regxmm,
|
|
Packit |
5c3484 |
m4_assert_numargs(1)
|
|
Packit |
5c3484 |
`x86_lookup(`$1',x86_opcode_regxmm_list)')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(x86_opcode_regxmm_list,
|
|
Packit |
5c3484 |
``%xmm0',0,
|
|
Packit |
5c3484 |
`%xmm1',1,
|
|
Packit |
5c3484 |
`%xmm2',2,
|
|
Packit |
5c3484 |
`%xmm3',3,
|
|
Packit |
5c3484 |
`%xmm4',4,
|
|
Packit |
5c3484 |
`%xmm5',5,
|
|
Packit |
5c3484 |
`%xmm6',6,
|
|
Packit |
5c3484 |
`%xmm7',7,
|
|
Packit |
5c3484 |
`%xmm8',8,
|
|
Packit |
5c3484 |
`%xmm9',9,
|
|
Packit |
5c3484 |
`%xmm10',10,
|
|
Packit |
5c3484 |
`%xmm11',11,
|
|
Packit |
5c3484 |
`%xmm12',12,
|
|
Packit |
5c3484 |
`%xmm13',13,
|
|
Packit |
5c3484 |
`%xmm14',14,
|
|
Packit |
5c3484 |
`%xmm15',15')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage: palignr($imm,%srcreg,%dstreg)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl Emit a palignr instruction, using a .byte sequence, since obsolete but
|
|
Packit |
5c3484 |
dnl still distributed versions of gas don't know SSSE3 instructions.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`palignr',
|
|
Packit |
5c3484 |
m4_assert_numargs(3)
|
|
Packit |
5c3484 |
`.byte 0x66,dnl
|
|
Packit |
5c3484 |
ifelse(eval(x86_opcode_regxmm($3) >= 8 || x86_opcode_regxmm($2) >= 8),1,
|
|
Packit |
5c3484 |
`eval(0x40+x86_opcode_regxmm($3)/8*4+x86_opcode_regxmm($2)/8),')dnl
|
|
Packit |
5c3484 |
0x0f,0x3a,0x0f,dnl
|
|
Packit |
5c3484 |
eval(0xc0+x86_opcode_regxmm($3)%8*8+x86_opcode_regxmm($2)%8),dnl
|
|
Packit |
5c3484 |
substr($1,1)')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl regnum(op) raw operand index (so slightly misnamed)
|
|
Packit |
5c3484 |
dnl regnumh(op) high bit of register operand nimber
|
|
Packit |
5c3484 |
dnl ix(op) 0 for reg operand, 1 for plain pointer operand.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`regnum',`x86_lookup(`$1',oplist)')
|
|
Packit |
5c3484 |
define(`regnumh',`eval(regnum($1)/8 & 1)')
|
|
Packit |
5c3484 |
define(`ix',`eval(regnum($1)/16)')
|
|
Packit |
5c3484 |
define(`oplist',
|
|
Packit |
5c3484 |
``%rax', 0, `%rcx', 1, `%rdx', 2, `%rbx', 3,
|
|
Packit |
5c3484 |
`%rsp', 4, `%rbp', 5, `%rsi', 6, `%rdi', 7,
|
|
Packit |
5c3484 |
`%r8', 8, `%r9', 9, `%r10', 10, `%r11', 11,
|
|
Packit |
5c3484 |
`%r12', 12, `%r13', 13, `%r14', 14, `%r15', 15,
|
|
Packit |
5c3484 |
`(%rax)',16, `(%rcx)',17, `(%rdx)',18, `(%rbx)',19,
|
|
Packit |
5c3484 |
`(%rsp)',20, `(%rbp)',21, `(%rsi)',22, `(%rdi)',23,
|
|
Packit |
5c3484 |
`(%r8)', 24, `(%r9)', 25, `(%r10)',26, `(%r11)',27,
|
|
Packit |
5c3484 |
`(%r12)',28, `(%r13)',29, `(%r14)',30, `(%r15)',31')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl mulx(reg1,reg2,reg3)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl or
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl mulx((reg1),reg2,reg3)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl where reg1 is any register but rsp,rbp,r12,r13, or
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl mulx(off,(reg1),reg2,reg3)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl where reg1 is any register but rsp,r12.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl The exceptions are due to special coding needed for some registers; rsp
|
|
Packit |
5c3484 |
dnl and r12 need an extra byte 0x24 at the end while rbp and r13 lack the
|
|
Packit |
5c3484 |
dnl offset-less form.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl Other addressing forms are not handled. Invalid forms are not properly
|
|
Packit |
5c3484 |
dnl detected. Offsets that don't fit one byte are not handled correctly.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`mulx',`dnl
|
|
Packit |
5c3484 |
.byte 0xc4`'dnl
|
|
Packit |
5c3484 |
ifelse(`$#',3,`dnl
|
|
Packit |
5c3484 |
,eval(0xe2^32*regnumh($1)^128*regnumh($3))`'dnl
|
|
Packit |
5c3484 |
,eval(0xfb-8*regnum($2))`'dnl
|
|
Packit |
5c3484 |
,0xf6`'dnl
|
|
Packit |
5c3484 |
,eval(0xc0+(7 & regnum($1))+8*(7 & regnum($3))-0xc0*ix($1))`'dnl
|
|
Packit |
5c3484 |
',`$#',4,`dnl
|
|
Packit |
5c3484 |
,eval(0xe2^32*regnumh($2)^128*regnumh($4))`'dnl
|
|
Packit |
5c3484 |
,eval(0xfb-8*regnum($3))`'dnl
|
|
Packit |
5c3484 |
,0xf6`'dnl
|
|
Packit |
5c3484 |
,eval(0x40+(7 & regnum($2))+8*(7 & regnum($4)))`'dnl
|
|
Packit |
5c3484 |
,eval(($1 + 256) % 256)`'dnl
|
|
Packit |
5c3484 |
')')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
dnl Usage
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl adcx(reg1,reg2)
|
|
Packit |
5c3484 |
dnl adox(reg1,reg2)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl or
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl adcx((reg1),reg2)
|
|
Packit |
5c3484 |
dnl adox((reg1),reg2)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl where reg1 is any register but rsp,rbp,r12,r13, or
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl adcx(off,(reg1),reg2)
|
|
Packit |
5c3484 |
dnl adox(off,(reg1),reg2)
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl where reg1 is any register but rsp,r12.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl The exceptions are due to special coding needed for some registers; rsp
|
|
Packit |
5c3484 |
dnl and r12 need an extra byte 0x24 at the end while rbp and r13 lack the
|
|
Packit |
5c3484 |
dnl offset-less form.
|
|
Packit |
5c3484 |
dnl
|
|
Packit |
5c3484 |
dnl Other addressing forms are not handled. Invalid forms are not properly
|
|
Packit |
5c3484 |
dnl detected. Offsets that don't fit one byte are not handled correctly.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`adx_helper',`dnl
|
|
Packit |
5c3484 |
,eval(0x48+regnumh($1)+4*regnumh($2))`'dnl
|
|
Packit |
5c3484 |
,0x0f`'dnl
|
|
Packit |
5c3484 |
,0x38`'dnl
|
|
Packit |
5c3484 |
,0xf6`'dnl
|
|
Packit |
5c3484 |
')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`adx',`dnl
|
|
Packit |
5c3484 |
ifelse(`$#',2,`dnl
|
|
Packit |
5c3484 |
adx_helper($1,$2)dnl
|
|
Packit |
5c3484 |
,eval(0xc0+(7 & regnum($1))+8*(7 & regnum($2))-0xc0*ix($1))`'dnl
|
|
Packit |
5c3484 |
',`$#',3,`dnl
|
|
Packit |
5c3484 |
adx_helper($2,$3)dnl
|
|
Packit |
5c3484 |
,eval(0x40+(7 & regnum($2))+8*(7 & regnum($3)))`'dnl
|
|
Packit |
5c3484 |
,eval(($1 + 256) % 256)`'dnl
|
|
Packit |
5c3484 |
')')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`adcx',`dnl
|
|
Packit |
5c3484 |
.byte 0x66`'dnl
|
|
Packit |
5c3484 |
adx($@)')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
define(`adox',`dnl
|
|
Packit |
5c3484 |
.byte 0xf3`'dnl
|
|
Packit |
5c3484 |
adx($@)')
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
divert`'dnl
|