mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
x86/x64: Support disassembly of VEX prefix and associated AVX/AVX2 instructions.
This commit is contained in:
parent
a9c9800367
commit
686194d12d
@ -76,7 +76,7 @@ local map_opc1_32 = {
|
||||
"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
|
||||
"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
|
||||
--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",
|
||||
--Dx
|
||||
"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",
|
||||
[0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
|
||||
[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,
|
||||
}, { __index = map_opc1_32 })
|
||||
|
||||
@ -112,12 +112,12 @@ local map_opc2 = {
|
||||
[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
|
||||
"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
|
||||
--1x
|
||||
"movupsXrm|movssXrm|movupdXrm|movsdXrm",
|
||||
"movupsXmr|movssXmr|movupdXmr|movsdXmr",
|
||||
"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
|
||||
"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
|
||||
"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
|
||||
"movlpsXmr||movlpdXmr",
|
||||
"unpcklpsXrm||unpcklpdXrm",
|
||||
"unpckhpsXrm||unpckhpdXrm",
|
||||
"unpcklpsXrvm||unpcklpdXrvm",
|
||||
"unpckhpsXrvm||unpckhpdXrvm",
|
||||
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
|
||||
"movhpsXmr||movhpdXmr",
|
||||
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
|
||||
@ -126,7 +126,7 @@ local map_opc2 = {
|
||||
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
|
||||
"movapsXrm||movapdXrm",
|
||||
"movapsXmr||movapdXmr",
|
||||
"cvtpi2psXrMm|cvtsi2ssXrVmt|cvtpi2pdXrMm|cvtsi2sdXrVmt",
|
||||
"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
|
||||
"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
|
||||
"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
|
||||
"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
|
||||
@ -142,27 +142,27 @@ local map_opc2 = {
|
||||
"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
|
||||
--5x
|
||||
"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
|
||||
"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm",
|
||||
"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm",
|
||||
"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm",
|
||||
"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm",
|
||||
"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm",
|
||||
"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
|
||||
"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
|
||||
"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
|
||||
"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
|
||||
"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
|
||||
"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
|
||||
"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
|
||||
"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
|
||||
"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
|
||||
"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
|
||||
--6x
|
||||
"punpcklbwPrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
|
||||
"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
|
||||
"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
|
||||
"||punpcklqdqXrm","||punpckhqdqXrm",
|
||||
"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
|
||||
"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
|
||||
"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
|
||||
"||punpcklqdqXrvm","||punpckhqdqXrvm",
|
||||
"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
|
||||
--7x
|
||||
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu",
|
||||
"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
|
||||
"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
|
||||
"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
|
||||
"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
|
||||
nil,nil,
|
||||
"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
|
||||
"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
|
||||
"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
|
||||
--8x
|
||||
"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
|
||||
@ -180,27 +180,27 @@ nil,nil,
|
||||
"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
|
||||
--Cx
|
||||
"xaddBmr","xaddVmr",
|
||||
"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","$movntiVmr|",
|
||||
"pinsrwPrWmu","pextrwDrPmu",
|
||||
"shufpsXrmu||shufpdXrmu","$cmpxchg!Qmp",
|
||||
"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
|
||||
"pinsrwPrvWmu","pextrwDrPmu",
|
||||
"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
|
||||
"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
|
||||
--Dx
|
||||
"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
|
||||
"paddqPrm","pmullwPrm",
|
||||
"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
|
||||
"paddqPrvm","pmullwPrvm",
|
||||
"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
|
||||
"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
|
||||
"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
|
||||
"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
|
||||
"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
|
||||
--Ex
|
||||
"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
|
||||
"pmulhuwPrm","pmulhwPrm",
|
||||
"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
|
||||
"pmulhuwPrvm","pmulhwPrvm",
|
||||
"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
|
||||
"psubsbPrm","psubswPrm","pminswPrm","porPrm",
|
||||
"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
|
||||
"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
|
||||
"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
|
||||
--Fx
|
||||
"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
|
||||
"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm$",
|
||||
"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
|
||||
"paddbPrm","paddwPrm","padddPrm","ud",
|
||||
"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
|
||||
"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
|
||||
"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
|
||||
"paddbPrvm","paddwPrvm","padddPrvm","ud",
|
||||
}
|
||||
assert(map_opc2[255] == "ud")
|
||||
|
||||
@ -208,46 +208,62 @@ assert(map_opc2[255] == "ud")
|
||||
local map_opc3 = {
|
||||
["38"] = { -- [66] 0f 38 xx
|
||||
--0x
|
||||
[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
|
||||
"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
|
||||
"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
|
||||
nil,nil,nil,nil,
|
||||
[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
|
||||
"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
|
||||
"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
|
||||
"||permilpsXrvm","||permilpdXrvm",nil,nil,
|
||||
--1x
|
||||
"||pblendvbXrma",nil,nil,nil,
|
||||
"||blendvpsXrma","||blendvpdXrma",nil,"||ptestXrm",
|
||||
nil,nil,nil,nil,
|
||||
"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
|
||||
"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
|
||||
"pabsbPrm","pabswPrm","pabsdPrm",nil,
|
||||
--2x
|
||||
"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
|
||||
"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
|
||||
"||pmuldqXrm","||pcmpeqqXrm","||$movntdqaXrm","||packusdwXrm",
|
||||
nil,nil,nil,nil,
|
||||
"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
|
||||
"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
|
||||
--3x
|
||||
"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
|
||||
"||pmovzxwqXrm","||pmovzxdqXrm",nil,"||pcmpgtqXrm",
|
||||
"||pminsbXrm","||pminsdXrm","||pminuwXrm","||pminudXrm",
|
||||
"||pmaxsbXrm","||pmaxsdXrm","||pmaxuwXrm","||pmaxudXrm",
|
||||
"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
|
||||
"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
|
||||
"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
|
||||
--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
|
||||
[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
|
||||
},
|
||||
|
||||
["3a"] = { -- [66] 0f 3a xx
|
||||
--0x
|
||||
[0x00]=nil,nil,nil,nil,nil,nil,nil,nil,
|
||||
"||roundpsXrmu","||roundpdXrmu","||roundssXrmu","||roundsdXrmu",
|
||||
"||blendpsXrmu","||blendpdXrmu","||pblendwXrmu","palignrPrmu",
|
||||
[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
|
||||
"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
|
||||
"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
|
||||
"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
|
||||
--1x
|
||||
nil,nil,nil,nil,
|
||||
"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
|
||||
nil,nil,nil,nil,nil,nil,nil,nil,
|
||||
"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
|
||||
nil,nil,nil,nil,
|
||||
--2x
|
||||
"||pinsrbXrVmu","||insertpsXrmu","||pinsrXrVmuS",nil,
|
||||
"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
|
||||
--3x
|
||||
[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
|
||||
--4x
|
||||
[0x40] = "||dppsXrmu",
|
||||
[0x41] = "||dppdXrmu",
|
||||
[0x42] = "||mpsadbwXrmu",
|
||||
[0x40] = "||dppsXrvmu",
|
||||
[0x41] = "||dppdXrvmu",
|
||||
[0x42] = "||mpsadbwXrvmu",
|
||||
[0x46] = "||perm2i128Xrvmu",
|
||||
[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
|
||||
[0x4c] = "||pblendvbXrvmb",
|
||||
--6x
|
||||
[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
|
||||
[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
|
||||
@ -354,17 +370,19 @@ local map_regs = {
|
||||
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
|
||||
X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"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" }
|
||||
|
||||
-- Maps for size names.
|
||||
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 = {
|
||||
B = "byte", W = "word", D = "dword",
|
||||
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.
|
||||
}
|
||||
|
||||
@ -387,10 +405,13 @@ local function putop(ctx, text, operands)
|
||||
if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
|
||||
if ctx.rex then
|
||||
local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
|
||||
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")
|
||||
if t ~= "" then text = "rex."..t.." "..text end
|
||||
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
|
||||
(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.rex = false
|
||||
ctx.rex = false; ctx.vexl = false; ctx.vexv = false
|
||||
end
|
||||
if ctx.seg then
|
||||
local text2, n = gsub(text, "%[", "["..ctx.seg..":")
|
||||
@ -405,6 +426,7 @@ local function putop(ctx, text, operands)
|
||||
end
|
||||
ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
|
||||
ctx.mrm = false
|
||||
ctx.vexv = false
|
||||
ctx.start = pos
|
||||
ctx.imm = nil
|
||||
end
|
||||
@ -413,7 +435,7 @@ end
|
||||
local function clearprefixes(ctx)
|
||||
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.rex = false; ctx.a32 = false
|
||||
ctx.rex = false; ctx.a32 = false; ctx.vexl = false
|
||||
end
|
||||
|
||||
-- Fallback for incomplete opcodes at the end.
|
||||
@ -450,9 +472,9 @@ end
|
||||
-- Process pattern string and generate the operands.
|
||||
local function putpat(ctx, name, pat)
|
||||
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
|
||||
local x = nil
|
||||
if p == "V" or p == "U" then
|
||||
@ -467,11 +489,13 @@ local function putpat(ctx, name, pat)
|
||||
elseif p == "B" then
|
||||
sz = "B"
|
||||
regs = ctx.rex and map_regs.B64 or map_regs.B
|
||||
elseif match(p, "[WDQMXFG]") then
|
||||
elseif match(p, "[WDQMXYFG]") then
|
||||
sz = p
|
||||
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
|
||||
regs = map_regs[sz]
|
||||
elseif p == "P" then
|
||||
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]
|
||||
elseif p == "S" then
|
||||
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
|
||||
x = format("0x%02x", imm)
|
||||
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
|
||||
local imm = getimm(ctx, pos, 2); if not imm then return end
|
||||
x = format("0x%x", imm)
|
||||
@ -616,8 +644,13 @@ local function putpat(ctx, name, pat)
|
||||
else
|
||||
x = "CR"..sp
|
||||
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 == "z" then x = "TR"..sp
|
||||
elseif p == "l" then vexl = false
|
||||
elseif p == "t" then
|
||||
else
|
||||
error("bad pattern `"..pat.."'")
|
||||
@ -692,7 +725,7 @@ map_act = {
|
||||
B = putpat, W = putpat, D = putpat, Q = putpat,
|
||||
V = putpat, U = putpat, T = putpat,
|
||||
M = putpat, X = putpat, P = putpat,
|
||||
F = putpat, G = putpat,
|
||||
F = putpat, G = putpat, Y = putpat,
|
||||
|
||||
-- Collect prefixes.
|
||||
[":"] = function(ctx, name, pat)
|
||||
@ -753,15 +786,68 @@ map_act = {
|
||||
|
||||
-- REX prefix.
|
||||
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
|
||||
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,
|
||||
|
||||
-- Special case for nop with REX prefix.
|
||||
nop = function(ctx, name, pat)
|
||||
return dispatch(ctx, ctx.rex and pat or "nop")
|
||||
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,
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user