diff --git a/common/h/entryIDs.h b/common/h/entryIDs.h index 7359edaf35..f95bd9b9ef 100644 --- a/common/h/entryIDs.h +++ b/common/h/entryIDs.h @@ -640,6 +640,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 0d16fefe2f..b44bd65a3c 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, @@ -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, @@ -336,6 +340,7 @@ enum { /** AUTOGENERATED */ SSEB4D_66, SSEB4E_66, SSEB4F_66, + SSEB64_66, SSEB65_66, SSEB66_66, SSEB75_66, @@ -439,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, @@ -477,6 +484,7 @@ enum { /** AUTOGENERATED */ SSET3F_66, SSET42_66, SSET44_66, + SSET46_66, SSET4A_66, SSET4B_66, SSET4C_66, @@ -1388,6 +1396,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") @@ -2832,12 +2841,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 }, @@ -3664,7 +3673,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 }, @@ -3980,15 +3989,15 @@ 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_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 */ @@ -4780,13 +4789,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 */ @@ -4840,7 +4849,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 */ @@ -4972,25 +4981,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 */ @@ -5032,7 +5041,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 */ @@ -5128,7 +5137,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 */ @@ -5179,6 +5188,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 }, @@ -5659,7 +5674,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 }, @@ -5675,7 +5690,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 }, @@ -5727,7 +5742,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 }, @@ -5799,7 +5814,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 }, @@ -5839,7 +5854,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 }, @@ -6935,6 +6950,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 }, @@ -7075,6 +7106,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 }, @@ -7408,6 +7443,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 }, @@ -7420,6 +7459,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 }, @@ -7560,6 +7603,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 }, @@ -7687,7 +7734,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 */ { @@ -8324,6 +8371,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; @@ -8599,6 +8647,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; @@ -8672,7 +8721,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); @@ -8683,6 +8732,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: @@ -8776,6 +8827,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 */ @@ -8817,6 +8869,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 */ @@ -8856,6 +8909,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: @@ -8885,6 +8939,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: @@ -8906,8 +8962,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; @@ -8947,6 +9005,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 */ @@ -8995,6 +9054,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 */ @@ -9023,6 +9084,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 @@ -9045,6 +9107,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; @@ -10073,6 +10146,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]); @@ -10090,6 +10169,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; } @@ -10117,7 +10199,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; diff --git a/instructionAPI/src/InstructionDecoder-aarch64.C b/instructionAPI/src/InstructionDecoder-aarch64.C index 048c00caad..5dfebbc218 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)); @@ -2211,11 +2211,24 @@ 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 = 64 - field<10, 15>(insn); + int scaleVal = field<10, 15>(insn); - Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6, scaleVal))); - insn_in_progress->appendOperand(scale, true, false); + if(!is64Bit && ((scaleVal >> 0x5) & 0x1) == 0x0) + isValid = false; + else { + Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6 + is64Bit, 64 - scaleVal))); + insn_in_progress->appendOperand(scale, true, false); + } } Expression::Ptr InstructionDecoder_aarch64::makeRaExpr() { @@ -2518,6 +2531,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 +2580,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) { 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() { } diff --git a/instructionAPI/src/InstructionDecoder-x86.C b/instructionAPI/src/InstructionDecoder-x86.C index bf68f539c5..bab7dfcfdd 100644 --- a/instructionAPI/src/InstructionDecoder-x86.C +++ b/instructionAPI/src/InstructionDecoder-x86.C @@ -1016,7 +1016,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; } 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) );