x86/x64: Support disassembly of VEX prefix and associated AVX/AVX2 instructions.

This commit is contained in:
Peter Cawley 2015-10-20 19:30:50 +01:00
parent a9c9800367
commit 686194d12d

View File

@ -76,7 +76,7 @@ local map_opc1_32 = {
"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", "movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI", "movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
--Cx --Cx
"shift!Bmu","shift!Vmu","retBw","ret","$lesVrm","$ldsVrm","movBmi","movVmi", "shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS", "enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
--Dx --Dx
"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", "shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
@ -101,7 +101,7 @@ local map_opc1_64 = setmetatable({
[0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb", [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
[0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb", [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
[0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb", [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
[0x82]=false, [0x9a]=false, [0xc4]=false, [0xc5]=false, [0xce]=false, [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
[0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false, [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
}, { __index = map_opc1_32 }) }, { __index = map_opc1_32 })
@ -112,12 +112,12 @@ local map_opc2 = {
[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret", [0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu", "invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
--1x --1x
"movupsXrm|movssXrm|movupdXrm|movsdXrm", "movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
"movupsXmr|movssXmr|movupdXmr|movsdXmr", "movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", "movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
"movlpsXmr||movlpdXmr", "movlpsXmr||movlpdXmr",
"unpcklpsXrm||unpcklpdXrm", "unpcklpsXrvm||unpcklpdXrvm",
"unpckhpsXrm||unpckhpdXrm", "unpckhpsXrvm||unpckhpdXrvm",
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", "movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
"movhpsXmr||movhpdXmr", "movhpsXmr||movhpdXmr",
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", "$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
@ -126,7 +126,7 @@ local map_opc2 = {
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, "movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
"movapsXrm||movapdXrm", "movapsXrm||movapdXrm",
"movapsXmr||movapdXmr", "movapsXmr||movapdXmr",
"cvtpi2psXrMm|cvtsi2ssXrVmt|cvtpi2pdXrMm|cvtsi2sdXrVmt", "cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr", "movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm", "cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm", "cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
@ -142,27 +142,27 @@ local map_opc2 = {
"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", "cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
--5x --5x
"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", "movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm", "rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm", "andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm", "orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm", "addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm", "cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", "cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm", "subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm", "divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
--6x --6x
"punpcklbwPrm","punpcklwdPrm","punpckldqPrm","packsswbPrm", "punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm", "pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm", "punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
"||punpcklqdqXrm","||punpckhqdqXrm", "||punpcklqdqXrvm","||punpckhqdqXrvm",
"movPrVSm","movqMrm|movdquXrm|movdqaXrm", "movPrVSm","movqMrm|movdquXrm|movdqaXrm",
--7x --7x
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu", "pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu",
"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu", "pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|", "pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$", "vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
nil,nil, nil,nil,
"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm", "||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr", "movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
--8x --8x
"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", "joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
@ -180,27 +180,27 @@ nil,nil,
"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt", "bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
--Cx --Cx
"xaddBmr","xaddVmr", "xaddBmr","xaddVmr",
"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","$movntiVmr|", "cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
"pinsrwPrWmu","pextrwDrPmu", "pinsrwPrvWmu","pextrwDrPmu",
"shufpsXrmu||shufpdXrmu","$cmpxchg!Qmp", "shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR", "bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
--Dx --Dx
"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm", "||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
"paddqPrm","pmullwPrm", "paddqPrvm","pmullwPrvm",
"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm", "|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
"psubusbPrm","psubuswPrm","pminubPrm","pandPrm", "psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm", "paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
--Ex --Ex
"pavgbPrm","psrawPrm","psradPrm","pavgwPrm", "pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
"pmulhuwPrm","pmulhwPrm", "pmulhuwPrvm","pmulhwPrvm",
"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr", "|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
"psubsbPrm","psubswPrm","pminswPrm","porPrm", "psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm", "paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
--Fx --Fx
"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm", "|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm$", "pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
"psubbPrm","psubwPrm","psubdPrm","psubqPrm", "psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
"paddbPrm","paddwPrm","padddPrm","ud", "paddbPrvm","paddwPrvm","padddPrvm","ud",
} }
assert(map_opc2[255] == "ud") assert(map_opc2[255] == "ud")
@ -208,46 +208,62 @@ assert(map_opc2[255] == "ud")
local map_opc3 = { local map_opc3 = {
["38"] = { -- [66] 0f 38 xx ["38"] = { -- [66] 0f 38 xx
--0x --0x
[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm", [0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm", "pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm", "psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
nil,nil,nil,nil, "||permilpsXrvm","||permilpdXrvm",nil,nil,
--1x --1x
"||pblendvbXrma",nil,nil,nil, "||pblendvbXrma",nil,nil,nil,
"||blendvpsXrma","||blendvpdXrma",nil,"||ptestXrm", "||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
nil,nil,nil,nil, "||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
"pabsbPrm","pabswPrm","pabsdPrm",nil, "pabsbPrm","pabswPrm","pabsdPrm",nil,
--2x --2x
"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm", "||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil, "||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
"||pmuldqXrm","||pcmpeqqXrm","||$movntdqaXrm","||packusdwXrm", "||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
nil,nil,nil,nil, "||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
--3x --3x
"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm", "||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
"||pmovzxwqXrm","||pmovzxdqXrm",nil,"||pcmpgtqXrm", "||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
"||pminsbXrm","||pminsdXrm","||pminuwXrm","||pminudXrm", "||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
"||pmaxsbXrm","||pmaxsdXrm","||pmaxuwXrm","||pmaxudXrm", "||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
--4x --4x
"||pmulddXrm","||phminposuwXrm", "||pmulddXrvm","||phminposuwXrm",nil,nil,
nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
--5x
[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
[0x5a] = "||broadcasti128XrlXm",
--7x
[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
--8x
[0x8c] = "||pmaskmovXrvVSm",
[0x8e] = "||pmaskmovVSmXvr",
--Fx --Fx
[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", [0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
}, },
["3a"] = { -- [66] 0f 3a xx ["3a"] = { -- [66] 0f 3a xx
--0x --0x
[0x00]=nil,nil,nil,nil,nil,nil,nil,nil, [0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
"||roundpsXrmu","||roundpdXrmu","||roundssXrmu","||roundsdXrmu", "||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
"||blendpsXrmu","||blendpdXrmu","||pblendwXrmu","palignrPrmu", "||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
--1x --1x
nil,nil,nil,nil, nil,nil,nil,nil,
"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru", "||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
nil,nil,nil,nil,nil,nil,nil,nil, "||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
nil,nil,nil,nil,
--2x --2x
"||pinsrbXrVmu","||insertpsXrmu","||pinsrXrVmuS",nil, "||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
--3x
[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
--4x --4x
[0x40] = "||dppsXrmu", [0x40] = "||dppsXrvmu",
[0x41] = "||dppdXrmu", [0x41] = "||dppdXrvmu",
[0x42] = "||mpsadbwXrmu", [0x42] = "||mpsadbwXrvmu",
[0x46] = "||perm2i128Xrvmu",
[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
[0x4c] = "||pblendvbXrvmb",
--6x --6x
[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", [0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", [0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
@ -354,17 +370,19 @@ local map_regs = {
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext! "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" }, "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
} }
local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
-- Maps for size names. -- Maps for size names.
local map_sz2n = { local map_sz2n = {
B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
} }
local map_sz2prefix = { local map_sz2prefix = {
B = "byte", W = "word", D = "dword", B = "byte", W = "word", D = "dword",
Q = "qword", Q = "qword",
M = "qword", X = "xword", M = "qword", X = "xword", Y = "yword",
F = "dword", G = "qword", -- No need for sizes/register names for these two. F = "dword", G = "qword", -- No need for sizes/register names for these two.
} }
@ -387,10 +405,13 @@ local function putop(ctx, text, operands)
if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
if ctx.rex then if ctx.rex then
local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "") (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
if t ~= "" then text = "rex."..t.." "..text end (ctx.vexl and "l" or "")
if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
if t ~= "" then text = ctx.rex.."."..t.." "..text
elseif ctx.rex == "vex" then text = "v"..text end
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false ctx.rex = false; ctx.vexl = false; ctx.vexv = false
end end
if ctx.seg then if ctx.seg then
local text2, n = gsub(text, "%[", "["..ctx.seg..":") local text2, n = gsub(text, "%[", "["..ctx.seg..":")
@ -405,6 +426,7 @@ local function putop(ctx, text, operands)
end end
ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text)) ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
ctx.mrm = false ctx.mrm = false
ctx.vexv = false
ctx.start = pos ctx.start = pos
ctx.imm = nil ctx.imm = nil
end end
@ -413,7 +435,7 @@ end
local function clearprefixes(ctx) local function clearprefixes(ctx)
ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false; ctx.a32 = false ctx.rex = false; ctx.a32 = false; ctx.vexl = false
end end
-- Fallback for incomplete opcodes at the end. -- Fallback for incomplete opcodes at the end.
@ -450,9 +472,9 @@ end
-- Process pattern string and generate the operands. -- Process pattern string and generate the operands.
local function putpat(ctx, name, pat) local function putpat(ctx, name, pat)
local operands, regs, sz, mode, sp, rm, sc, rx, sdisp local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
local code, pos, stop = ctx.code, ctx.pos, ctx.stop local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
-- Chars used: 1DFGIMPQRSTUVWXacdfgijmoprstuwxyz -- Chars used: 1DFGIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
for p in gmatch(pat, ".") do for p in gmatch(pat, ".") do
local x = nil local x = nil
if p == "V" or p == "U" then if p == "V" or p == "U" then
@ -467,11 +489,13 @@ local function putpat(ctx, name, pat)
elseif p == "B" then elseif p == "B" then
sz = "B" sz = "B"
regs = ctx.rex and map_regs.B64 or map_regs.B regs = ctx.rex and map_regs.B64 or map_regs.B
elseif match(p, "[WDQMXFG]") then elseif match(p, "[WDQMXYFG]") then
sz = p sz = p
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz] regs = map_regs[sz]
elseif p == "P" then elseif p == "P" then
sz = ctx.o16 and "X" or "M"; ctx.o16 = false sz = ctx.o16 and "X" or "M"; ctx.o16 = false
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz] regs = map_regs[sz]
elseif p == "S" then elseif p == "S" then
name = name..lower(sz) name = name..lower(sz)
@ -484,6 +508,10 @@ local function putpat(ctx, name, pat)
local imm = getimm(ctx, pos, 1); if not imm then return end local imm = getimm(ctx, pos, 1); if not imm then return end
x = format("0x%02x", imm) x = format("0x%02x", imm)
pos = pos+1 pos = pos+1
elseif p == "b" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = regs[imm/16+1]
pos = pos+1
elseif p == "w" then elseif p == "w" then
local imm = getimm(ctx, pos, 2); if not imm then return end local imm = getimm(ctx, pos, 2); if not imm then return end
x = format("0x%x", imm) x = format("0x%x", imm)
@ -616,8 +644,13 @@ local function putpat(ctx, name, pat)
else else
x = "CR"..sp x = "CR"..sp
end end
elseif p == "v" then
if ctx.vexv then
x = regs[ctx.vexv+1]; ctx.vexv = false
end
elseif p == "y" then x = "DR"..sp elseif p == "y" then x = "DR"..sp
elseif p == "z" then x = "TR"..sp elseif p == "z" then x = "TR"..sp
elseif p == "l" then vexl = false
elseif p == "t" then elseif p == "t" then
else else
error("bad pattern `"..pat.."'") error("bad pattern `"..pat.."'")
@ -692,7 +725,7 @@ map_act = {
B = putpat, W = putpat, D = putpat, Q = putpat, B = putpat, W = putpat, D = putpat, Q = putpat,
V = putpat, U = putpat, T = putpat, V = putpat, U = putpat, T = putpat,
M = putpat, X = putpat, P = putpat, M = putpat, X = putpat, P = putpat,
F = putpat, G = putpat, F = putpat, G = putpat, Y = putpat,
-- Collect prefixes. -- Collect prefixes.
[":"] = function(ctx, name, pat) [":"] = function(ctx, name, pat)
@ -753,15 +786,68 @@ map_act = {
-- REX prefix. -- REX prefix.
rex = function(ctx, name, pat) rex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX prefix allowed. if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
for p in gmatch(pat, ".") do ctx["rex"..p] = true end for p in gmatch(pat, ".") do ctx["rex"..p] = true end
ctx.rex = true ctx.rex = "rex"
end,
-- VEX prefix.
vex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
ctx.rex = "vex"
local pos = ctx.pos
if ctx.mrm then
ctx.mrm = nil
pos = pos-1
end
local b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b < 128 then ctx.rexr = true end
local m = 1
if pat == "3" then
m = b%32; b = (b-m)/32
local nb = b%2; b = (b-nb)/2
if nb == 0 then ctx.rexb = true end
local nx = b%2; b = (b-nx)/2
if nx == 0 then ctx.rexx = true end
b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b >= 128 then ctx.rexw = true end
end
ctx.pos = pos
local map
if m == 1 then map = map_opc2
elseif m == 2 then map = map_opc3["38"]
elseif m == 3 then map = map_opc3["3a"]
else return unknown(ctx) end
local p = b%4; b = (b-p)/4
if p == 1 then ctx.o16 = "o16"
elseif p == 2 then ctx.rep = "rep"
elseif p == 3 then ctx.rep = "repne" end
local l = b%2; b = (b-l)/2
if l ~= 0 then ctx.vexl = true end
ctx.vexv = (-1-b)%16
return dispatchmap(ctx, map)
end, end,
-- Special case for nop with REX prefix. -- Special case for nop with REX prefix.
nop = function(ctx, name, pat) nop = function(ctx, name, pat)
return dispatch(ctx, ctx.rex and pat or "nop") return dispatch(ctx, ctx.rex and pat or "nop")
end, end,
-- Special case for 0F 77.
emms = function(ctx, name, pat)
if ctx.rex ~= "vex" then
return putop(ctx, "emms")
elseif ctx.vexl then
ctx.vexl = false
return putop(ctx, "zeroall")
else
return putop(ctx, "zeroupper")
end
end,
} }
------------------------------------------------------------------------------ ------------------------------------------------------------------------------