aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jit/dis_x86.lua225
1 files changed, 155 insertions, 70 deletions
diff --git a/src/jit/dis_x86.lua b/src/jit/dis_x86.lua
index 6bc38066..49bbcad0 100644
--- a/src/jit/dis_x86.lua
+++ b/src/jit/dis_x86.lua
@@ -15,13 +15,12 @@
15-- Intel and AMD manuals. The supported instruction set is quite extensive 15-- Intel and AMD manuals. The supported instruction set is quite extensive
16-- and reflects what a current generation Intel or AMD CPU implements in 16-- and reflects what a current generation Intel or AMD CPU implements in
17-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3, 17-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
18-- SSE4.1, SSE4.2, SSE4a and even privileged and hypervisor (VMX/SVM) 18-- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor
19-- instructions. 19-- (VMX/SVM) instructions.
20-- 20--
21-- Notes: 21-- Notes:
22-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported. 22-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
23-- * No attempt at optimization has been made -- it's fast enough for my needs. 23-- * No attempt at optimization has been made -- it's fast enough for my needs.
24-- * The public API may change when more architectures are added.
25------------------------------------------------------------------------------ 24------------------------------------------------------------------------------
26 25
27local type = type 26local type = type
@@ -78,7 +77,7 @@ local map_opc1_32 = {
78"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", 77"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
79"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI", 78"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
80--Cx 79--Cx
81"shift!Bmu","shift!Vmu","retBw","ret","$lesVrm","$ldsVrm","movBmi","movVmi", 80"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
82"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS", 81"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
83--Dx 82--Dx
84"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", 83"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
@@ -103,7 +102,7 @@ local map_opc1_64 = setmetatable({
103 [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb", 102 [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
104 [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb", 103 [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
105 [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb", 104 [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
106 [0x82]=false, [0x9a]=false, [0xc4]=false, [0xc5]=false, [0xce]=false, 105 [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
107 [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false, 106 [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
108}, { __index = map_opc1_32 }) 107}, { __index = map_opc1_32 })
109 108
@@ -114,12 +113,12 @@ local map_opc2 = {
114[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret", 113[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
115"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu", 114"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
116--1x 115--1x
117"movupsXrm|movssXrm|movupdXrm|movsdXrm", 116"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
118"movupsXmr|movssXmr|movupdXmr|movsdXmr", 117"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
119"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", 118"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
120"movlpsXmr||movlpdXmr", 119"movlpsXmr||movlpdXmr",
121"unpcklpsXrm||unpcklpdXrm", 120"unpcklpsXrvm||unpcklpdXrvm",
122"unpckhpsXrm||unpckhpdXrm", 121"unpckhpsXrvm||unpckhpdXrvm",
123"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", 122"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
124"movhpsXmr||movhpdXmr", 123"movhpsXmr||movhpdXmr",
125"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", 124"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
@@ -128,7 +127,7 @@ local map_opc2 = {
128"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, 127"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
129"movapsXrm||movapdXrm", 128"movapsXrm||movapdXrm",
130"movapsXmr||movapdXmr", 129"movapsXmr||movapdXmr",
131"cvtpi2psXrMm|cvtsi2ssXrVmt|cvtpi2pdXrMm|cvtsi2sdXrVmt", 130"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
132"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr", 131"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
133"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm", 132"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
134"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm", 133"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
@@ -144,27 +143,27 @@ local map_opc2 = {
144"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", 143"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
145--5x 144--5x
146"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", 145"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
147"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm", 146"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
148"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm", 147"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
149"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm", 148"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
150"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm", 149"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
151"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm", 150"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
152"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", 151"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
153"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm", 152"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
154"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm", 153"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
155--6x 154--6x
156"punpcklbwPrm","punpcklwdPrm","punpckldqPrm","packsswbPrm", 155"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
157"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm", 156"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
158"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm", 157"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
159"||punpcklqdqXrm","||punpckhqdqXrm", 158"||punpcklqdqXrvm","||punpckhqdqXrvm",
160"movPrVSm","movqMrm|movdquXrm|movdqaXrm", 159"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
161--7x 160--7x
162"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu", 161"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu",
163"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu", 162"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
164"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|", 163"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
165"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$", 164"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
166nil,nil, 165nil,nil,
167"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm", 166"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
168"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr", 167"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
169--8x 168--8x
170"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", 169"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
@@ -182,27 +181,27 @@ nil,nil,
182"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt", 181"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
183--Cx 182--Cx
184"xaddBmr","xaddVmr", 183"xaddBmr","xaddVmr",
185"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","$movntiVmr|", 184"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
186"pinsrwPrWmu","pextrwDrPmu", 185"pinsrwPrvWmu","pextrwDrPmu",
187"shufpsXrmu||shufpdXrmu","$cmpxchg!Qmp", 186"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
188"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR", 187"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
189--Dx 188--Dx
190"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm", 189"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
191"paddqPrm","pmullwPrm", 190"paddqPrvm","pmullwPrvm",
192"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm", 191"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
193"psubusbPrm","psubuswPrm","pminubPrm","pandPrm", 192"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
194"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm", 193"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
195--Ex 194--Ex
196"pavgbPrm","psrawPrm","psradPrm","pavgwPrm", 195"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
197"pmulhuwPrm","pmulhwPrm", 196"pmulhuwPrvm","pmulhwPrvm",
198"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr", 197"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
199"psubsbPrm","psubswPrm","pminswPrm","porPrm", 198"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
200"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm", 199"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
201--Fx 200--Fx
202"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm", 201"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
203"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm$", 202"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
204"psubbPrm","psubwPrm","psubdPrm","psubqPrm", 203"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
205"paddbPrm","paddwPrm","padddPrm","ud", 204"paddbPrvm","paddwPrvm","padddPrvm","ud",
206} 205}
207assert(map_opc2[255] == "ud") 206assert(map_opc2[255] == "ud")
208 207
@@ -210,46 +209,62 @@ assert(map_opc2[255] == "ud")
210local map_opc3 = { 209local map_opc3 = {
211["38"] = { -- [66] 0f 38 xx 210["38"] = { -- [66] 0f 38 xx
212--0x 211--0x
213[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm", 212[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
214"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm", 213"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
215"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm", 214"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
216nil,nil,nil,nil, 215"||permilpsXrvm","||permilpdXrvm",nil,nil,
217--1x 216--1x
218"||pblendvbXrma",nil,nil,nil, 217"||pblendvbXrma",nil,nil,nil,
219"||blendvpsXrma","||blendvpdXrma",nil,"||ptestXrm", 218"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
220nil,nil,nil,nil, 219"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
221"pabsbPrm","pabswPrm","pabsdPrm",nil, 220"pabsbPrm","pabswPrm","pabsdPrm",nil,
222--2x 221--2x
223"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm", 222"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
224"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil, 223"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
225"||pmuldqXrm","||pcmpeqqXrm","||$movntdqaXrm","||packusdwXrm", 224"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
226nil,nil,nil,nil, 225"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
227--3x 226--3x
228"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm", 227"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
229"||pmovzxwqXrm","||pmovzxdqXrm",nil,"||pcmpgtqXrm", 228"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
230"||pminsbXrm","||pminsdXrm","||pminuwXrm","||pminudXrm", 229"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
231"||pmaxsbXrm","||pmaxsdXrm","||pmaxuwXrm","||pmaxudXrm", 230"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
232--4x 231--4x
233"||pmulddXrm","||phminposuwXrm", 232"||pmulddXrvm","||phminposuwXrm",nil,nil,
233nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
234--5x
235[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
236[0x5a] = "||broadcasti128XrlXm",
237--7x
238[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
239--8x
240[0x8c] = "||pmaskmovXrvVSm",
241[0x8e] = "||pmaskmovVSmXvr",
234--Fx 242--Fx
235[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", 243[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
236}, 244},
237 245
238["3a"] = { -- [66] 0f 3a xx 246["3a"] = { -- [66] 0f 3a xx
239--0x 247--0x
240[0x00]=nil,nil,nil,nil,nil,nil,nil,nil, 248[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
241"||roundpsXrmu","||roundpdXrmu","||roundssXrmu","||roundsdXrmu", 249"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
242"||blendpsXrmu","||blendpdXrmu","||pblendwXrmu","palignrPrmu", 250"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
251"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
243--1x 252--1x
244nil,nil,nil,nil, 253nil,nil,nil,nil,
245"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru", 254"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
246nil,nil,nil,nil,nil,nil,nil,nil, 255"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
256nil,nil,nil,nil,
247--2x 257--2x
248"||pinsrbXrVmu","||insertpsXrmu","||pinsrXrVmuS",nil, 258"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
259--3x
260[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
249--4x 261--4x
250[0x40] = "||dppsXrmu", 262[0x40] = "||dppsXrvmu",
251[0x41] = "||dppdXrmu", 263[0x41] = "||dppdXrvmu",
252[0x42] = "||mpsadbwXrmu", 264[0x42] = "||mpsadbwXrvmu",
265[0x46] = "||perm2i128Xrvmu",
266[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
267[0x4c] = "||pblendvbXrvmb",
253--6x 268--6x
254[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", 269[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
255[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", 270[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
@@ -356,17 +371,19 @@ local map_regs = {
356 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext! 371 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
357 X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 372 X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
358 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" }, 373 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
374 Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
375 "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
359} 376}
360local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } 377local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
361 378
362-- Maps for size names. 379-- Maps for size names.
363local map_sz2n = { 380local map_sz2n = {
364 B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, 381 B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
365} 382}
366local map_sz2prefix = { 383local map_sz2prefix = {
367 B = "byte", W = "word", D = "dword", 384 B = "byte", W = "word", D = "dword",
368 Q = "qword", 385 Q = "qword",
369 M = "qword", X = "xword", 386 M = "qword", X = "xword", Y = "yword",
370 F = "dword", G = "qword", -- No need for sizes/register names for these two. 387 F = "dword", G = "qword", -- No need for sizes/register names for these two.
371} 388}
372 389
@@ -389,10 +406,13 @@ local function putop(ctx, text, operands)
389 if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end 406 if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
390 if ctx.rex then 407 if ctx.rex then
391 local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. 408 local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
392 (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "") 409 (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
393 if t ~= "" then text = "rex."..t.." "..text end 410 (ctx.vexl and "l" or "")
411 if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
412 if t ~= "" then text = ctx.rex.."."..t.." "..text
413 elseif ctx.rex == "vex" then text = "v"..text end
394 ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false 414 ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
395 ctx.rex = false 415 ctx.rex = false; ctx.vexl = false; ctx.vexv = false
396 end 416 end
397 if ctx.seg then 417 if ctx.seg then
398 local text2, n = gsub(text, "%[", "["..ctx.seg..":") 418 local text2, n = gsub(text, "%[", "["..ctx.seg..":")
@@ -407,6 +427,7 @@ local function putop(ctx, text, operands)
407 end 427 end
408 ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text)) 428 ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
409 ctx.mrm = false 429 ctx.mrm = false
430 ctx.vexv = false
410 ctx.start = pos 431 ctx.start = pos
411 ctx.imm = nil 432 ctx.imm = nil
412end 433end
@@ -415,7 +436,7 @@ end
415local function clearprefixes(ctx) 436local function clearprefixes(ctx)
416 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false 437 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
417 ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false 438 ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
418 ctx.rex = false; ctx.a32 = false 439 ctx.rex = false; ctx.a32 = false; ctx.vexl = false
419end 440end
420 441
421-- Fallback for incomplete opcodes at the end. 442-- Fallback for incomplete opcodes at the end.
@@ -452,9 +473,9 @@ end
452-- Process pattern string and generate the operands. 473-- Process pattern string and generate the operands.
453local function putpat(ctx, name, pat) 474local function putpat(ctx, name, pat)
454 local operands, regs, sz, mode, sp, rm, sc, rx, sdisp 475 local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
455 local code, pos, stop = ctx.code, ctx.pos, ctx.stop 476 local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
456 477
457 -- Chars used: 1DFGIMPQRSTUVWXacdfgijmoprstuwxyz 478 -- Chars used: 1DFGIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
458 for p in gmatch(pat, ".") do 479 for p in gmatch(pat, ".") do
459 local x = nil 480 local x = nil
460 if p == "V" or p == "U" then 481 if p == "V" or p == "U" then
@@ -469,11 +490,13 @@ local function putpat(ctx, name, pat)
469 elseif p == "B" then 490 elseif p == "B" then
470 sz = "B" 491 sz = "B"
471 regs = ctx.rex and map_regs.B64 or map_regs.B 492 regs = ctx.rex and map_regs.B64 or map_regs.B
472 elseif match(p, "[WDQMXFG]") then 493 elseif match(p, "[WDQMXYFG]") then
473 sz = p 494 sz = p
495 if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
474 regs = map_regs[sz] 496 regs = map_regs[sz]
475 elseif p == "P" then 497 elseif p == "P" then
476 sz = ctx.o16 and "X" or "M"; ctx.o16 = false 498 sz = ctx.o16 and "X" or "M"; ctx.o16 = false
499 if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
477 regs = map_regs[sz] 500 regs = map_regs[sz]
478 elseif p == "S" then 501 elseif p == "S" then
479 name = name..lower(sz) 502 name = name..lower(sz)
@@ -486,6 +509,10 @@ local function putpat(ctx, name, pat)
486 local imm = getimm(ctx, pos, 1); if not imm then return end 509 local imm = getimm(ctx, pos, 1); if not imm then return end
487 x = format("0x%02x", imm) 510 x = format("0x%02x", imm)
488 pos = pos+1 511 pos = pos+1
512 elseif p == "b" then
513 local imm = getimm(ctx, pos, 1); if not imm then return end
514 x = regs[imm/16+1]
515 pos = pos+1
489 elseif p == "w" then 516 elseif p == "w" then
490 local imm = getimm(ctx, pos, 2); if not imm then return end 517 local imm = getimm(ctx, pos, 2); if not imm then return end
491 x = format("0x%x", imm) 518 x = format("0x%x", imm)
@@ -618,8 +645,13 @@ local function putpat(ctx, name, pat)
618 else 645 else
619 x = "CR"..sp 646 x = "CR"..sp
620 end 647 end
648 elseif p == "v" then
649 if ctx.vexv then
650 x = regs[ctx.vexv+1]; ctx.vexv = false
651 end
621 elseif p == "y" then x = "DR"..sp 652 elseif p == "y" then x = "DR"..sp
622 elseif p == "z" then x = "TR"..sp 653 elseif p == "z" then x = "TR"..sp
654 elseif p == "l" then vexl = false
623 elseif p == "t" then 655 elseif p == "t" then
624 else 656 else
625 error("bad pattern `"..pat.."'") 657 error("bad pattern `"..pat.."'")
@@ -694,7 +726,7 @@ map_act = {
694 B = putpat, W = putpat, D = putpat, Q = putpat, 726 B = putpat, W = putpat, D = putpat, Q = putpat,
695 V = putpat, U = putpat, T = putpat, 727 V = putpat, U = putpat, T = putpat,
696 M = putpat, X = putpat, P = putpat, 728 M = putpat, X = putpat, P = putpat,
697 F = putpat, G = putpat, 729 F = putpat, G = putpat, Y = putpat,
698 730
699 -- Collect prefixes. 731 -- Collect prefixes.
700 [":"] = function(ctx, name, pat) 732 [":"] = function(ctx, name, pat)
@@ -755,15 +787,68 @@ map_act = {
755 787
756 -- REX prefix. 788 -- REX prefix.
757 rex = function(ctx, name, pat) 789 rex = function(ctx, name, pat)
758 if ctx.rex then return unknown(ctx) end -- Only 1 REX prefix allowed. 790 if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
759 for p in gmatch(pat, ".") do ctx["rex"..p] = true end 791 for p in gmatch(pat, ".") do ctx["rex"..p] = true end
760 ctx.rex = true 792 ctx.rex = "rex"
793 end,
794
795 -- VEX prefix.
796 vex = function(ctx, name, pat)
797 if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
798 ctx.rex = "vex"
799 local pos = ctx.pos
800 if ctx.mrm then
801 ctx.mrm = nil
802 pos = pos-1
803 end
804 local b = byte(ctx.code, pos, pos)
805 if not b then return incomplete(ctx) end
806 pos = pos+1
807 if b < 128 then ctx.rexr = true end
808 local m = 1
809 if pat == "3" then
810 m = b%32; b = (b-m)/32
811 local nb = b%2; b = (b-nb)/2
812 if nb == 0 then ctx.rexb = true end
813 local nx = b%2; b = (b-nx)/2
814 if nx == 0 then ctx.rexx = true end
815 b = byte(ctx.code, pos, pos)
816 if not b then return incomplete(ctx) end
817 pos = pos+1
818 if b >= 128 then ctx.rexw = true end
819 end
820 ctx.pos = pos
821 local map
822 if m == 1 then map = map_opc2
823 elseif m == 2 then map = map_opc3["38"]
824 elseif m == 3 then map = map_opc3["3a"]
825 else return unknown(ctx) end
826 local p = b%4; b = (b-p)/4
827 if p == 1 then ctx.o16 = "o16"
828 elseif p == 2 then ctx.rep = "rep"
829 elseif p == 3 then ctx.rep = "repne" end
830 local l = b%2; b = (b-l)/2
831 if l ~= 0 then ctx.vexl = true end
832 ctx.vexv = (-1-b)%16
833 return dispatchmap(ctx, map)
761 end, 834 end,
762 835
763 -- Special case for nop with REX prefix. 836 -- Special case for nop with REX prefix.
764 nop = function(ctx, name, pat) 837 nop = function(ctx, name, pat)
765 return dispatch(ctx, ctx.rex and pat or "nop") 838 return dispatch(ctx, ctx.rex and pat or "nop")
766 end, 839 end,
840
841 -- Special case for 0F 77.
842 emms = function(ctx, name, pat)
843 if ctx.rex ~= "vex" then
844 return putop(ctx, "emms")
845 elseif ctx.vexl then
846 ctx.vexl = false
847 return putop(ctx, "zeroall")
848 else
849 return putop(ctx, "zeroupper")
850 end
851 end,
767} 852}
768 853
769------------------------------------------------------------------------------ 854------------------------------------------------------------------------------