tcg/i386: Add vector operations

The x86 vector instruction set is extremely irregular. With newer
editions, Intel has filled in some of the blanks. However, we don't
get many 64-bit operations until SSE4.2, introduced in 2009.

The subsequent edition was for AVX1, introduced in 2011, which added
three-operand addressing, and adjusts how all instructions should be
encoded.

Given the relatively narrow 2 year window between possible to support
and desirable to support, and to vastly simplify code maintainence,
I am only planning to support AVX1 and later cpus.

Backports commit 770c2fc7bb70804ae9869995fd02dadd6d7656ac from qemu
This commit is contained in:
Richard Henderson 2018-03-06 16:20:28 -05:00 committed by Lioncash
parent 16a0a3e156
commit b3e89e9996
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
18 changed files with 1067 additions and 62 deletions

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_aarch64
#define handle_vsel handle_vsel_aarch64
#define has_help_option has_help_option_aarch64
#define have_avx1 have_avx1_aarch64
#define have_avx2 have_avx2_aarch64
#define have_bmi1 have_bmi1_aarch64
#define have_bmi2 have_bmi2_aarch64
#define have_popcnt have_popcnt_aarch64
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_aarch64
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_aarch64
#define tcg_allowed tcg_allowed_aarch64
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_aarch64
#define tcg_canonicalize_memop tcg_canonicalize_memop_aarch64
#define tcg_commit tcg_commit_aarch64
#define tcg_cond_to_jcc tcg_cond_to_jcc_aarch64

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_aarch64eb
#define handle_vsel handle_vsel_aarch64eb
#define has_help_option has_help_option_aarch64eb
#define have_avx1 have_avx1_aarch64eb
#define have_avx2 have_avx2_aarch64eb
#define have_bmi1 have_bmi1_aarch64eb
#define have_bmi2 have_bmi2_aarch64eb
#define have_popcnt have_popcnt_aarch64eb
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_aarch64eb
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_aarch64eb
#define tcg_allowed tcg_allowed_aarch64eb
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_aarch64eb
#define tcg_canonicalize_memop tcg_canonicalize_memop_aarch64eb
#define tcg_commit tcg_commit_aarch64eb
#define tcg_cond_to_jcc tcg_cond_to_jcc_aarch64eb

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_arm
#define handle_vsel handle_vsel_arm
#define has_help_option has_help_option_arm
#define have_avx1 have_avx1_arm
#define have_avx2 have_avx2_arm
#define have_bmi1 have_bmi1_arm
#define have_bmi2 have_bmi2_arm
#define have_popcnt have_popcnt_arm
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_arm
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_arm
#define tcg_allowed tcg_allowed_arm
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_arm
#define tcg_canonicalize_memop tcg_canonicalize_memop_arm
#define tcg_commit tcg_commit_arm
#define tcg_cond_to_jcc tcg_cond_to_jcc_arm

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_armeb
#define handle_vsel handle_vsel_armeb
#define has_help_option has_help_option_armeb
#define have_avx1 have_avx1_armeb
#define have_avx2 have_avx2_armeb
#define have_bmi1 have_bmi1_armeb
#define have_bmi2 have_bmi2_armeb
#define have_popcnt have_popcnt_armeb
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_armeb
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_armeb
#define tcg_allowed tcg_allowed_armeb
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_armeb
#define tcg_canonicalize_memop tcg_canonicalize_memop_armeb
#define tcg_commit tcg_commit_armeb
#define tcg_cond_to_jcc tcg_cond_to_jcc_armeb

View file

@ -1404,6 +1404,8 @@ symbols = (
'handle_vrint',
'handle_vsel',
'has_help_option',
'have_avx1',
'have_avx2',
'have_bmi1',
'have_bmi2',
'have_popcnt',
@ -3066,6 +3068,7 @@ symbols = (
'tcg_add_param_i64',
'tcg_add_target_add_op_defs',
'tcg_allowed',
'tcg_can_emit_vec_op',
'tcg_canonicalize_memop',
'tcg_commit',
'tcg_cond_to_jcc',

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_m68k
#define handle_vsel handle_vsel_m68k
#define has_help_option has_help_option_m68k
#define have_avx1 have_avx1_m68k
#define have_avx2 have_avx2_m68k
#define have_bmi1 have_bmi1_m68k
#define have_bmi2 have_bmi2_m68k
#define have_popcnt have_popcnt_m68k
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_m68k
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_m68k
#define tcg_allowed tcg_allowed_m68k
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_m68k
#define tcg_canonicalize_memop tcg_canonicalize_memop_m68k
#define tcg_commit tcg_commit_m68k
#define tcg_cond_to_jcc tcg_cond_to_jcc_m68k

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_mips
#define handle_vsel handle_vsel_mips
#define has_help_option has_help_option_mips
#define have_avx1 have_avx1_mips
#define have_avx2 have_avx2_mips
#define have_bmi1 have_bmi1_mips
#define have_bmi2 have_bmi2_mips
#define have_popcnt have_popcnt_mips
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_mips
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_mips
#define tcg_allowed tcg_allowed_mips
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_mips
#define tcg_canonicalize_memop tcg_canonicalize_memop_mips
#define tcg_commit tcg_commit_mips
#define tcg_cond_to_jcc tcg_cond_to_jcc_mips

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_mips64
#define handle_vsel handle_vsel_mips64
#define has_help_option has_help_option_mips64
#define have_avx1 have_avx1_mips64
#define have_avx2 have_avx2_mips64
#define have_bmi1 have_bmi1_mips64
#define have_bmi2 have_bmi2_mips64
#define have_popcnt have_popcnt_mips64
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_mips64
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_mips64
#define tcg_allowed tcg_allowed_mips64
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_mips64
#define tcg_canonicalize_memop tcg_canonicalize_memop_mips64
#define tcg_commit tcg_commit_mips64
#define tcg_cond_to_jcc tcg_cond_to_jcc_mips64

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_mips64el
#define handle_vsel handle_vsel_mips64el
#define has_help_option has_help_option_mips64el
#define have_avx1 have_avx1_mips64el
#define have_avx2 have_avx2_mips64el
#define have_bmi1 have_bmi1_mips64el
#define have_bmi2 have_bmi2_mips64el
#define have_popcnt have_popcnt_mips64el
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_mips64el
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_mips64el
#define tcg_allowed tcg_allowed_mips64el
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_mips64el
#define tcg_canonicalize_memop tcg_canonicalize_memop_mips64el
#define tcg_commit tcg_commit_mips64el
#define tcg_cond_to_jcc tcg_cond_to_jcc_mips64el

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_mipsel
#define handle_vsel handle_vsel_mipsel
#define has_help_option has_help_option_mipsel
#define have_avx1 have_avx1_mipsel
#define have_avx2 have_avx2_mipsel
#define have_bmi1 have_bmi1_mipsel
#define have_bmi2 have_bmi2_mipsel
#define have_popcnt have_popcnt_mipsel
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_mipsel
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_mipsel
#define tcg_allowed tcg_allowed_mipsel
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_mipsel
#define tcg_canonicalize_memop tcg_canonicalize_memop_mipsel
#define tcg_commit tcg_commit_mipsel
#define tcg_cond_to_jcc tcg_cond_to_jcc_mipsel

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_powerpc
#define handle_vsel handle_vsel_powerpc
#define has_help_option has_help_option_powerpc
#define have_avx1 have_avx1_powerpc
#define have_avx2 have_avx2_powerpc
#define have_bmi1 have_bmi1_powerpc
#define have_bmi2 have_bmi2_powerpc
#define have_popcnt have_popcnt_powerpc
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_powerpc
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_powerpc
#define tcg_allowed tcg_allowed_powerpc
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_powerpc
#define tcg_canonicalize_memop tcg_canonicalize_memop_powerpc
#define tcg_commit tcg_commit_powerpc
#define tcg_cond_to_jcc tcg_cond_to_jcc_powerpc

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_sparc
#define handle_vsel handle_vsel_sparc
#define has_help_option has_help_option_sparc
#define have_avx1 have_avx1_sparc
#define have_avx2 have_avx2_sparc
#define have_bmi1 have_bmi1_sparc
#define have_bmi2 have_bmi2_sparc
#define have_popcnt have_popcnt_sparc
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_sparc
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_sparc
#define tcg_allowed tcg_allowed_sparc
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_sparc
#define tcg_canonicalize_memop tcg_canonicalize_memop_sparc
#define tcg_commit tcg_commit_sparc
#define tcg_cond_to_jcc tcg_cond_to_jcc_sparc

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_sparc64
#define handle_vsel handle_vsel_sparc64
#define has_help_option has_help_option_sparc64
#define have_avx1 have_avx1_sparc64
#define have_avx2 have_avx2_sparc64
#define have_bmi1 have_bmi1_sparc64
#define have_bmi2 have_bmi2_sparc64
#define have_popcnt have_popcnt_sparc64
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_sparc64
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_sparc64
#define tcg_allowed tcg_allowed_sparc64
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_sparc64
#define tcg_canonicalize_memop tcg_canonicalize_memop_sparc64
#define tcg_commit tcg_commit_sparc64
#define tcg_cond_to_jcc tcg_cond_to_jcc_sparc64

View file

@ -30,10 +30,10 @@
#ifdef __x86_64__
# define TCG_TARGET_REG_BITS 64
# define TCG_TARGET_NB_REGS 16
# define TCG_TARGET_NB_REGS 32
#else
# define TCG_TARGET_REG_BITS 32
# define TCG_TARGET_NB_REGS 8
# define TCG_TARGET_NB_REGS 24
#endif
typedef enum {
@ -56,6 +56,26 @@ typedef enum {
TCG_REG_R13,
TCG_REG_R14,
TCG_REG_R15,
TCG_REG_XMM0,
TCG_REG_XMM1,
TCG_REG_XMM2,
TCG_REG_XMM3,
TCG_REG_XMM4,
TCG_REG_XMM5,
TCG_REG_XMM6,
TCG_REG_XMM7,
/* 64-bit registers; likewise always define. */
TCG_REG_XMM8,
TCG_REG_XMM9,
TCG_REG_XMM10,
TCG_REG_XMM11,
TCG_REG_XMM12,
TCG_REG_XMM13,
TCG_REG_XMM14,
TCG_REG_XMM15,
TCG_REG_RAX = TCG_REG_EAX,
TCG_REG_RCX = TCG_REG_ECX,
TCG_REG_RDX = TCG_REG_EDX,
@ -77,6 +97,41 @@ typedef enum {
extern bool have_bmi1;
extern bool have_popcnt;
extern bool have_avx1;
extern bool have_avx2;
// UNICORN FIXME:
// Taken from cpuid.h in mainline qemu.
// The cpuid mechanism should just be
// backported instead
/* Leaf 1, %ecx */
#ifndef bit_SSE4_1
#define bit_SSE4_1 (1 << 19)
#endif
#ifndef bit_MOVBE
#define bit_MOVBE (1 << 22)
#endif
#ifndef bit_OSXSAVE
#define bit_OSXSAVE (1 << 27)
#endif
#ifndef bit_AVX
#define bit_AVX (1 << 28)
#endif
/* Leaf 7, %ebx */
#ifndef bit_BMI
#define bit_BMI (1 << 3)
#endif
#ifndef bit_AVX2
#define bit_AVX2 (1 << 5)
#endif
#ifndef bit_BMI2
#define bit_BMI2 (1 << 8)
#endif
/* Leaf 0x80000001, %ecx */
#ifndef bit_LZCNT
#define bit_LZCNT (1 << 5)
#endif
/* optional instructions */
#define TCG_TARGET_HAS_div2_i32 1
@ -146,6 +201,21 @@ extern bool have_popcnt;
#define TCG_TARGET_HAS_mulsh_i64 0
#endif
/* We do not support older SSE systems, only beginning with AVX1. */
#define TCG_TARGET_HAS_v64 have_avx1
#define TCG_TARGET_HAS_v128 have_avx1
#define TCG_TARGET_HAS_v256 have_avx2
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 0
#define TCG_TARGET_HAS_not_vec 0
#define TCG_TARGET_HAS_neg_vec 0
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 0
#define TCG_TARGET_HAS_cmp_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
(((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
((ofs) == 0 && (len) == 16))

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
/* Target-specific opcodes for host vector expansion. These will be
emitted by tcg_expand_vec_op. For those familiar with GCC internals,
consider these to be UNSPEC with names. */
DEF(x86_shufps_vec, 1, 2, 1, IMPLVEC)
DEF(x86_vpblendvb_vec, 1, 3, 0, IMPLVEC)
DEF(x86_blend_vec, 1, 2, 1, IMPLVEC)
DEF(x86_packss_vec, 1, 2, 0, IMPLVEC)
DEF(x86_packus_vec, 1, 2, 0, IMPLVEC)
DEF(x86_psrldq_vec, 1, 1, 1, IMPLVEC)
DEF(x86_vperm2i128_vec, 1, 2, 1, IMPLVEC)
DEF(x86_punpckl_vec, 1, 2, 0, IMPLVEC)
DEF(x86_punpckh_vec, 1, 2, 0, IMPLVEC)

View file

@ -1098,7 +1098,7 @@ static inline TCGv_i64 tcg_temp_local_new_i64(TCGContext *s)
}
// UNICORN: Added
#define TCG_OP_DEFS_TABLE_SIZE 162
#define TCG_OP_DEFS_TABLE_SIZE 171
extern const TCGOpDef tcg_op_defs_org[TCG_OP_DEFS_TABLE_SIZE];
typedef struct TCGTargetOpDef {

View file

@ -1398,6 +1398,8 @@
#define handle_vrint handle_vrint_x86_64
#define handle_vsel handle_vsel_x86_64
#define has_help_option has_help_option_x86_64
#define have_avx1 have_avx1_x86_64
#define have_avx2 have_avx2_x86_64
#define have_bmi1 have_bmi1_x86_64
#define have_bmi2 have_bmi2_x86_64
#define have_popcnt have_popcnt_x86_64
@ -3060,6 +3062,7 @@
#define tcg_add_param_i64 tcg_add_param_i64_x86_64
#define tcg_add_target_add_op_defs tcg_add_target_add_op_defs_x86_64
#define tcg_allowed tcg_allowed_x86_64
#define tcg_can_emit_vec_op tcg_can_emit_vec_op_x86_64
#define tcg_canonicalize_memop tcg_canonicalize_memop_x86_64
#define tcg_commit tcg_commit_x86_64
#define tcg_cond_to_jcc tcg_cond_to_jcc_x86_64