summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2013-02-21 00:05:17 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2013-02-21 00:05:17 -0500
commitc0019e3e9eac21f2391794a07025a1d6d030fb9c (patch)
treed3fe3ea7d372f24c9f3239a2bd44a597ff48350a
parente0e285ad88ce1dfb495623ec612a4b91c3ada289 (diff)
Support for vgather
-rw-r--r--simplex86.c24
-rw-r--r--simplex86.h10
-rw-r--r--testsuite.c8
3 files changed, 40 insertions, 2 deletions
diff --git a/simplex86.c b/simplex86.c
index 8620679..900715c 100644
--- a/simplex86.c
+++ b/simplex86.c
@@ -65,6 +65,7 @@ typedef enum
E_NP, /* opcode only */
E_M, /* modrm/d */
E_VM, /* modrm/d with source in VEX */
+ E_RMV,
E_D, /* immediate data, no opcode */
E_ANNOTATE, /* generate an annotation */
E_N_ENCODINGS
@@ -704,6 +705,24 @@ static const variant_t variants[] =
{ I_vmaskmovpd, { A_MEM, A_AVX, A_AVX }, F_AVX, E_MVR, 0x2f, VEX(256,0x66,0x0f38,W0) },
{ I_vzeroupper, { 0 }, F_AVX, E_NP, 0x77, VEX(128,0x00,0x0f,WIG) },
{ I_vzeroall, { 0 }, F_AVX, E_NP, 0x77, VEX(256,0x00,0x0f,WIG) },
+
+ /* AVX 2 */
+ { I_vgatherdd, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x90, VEX(128,0x66,0x0f38,W0) },
+ { I_vgatherdd, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x90, VEX(256,0x66,0x0f38,W0) },
+ { I_vgatherqd, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x91, VEX(128,0x66,0x0f38,W0) },
+ { I_vgatherqd, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x91, VEX(256,0x66,0x0f38,W0) },
+ { I_vgatherdq, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x90, VEX(128,0x66,0x0f38,W1) },
+ { I_vgatherdq, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x90, VEX(256,0x66,0x0f38,W1) },
+ { I_vgatherqq, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x91, VEX(128,0x66,0x0f38,W1) },
+ { I_vgatherqq, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x91, VEX(256,0x66,0x0f38,W1) },
+ { I_vgatherdps, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x92, VEX(128,0x66,0x0f38,W0) },
+ { I_vgatherdps, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x92, VEX(256,0x66,0x0f38,W0) },
+ { I_vgatherqps, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x93, VEX(128,0x66,0x0f38,W0) },
+ { I_vgatherqps, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x93, VEX(256,0x66,0x0f38,W0) },
+ { I_vgatherdpd, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x92, VEX(128,0x66,0x0f38,W1) },
+ { I_vgatherdpd, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x92, VEX(256,0x66,0x0f38,W1) },
+ { I_vgatherqpd, { A_SSE, A_MEM, A_SSE }, F_AVX2, E_RMV, 0x93, VEX(128,0x66,0x0f38,W1) },
+ { I_vgatherqpd, { A_AVX, A_MEM, A_AVX }, F_AVX2, E_RMV, 0x93, VEX(256,0x66,0x0f38,W1) },
/* CVT16 */
{ I_vcvtph2ps, { A_SSE, A_SSEM }, F_CVT16, E_RM, 0x13, VEX(128,0x66,0x0f38,W0) },
@@ -1809,6 +1828,11 @@ emit (fragment_t *frag, const variant_t *variant, const op_t ops[4])
vex_regno = GET_REGNO (ops[1]);
break;
+ case E_RMV:
+ c = emit_reg_regm (c, ops[0], ops[1], &r, &x, &b, &ann);
+ vex_regno = GET_REGNO (ops[2]);
+ break;
+
case E_VM:
c = emit_reg_regm (c, MODRM_OP (variant->info), ops[1], &r, &x, &b, &ann);
vex_regno = GET_REGNO (ops[0]);
diff --git a/simplex86.h b/simplex86.h
index fc7ff87..bcafb24 100644
--- a/simplex86.h
+++ b/simplex86.h
@@ -504,7 +504,15 @@ typedef enum
PROCESS_INSTRUCTION (crc32_8, 2) \
PROCESS_INSTRUCTION (crc32_16, 2) \
PROCESS_INSTRUCTION (crc32_32, 2) \
- PROCESS_INSTRUCTION (crc32_64, 2)
+ PROCESS_INSTRUCTION (crc32_64, 2) \
+ PROCESS_INSTRUCTION (vgatherdd, 3) \
+ PROCESS_INSTRUCTION (vgatherqd, 3) \
+ PROCESS_INSTRUCTION (vgatherdq, 3) \
+ PROCESS_INSTRUCTION (vgatherqq, 3) \
+ PROCESS_INSTRUCTION (vgatherdps, 3) \
+ PROCESS_INSTRUCTION (vgatherqps, 3) \
+ PROCESS_INSTRUCTION (vgatherdpd, 3) \
+ PROCESS_INSTRUCTION (vgatherqpd, 3) \
enum
{
diff --git a/testsuite.c b/testsuite.c
index 5090514..349a718 100644
--- a/testsuite.c
+++ b/testsuite.c
@@ -42,6 +42,12 @@ test_shifts (assembler_t *as)
fragment_t *frag = fragment_new (as);
BEGIN_ASM (frag)
+ I_vgatherdd, ymm0, INDEX(r9, 23417, ymm0, 8), ymm2,
+ I_vgatherdd, ymm0, INDEX(eax, 23423, ymm9, 2), ymm12,
+ I_vgatherdd, ymm0, INDEX(rax, 23423, ymm9, 2), ymm12,
+ I_vgatherdps, ymm0, INDEX(r9, 23417, ymm0, 8), ymm2,
+ I_vgatherdps, ymm0, INDEX(eax, 23423, ymm9, 2), ymm12,
+ I_vgatherqpd, ymm0, INDEX(rax, 23423, ymm9, 2), ymm12,
I_add, PTR (rax), al,
I_movabs, rbx, IMM64 (0xaaaabbbbeeeeffff),
I_stmxcsr, PTR (rbx),
@@ -388,7 +394,7 @@ main ()
*/
success &= run_test (as, "test_crc32", test_crc32, 0x3ce8ed36 );
success &= run_test (as, "avx_supported", avx_supported, 0xeeaec30c);
- success &= run_test (as, "test_shifts", test_shifts, 0x8aa3c8ae);
+ success &= run_test (as, "test_shifts", test_shifts, 0x4a641094);
success &= run_test (as, "test_float", test_float, 0xc193030 );
success &= run_test (as, "test_convert", test_convert, 0x9d52c83b);
success &= run_test (as, "test_misc", test_misc, 0xc6b9051f);