Add support for the following AMD instructions added in their July 2007

documentation update:
 - LZCNT
 - POPCNT
 - EXTRQ
 - INSERTQ
 - MOVNTSD
 - MOVNTSS

This required some new tricks in the x86 code, as EXTRQ and INSERTQ have
two imm8 parameters (the first one of which goes into the EA field), and
INSERTQ has a *4* parameter version (xmm1, xmm2, imm8, imm8).  Instead of
globally making the structures 4 wide, we just special-case INSERTQ.

svn path=/trunk/yasm/; revision=1909
multiarch
Peter Johnson 17 years ago
parent 589c25b451
commit aea53cfd9e
  1. 2
      modules/arch/x86/tests/Makefile.inc
  2. 31
      modules/arch/x86/tests/amd200707.asm
  3. 212
      modules/arch/x86/tests/amd200707.hex
  4. 6
      modules/arch/x86/x86arch.h
  5. 65
      modules/arch/x86/x86bc.c
  6. 123
      modules/arch/x86/x86id.c
  7. 8
      modules/arch/x86/x86parse.gap

@ -11,6 +11,8 @@ EXTRA_DIST += modules/arch/x86/tests/addrop.errwarn
EXTRA_DIST += modules/arch/x86/tests/addrop.hex
EXTRA_DIST += modules/arch/x86/tests/addrop-err.asm
EXTRA_DIST += modules/arch/x86/tests/addrop-err.errwarn
EXTRA_DIST += modules/arch/x86/tests/amd200707.asm
EXTRA_DIST += modules/arch/x86/tests/amd200707.hex
EXTRA_DIST += modules/arch/x86/tests/arithsmall.asm
EXTRA_DIST += modules/arch/x86/tests/arithsmall.errwarn
EXTRA_DIST += modules/arch/x86/tests/arithsmall.hex

@ -0,0 +1,31 @@
bits 64
extrq xmm0, 5, 4
extrq xmm6, 0, 7
extrq xmm2, xmm3
insertq xmm0, xmm1, 5, 4
insertq xmm5, xmm6, 0, 7
insertq xmm2, xmm3
movntsd [0], xmm1
movntsd qword [0], xmm5
movntss [0], xmm3
movntss dword [0], xmm7
lzcnt ax, bx
lzcnt cx, word [0]
lzcnt dx, [0]
lzcnt eax, ebx
lzcnt ecx, dword [0]
lzcnt edx, [0]
lzcnt rax, rbx
lzcnt rcx, qword [0]
lzcnt rdx, [0]
popcnt ax, bx
popcnt cx, word [0]
popcnt dx, [0]
popcnt eax, ebx
popcnt ecx, dword [0]
popcnt edx, [0]
popcnt rax, rbx
popcnt rcx, qword [0]
popcnt rdx, [0]

@ -0,0 +1,212 @@
66
0f
78
c0
05
04
66
0f
78
c6
00
07
66
0f
79
d3
f2
0f
78
c1
05
04
f2
0f
78
ee
00
07
f2
0f
79
d3
f2
0f
2b
0c
25
00
00
00
00
f2
0f
2b
2c
25
00
00
00
00
f3
0f
2b
1c
25
00
00
00
00
f3
0f
2b
3c
25
00
00
00
00
66
f3
0f
bd
c3
66
f3
0f
bd
0c
25
00
00
00
00
66
f3
0f
bd
14
25
00
00
00
00
f3
0f
bd
c3
f3
0f
bd
0c
25
00
00
00
00
f3
0f
bd
14
25
00
00
00
00
f3
48
0f
bd
c3
f3
48
0f
bd
0c
25
00
00
00
00
f3
48
0f
bd
14
25
00
00
00
00
66
f3
0f
b8
c3
66
f3
0f
b8
0c
25
00
00
00
00
66
f3
0f
b8
14
25
00
00
00
00
f3
0f
b8
c3
f3
0f
b8
0c
25
00
00
00
00
f3
0f
b8
14
25
00
00
00
00
f3
48
0f
b8
c3
f3
48
0f
b8
0c
25
00
00
00
00
f3
48
0f
b8
14
25
00
00
00
00

@ -163,10 +163,10 @@ void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
yasm_bytecode *precbc);
void yasm_x86__ea_set_disponly(x86_effaddr *x86_ea);
x86_effaddr *yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
unsigned int bits);
x86_effaddr *yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg,
unsigned char *rex, unsigned int bits);
x86_effaddr *yasm_x86__ea_create_imm
(/*@keep@*/ yasm_expr *imm, unsigned int im_len);
(x86_effaddr *x86_ea, /*@keep@*/ yasm_expr *imm, unsigned int im_len);
yasm_effaddr *yasm_x86__ea_create_expr(yasm_arch *arch,
/*@keep@*/ yasm_expr *e);
void yasm_x86__ea_destroy(yasm_effaddr *ea);

@ -172,17 +172,10 @@ yasm_x86__ea_set_disponly(x86_effaddr *x86_ea)
x86_ea->need_sib = 0;
}
x86_effaddr *
yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
unsigned int bits)
static x86_effaddr *
ea_create(void)
{
x86_effaddr *x86_ea;
unsigned char rm;
if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B))
return NULL;
x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
x86_effaddr *x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
yasm_value_initialize(&x86_ea->ea.disp, NULL, 0);
x86_ea->ea.need_nonzero_len = 0;
@ -190,9 +183,9 @@ yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
x86_ea->ea.nosplit = 0;
x86_ea->ea.strong = 0;
x86_ea->ea.segreg = 0;
x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */
x86_ea->valid_modrm = 1;
x86_ea->need_modrm = 1;
x86_ea->modrm = 0;
x86_ea->valid_modrm = 0;
x86_ea->need_modrm = 0;
x86_ea->sib = 0;
x86_ea->valid_sib = 0;
x86_ea->need_sib = 0;
@ -200,13 +193,31 @@ yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
return x86_ea;
}
x86_effaddr *
yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg,
unsigned char *rex, unsigned int bits)
{
unsigned char rm;
if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B))
return NULL;
if (!x86_ea)
x86_ea = ea_create();
x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */
x86_ea->valid_modrm = 1;
x86_ea->need_modrm = 1;
return x86_ea;
}
yasm_effaddr *
yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
x86_effaddr *x86_ea;
x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
x86_ea = ea_create();
if (arch_x86->parser == X86_PARSER_GAS) {
/* Need to change foo+rip into foo wrt rip.
@ -224,16 +235,8 @@ yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
}
}
yasm_value_initialize(&x86_ea->ea.disp, e, 0);
x86_ea->ea.need_nonzero_len = 0;
x86_ea->ea.need_disp = 1;
x86_ea->ea.nosplit = 0;
x86_ea->ea.strong = 0;
x86_ea->ea.segreg = 0;
x86_ea->modrm = 0;
x86_ea->valid_modrm = 0;
x86_ea->need_modrm = 1;
x86_ea->sib = 0;
x86_ea->valid_sib = 0;
/* We won't know whether we need an SIB until we know more about expr and
* the BITS/address override setting.
*/
@ -244,23 +247,13 @@ yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
/*@-compmempass@*/
x86_effaddr *
yasm_x86__ea_create_imm(yasm_expr *imm, unsigned int im_len)
yasm_x86__ea_create_imm(x86_effaddr *x86_ea, yasm_expr *imm,
unsigned int im_len)
{
x86_effaddr *x86_ea;
x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
if (!x86_ea)
x86_ea = ea_create();
yasm_value_initialize(&x86_ea->ea.disp, imm, im_len);
x86_ea->ea.need_disp = 1;
x86_ea->ea.nosplit = 0;
x86_ea->ea.strong = 0;
x86_ea->ea.segreg = 0;
x86_ea->modrm = 0;
x86_ea->valid_modrm = 0;
x86_ea->need_modrm = 0;
x86_ea->sib = 0;
x86_ea->valid_sib = 0;
x86_ea->need_sib = 0;
return x86_ea;
}

@ -2210,15 +2210,43 @@ static const x86_insn_info sse4m16_insn[] = {
{OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }
};
static const x86_insn_info popcnt_insn[] = {
{ CPU_SSE42, MOD_GasSufW, 16, 0, 0xF3, 2, {0x0F, 0xB8, 0}, 0, 2,
static const x86_insn_info cnt_insn[] = {
{ CPU_SSE42, MOD_Op1Add|MOD_GasSufW, 16, 0, 0xF3, 2, {0x0F, 0x00, 0}, 0, 2,
{OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
{ CPU_SSE42, MOD_GasSufL, 32, 0, 0xF3, 2, {0x0F, 0xB8, 0}, 0, 2,
{ CPU_SSE42, MOD_Op1Add|MOD_GasSufL, 32, 0, 0xF3, 2, {0x0F, 0x00, 0}, 0, 2,
{OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
{ CPU_SSE42|CPU_64, MOD_GasSufQ, 64, 0, 0xF3, 2, {0x0F, 0xB8, 0}, 0, 2,
{ CPU_SSE42|CPU_64, MOD_Op1Add|MOD_GasSufQ, 64, 0, 0xF3, 2,
{0x0F, 0x00, 0}, 0, 2,
{OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
};
static const x86_insn_info extrq_insn[] = {
{ CPU_SSE41, 0, 0, 0, 0x66, 2, {0x0F, 0x78, 0}, 0, 3,
{OPT_SIMDReg|OPS_128|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_EA,
OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
{ CPU_SSE41, 0, 0, 0, 0x66, 2, {0x0F, 0x79, 0}, 0, 2,
{OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }
};
static const unsigned long insertq_4operands[] =
{OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA,
OPT_Imm|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm};
static const x86_insn_info insertq_insn[] = {
{ CPU_SSE41, 0, 0, 0, 0xF2, 2, {0x0F, 0x78, 0}, 0, 4, {0, 0, 0} },
{ CPU_SSE41, 0, 0, 0, 0xF2, 2, {0x0F, 0x79, 0}, 0, 2,
{OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }
};
static const x86_insn_info movntsd_insn[] = {
{ CPU_SSE41, 0, 0, 0, 0xF2, 2, {0x0F, 0x2B, 0}, 0, 2,
{OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
};
static const x86_insn_info movntss_insn[] = {
{ CPU_SSE41, 0, 0, 0, 0xF3, 2, {0x0F, 0x2B, 0}, 0, 2,
{OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
};
/* AMD 3DNow! instructions */
static const x86_insn_info now3d_insn[] = {
{ CPU_3DNow, MOD_Imm8, 0, 0, 0, 2, {0x0F, 0x0F, 0}, 0, 2,
@ -2525,6 +2553,7 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
*/
for (; num_info>0 && !found; num_info--, info++) {
yasm_insn_operand *op, **use_ops;
const unsigned long *info_ops = info->operands;
unsigned long icpu;
unsigned int size;
int mismatch = 0;
@ -2570,11 +2599,15 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
break;
}
/* 4-operand special case for insertq */
if (info->num_operands > 3)
info_ops = insertq_4operands;
/* Match each operand type and size */
for (i = 0, op = use_ops[0]; op && i<info->num_operands && !mismatch;
op = use_ops[++i]) {
/* Check operand type */
switch ((int)(info->operands[i] & OPT_MASK)) {
switch ((int)(info_ops[i] & OPT_MASK)) {
case OPT_Imm:
if (op->type != YASM_INSN__OPERAND_IMM)
mismatch = 1;
@ -2649,40 +2682,40 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
break;
case OPT_Areg:
if (op->type != YASM_INSN__OPERAND_REG ||
((info->operands[i] & OPS_MASK) == OPS_8 &&
((info_ops[i] & OPS_MASK) == OPS_8 &&
op->data.reg != (X86_REG8 | 0) &&
op->data.reg != (X86_REG8X | 0)) ||
((info->operands[i] & OPS_MASK) == OPS_16 &&
((info_ops[i] & OPS_MASK) == OPS_16 &&
op->data.reg != (X86_REG16 | 0)) ||
((info->operands[i] & OPS_MASK) == OPS_32 &&
((info_ops[i] & OPS_MASK) == OPS_32 &&
op->data.reg != (X86_REG32 | 0)) ||
((info->operands[i] & OPS_MASK) == OPS_64 &&
((info_ops[i] & OPS_MASK) == OPS_64 &&
op->data.reg != (X86_REG64 | 0)))
mismatch = 1;
break;
case OPT_Creg:
if (op->type != YASM_INSN__OPERAND_REG ||
((info->operands[i] & OPS_MASK) == OPS_8 &&
((info_ops[i] & OPS_MASK) == OPS_8 &&
op->data.reg != (X86_REG8 | 1) &&
op->data.reg != (X86_REG8X | 1)) ||
((info->operands[i] & OPS_MASK) == OPS_16 &&
((info_ops[i] & OPS_MASK) == OPS_16 &&
op->data.reg != (X86_REG16 | 1)) ||
((info->operands[i] & OPS_MASK) == OPS_32 &&
((info_ops[i] & OPS_MASK) == OPS_32 &&
op->data.reg != (X86_REG32 | 1)) ||
((info->operands[i] & OPS_MASK) == OPS_64 &&
((info_ops[i] & OPS_MASK) == OPS_64 &&
op->data.reg != (X86_REG64 | 1)))
mismatch = 1;
break;
case OPT_Dreg:
if (op->type != YASM_INSN__OPERAND_REG ||
((info->operands[i] & OPS_MASK) == OPS_8 &&
((info_ops[i] & OPS_MASK) == OPS_8 &&
op->data.reg != (X86_REG8 | 2) &&
op->data.reg != (X86_REG8X | 2)) ||
((info->operands[i] & OPS_MASK) == OPS_16 &&
((info_ops[i] & OPS_MASK) == OPS_16 &&
op->data.reg != (X86_REG16 | 2)) ||
((info->operands[i] & OPS_MASK) == OPS_32 &&
((info_ops[i] & OPS_MASK) == OPS_32 &&
op->data.reg != (X86_REG32 | 2)) ||
((info->operands[i] & OPS_MASK) == OPS_64 &&
((info_ops[i] & OPS_MASK) == OPS_64 &&
op->data.reg != (X86_REG64 | 2)))
mismatch = 1;
break;
@ -2773,7 +2806,7 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
break;
/* Check operand size */
size = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT];
size = size_lookup[(info_ops[i] & OPS_MASK)>>OPS_SHIFT];
if (suffix != 0) {
/* Require relaxed operands for GAS mode (don't allow
* per-operand sizing).
@ -2782,11 +2815,11 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
/* Register size must exactly match */
if (yasm_x86__get_reg_size(op->data.reg) != size)
mismatch = 1;
} else if (((info->operands[i] & OPT_MASK) == OPT_Imm
|| (info->operands[i] & OPT_MASK) == OPT_ImmNotSegOff
|| (info->operands[i] & OPT_MASK) == OPT_Imm1)
&& (info->operands[i] & OPS_RMASK) != OPS_Relaxed
&& (info->operands[i] & OPA_MASK) != OPA_JmpRel)
} else if (((info_ops[i] & OPT_MASK) == OPT_Imm
|| (info_ops[i] & OPT_MASK) == OPT_ImmNotSegOff
|| (info_ops[i] & OPT_MASK) == OPT_Imm1)
&& (info_ops[i] & OPS_RMASK) != OPS_Relaxed
&& (info_ops[i] & OPA_MASK) != OPA_JmpRel)
mismatch = 1;
} else {
if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
@ -2800,7 +2833,7 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
if ((bypass == 1 && i == 0) || (bypass == 2 && i == 1)
|| (bypass == 3 && i == 3))
;
else if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) {
else if ((info_ops[i] & OPS_RMASK) == OPS_Relaxed) {
/* Relaxed checking */
if (size != 0 && op->size != size && op->size != 0)
mismatch = 1;
@ -2817,7 +2850,7 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
/* Check for 64-bit effective address size in NASM mode */
if (suffix == 0 && op->type == YASM_INSN__OPERAND_MEMORY) {
if ((info->operands[i] & OPEAS_MASK) == OPEAS_64) {
if ((info_ops[i] & OPEAS_MASK) == OPEAS_64) {
if (op->data.ea->disp.size != 64)
mismatch = 1;
} else if (op->data.ea->disp.size == 64)
@ -2828,7 +2861,7 @@ x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
break;
/* Check target modifier */
switch ((int)(info->operands[i] & OPTM_MASK)) {
switch ((int)(info_ops[i] & OPTM_MASK)) {
case OPTM_None:
if (op->targetmod != 0)
mismatch = 1;
@ -2944,7 +2977,9 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
/* Build local array of operands from list, since we know we have a max
* of 3 operands.
*/
if (id_insn->insn.num_operands > 3) {
if (id_insn->insn.num_operands == 4 && info == insertq_insn)
;
else if (id_insn->insn.num_operands > 3) {
yasm_error_set(YASM_ERROR_TYPE, N_("too many operands"));
return;
}
@ -3085,15 +3120,20 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
/* Go through operands and assign */
if (id_insn->insn.num_operands > 0) {
yasm_insn_operand **use_ops = ops;
const unsigned long *info_ops = info->operands;
/* Use reversed operands in GAS mode if not otherwise specified */
if (id_insn->parser == X86_PARSER_GAS
&& !(info->modifiers & MOD_GasNoRev))
use_ops = rev_ops;
/* 4-operand special case for insertq */
if (info->num_operands > 3)
info_ops = insertq_4operands;
for (i = 0, op = use_ops[0]; op && i<info->num_operands;
op = use_ops[++i]) {
switch ((int)(info->operands[i] & OPA_MASK)) {
switch ((int)(info_ops[i] & OPA_MASK)) {
case OPA_None:
/* Throw away the operand contents */
switch (op->type) {
@ -3111,23 +3151,25 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
case OPA_EA:
switch (op->type) {
case YASM_INSN__OPERAND_REG:
insn->x86_ea = yasm_x86__ea_create_reg(
(unsigned long)op->data.reg, &insn->rex,
mode_bits);
insn->x86_ea =
yasm_x86__ea_create_reg(insn->x86_ea,
(unsigned long)op->data.reg, &insn->rex,
mode_bits);
break;
case YASM_INSN__OPERAND_SEGREG:
yasm_internal_error(
N_("invalid operand conversion"));
case YASM_INSN__OPERAND_MEMORY:
insn->x86_ea = (x86_effaddr *)op->data.ea;
if ((info->operands[i] & OPT_MASK) == OPT_MemOffs)
if ((info_ops[i] & OPT_MASK) == OPT_MemOffs)
/* Special-case for MOV MemOffs instruction */
yasm_x86__ea_set_disponly(insn->x86_ea);
break;
case YASM_INSN__OPERAND_IMM:
insn->x86_ea =
yasm_x86__ea_create_imm(op->data.val,
size_lookup[(info->operands[i] &
yasm_x86__ea_create_imm(insn->x86_ea,
op->data.val,
size_lookup[(info_ops[i] &
OPS_MASK)>>OPS_SHIFT]);
break;
}
@ -3135,7 +3177,7 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
case OPA_Imm:
if (op->type == YASM_INSN__OPERAND_IMM) {
imm = op->data.val;
im_len = size_lookup[(info->operands[i] &
im_len = size_lookup[(info_ops[i] &
OPS_MASK)>>OPS_SHIFT];
} else
yasm_internal_error(N_("invalid operand conversion"));
@ -3143,7 +3185,7 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
case OPA_SImm:
if (op->type == YASM_INSN__OPERAND_IMM) {
imm = op->data.val;
im_len = size_lookup[(info->operands[i] &
im_len = size_lookup[(info_ops[i] &
OPS_MASK)>>OPS_SHIFT];
im_sign = 1;
} else
@ -3182,7 +3224,8 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
case OPA_SpareEA:
if (op->type == YASM_INSN__OPERAND_REG) {
insn->x86_ea =
yasm_x86__ea_create_reg((unsigned long)op->data.reg,
yasm_x86__ea_create_reg(insn->x86_ea,
(unsigned long)op->data.reg,
&insn->rex, mode_bits);
if (!insn->x86_ea ||
yasm_x86__set_rex_from_reg(&insn->rex, &spare,
@ -3223,10 +3266,10 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
yasm_internal_error(N_("unknown operand action"));
}
if ((info->operands[i] & OPS_MASK) == OPS_BITS)
if ((info_ops[i] & OPS_MASK) == OPS_BITS)
insn->common.opersize = (unsigned char)mode_bits;
switch ((int)(info->operands[i] & OPAP_MASK)) {
switch ((int)(info_ops[i] & OPAP_MASK)) {
case OPAP_None:
break;
case OPAP_SImm8:
@ -3326,7 +3369,7 @@ x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
/* Build ModRM EA - CAUTION: this depends on
* opcode 0 being a mov instruction!
*/
insn->x86_ea = yasm_x86__ea_create_reg(
insn->x86_ea = yasm_x86__ea_create_reg(insn->x86_ea,
(unsigned long)insn->opcode.opcode[0]-0xB8, &rex_temp, 64);
/* Make the imm32s form permanent. */

@ -809,12 +809,17 @@ INSN - pmovzxwq NONE sse4m32 0x34 CPU_SSE41
INSN - pmovzxdq NONE sse4m64 0x35 CPU_SSE41
INSN - pmuldq NONE sse4 0x28 CPU_SSE41
INSN - pmulld NONE sse4 0x40 CPU_SSE41
INSN - popcnt "wlq" popcnt 0 CPU_SSE42
INSN - popcnt "wlq" cnt 0xB8 CPU_SSE42
INSN - ptest NONE sse4 0x17 CPU_SSE41
INSN - roundpd NONE sse4imm 0x09 CPU_SSE41
INSN - roundps NONE sse4imm 0x08 CPU_SSE41
INSN - roundsd NONE sse4imm 0x0B CPU_SSE41
INSN - roundss NONE sse4imm 0x0A CPU_SSE41
# AMD SSE4.1 instructions
INSN - extrq NONE extrq 0 CPU_SSE41
INSN - insertq NONE insertq 0 CPU_SSE41
INSN - movntsd NONE movntsd 0 CPU_SSE41
INSN - movntss NONE movntss 0 CPU_SSE41
# AMD 3DNow! instructions
INSN - prefetch NONE twobytemem 0x000F0D CPU_3DNow
INSN - prefetchw NONE twobytemem 0x010F0D CPU_3DNow
@ -846,6 +851,7 @@ INSN - pswapd NONE now3d 0xBB CPU_Athlon|CPU_3DNow
# AMD extensions
INSN - syscall NONE twobyte 0x0F05 CPU_686|CPU_AMD
INSN - sysret "lq" twobyte 0x0F07 CPU_686|CPU_AMD|CPU_Priv
INSN - lzcnt "wlq" cnt 0xBD CPU_686|CPU_AMD
# AMD x86-64 extensions
INSN - swapgs NONE threebyte 0x0F01F8 CPU_Hammer|CPU_64
INSN - rdtscp NONE threebyte 0x0F01F9 CPU_686|CPU_AMD|CPU_Priv

Loading…
Cancel
Save