summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorkk208521 <none@none>2007-10-15 20:04:53 -0700
committerkk208521 <none@none>2007-10-15 20:04:53 -0700
commitd0f8ff6ee41946134faff06b3a9f643e21aefa78 (patch)
tree6b201422d80bd47c180c86fc142370c89fda9a90 /usr/src
parent802b83c445ef5ffc9777155491dfe4fcd9793946 (diff)
downloadillumos-joyent-d0f8ff6ee41946134faff06b3a9f643e21aefa78.tar.gz
6526262 cpuid ssse3 feature not noted on Intel Woodcrest/Conroe processors
6563039 Need support for Intel's SSE4.1 and SSE4.2 instructions
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/common/dis/i386/dis_tables.c271
-rw-r--r--usr/src/common/elfcap/elfcap.c11
-rw-r--r--usr/src/uts/common/sys/auxv_386.h7
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c25
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h9
5 files changed, 319 insertions, 4 deletions
diff --git a/usr/src/common/dis/i386/dis_tables.c b/usr/src/common/dis/i386/dis_tables.c
index ed2b1825fd..63f4bdc346 100644
--- a/usr/src/common/dis/i386/dis_tables.c
+++ b/usr/src/common/dis/i386/dis_tables.c
@@ -1,4 +1,5 @@
/*
+ *
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
@@ -149,6 +150,7 @@ enum {
CWD, /* so data16 can be evaluated for cwd and variants */
RET, /* single immediate 16-bit operand */
MOVZ, /* for movs and movz, with different size operands */
+ CRC32, /* for crc32, with different size operands */
XADDB, /* for xaddb */
MOVSXZ, /* AMD64 mov sign extend 32 to 64 bit instruction */
@@ -163,6 +165,7 @@ enum {
MMOS, /* Prefixable MMX/SIMD-Int mm -> mm/mem */
MMOMS, /* Prefixable MMX/SIMD-Int mm -> mem */
MMOPM, /* MMX/SIMD-Int mm/mem -> mm,imm8 */
+ MMOPM_66o, /* MMX/SIMD-Int 0x66 optional mm/mem -> mm,imm8 */
MMOPRM, /* Prefixable MMX/SIMD-Int r32/mem -> mm,imm8 */
MMOSH, /* Prefixable MMX mm,imm8 */
MM, /* MMX/SIMD-Int mm/mem -> mm */
@@ -177,12 +180,19 @@ enum {
XMMOM, /* Prefixable SIMD xmm -> mem */
XMMOMS, /* Prefixable SIMD mem -> xmm */
XMM, /* SIMD xmm/mem -> xmm */
+ XMM_66r, /* SIMD 0x66 prefix required xmm/mem -> xmm */
+ XMM_66o, /* SIMD 0x66 prefix optional xmm/mem -> xmm */
XMMXIMPL, /* SIMD xmm -> xmm (mem) */
XMM3P, /* SIMD xmm -> r32,imm8 */
+ XMM3PM_66r, /* SIMD 0x66 prefix required xmm -> r32/mem,imm8 */
XMMP, /* SIMD xmm/mem w/to xmm,imm8 */
+ XMMP_66o, /* SIMD 0x66 prefix optional xmm/mem w/to xmm,imm8 */
+ XMMP_66r, /* SIMD 0x66 prefix required xmm/mem w/to xmm,imm8 */
XMMPRM, /* SIMD r32/mem -> xmm,imm8 */
+ XMMPRM_66r, /* SIMD 0x66 prefix required r32/mem -> xmm,imm8 */
XMMS, /* SIMD xmm -> xmm/mem */
XMMM, /* SIMD mem -> xmm */
+ XMMM_66r, /* SIMD 0x66 prefix required mem -> xmm */
XMMMS, /* SIMD xmm -> mem */
XMM3MX, /* SIMD r32/mem -> xmm */
XMM3MXS, /* SIMD xmm -> r32/mem */
@@ -801,6 +811,170 @@ const instable_t dis_opSIMDrepz[256] = {
/* [FC] */ INVALID, INVALID, INVALID, INVALID,
};
+const instable_t dis_op0F38[256] = {
+/* [00] */ TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
+/* [04] */ TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16), TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
+/* [08] */ TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
+/* [0C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [10] */ TNSZ("pblendvb",XMM_66r,16),INVALID, INVALID, INVALID,
+/* [14] */ TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID, TNSZ("ptest",XMM_66r,16),
+/* [18] */ INVALID, INVALID, INVALID, INVALID,
+/* [1C] */ TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
+
+/* [20] */ TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
+/* [24] */ TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID, INVALID,
+/* [28] */ TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
+/* [2C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [30] */ TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
+/* [34] */ TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID, TNSZ("pcmpgtq",XMM_66r,16),
+/* [38] */ TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
+/* [3C] */ TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
+
+/* [40] */ TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID, INVALID,
+/* [44] */ INVALID, INVALID, INVALID, INVALID,
+/* [48] */ INVALID, INVALID, INVALID, INVALID,
+/* [4C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [50] */ INVALID, INVALID, INVALID, INVALID,
+/* [54] */ INVALID, INVALID, INVALID, INVALID,
+/* [58] */ INVALID, INVALID, INVALID, INVALID,
+/* [5C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [60] */ INVALID, INVALID, INVALID, INVALID,
+/* [64] */ INVALID, INVALID, INVALID, INVALID,
+/* [68] */ INVALID, INVALID, INVALID, INVALID,
+/* [6C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [70] */ INVALID, INVALID, INVALID, INVALID,
+/* [74] */ INVALID, INVALID, INVALID, INVALID,
+/* [78] */ INVALID, INVALID, INVALID, INVALID,
+/* [7C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [80] */ INVALID, INVALID, INVALID, INVALID,
+/* [84] */ INVALID, INVALID, INVALID, INVALID,
+/* [88] */ INVALID, INVALID, INVALID, INVALID,
+/* [8C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [90] */ INVALID, INVALID, INVALID, INVALID,
+/* [94] */ INVALID, INVALID, INVALID, INVALID,
+/* [98] */ INVALID, INVALID, INVALID, INVALID,
+/* [9C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [A0] */ INVALID, INVALID, INVALID, INVALID,
+/* [A4] */ INVALID, INVALID, INVALID, INVALID,
+/* [A8] */ INVALID, INVALID, INVALID, INVALID,
+/* [AC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [B0] */ INVALID, INVALID, INVALID, INVALID,
+/* [B4] */ INVALID, INVALID, INVALID, INVALID,
+/* [B8] */ INVALID, INVALID, INVALID, INVALID,
+/* [BC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [C0] */ INVALID, INVALID, INVALID, INVALID,
+/* [C4] */ INVALID, INVALID, INVALID, INVALID,
+/* [C8] */ INVALID, INVALID, INVALID, INVALID,
+/* [CC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [D0] */ INVALID, INVALID, INVALID, INVALID,
+/* [D4] */ INVALID, INVALID, INVALID, INVALID,
+/* [D8] */ INVALID, INVALID, INVALID, INVALID,
+/* [DC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [E0] */ INVALID, INVALID, INVALID, INVALID,
+/* [E4] */ INVALID, INVALID, INVALID, INVALID,
+/* [E8] */ INVALID, INVALID, INVALID, INVALID,
+/* [EC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [F0] */ TNS("crc32b",CRC32), TS("crc32",CRC32), INVALID, INVALID,
+/* [F4] */ INVALID, INVALID, INVALID, INVALID,
+/* [F8] */ INVALID, INVALID, INVALID, INVALID,
+/* [FC] */ INVALID, INVALID, INVALID, INVALID,
+};
+
+const instable_t dis_op0F3A[256] = {
+/* [00] */ INVALID, INVALID, INVALID, INVALID,
+/* [04] */ INVALID, INVALID, INVALID, INVALID,
+/* [08] */ TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
+/* [0C] */ TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
+
+/* [10] */ INVALID, INVALID, INVALID, INVALID,
+/* [14] */ TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
+/* [18] */ INVALID, INVALID, INVALID, INVALID,
+/* [1C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [20] */ TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
+/* [24] */ INVALID, INVALID, INVALID, INVALID,
+/* [28] */ INVALID, INVALID, INVALID, INVALID,
+/* [2C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [30] */ INVALID, INVALID, INVALID, INVALID,
+/* [34] */ INVALID, INVALID, INVALID, INVALID,
+/* [38] */ INVALID, INVALID, INVALID, INVALID,
+/* [3C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [40] */ TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
+/* [44] */ INVALID, INVALID, INVALID, INVALID,
+/* [48] */ INVALID, INVALID, INVALID, INVALID,
+/* [4C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [50] */ INVALID, INVALID, INVALID, INVALID,
+/* [54] */ INVALID, INVALID, INVALID, INVALID,
+/* [58] */ INVALID, INVALID, INVALID, INVALID,
+/* [5C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [60] */ TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
+/* [64] */ INVALID, INVALID, INVALID, INVALID,
+/* [68] */ INVALID, INVALID, INVALID, INVALID,
+/* [6C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [70] */ INVALID, INVALID, INVALID, INVALID,
+/* [74] */ INVALID, INVALID, INVALID, INVALID,
+/* [78] */ INVALID, INVALID, INVALID, INVALID,
+/* [7C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [80] */ INVALID, INVALID, INVALID, INVALID,
+/* [84] */ INVALID, INVALID, INVALID, INVALID,
+/* [88] */ INVALID, INVALID, INVALID, INVALID,
+/* [8C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [90] */ INVALID, INVALID, INVALID, INVALID,
+/* [94] */ INVALID, INVALID, INVALID, INVALID,
+/* [98] */ INVALID, INVALID, INVALID, INVALID,
+/* [9C] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [A0] */ INVALID, INVALID, INVALID, INVALID,
+/* [A4] */ INVALID, INVALID, INVALID, INVALID,
+/* [A8] */ INVALID, INVALID, INVALID, INVALID,
+/* [AC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [B0] */ INVALID, INVALID, INVALID, INVALID,
+/* [B4] */ INVALID, INVALID, INVALID, INVALID,
+/* [B8] */ INVALID, INVALID, INVALID, INVALID,
+/* [BC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [C0] */ INVALID, INVALID, INVALID, INVALID,
+/* [C4] */ INVALID, INVALID, INVALID, INVALID,
+/* [C8] */ INVALID, INVALID, INVALID, INVALID,
+/* [CC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [D0] */ INVALID, INVALID, INVALID, INVALID,
+/* [D4] */ INVALID, INVALID, INVALID, INVALID,
+/* [D8] */ INVALID, INVALID, INVALID, INVALID,
+/* [DC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [E0] */ INVALID, INVALID, INVALID, INVALID,
+/* [E4] */ INVALID, INVALID, INVALID, INVALID,
+/* [E8] */ INVALID, INVALID, INVALID, INVALID,
+/* [EC] */ INVALID, INVALID, INVALID, INVALID,
+
+/* [F0] */ INVALID, INVALID, INVALID, INVALID,
+/* [F4] */ INVALID, INVALID, INVALID, INVALID,
+/* [F8] */ INVALID, INVALID, INVALID, INVALID,
+/* [FC] */ INVALID, INVALID, INVALID, INVALID,
+};
+
/*
* Decode table for 0x0F opcodes
*/
@@ -1758,6 +1932,8 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode)
uint_t rex_prefix = 0; /* amd64 register extension prefix */
size_t off;
+ instable_t dp_mmx;
+
x->d86_len = 0;
x->d86_rmindex = -1;
x->d86_error = 0;
@@ -1910,6 +2086,74 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode)
dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
dp = (instable_t *)&dis_op0FC8[0];
+ } else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
+ if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
+ goto error;
+ if (opnd_size == SIZE16)
+ opnd_size = SIZE32;
+
+ dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
+#ifdef DIS_TEXT
+ if (strcmp(dp->it_name, "INVALID") == 0)
+ goto error;
+#endif
+ switch (dp->it_adrmode) {
+ case XMMP_66r:
+ case XMMPRM_66r:
+ case XMM3PM_66r:
+ if (opnd_size_prefix == 0) {
+ goto error;
+ }
+ break;
+ case XMMP_66o:
+ if (opnd_size_prefix == 0) {
+ /* SSSE3 MMX instructions */
+ dp_mmx = *dp;
+ dp = &dp_mmx;
+ dp->it_adrmode = MMOPM_66o;
+#ifdef DIS_MEM
+ dp->it_size = 8;
+#endif
+ }
+ break;
+ default:
+ goto error;
+ }
+ } else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
+ if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
+ goto error;
+ dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
+#ifdef DIS_TEXT
+ if (strcmp(dp->it_name, "INVALID") == 0)
+ goto error;
+#endif
+ switch (dp->it_adrmode) {
+ case XMM_66r:
+ case XMMM_66r:
+ if (opnd_size_prefix == 0) {
+ goto error;
+ }
+ break;
+ case XMM_66o:
+ if (opnd_size_prefix == 0) {
+ /* SSSE3 MMX instructions */
+ dp_mmx = *dp;
+ dp = &dp_mmx;
+ dp->it_adrmode = MM;
+#ifdef DIS_MEM
+ dp->it_size = 8;
+#endif
+ }
+ break;
+ case CRC32:
+ if (rep_prefix != 0xF2) {
+ goto error;
+ }
+ rep_prefix = 0;
+ break;
+ default:
+ goto error;
+ }
} else {
dp = (instable_t *)&dis_op0F[opcode4][opcode5];
}
@@ -2166,6 +2410,20 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode)
wbit = WBIT(opcode5);
dtrace_get_operand(x, mode, r_m, wbit, 0);
break;
+ case CRC32:
+ opnd_size = SIZE32;
+ if (rex_prefix & REX_W)
+ opnd_size = SIZE64;
+ x->d86_opnd_size = opnd_size;
+
+ dtrace_get_modrm(x, &mode, &reg, &r_m);
+ dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
+ dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
+ wbit = WBIT(opcode7);
+ if (opnd_size_prefix)
+ x->d86_opnd_size = opnd_size = SIZE16;
+ dtrace_get_operand(x, mode, r_m, wbit, 0);
+ break;
/*
* imul instruction, with either 8-bit or longer immediate
@@ -2549,12 +2807,19 @@ xmm3p:
NOMEM;
break;
+ case XMM3PM_66r:
+ wbit = XMM_OPND;
+ dtrace_get_modrm(x, &mode, &reg, &r_m);
+ THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1);
+ break;
+
/* MMX/SIMD-Int predicated r32/mem to mm reg */
case MMOPRM:
wbit = LONG_OPND;
w2 = MM_OPND;
goto xmmprm;
case XMMPRM:
+ case XMMPRM_66r:
wbit = LONG_OPND;
w2 = XMM_OPND;
xmmprm:
@@ -2563,6 +2828,7 @@ xmmprm:
/* MMX/SIMD-Int predicated mm/mem to mm reg */
case MMOPM:
+ case MMOPM_66o:
wbit = w2 = MM_OPND;
goto xmmprm;
@@ -2578,6 +2844,8 @@ xmmprm:
/* SIMD memory or xmm reg operand to xmm reg */
case XMM:
+ case XMM_66o:
+ case XMM_66r:
case XMMO:
case XMMXIMPL:
wbit = XMM_OPND;
@@ -2622,6 +2890,7 @@ xmmprm:
/* SIMD memory to xmm reg */
case XMMM:
+ case XMMM_66r:
case XMMOM:
wbit = XMM_OPND;
dtrace_get_modrm(x, &mode, &reg, &r_m);
@@ -2684,6 +2953,8 @@ xmmprm:
/* SIMD predicated memory or xmm reg with/to xmm reg */
case XMMP:
+ case XMMP_66r:
+ case XMMP_66o:
case XMMOPM:
wbit = XMM_OPND;
THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
diff --git a/usr/src/common/elfcap/elfcap.c b/usr/src/common/elfcap/elfcap.c
index 4bafbcf64f..dadee833b5 100644
--- a/usr/src/common/elfcap/elfcap.c
+++ b/usr/src/common/elfcap/elfcap.c
@@ -172,6 +172,9 @@ static const char Hw1_i_tscp[] = "TSCP";
static const char Hw1_i_amd_sse4a[] = "AMD_SSE4A";
static const char Hw1_i_popcnt[] = "POPCNT";
static const char Hw1_i_amd_lzcnt[] = "AMD_LZCNT";
+static const char Hw1_i_ssse3[] = "SSSE3";
+static const char Hw1_i_sse4_1[] = "SSE4.1";
+static const char Hw1_i_sse4_2[] = "SSE4.2";
#elif CAP_LOWERCASE
static const char Hw1_i_fpu[] = "fpu";
static const char Hw1_i_tsc[] = "tsc";
@@ -195,6 +198,9 @@ static const char Hw1_i_tscp[] = "tscp";
static const char Hw1_i_amd_sse4a[] = "amd_sse4a";
static const char Hw1_i_popcnt[] = "popcnt";
static const char Hw1_i_amd_lzcnt[] = "amd_lzcnt";
+static const char Hw1_i_ssse3[] = "ssse3";
+static const char Hw1_i_sse4_1[] = "sse4.1";
+static const char Hw1_i_sse4_2[] = "sse4.2";
#else
#error "Hardware Capabilities (intel) - what case do you want?"
#endif
@@ -229,7 +235,10 @@ static const Cap_desc hw1_i[] = {
sizeof (Hw1_i_amd_sse4a) - 1 },
{ AV_386_POPCNT, Hw1_i_popcnt, sizeof (Hw1_i_popcnt) - 1 },
{ AV_386_AMD_LZCNT, Hw1_i_amd_lzcnt,
- sizeof (Hw1_i_amd_lzcnt) - 1 }
+ sizeof (Hw1_i_amd_lzcnt) - 1 },
+ { AV_386_SSSE3, Hw1_i_ssse3, sizeof (Hw1_i_ssse3) - 1 },
+ { AV_386_SSE4_1, Hw1_i_sse4_1, sizeof (Hw1_i_sse4_1) - 1 },
+ { AV_386_SSE4_2, Hw1_i_sse4_2, sizeof (Hw1_i_sse4_2) - 1 }
};
static const uint_t hw1_i_num = sizeof (hw1_i) / sizeof (Cap_desc);
diff --git a/usr/src/uts/common/sys/auxv_386.h b/usr/src/uts/common/sys/auxv_386.h
index cfc83404f9..29b1e6145c 100644
--- a/usr/src/uts/common/sys/auxv_386.h
+++ b/usr/src/uts/common/sys/auxv_386.h
@@ -64,10 +64,15 @@ extern "C" {
#define AV_386_AMD_SSE4A 0x80000 /* AMD's SSE4A insns */
#define AV_386_POPCNT 0x100000 /* POPCNT insn */
#define AV_386_AMD_LZCNT 0x200000 /* AMD's LZCNT insn */
+#define AV_386_SSSE3 0x400000 /* Intel SSSE3 insns */
+#define AV_386_SSE4_1 0x800000 /* Intel SSE4.1 insns */
+#define AV_386_SSE4_2 0x1000000 /* Intel SSE4.2 insns */
#define FMT_AV_386 \
"\20" \
- "\26amd_lzcnt\25popcnt\24amd_sse4a\23tscp\22ahf\21cx16" \
+ "\31sse4.2" \
+ "\30sse4.1\27ssse3\26amd_lzcnt\25popcnt" \
+ "\24amd_sse4a\23tscp\22ahf\21cx16" \
"\20mon\17sse3\16pause\15sse2\14sse\13fxsr\12amd3dx\11amd3d" \
"\10amdmmx\7mmx\6cmov\5amdsysc\4sep\3cx8\2tsc\1fpu"
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index 76a53e25ed..6ee22a48a2 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -916,6 +916,14 @@ cpuid_pass1(cpu_t *cpu)
feature |= X86_SSE2;
if (cp->cp_ecx & CPUID_INTC_ECX_SSE3)
feature |= X86_SSE3;
+ if (cpi->cpi_vendor == X86_VENDOR_Intel) {
+ if (cp->cp_ecx & CPUID_INTC_ECX_SSSE3)
+ feature |= X86_SSSE3;
+ if (cp->cp_ecx & CPUID_INTC_ECX_SSE4_1)
+ feature |= X86_SSE4_1;
+ if (cp->cp_ecx & CPUID_INTC_ECX_SSE4_2)
+ feature |= X86_SSE4_2;
+ }
}
if (cp->cp_edx & CPUID_INTC_EDX_DE)
feature |= X86_DE;
@@ -2017,6 +2025,15 @@ cpuid_pass4(cpu_t *cpu)
if ((x86_feature & X86_SSE3) == 0)
*ecx &= ~CPUID_INTC_ECX_SSE3;
+ if (cpi->cpi_vendor == X86_VENDOR_Intel) {
+ if ((x86_feature & X86_SSSE3) == 0)
+ *ecx &= ~CPUID_INTC_ECX_SSSE3;
+ if ((x86_feature & X86_SSE4_1) == 0)
+ *ecx &= ~CPUID_INTC_ECX_SSE4_1;
+ if ((x86_feature & X86_SSE4_2) == 0)
+ *ecx &= ~CPUID_INTC_ECX_SSE4_2;
+ }
+
/*
* [no explicit support required beyond x87 fp context]
*/
@@ -2035,6 +2052,14 @@ cpuid_pass4(cpu_t *cpu)
hwcap_flags |= AV_386_SSE2;
if (*ecx & CPUID_INTC_ECX_SSE3)
hwcap_flags |= AV_386_SSE3;
+ if (cpi->cpi_vendor == X86_VENDOR_Intel) {
+ if (*ecx & CPUID_INTC_ECX_SSSE3)
+ hwcap_flags |= AV_386_SSSE3;
+ if (*ecx & CPUID_INTC_ECX_SSE4_1)
+ hwcap_flags |= AV_386_SSE4_1;
+ if (*ecx & CPUID_INTC_ECX_SSE4_2)
+ hwcap_flags |= AV_386_SSE4_2;
+ }
if (*ecx & CPUID_INTC_ECX_POPCNT)
hwcap_flags |= AV_386_POPCNT;
if (*edx & CPUID_INTC_EDX_FPU)
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index ff785bca1f..3763fd7f15 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -106,11 +106,13 @@ extern "C" {
/* 0x00010000 - reserved */
/* 0x00020000 - reserved */
#define CPUID_INTC_ECX_DCA 0x00040000 /* direct cache access */
+#define CPUID_INTC_ECX_SSE4_1 0x00080000 /* SSE4.1 insns */
+#define CPUID_INTC_ECX_SSE4_2 0x00100000 /* SSE4.2 insns */
#define CPUID_INTC_ECX_POPCNT 0x00800000 /* POPCNT insn */
#define FMT_CPUID_INTC_ECX \
"\20" \
- "\30popcnt\23dca" \
+ "\30popcnt\25sse4.2\24sse4.1\23dca" \
"\20\17etprd\16cx16\13cid\12ssse3\11tm2" \
"\10est\7smx\6vmx\5dscpl\4mon\1sse3"
@@ -324,10 +326,13 @@ extern "C" {
#define X86_MWAIT 0x00400000
#define X86_SSE4A 0x00800000
#define X86_CPUID 0x01000000
+#define X86_SSSE3 0x02000000
+#define X86_SSE4_1 0x04000000
+#define X86_SSE4_2 0x08000000
#define FMT_X86_FEATURE \
"\20" \
- "\31cpuid" \
+ "\34sse4_2\33sse4_1\32ssse3\31cpuid" \
"\30sse4a\27mwait\26tscp\25cmp\24cx16\23sse3\22nx\21asysc"\
"\20htt\17sse2\16sse\15sep\14pat\13cx8\12pae\11mca" \
"\10mmx\7cmov\6de\5pge\4mtrr\3msr\2tsc\1lgpg"