From ff68cf0f8ed2699a1d34845928c0cf3b82c1f76a Mon Sep 17 00:00:00 2001 From: John Detter Date: Mon, 7 Nov 2016 09:18:05 -0600 Subject: [PATCH 1/7] Fixed several of Nathan's reported issues including #193 --- common/h/entryIDs.h | 1 + common/src/arch-x86.C | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/common/h/entryIDs.h b/common/h/entryIDs.h index d4576780d2..6ae4a29b0e 100644 --- a/common/h/entryIDs.h +++ b/common/h/entryIDs.h @@ -612,6 +612,7 @@ enum entryID { e_vblendvps, e_vblendvpd, e_vpblendmw, + e_vpblendmd, e_vpblendmb, e_vpblendvb, e_vcmppd, diff --git a/common/src/arch-x86.C b/common/src/arch-x86.C index 427cd98690..e10fa31be8 100644 --- a/common/src/arch-x86.C +++ b/common/src/arch-x86.C @@ -248,7 +248,7 @@ SSEB00 = 0, SSEB01, SSEB02, SSEB03, SSEB04, SSEB05, SSEB06, SSEB07, SSEB40, SSEB41, SSEB42, SSEB43, SSEB44, SSEB45, SSEB46, SSEB47, SSEB4C, SSEB4D, SSEB4E, SSEB4F, SSEB58, SSEB59, SSEB5A, - SSEB65, SSEB66, + SSEB64, SSEB65, SSEB66, SSEB75, SSEB76, SSEB77, SSEB78, SSEB79, SSEB7C, SSEB7D, SSEB7E, SSEB7F, SSEB83, @@ -336,6 +336,7 @@ enum { /** AUTOGENERATED */ SSEB4D_66, SSEB4E_66, SSEB4F_66, + SSEB64_66, SSEB65_66, SSEB66_66, SSEB75_66, @@ -1356,6 +1357,7 @@ COMMON_EXPORT dyn_hash_map entryNames_IAPI = map_list_of (e_vblendvps, "vblendvps") (e_vblendvpd, "vblendvpd") (e_vpblendmb, "vpblendmb") + (e_vpblendmd, "vpblendmd") (e_vpblendmw, "vpblendmw") (e_vpblendvb, "vpblendvb") (e_vcmppd, "vcmppd") @@ -2801,12 +2803,12 @@ static ia32_entry threeByteMap[256] = { { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - /* 65 */ - { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + /* 60 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_sse_bis, SSEB64, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_sse_bis, SSEB65, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_sse_bis, SSEB66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -3633,7 +3635,7 @@ static ia32_entry groupMap2[][2][8] = { { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, - { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_grpsse, G12SSE100B, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, @@ -3949,7 +3951,7 @@ static ia32_entry sseMap[][4] = { { e_movntsd, t_done, 0, true, { Wq, Vq, Zz }, 0, s1W2R | (fNT << FPOS) }, }, { /* SSE2C */ - { e_cvttps2pi, t_done, 0, true, { Qq, Wps, Zz }, 0, s1W2R }, + { e_cvttps2pi, t_done, 0, true, { Pq, Wps, Zz }, 0, s1W2R }, { e_cvttss2si, t_sse_mult, SSE2C_F3, true, { Gv, Wss, Zz }, 0, s1W2R }, { e_cvttpd2pi, t_done, 0, true, { Qdq, Wpd, Zz }, 0, s1W2R }, { e_cvttsd2si, t_sse_mult, SSE2C_F2, true, { Gv, Wsd, Zz }, 0, s1W2R }, @@ -5148,6 +5150,12 @@ static ia32_entry sseMapBis[][5] = { { e_vbroadcastf128, t_done, 0, true, { Vsd, Wq, Zz }, 0, s1W2R }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } + }, { /* SSEB64 */ + { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_sse_bis_mult, SSEB64_66, false, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB65 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -7044,6 +7052,10 @@ ia32_entry sseMapBisMult[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_vexw, VEXW89, false, { Zz, Zz, Zz }, 0, 0 } + }, { /* SSEB65_66 */ + { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + { e_vpblendmd, t_done, 0, true, { Vpd, Hpd, Wpd }, 0, s1RW2R3R }, }, { /* SSEB65_66 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -7656,7 +7668,7 @@ static ia32_entry ssegrpMap_VEX[][2] = { /* G12SSE100B */ { { e_vpsraw, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R }, - { e_vpsraw, t_done, 0, true, { Pdq, Ib, Zz }, 0, s1RW2R } + { e_vpsraw, t_done, 0, true, { Vps, Wps, Ib }, 0, s1RW2R } }, /* G12SSE110B */ { @@ -8293,6 +8305,7 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32 /* First decode any prefixes for this instruction */ if (!ia32_decode_prefixes(addr, instruct)) { + fprintf(stderr, "PREFIX DECODE FAILURE.\n"); instruct.size = 1; instruct.entry = NULL; instruct.legacy_type = ILLEGAL; @@ -10042,6 +10055,12 @@ bool ia32_decode_prefixes(const unsigned char* addr, ia32_instruction& instruct) pref.vex_present = true; pref.vex_type = VEX_TYPE_EVEX; memmove(&pref.vex_prefix, addr + 1, 3); +#ifdef VEX_DEBUG + printf("EVEX PREFIX: 0x%x 0x%x 0x%x\n", + pref.vex_prefix[0], + pref.vex_prefix[1], + pref.vex_prefix[2]); +#endif pref.vex_sse_mult = 2; pref.vex_vvvv_reg = EVEXGET_VVVV(pref.vex_prefix[1], pref.vex_prefix[2]); pref.vex_ll = EVEXGET_LL(pref.vex_prefix[2]); @@ -10059,6 +10078,9 @@ bool ia32_decode_prefixes(const unsigned char* addr, ia32_instruction& instruct) /* VEX_LL must be 0, 1, or 2 */ if(pref.vex_ll >= 3 || pref.vex_ll < 0) { +#ifdef VEX_DEBUG + printf("VEX PREFIX LL Invalid: %d\n", pref.vex_ll); +#endif err = true; break; } @@ -10086,7 +10108,10 @@ bool ia32_decode_prefixes(const unsigned char* addr, ia32_instruction& instruct) || ((pref.vex_prefix[1] & (unsigned int)(1 << 2)) == 0)) { #ifdef VEX_DEBUG - printf("EVEX PREFIX INVALID!\n"); + printf("EVEX PREFIX INVALID! 0x%x 0x%x 0x%x != 0 || 0x%x != 1\n", + pref.vex_prefix[0], pref.vex_prefix[1], + pref.vex_prefix[0] & (unsigned int)(0x03 << 2), + pref.vex_prefix[1] & (unsigned int)(1 << 2)); #endif err = true; break; From 2d7be7a0973aef10aa39859fd9eda96bb8b1aa76 Mon Sep 17 00:00:00 2001 From: John Detter Date: Tue, 22 Nov 2016 07:37:48 -0600 Subject: [PATCH 2/7] Removed unreachable instructions. Moved all remaining VEX instruction from SSE tables into proper VEX tables. Fixes #213 #199 #193 #195 #196 --- common/src/arch-x86.C | 98 +++++++++++++++++---- instructionAPI/src/InstructionDecoder-x86.C | 2 +- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/common/src/arch-x86.C b/common/src/arch-x86.C index e10fa31be8..5d3f9baa3b 100644 --- a/common/src/arch-x86.C +++ b/common/src/arch-x86.C @@ -309,6 +309,10 @@ enum { /** AUTOGENERATED */ SSEB29_66, SSEB29_F3, SSEB2A_66, SSEB2A_F3, SSEB2B_66, + SSEB2C_66, + SSEB2D_66, + SSEB2E_66, + SSEB2F_66, SSEB30_66, SSEB30_F3, SSEB31_66, SSEB31_F3, SSEB32_66, SSEB32_F3, @@ -440,9 +444,11 @@ SSET00 = 0, SSET01, SSET02, SSET03, SSET04, SSET05, SSET06, enum { /** AUTOGENERATED */ SSET00_66 = 0, SSET01_66, + SSET02_66, SSET03_66, SSET04_66, SSET05_66, + SSET06_66, SSET08_66, SSET09_66, SSET0A_66, @@ -478,6 +484,7 @@ enum { /** AUTOGENERATED */ SSET3F_66, SSET42_66, SSET44_66, + SSET46_66, SSET4A_66, SSET4B_66, SSET4C_66, @@ -3953,13 +3960,13 @@ static ia32_entry sseMap[][4] = { { /* SSE2C */ { e_cvttps2pi, t_done, 0, true, { Pq, Wps, Zz }, 0, s1W2R }, { e_cvttss2si, t_sse_mult, SSE2C_F3, true, { Gv, Wss, Zz }, 0, s1W2R }, - { e_cvttpd2pi, t_done, 0, true, { Qdq, Wpd, Zz }, 0, s1W2R }, + { e_cvttpd2pi, t_done, 0, true, { Pdq, Wpd, Zz }, 0, s1W2R }, { e_cvttsd2si, t_sse_mult, SSE2C_F2, true, { Gv, Wsd, Zz }, 0, s1W2R }, }, { /* SSE2D */ - { e_cvtps2pi, t_done, 0, true, { Qq, Wps, Zz }, 0, s1W2R }, + { e_cvtps2pi, t_done, 0, true, { Pq, Wps, Zz }, 0, s1W2R }, { e_cvtss2si, t_sse_mult, SSE2D_F3, true, { Gv, Wss, Zz }, 0, s1W2R }, - { e_cvtpd2pi, t_done, 0, true, { Qdq, Wpd, Zz }, 0, s1W2R }, + { e_cvtpd2pi, t_done, 0, true, { Pdq, Wpd, Zz }, 0, s1W2R }, { e_cvtsd2si, t_sse_mult, SSE2D_F2, true, { Gv, Wsd, Zz }, 0, s1W2R }, }, { /* SSE2E */ @@ -4751,13 +4758,13 @@ static ia32_entry sseMapBis[][5] = { }, { /* SSEB0C */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vpermilps, t_sse_bis_mult, SSEB0C_66, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB0C_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB0D */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vpermilpd, t_sse_bis_mult, SSEB0D_66, true, { Vpd, Hpd, Wpd }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB0D_66, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB0E */ @@ -4811,7 +4818,7 @@ static ia32_entry sseMapBis[][5] = { }, { /* SSEB16 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vpermps, t_sse_bis_mult, SSEB16_66, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB16_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB17 */ @@ -4943,25 +4950,25 @@ static ia32_entry sseMapBis[][5] = { }, { /* SSEB2C */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vmaskmovps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB2C_66, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB2D */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vmaskmovpd, t_done, 0, true, { Vpd, Hpd, Wpd }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB2D_66, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB2E */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vmaskmovps, t_done, 0, true, { Wps, Hps, Vps }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB2E_66, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB2F */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vmaskmovpd, t_done, 0, true, { Wpd, Hpd, Vpd }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB2F_66, true, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB30 */ @@ -5003,7 +5010,7 @@ static ia32_entry sseMapBis[][5] = { }, { /* SSEB36 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vpermd, t_sse_bis_mult, SSEB36_66, true, { Vdq, Hdq, Wdq }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB36_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB37 */ @@ -5099,7 +5106,7 @@ static ia32_entry sseMapBis[][5] = { }, { /* SSEB46 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vpsravd, t_sse_bis_mult, SSEB46_66, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + { e_No_Entry, t_sse_bis_mult, SSEB46_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSEB47 */ @@ -5636,7 +5643,7 @@ static ia32_entry sseMapTer[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSET02 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vpblendd, t_done, 0, true, { Vpd, Hpd, Upd }, 0, s1W2R3R4R }, + { e_No_Entry, t_sse_ter_mult, SSET02_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSET03 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -5652,7 +5659,7 @@ static ia32_entry sseMapTer[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSET06 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vperm2f128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_No_Entry, t_sse_ter_mult, SSET06_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSET08 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -5704,7 +5711,7 @@ static ia32_entry sseMapTer[][3] = { e_extractps, t_done, 0, true, { Ed, Vdq, Ib }, 0, s1W2R3R }, }, { /* SSET18 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vinsertf128, t_sse_ter_mult, SSET18_66, true, { Vdq, Hps, Wps }, 0, s1W2R3R4R }, + { e_No_Entry, t_sse_ter_mult, SSET18_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, }, { /* SSET19 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -5776,7 +5783,7 @@ static ia32_entry sseMapTer[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSET38 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vinserti128, t_sse_ter_mult, SSET38_66, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_No_Entry, t_sse_ter_mult, SSET38_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, }, { /* SSET39 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -5816,7 +5823,7 @@ static ia32_entry sseMapTer[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, }, { /* SSET46 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, - { e_vperm2i128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_No_Entry, t_sse_ter_mult, SSET46_66, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 } }, { /* SSET4A */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -6912,6 +6919,22 @@ ia32_entry sseMapBisMult[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_vpackusdw, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, { e_vpackusdw, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + }, { /* SSEB2C_66 */ + { e_vmaskmovps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + { e_vmaskmovps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + { e_vmaskmovps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, + }, { /* SSEB2D_66 */ + { e_vmaskmovpd, t_done, 0, true, { Vpd, Hpd, Wpd }, 0, s1W2R3R }, + { e_vmaskmovpd, t_done, 0, true, { Vpd, Hpd, Wpd }, 0, s1W2R3R }, + { e_vmaskmovpd, t_done, 0, true, { Vpd, Hpd, Wpd }, 0, s1W2R3R }, + }, { /* SSEB2E_66 */ + { e_vmaskmovps, t_done, 0, true, { Wps, Hps, Vps }, 0, s1W2R3R }, + { e_vmaskmovps, t_done, 0, true, { Wps, Hps, Vps }, 0, s1W2R3R }, + { e_vmaskmovps, t_done, 0, true, { Wps, Hps, Vps }, 0, s1W2R3R }, + }, { /* SSEB2F_66 */ + { e_vmaskmovpd, t_done, 0, true, { Wpd, Hpd, Vpd }, 0, s1W2R3R }, + { e_vmaskmovpd, t_done, 0, true, { Wpd, Hpd, Vpd }, 0, s1W2R3R }, + { e_vmaskmovpd, t_done, 0, true, { Wpd, Hpd, Vpd }, 0, s1W2R3R }, }, { /* SSEB30_66 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_vpmovzxbw, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, @@ -7389,6 +7412,10 @@ ia32_entry sseMapTerMult[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_vpermpd, t_done, 0, true, { Wpd, Vpd, Ib }, 0, s1W2R3R }, { e_vpermpd, t_done, 0, true, { Vpd, Hpd, Ib }, 0, s1W2R3R }, + }, { /* SSET02_66 */ + { e_vpblendd, t_done, 0, true, { Vpd, Hpd, Upd }, 0, s1W2R3R4R }, + { e_vpblendd, t_done, 0, true, { Vpd, Hpd, Upd }, 0, s1W2R3R4R }, + { e_vpblendd, t_done, 0, true, { Vpd, Hpd, Upd }, 0, s1W2R3R4R }, }, { /* SSET03_66 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -7401,6 +7428,10 @@ ia32_entry sseMapTerMult[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_vpermilpd, t_done, 0, true, { Wpd, Vpd, Ib }, 0, s1W2R3R }, { e_vpermilpd, t_done, 0, true, { Wpd, Vpd, Ib }, 0, s1W2R3R }, + }, { /* SSET06_66 */ + { e_vperm2f128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_vperm2f128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_vperm2f128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, }, { /* SSET08_66 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, @@ -7541,6 +7572,10 @@ ia32_entry sseMapTerMult[][3] = { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_vpclmullqlqdq, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, + }, { /* SSET46_66 */ + { e_vperm2i128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_vperm2i128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, + { e_vperm2i128, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, }, { /* SSET4A_66 */ { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, { e_vblendvps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R4R }, @@ -8581,6 +8616,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, { ia32_prefixes& pref = instruct.prf; unsigned int table, nxtab, idx; + bool vextab = false; /* Did we end in a table that supports VEX? */ int sseidx = 0; ia32_entry* gotit = NULL; int condbits = 0; @@ -8654,7 +8690,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, gotit = &oneByteMap[idx]; nxtab = gotit->otable; } - + if(capa & IA32_DECODE_CONDITION) { assert(instruct.cond != NULL); @@ -8665,6 +8701,8 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, while(nxtab != t_done) { table = nxtab; + vextab = false; + switch(table) { case t_twoB: @@ -8758,6 +8796,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, fprintf(stderr, "NEXT TAB == VEXW? %s\n", nxtab == t_vexw ? "YES" : "NO"); #endif + vextab = true; break; case t_sse_bis: /* Decode the sse prefix for this type */ @@ -8799,6 +8838,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, #ifdef VEX_DEBUG fprintf(stderr, "SSEB MULT idx: %d sseMul: %d\n", idx, pref.vex_sse_mult); #endif + vextab = true; break; case t_sse_ter: /* Decode the sse prefix for this type */ @@ -8838,6 +8878,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, #ifdef VEX_DEBUG fprintf(stderr, "SSET MULT idx: %d sseMul: %d\n", idx, pref.vex_sse_mult); #endif + vextab = true; break; case t_grp: @@ -8867,6 +8908,8 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, gotit = &groupMap2[idx-Grp12][mod==3][reg]; nxtab = gotit->otable; } + + vextab = true; break; } case t_grpsse: @@ -8888,8 +8931,10 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, // sseidx >>= 1; idx = gotit->tabidx; if(pref.vex_present) + { gotit = &ssegrpMap_VEX[idx][sseidx]; - else + vextab = true; + } else gotit = &ssegrpMap[idx][sseidx]; nxtab = gotit->otable; @@ -8929,6 +8974,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, gotit = &vex2Map[idx][pref.vex_ll]; /* Set the next table - this is almost always t_done */ nxtab = gotit->otable; + vextab = true; break; case t_vexw: /* This MUST have a vex prefix and must NOT be VEX2 */ @@ -8977,6 +9023,8 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, instruct.entry = gotit; return -1; } + + vextab = true; break; case t_sse_vex_mult: /* Get the SSE entry */ @@ -9005,6 +9053,7 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, } else gotit = &sseVexMult[idx][0]; nxtab = gotit->otable; + vextab = true; break; case t_ill: #ifdef VEX_DEBUG @@ -9027,6 +9076,17 @@ int ia32_decode_opcode(unsigned int capa, const unsigned char* addr, } } + /* If we have a vex prefex, we need to be in a VEX table */ + if(pref.vex_present && !vextab) + { +#ifdef VEX_DEBUG + printf("ERROR: This instruction doesn't support VEX prefixes.\n"); +#endif + instruct.legacy_type = ILLEGAL; + instruct.entry = gotit; + return -1; + } + /* We should have a valid decoding or we should have returned by now */ assert(gotit != NULL); instruct.legacy_type = gotit->legacyType; diff --git a/instructionAPI/src/InstructionDecoder-x86.C b/instructionAPI/src/InstructionDecoder-x86.C index 70fd7843bd..b5f8b560d1 100644 --- a/instructionAPI/src/InstructionDecoder-x86.C +++ b/instructionAPI/src/InstructionDecoder-x86.C @@ -1009,7 +1009,7 @@ namespace Dyninst // Selects a general purpose register from VEX.vvvv (VEX3 or EVEX) if(!pref.vex_present) { - assert(!"Non VEX3 or EVEX instruction with am_B addressing mode!"); + // assert(!"Non VEX3 or EVEX instruction with am_B addressing mode!"); return false; } From f236c311f4e41b17595e6d7266a8974a10df7f72 Mon Sep 17 00:00:00 2001 From: Sunny Shah Date: Wed, 30 Nov 2016 13:12:00 -0600 Subject: [PATCH 3/7] Issue #233 ([ARM Decoding] Bad shift amounts.) Mark ADD/SUB shoted-register variants and logical shifted-register variants as invalid if shift amount is reserved. --- instructionAPI/src/InstructionDecoder-aarch64.C | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/instructionAPI/src/InstructionDecoder-aarch64.C b/instructionAPI/src/InstructionDecoder-aarch64.C index 0c95fcd324..918fed5f69 100644 --- a/instructionAPI/src/InstructionDecoder-aarch64.C +++ b/instructionAPI/src/InstructionDecoder-aarch64.C @@ -2518,6 +2518,12 @@ Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){ entryID curID; if (IS_INSN_BITFIELD(insn)) { + if((is64Bit && nField != 0x1) || + (!is64Bit && (nField != 0 || (immr & 0x20) != 0 || (immVal & 0x20) != 0))) { + isValid = false; + return; + } + if (!fix_bitfieldinsn_alias(immr, immVal)) return; @@ -2561,6 +2567,9 @@ Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){ if (IS_INSN_ADDSUB_SHIFT(insn) || IS_INSN_LOGICAL_SHIFT(insn)) //add-sub shifted | logical shifted { processShiftFieldShiftedInsn(immLen, immVal); + + if((IS_INSN_ADDSUB_SHIFT(insn) && shiftField == 0x3) || (!is64Bit && ((immVal >> 5) & 0x1) == 0x1)) + isValid = false; } else if (IS_INSN_ADDSUB_IMM(insn)) //add-sub (immediate) { From 409263315ff647c8ea180fd28d21f91548ca9fe5 Mon Sep 17 00:00:00 2001 From: Sunny Shah Date: Thu, 1 Dec 2016 00:23:50 -0600 Subject: [PATCH 4/7] Issue #238 ([ARM Decoding] We should print the full operands of PRFUM) Fix destination and second source operand parsing for PRFUM. --- instructionAPI/src/InstructionDecoder-aarch64.C | 4 ++-- instructionAPI/src/aarch64_opcode_tables.C | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instructionAPI/src/InstructionDecoder-aarch64.C b/instructionAPI/src/InstructionDecoder-aarch64.C index 918fed5f69..3199d71e8e 100644 --- a/instructionAPI/src/InstructionDecoder-aarch64.C +++ b/instructionAPI/src/InstructionDecoder-aarch64.C @@ -1245,7 +1245,7 @@ namespace Dyninst { scale += field<31, 31>(insn); //return makeMultiplyExpression(imm7, scale, s64); - return Immediate::makeImmediate(Result(u32, immVal << scale)); + return Immediate::makeImmediate(Result(s64, sign_extend64(immLen, immVal) << scale)); } Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndex_addOffset9() { @@ -2059,7 +2059,7 @@ Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){ makeRegisterExpression(makeAarch64RegID(is64Bit ? aarch64::x0 : aarch64::w0, encoding)), true, false); } - else if (op == aarch64_op_prfm_imm || op == aarch64_op_prfm_lit || op == aarch64_op_prfm_reg) { + else if (op == aarch64_op_prfm_imm || op == aarch64_op_prfm_lit || op == aarch64_op_prfm_reg || op == aarch64_op_prfum) { Expression::Ptr prfop; Result arg = Result(u32, unsign_extend32(5, encoding)); diff --git a/instructionAPI/src/aarch64_opcode_tables.C b/instructionAPI/src/aarch64_opcode_tables.C index 9f62e04171..6b39d66732 100644 --- a/instructionAPI/src/aarch64_opcode_tables.C +++ b/instructionAPI/src/aarch64_opcode_tables.C @@ -457,7 +457,7 @@ void aarch64_insn_entry::buildInsnTable() main_insn_table.push_back(aarch64_insn_entry(aarch64_op_prfm_imm, "prfm", list_of( (operandFactory) fn(OPRimm<21 COMMA 10>) )( fn(OPRRnL) )( fn(OPRRt) ), 4185915392, 4290772992) ); main_insn_table.push_back(aarch64_insn_entry(aarch64_op_prfm_lit, "prfm", list_of( (operandFactory) fn(OPRimm<23 COMMA 5>) )( fn(OPRRt) ), 3623878656, 4278190080) ); main_insn_table.push_back(aarch64_insn_entry(aarch64_op_prfm_reg, "prfm", list_of( fn(OPRRm) )( fn(OPRoption<15 COMMA 13>) )( fn(OPRS<12 COMMA 12>) )( fn(OPRRnL) )( fn(OPRRt) ), 4171237376, 4292873216) ); - main_insn_table.push_back(aarch64_insn_entry(aarch64_op_prfum, "prfum", list_of( (operandFactory) fn(OPRimm<20 COMMA 12>) )( fn(OPRRn) )( fn(OPRRt) ), 4169138176, 4292873216) ); + main_insn_table.push_back(aarch64_insn_entry(aarch64_op_prfum, "prfum", list_of( (operandFactory) fn(OPRimm<20 COMMA 12>) )( fn(OPRRnL) )( fn(OPRRt) ), 4169138176, 4292873216) ); main_insn_table.push_back(aarch64_insn_entry(aarch64_op_raddhn_advsimd, "raddhn", list_of( fn(setSIMDMode) )( fn(OPRQ) )( fn(OPRsize<23 COMMA 22>) )( fn(OPRRm) )( fn(OPRRn) )( fn(OPRRd) ), 773865472, 3206609920) ); main_insn_table.push_back(aarch64_insn_entry(aarch64_op_rbit_advsimd, "rbit", list_of( fn(setSIMDMode) )( fn(OPRQ) )( fn(OPRRn) )( fn(OPRRd) ), 778065920, 3221224448) ); main_insn_table.push_back(aarch64_insn_entry(aarch64_op_rbit_int, "rbit", list_of( fn(OPRsf) )( fn(OPRRn) )( fn(OPRRd) ), 1522532352, 2147482624) ); From 60416ae685b3f3ce0580c9721a1c11898e4c9ec0 Mon Sep 17 00:00:00 2001 From: Sunny Shah Date: Thu, 1 Dec 2016 00:43:54 -0600 Subject: [PATCH 5/7] Issue #240 ([ARM Decoding] Convert instruction immediate should not be larger than the register size) Mark fixed-point to floating point conversion instructions with bit<31> = 0 and bit<15> = 0 as invalid. --- instructionAPI/src/InstructionDecoder-aarch64.C | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/instructionAPI/src/InstructionDecoder-aarch64.C b/instructionAPI/src/InstructionDecoder-aarch64.C index 3199d71e8e..ca01dac834 100644 --- a/instructionAPI/src/InstructionDecoder-aarch64.C +++ b/instructionAPI/src/InstructionDecoder-aarch64.C @@ -2212,10 +2212,14 @@ Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){ } void InstructionDecoder_aarch64::OPRscale() { - int scaleVal = 64 - field<10, 15>(insn); - - Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6, scaleVal))); - insn_in_progress->appendOperand(scale, true, false); + int scaleVal = field<10, 15>(insn); + + if(!is64Bit && ((scaleVal >> 0x5) & 0x1) == 0x0) + isValid = false; + else { + Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6, 64 - scaleVal))); + insn_in_progress->appendOperand(scale, true, false); + } } Expression::Ptr InstructionDecoder_aarch64::makeRaExpr() { From d4c5b36b777fc067fcc58ef991b144828b20e5ab Mon Sep 17 00:00:00 2001 From: Sunny Shah Date: Thu, 1 Dec 2016 23:55:59 -0600 Subject: [PATCH 6/7] Issue #241 ([ARM Decoding] Convert instruction immediates appear incorrect at 64) Use different number of bits for size of 'fbits' operand in 32 vs 64 bit modes of the scalar to fixed-point FP instructions. --- instructionAPI/src/InstructionDecoder-aarch64.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instructionAPI/src/InstructionDecoder-aarch64.C b/instructionAPI/src/InstructionDecoder-aarch64.C index ca01dac834..3542795eb6 100644 --- a/instructionAPI/src/InstructionDecoder-aarch64.C +++ b/instructionAPI/src/InstructionDecoder-aarch64.C @@ -2217,7 +2217,7 @@ Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){ if(!is64Bit && ((scaleVal >> 0x5) & 0x1) == 0x0) isValid = false; else { - Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6, 64 - scaleVal))); + Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6 + is64Bit, 64 - scaleVal))); insn_in_progress->appendOperand(scale, true, false); } } From 8012061aa80b44d6ac176b4662f33bbe52e4c2b1 Mon Sep 17 00:00:00 2001 From: Sunny Shah Date: Fri, 2 Dec 2016 00:31:32 -0600 Subject: [PATCH 7/7] Issue #245 (ARM Decoding] Paired memory accesses must access aligned memory) Detect invalid instructions in the load/store pair and load/store non-temporal pair categories. --- instructionAPI/src/InstructionDecoder-aarch64.C | 9 +++++++++ instructionAPI/src/InstructionDecoder-aarch64.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/instructionAPI/src/InstructionDecoder-aarch64.C b/instructionAPI/src/InstructionDecoder-aarch64.C index 3542795eb6..35f959cc51 100644 --- a/instructionAPI/src/InstructionDecoder-aarch64.C +++ b/instructionAPI/src/InstructionDecoder-aarch64.C @@ -2211,6 +2211,15 @@ Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){ sField = field(insn); } + void InstructionDecoder_aarch64::OPRopc() { + int opcVal = field<30, 31>(insn); + int lopc = (field<22, 22>(insn) << 1) | (opcVal & 0x1); + + if((IS_INSN_LDST_PAIR_NOALLOC(insn) && (opcVal & 0x1) == 0x1) || + (IS_INSN_LDST_PAIR(insn) && (opcVal == 0x3 || lopc == 0x1))) + isValid = false; + } + void InstructionDecoder_aarch64::OPRscale() { int scaleVal = field<10, 15>(insn); diff --git a/instructionAPI/src/InstructionDecoder-aarch64.h b/instructionAPI/src/InstructionDecoder-aarch64.h index e4320dc65a..b272267837 100644 --- a/instructionAPI/src/InstructionDecoder-aarch64.h +++ b/instructionAPI/src/InstructionDecoder-aarch64.h @@ -480,7 +480,7 @@ namespace Dyninst { void OPRh(); - void OPRopc() { } + void OPRopc(); void OPRopcode() { }