1------------------------------------------------------------------------------
2-- DynASM x86/x64 module.
3--
4-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7
8local x64 = x64
9
10-- Module information:
11local _info = {
12  arch =	x64 and "x64" or "x86",
13  description =	"DynASM x86/x64 module",
14  version =	"1.4.0",
15  vernum =	 10400,
16  release =	"2015-10-18",
17  author =	"Mike Pall",
18  license =	"MIT",
19}
20
21-- Exported glue functions for the arch-specific module.
22local _M = { _info = _info }
23
24-- Cache library functions.
25local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
26local assert, unpack, setmetatable = assert, unpack or table.unpack, setmetatable
27local _s = string
28local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
29local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
30local concat, sort, remove = table.concat, table.sort, table.remove
31local bit = bit or require("bit")
32local band, bxor, shl, shr = bit.band, bit.bxor, bit.lshift, bit.rshift
33
34-- Inherited tables and callbacks.
35local g_opt, g_arch
36local wline, werror, wfatal, wwarn
37
38-- Action name list.
39-- CHECK: Keep this in sync with the C code!
40local action_names = {
41  -- int arg, 1 buffer pos:
42  "DISP",  "IMM_S", "IMM_B", "IMM_W", "IMM_D",  "IMM_WB", "IMM_DB",
43  -- action arg (1 byte), int arg, 1 buffer pos (reg/num):
44  "VREG", "SPACE",
45  -- ptrdiff_t arg, 1 buffer pos (address): !x64
46  "SETLABEL", "REL_A",
47  -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
48  "REL_LG", "REL_PC",
49  -- action arg (1 byte) or int arg, 1 buffer pos (link):
50  "IMM_LG", "IMM_PC",
51  -- action arg (1 byte) or int arg, 1 buffer pos (offset):
52  "LABEL_LG", "LABEL_PC",
53  -- action arg (1 byte), 1 buffer pos (offset):
54  "ALIGN",
55  -- action args (2 bytes), no buffer pos.
56  "EXTERN",
57  -- action arg (1 byte), no buffer pos.
58  "ESC",
59  -- no action arg, no buffer pos.
60  "MARK",
61  -- action arg (1 byte), no buffer pos, terminal action:
62  "SECTION",
63  -- no args, no buffer pos, terminal action:
64  "STOP"
65}
66
67-- Maximum number of section buffer positions for dasm_put().
68-- CHECK: Keep this in sync with the C code!
69local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
70
71-- Action name -> action number (dynamically generated below).
72local map_action = {}
73-- First action number. Everything below does not need to be escaped.
74local actfirst = 256-#action_names
75
76-- Action list buffer and string (only used to remove dupes).
77local actlist = {}
78local actstr = ""
79
80-- Argument list for next dasm_put(). Start with offset 0 into action list.
81local actargs = { 0 }
82
83-- Current number of section buffer positions for dasm_put().
84local secpos = 1
85
86-- VREG kind encodings, pre-shifted by 5 bits.
87local map_vreg = {
88  ["modrm.rm.m"] = 0x00,
89  ["modrm.rm.r"] = 0x20,
90  ["opcode"] =     0x20,
91  ["sib.base"] =   0x20,
92  ["sib.index"] =  0x40,
93  ["modrm.reg"] =  0x80,
94  ["vex.v"] =      0xa0,
95  ["imm.hi"] =     0xc0,
96}
97
98-- Current number of VREG actions contributing to REX/VEX shrinkage.
99local vreg_shrink_count = 0
100
101------------------------------------------------------------------------------
102
103-- Compute action numbers for action names.
104for n,name in ipairs(action_names) do
105  local num = actfirst + n - 1
106  map_action[name] = num
107end
108
109-- Dump action names and numbers.
110local function dumpactions(out)
111  out:write("DynASM encoding engine action codes:\n")
112  for n,name in ipairs(action_names) do
113    local num = map_action[name]
114    out:write(format("  %-10s %02X  %d\n", name, num, num))
115  end
116  out:write("\n")
117end
118
119-- Write action list buffer as a huge static C array.
120local function writeactions(out, name)
121  local nn = #actlist
122  local last = actlist[nn] or 255
123  actlist[nn] = nil -- Remove last byte.
124  if nn == 0 then nn = 1 end
125  out:write("static const unsigned char ", name, "[", nn, "] = {\n")
126  local s = "  "
127  for n,b in ipairs(actlist) do
128    s = s..b..","
129    if #s >= 75 then
130      assert(out:write(s, "\n"))
131      s = "  "
132    end
133  end
134  out:write(s, last, "\n};\n\n") -- Add last byte back.
135end
136
137------------------------------------------------------------------------------
138
139-- Add byte to action list.
140local function wputxb(n)
141  assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range")
142  actlist[#actlist+1] = n
143end
144
145-- Add action to list with optional arg. Advance buffer pos, too.
146local function waction(action, a, num)
147  wputxb(assert(map_action[action], "bad action name `"..action.."'"))
148  if a then actargs[#actargs+1] = a end
149  if a or num then secpos = secpos + (num or 1) end
150end
151
152-- Optionally add a VREG action.
153local function wvreg(kind, vreg, psz, sk, defer)
154  if not vreg then return end
155  waction("VREG", vreg)
156  local b = assert(map_vreg[kind], "bad vreg kind `"..vreg.."'")
157  if b < (sk or 0) then
158    vreg_shrink_count = vreg_shrink_count + 1
159  end
160  if not defer then
161    b = b + vreg_shrink_count * 8
162    vreg_shrink_count = 0
163  end
164  wputxb(b + (psz or 0))
165end
166
167-- Add call to embedded DynASM C code.
168local function wcall(func, args)
169  wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
170end
171
172-- Delete duplicate action list chunks. A tad slow, but so what.
173local function dedupechunk(offset)
174  local al, as = actlist, actstr
175  local chunk = char(unpack(al, offset+1, #al))
176  local orig = find(as, chunk, 1, true)
177  if orig then
178    actargs[1] = orig-1 -- Replace with original offset.
179    for i=offset+1,#al do al[i] = nil end -- Kill dupe.
180  else
181    actstr = as..chunk
182  end
183end
184
185-- Flush action list (intervening C code or buffer pos overflow).
186local function wflush(term)
187  local offset = actargs[1]
188  if #actlist == offset then return end -- Nothing to flush.
189  if not term then waction("STOP") end -- Terminate action list.
190  dedupechunk(offset)
191  wcall("put", actargs) -- Add call to dasm_put().
192  actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
193  secpos = 1 -- The actionlist offset occupies a buffer position, too.
194end
195
196-- Put escaped byte.
197local function wputb(n)
198  if n >= actfirst then waction("ESC") end -- Need to escape byte.
199  wputxb(n)
200end
201
202------------------------------------------------------------------------------
203
204-- Global label name -> global label number. With auto assignment on 1st use.
205local next_global = 10
206local map_global = setmetatable({}, { __index = function(t, name)
207  if not match(name, "^[%a_][%w_@]*$") then werror("bad global label") end
208  local n = next_global
209  if n > 246 then werror("too many global labels") end
210  next_global = n + 1
211  t[name] = n
212  return n
213end})
214
215-- Dump global labels.
216local function dumpglobals(out, lvl)
217  local t = {}
218  for name, n in pairs(map_global) do t[n] = name end
219  out:write("Global labels:\n")
220  for i=10,next_global-1 do
221    out:write(format("  %s\n", t[i]))
222  end
223  out:write("\n")
224end
225
226-- Write global label enum.
227local function writeglobals(out, prefix)
228  local t = {}
229  for name, n in pairs(map_global) do t[n] = name end
230  out:write("enum {\n")
231  for i=10,next_global-1 do
232    out:write("  ", prefix, gsub(t[i], "@.*", ""), ",\n")
233  end
234  out:write("  ", prefix, "_MAX\n};\n")
235end
236
237-- Write global label names.
238local function writeglobalnames(out, name)
239  local t = {}
240  for name, n in pairs(map_global) do t[n] = name end
241  out:write("static const char *const ", name, "[] = {\n")
242  for i=10,next_global-1 do
243    out:write("  \"", t[i], "\",\n")
244  end
245  out:write("  (const char *)0\n};\n")
246end
247
248------------------------------------------------------------------------------
249
250-- Extern label name -> extern label number. With auto assignment on 1st use.
251local next_extern = -1
252local map_extern = setmetatable({}, { __index = function(t, name)
253  -- No restrictions on the name for now.
254  local n = next_extern
255  if n < -256 then werror("too many extern labels") end
256  next_extern = n - 1
257  t[name] = n
258  return n
259end})
260
261-- Dump extern labels.
262local function dumpexterns(out, lvl)
263  local t = {}
264  for name, n in pairs(map_extern) do t[-n] = name end
265  out:write("Extern labels:\n")
266  for i=1,-next_extern-1 do
267    out:write(format("  %s\n", t[i]))
268  end
269  out:write("\n")
270end
271
272-- Write extern label names.
273local function writeexternnames(out, name)
274  local t = {}
275  for name, n in pairs(map_extern) do t[-n] = name end
276  out:write("static const char *const ", name, "[] = {\n")
277  for i=1,-next_extern-1 do
278    out:write("  \"", t[i], "\",\n")
279  end
280  out:write("  (const char *)0\n};\n")
281end
282
283------------------------------------------------------------------------------
284
285-- Arch-specific maps.
286local map_archdef = {}		-- Ext. register name -> int. name.
287local map_reg_rev = {}		-- Int. register name -> ext. name.
288local map_reg_num = {}		-- Int. register name -> register number.
289local map_reg_opsize = {}	-- Int. register name -> operand size.
290local map_reg_valid_base = {}	-- Int. register name -> valid base register?
291local map_reg_valid_index = {}	-- Int. register name -> valid index register?
292local map_reg_needrex = {}	-- Int. register name -> need rex vs. no rex.
293local reg_list = {}		-- Canonical list of int. register names.
294
295local map_type = {}		-- Type name -> { ctype, reg }
296local ctypenum = 0		-- Type number (for _PTx macros).
297
298local addrsize = x64 and "q" or "d"	-- Size for address operands.
299
300-- Helper functions to fill register maps.
301local function mkrmap(sz, cl, names)
302  local cname = format("@%s", sz)
303  reg_list[#reg_list+1] = cname
304  map_archdef[cl] = cname
305  map_reg_rev[cname] = cl
306  map_reg_num[cname] = -1
307  map_reg_opsize[cname] = sz
308  if sz == addrsize or sz == "d" then
309    map_reg_valid_base[cname] = true
310    map_reg_valid_index[cname] = true
311  end
312  if names then
313    for n,name in ipairs(names) do
314      local iname = format("@%s%x", sz, n-1)
315      reg_list[#reg_list+1] = iname
316      map_archdef[name] = iname
317      map_reg_rev[iname] = name
318      map_reg_num[iname] = n-1
319      map_reg_opsize[iname] = sz
320      if sz == "b" and n > 4 then map_reg_needrex[iname] = false end
321      if sz == addrsize or sz == "d" then
322	map_reg_valid_base[iname] = true
323	map_reg_valid_index[iname] = true
324      end
325    end
326  end
327  for i=0,(x64 and sz ~= "f") and 15 or 7 do
328    local needrex = sz == "b" and i > 3
329    local iname = format("@%s%x%s", sz, i, needrex and "R" or "")
330    if needrex then map_reg_needrex[iname] = true end
331    local name
332    if sz == "o" or sz == "y" then name = format("%s%d", cl, i)
333    elseif sz == "f" then name = format("st%d", i)
334    else name = format("r%d%s", i, sz == addrsize and "" or sz) end
335    map_archdef[name] = iname
336    if not map_reg_rev[iname] then
337      reg_list[#reg_list+1] = iname
338      map_reg_rev[iname] = name
339      map_reg_num[iname] = i
340      map_reg_opsize[iname] = sz
341      if sz == addrsize or sz == "d" then
342	map_reg_valid_base[iname] = true
343	map_reg_valid_index[iname] = true
344      end
345    end
346  end
347  reg_list[#reg_list+1] = ""
348end
349
350-- Integer registers (qword, dword, word and byte sized).
351if x64 then
352  mkrmap("q", "Rq", {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"})
353end
354mkrmap("d", "Rd", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"})
355mkrmap("w", "Rw", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
356mkrmap("b", "Rb", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
357map_reg_valid_index[map_archdef.esp] = false
358if x64 then map_reg_valid_index[map_archdef.rsp] = false end
359if x64 then map_reg_needrex[map_archdef.Rb] = true end
360map_archdef["Ra"] = "@"..addrsize
361
362-- FP registers (internally tword sized, but use "f" as operand size).
363mkrmap("f", "Rf")
364
365-- SSE registers (oword sized, but qword and dword accessible).
366mkrmap("o", "xmm")
367
368-- AVX registers (yword sized, but oword, qword and dword accessible).
369mkrmap("y", "ymm")
370
371-- Operand size prefixes to codes.
372local map_opsize = {
373  byte = "b", word = "w", dword = "d", qword = "q", oword = "o", yword = "y",
374  tword = "t", aword = addrsize,
375}
376
377-- Operand size code to number.
378local map_opsizenum = {
379  b = 1, w = 2, d = 4, q = 8, o = 16, y = 32, t = 10,
380}
381
382-- Operand size code to name.
383local map_opsizename = {
384  b = "byte", w = "word", d = "dword", q = "qword", o = "oword", y = "yword",
385  t = "tword", f = "fpword",
386}
387
388-- Valid index register scale factors.
389local map_xsc = {
390  ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3,
391}
392
393-- Condition codes.
394local map_cc = {
395  o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,
396  s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,
397  c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,
398  pe = 10, po = 11, nge = 12, ge = 13, ng = 14, g = 15,
399}
400
401
402-- Reverse defines for registers.
403function _M.revdef(s)
404  return gsub(s, "@%w+", map_reg_rev)
405end
406
407-- Dump register names and numbers
408local function dumpregs(out)
409  out:write("Register names, sizes and internal numbers:\n")
410  for _,reg in ipairs(reg_list) do
411    if reg == "" then
412      out:write("\n")
413    else
414      local name = map_reg_rev[reg]
415      local num = map_reg_num[reg]
416      local opsize = map_opsizename[map_reg_opsize[reg]]
417      out:write(format("  %-5s %-8s %s\n", name, opsize,
418		       num < 0 and "(variable)" or num))
419    end
420  end
421end
422
423------------------------------------------------------------------------------
424
425-- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).
426local function wputlabel(aprefix, imm, num)
427  if type(imm) == "number" then
428    if imm < 0 then
429      waction("EXTERN")
430      wputxb(aprefix == "IMM_" and 0 or 1)
431      imm = -imm-1
432    else
433      waction(aprefix.."LG", nil, num);
434    end
435    wputxb(imm)
436  else
437    waction(aprefix.."PC", imm, num)
438  end
439end
440
441-- Put signed byte or arg.
442local function wputsbarg(n)
443  if type(n) == "number" then
444    if n < -128 or n > 127 then
445      werror("signed immediate byte out of range")
446    end
447    if n < 0 then n = n + 256 end
448    wputb(n)
449  else waction("IMM_S", n) end
450end
451
452-- Put unsigned byte or arg.
453local function wputbarg(n)
454  if type(n) == "number" then
455    if n < 0 or n > 255 then
456      werror("unsigned immediate byte out of range")
457    end
458    wputb(n)
459  else waction("IMM_B", n) end
460end
461
462-- Put unsigned word or arg.
463local function wputwarg(n)
464  if type(n) == "number" then
465    if shr(n, 16) ~= 0 then
466      werror("unsigned immediate word out of range")
467    end
468    wputb(band(n, 255)); wputb(shr(n, 8));
469  else waction("IMM_W", n) end
470end
471
472-- Put signed or unsigned dword or arg.
473local function wputdarg(n)
474  local tn = type(n)
475  if tn == "number" then
476    wputb(band(n, 255))
477    wputb(band(shr(n, 8), 255))
478    wputb(band(shr(n, 16), 255))
479    wputb(shr(n, 24))
480  elseif tn == "table" then
481    wputlabel("IMM_", n[1], 1)
482  else
483    waction("IMM_D", n)
484  end
485end
486
487-- Put operand-size dependent number or arg (defaults to dword).
488local function wputszarg(sz, n)
489  if not sz or sz == "d" or sz == "q" then wputdarg(n)
490  elseif sz == "w" then wputwarg(n)
491  elseif sz == "b" then wputbarg(n)
492  elseif sz == "s" then wputsbarg(n)
493  else werror("bad operand size") end
494end
495
496-- Put multi-byte opcode with operand-size dependent modifications.
497local function wputop(sz, op, rex, vex, vregr, vregxb)
498  local psz, sk = 0, nil
499  if vex then
500    local tail
501    if vex.m == 1 and band(rex, 11) == 0 then
502      if x64 and vregxb then
503	sk = map_vreg["modrm.reg"]
504      else
505	wputb(0xc5)
506      tail = shl(bxor(band(rex, 4), 4), 5)
507      psz = 3
508      end
509    end
510    if not tail then
511      wputb(0xc4)
512      wputb(shl(bxor(band(rex, 7), 7), 5) + vex.m)
513      tail = shl(band(rex, 8), 4)
514      psz = 4
515    end
516    local reg, vreg = 0, nil
517    if vex.v then
518      reg = vex.v.reg
519      if not reg then werror("bad vex operand") end
520      if reg < 0 then reg = 0; vreg = vex.v.vreg end
521    end
522    if sz == "y" or vex.l then tail = tail + 4 end
523    wputb(tail + shl(bxor(reg, 15), 3) + vex.p)
524    wvreg("vex.v", vreg)
525    rex = 0
526    if op >= 256 then werror("bad vex opcode") end
527  else
528    if rex ~= 0 then
529      if not x64 then werror("bad operand size") end
530    elseif (vregr or vregxb) and x64 then
531      rex = 0x10
532      sk = map_vreg["vex.v"]
533    end
534  end
535  local r
536  if sz == "w" then wputb(102) end
537  -- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
538  if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
539  if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end
540  if op >= 65536 then
541    if rex ~= 0 then
542      local opc3 = band(op, 0xffff00)
543      if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
544	wputb(64 + band(rex, 15)); rex = 0; psz = 2
545      end
546    end
547    wputb(shr(op, 16)); op = band(op, 0xffff); psz = psz + 1
548  end
549  if op >= 256 then
550    local b = shr(op, 8)
551    if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0; psz = 2 end
552    wputb(b); op = band(op, 255); psz = psz + 1
553  end
554  if rex ~= 0 then wputb(64 + band(rex, 15)); psz = 2 end
555  if sz == "b" then op = op - 1 end
556  wputb(op)
557  return psz, sk
558end
559
560-- Put ModRM or SIB formatted byte.
561local function wputmodrm(m, s, rm, vs, vrm)
562  assert(m < 4 and s < 16 and rm < 16, "bad modrm operands")
563  wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7))
564end
565
566-- Put ModRM/SIB plus optional displacement.
567local function wputmrmsib(t, imark, s, vsreg, psz, sk)
568  local vreg, vxreg
569  local reg, xreg = t.reg, t.xreg
570  if reg and reg < 0 then reg = 0; vreg = t.vreg end
571  if xreg and xreg < 0 then xreg = 0; vxreg = t.vxreg end
572  if s < 0 then s = 0 end
573
574  -- Register mode.
575  if sub(t.mode, 1, 1) == "r" then
576    wputmodrm(3, s, reg)
577    wvreg("modrm.reg", vsreg, psz+1, sk, vreg)
578    wvreg("modrm.rm.r", vreg, psz+1, sk)
579    return
580  end
581
582  local disp = t.disp
583  local tdisp = type(disp)
584  -- No base register?
585  if not reg then
586    local riprel = false
587    if xreg then
588      -- Indexed mode with index register only.
589      -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
590      wputmodrm(0, s, 4)
591      if imark == "I" then waction("MARK") end
592      wvreg("modrm.reg", vsreg, psz+1, sk, vxreg)
593      wputmodrm(t.xsc, xreg, 5)
594      wvreg("sib.index", vxreg, psz+2, sk)
595    else
596      -- Pure 32 bit displacement.
597      if x64 and tdisp ~= "table" then
598	wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
599	wvreg("modrm.reg", vsreg, psz+1, sk)
600	if imark == "I" then waction("MARK") end
601	wputmodrm(0, 4, 5)
602      else
603	riprel = x64
604	wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
605	wvreg("modrm.reg", vsreg, psz+1, sk)
606	if imark == "I" then waction("MARK") end
607      end
608    end
609    if riprel then -- Emit rip-relative displacement.
610      if match("UWSiI", imark) then
611	werror("NYI: rip-relative displacement followed by immediate")
612      end
613      -- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
614      wputlabel("REL_", disp[1], 2)
615    else
616      wputdarg(disp)
617    end
618    return
619  end
620
621  local m
622  if tdisp == "number" then -- Check displacement size at assembly time.
623    if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
624      if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]
625    elseif disp >= -128 and disp <= 127 then m = 1
626    else m = 2 end
627  elseif tdisp == "table" then
628    m = 2
629  end
630
631  -- Index register present or esp as base register: need SIB encoding.
632  if xreg or band(reg, 7) == 4 then
633    wputmodrm(m or 2, s, 4) -- ModRM.
634    if m == nil or imark == "I" then waction("MARK") end
635    wvreg("modrm.reg", vsreg, psz+1, sk, vxreg or vreg)
636    wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
637    wvreg("sib.index", vxreg, psz+2, sk, vreg)
638    wvreg("sib.base", vreg, psz+2, sk)
639  else
640    wputmodrm(m or 2, s, reg) -- ModRM.
641    if (imark == "I" and (m == 1 or m == 2)) or
642       (m == nil and (vsreg or vreg)) then waction("MARK") end
643    wvreg("modrm.reg", vsreg, psz+1, sk, vreg)
644    wvreg("modrm.rm.m", vreg, psz+1, sk)
645  end
646
647  -- Put displacement.
648  if m == 1 then wputsbarg(disp)
649  elseif m == 2 then wputdarg(disp)
650  elseif m == nil then waction("DISP", disp) end
651end
652
653------------------------------------------------------------------------------
654
655-- Return human-readable operand mode string.
656local function opmodestr(op, args)
657  local m = {}
658  for i=1,#args do
659    local a = args[i]
660    m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")
661  end
662  return op.." "..concat(m, ",")
663end
664
665-- Convert number to valid integer or nil.
666local function toint(expr)
667  local n = tonumber(expr)
668  if n then
669    if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
670      werror("bad integer number `"..expr.."'")
671    end
672    return n
673  end
674end
675
676-- Parse immediate expression.
677local function immexpr(expr)
678  -- &expr (pointer)
679  if sub(expr, 1, 1) == "&" then
680    return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))
681  end
682
683  local prefix = sub(expr, 1, 2)
684  -- =>expr (pc label reference)
685  if prefix == "=>" then
686    return "iJ", sub(expr, 3)
687  end
688  -- ->name (global label reference)
689  if prefix == "->" then
690    return "iJ", map_global[sub(expr, 3)]
691  end
692
693  -- [<>][1-9] (local label reference)
694  local dir, lnum = match(expr, "^([<>])([1-9])$")
695  if dir then -- Fwd: 247-255, Bkwd: 1-9.
696    return "iJ", lnum + (dir == ">" and 246 or 0)
697  end
698
699  local extname = match(expr, "^extern%s+(%S+)$")
700  if extname then
701    return "iJ", map_extern[extname]
702  end
703
704  -- expr (interpreted as immediate)
705  return "iI", expr
706end
707
708-- Parse displacement expression: +-num, +-expr, +-opsize*num
709local function dispexpr(expr)
710  local disp = expr == "" and 0 or toint(expr)
711  if disp then return disp end
712  local c, dispt = match(expr, "^([+-])%s*(.+)$")
713  if c == "+" then
714    expr = dispt
715  elseif not c then
716    werror("bad displacement expression `"..expr.."'")
717  end
718  local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")
719  local ops, imm = map_opsize[opsize], toint(tailops)
720  if ops and imm then
721    if c == "-" then imm = -imm end
722    return imm*map_opsizenum[ops]
723  end
724  local mode, iexpr = immexpr(dispt)
725  if mode == "iJ" then
726    if c == "-" then werror("cannot invert label reference") end
727    return { iexpr }
728  end
729  return expr -- Need to return original signed expression.
730end
731
732-- Parse register or type expression.
733local function rtexpr(expr)
734  if not expr then return end
735  local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")
736  local tp = map_type[tname or expr]
737  if tp then
738    local reg = ovreg or tp.reg
739    local rnum = map_reg_num[reg]
740    if not rnum then
741      werror("type `"..(tname or expr).."' needs a register override")
742    end
743    if not map_reg_valid_base[reg] then
744      werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")
745    end
746    return reg, rnum, tp
747  end
748  return expr, map_reg_num[expr]
749end
750
751-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
752local function parseoperand(param)
753  local t = {}
754
755  local expr = param
756  local opsize, tailops = match(param, "^(%w+)%s*(.+)$")
757  if opsize then
758    t.opsize = map_opsize[opsize]
759    if t.opsize then expr = tailops end
760  end
761
762  local br = match(expr, "^%[%s*(.-)%s*%]$")
763  repeat
764    if br then
765      t.mode = "xm"
766
767      -- [disp]
768      t.disp = toint(br)
769      if t.disp then
770	t.mode = x64 and "xm" or "xmO"
771	break
772      end
773
774      -- [reg...]
775      local tp
776      local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")
777      reg, t.reg, tp = rtexpr(reg)
778      if not t.reg then
779	-- [expr]
780	t.mode = x64 and "xm" or "xmO"
781	t.disp = dispexpr("+"..br)
782	break
783      end
784
785      if t.reg == -1 then
786	t.vreg, tailr = match(tailr, "^(%b())(.*)$")
787	if not t.vreg then werror("bad variable register expression") end
788      end
789
790      -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]
791      local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")
792      if xsc then
793	if not map_reg_valid_index[reg] then
794	  werror("bad index register `"..map_reg_rev[reg].."'")
795	end
796	t.xsc = map_xsc[xsc]
797	t.xreg = t.reg
798	t.vxreg = t.vreg
799	t.reg = nil
800	t.vreg = nil
801	t.disp = dispexpr(tailsc)
802	break
803      end
804      if not map_reg_valid_base[reg] then
805	werror("bad base register `"..map_reg_rev[reg].."'")
806      end
807
808      -- [reg] or [reg+-disp]
809      t.disp = toint(tailr) or (tailr == "" and 0)
810      if t.disp then break end
811
812      -- [reg+xreg...]
813      local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
814      xreg, t.xreg, tp = rtexpr(xreg)
815      if not t.xreg then
816	-- [reg+-expr]
817	t.disp = dispexpr(tailr)
818	break
819      end
820      if not map_reg_valid_index[xreg] then
821	werror("bad index register `"..map_reg_rev[xreg].."'")
822      end
823
824      if t.xreg == -1 then
825	t.vxreg, tailx = match(tailx, "^(%b())(.*)$")
826	if not t.vxreg then werror("bad variable register expression") end
827      end
828
829      -- [reg+xreg*xsc...]
830      local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")
831      if xsc then
832	t.xsc = map_xsc[xsc]
833	tailx = tailsc
834      end
835
836      -- [...] or [...+-disp] or [...+-expr]
837      t.disp = dispexpr(tailx)
838    else
839      -- imm or opsize*imm
840      local imm = toint(expr)
841      if not imm and sub(expr, 1, 1) == "*" and t.opsize then
842	imm = toint(sub(expr, 2))
843	if imm then
844	  imm = imm * map_opsizenum[t.opsize]
845	  t.opsize = nil
846	end
847      end
848      if imm then
849	if t.opsize then werror("bad operand size override") end
850	local m = "i"
851	if imm == 1 then m = m.."1" end
852	if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end
853	if imm >= -128 and imm <= 127 then m = m.."S" end
854	t.imm = imm
855	t.mode = m
856	break
857      end
858
859      local tp
860      local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")
861      reg, t.reg, tp = rtexpr(reg)
862      if t.reg then
863	if t.reg == -1 then
864	  t.vreg, tailr = match(tailr, "^(%b())(.*)$")
865	  if not t.vreg then werror("bad variable register expression") end
866	end
867	-- reg
868	if tailr == "" then
869	  if t.opsize then werror("bad operand size override") end
870	  t.opsize = map_reg_opsize[reg]
871	  if t.opsize == "f" then
872	    t.mode = t.reg == 0 and "fF" or "f"
873	  else
874	    if reg == "@w4" or (x64 and reg == "@d4") then
875	      wwarn("bad idea, try again with `"..(x64 and "rsp'" or "esp'"))
876	    end
877	    t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")
878	  end
879	  t.needrex = map_reg_needrex[reg]
880	  break
881	end
882
883	-- type[idx], type[idx].field, type->field -> [reg+offset_expr]
884	if not tp then werror("bad operand `"..param.."'") end
885	t.mode = "xm"
886	t.disp = format(tp.ctypefmt, tailr)
887      else
888	t.mode, t.imm = immexpr(expr)
889	if sub(t.mode, -1) == "J" then
890	  if t.opsize and t.opsize ~= addrsize then
891	    werror("bad operand size override")
892	  end
893	  t.opsize = addrsize
894	end
895      end
896    end
897  until true
898  return t
899end
900
901------------------------------------------------------------------------------
902-- x86 Template String Description
903-- ===============================
904--
905-- Each template string is a list of [match:]pattern pairs,
906-- separated by "|". The first match wins. No match means a
907-- bad or unsupported combination of operand modes or sizes.
908--
909-- The match part and the ":" is omitted if the operation has
910-- no operands. Otherwise the first N characters are matched
911-- against the mode strings of each of the N operands.
912--
913-- The mode string for each operand type is (see parseoperand()):
914--   Integer register: "rm", +"R" for eax, ax, al, +"C" for cl
915--   FP register:      "f",  +"F" for st0
916--   Index operand:    "xm", +"O" for [disp] (pure offset)
917--   Immediate:        "i",  +"S" for signed 8 bit, +"1" for 1,
918--                     +"I" for arg, +"P" for pointer
919--   Any:              +"J" for valid jump targets
920--
921-- So a match character "m" (mixed) matches both an integer register
922-- and an index operand (to be encoded with the ModRM/SIB scheme).
923-- But "r" matches only a register and "x" only an index operand
924-- (e.g. for FP memory access operations).
925--
926-- The operand size match string starts right after the mode match
927-- characters and ends before the ":". "dwb" or "qdwb" is assumed, if empty.
928-- The effective data size of the operation is matched against this list.
929--
930-- If only the regular "b", "w", "d", "q", "t" operand sizes are
931-- present, then all operands must be the same size. Unspecified sizes
932-- are ignored, but at least one operand must have a size or the pattern
933-- won't match (use the "byte", "word", "dword", "qword", "tword"
934-- operand size overrides. E.g.: mov dword [eax], 1).
935--
936-- If the list has a "1" or "2" prefix, the operand size is taken
937-- from the respective operand and any other operand sizes are ignored.
938-- If the list contains only ".", all operand sizes are ignored.
939-- If the list has a "/" prefix, the concatenated (mixed) operand sizes
940-- are compared to the match.
941--
942-- E.g. "rrdw" matches for either two dword registers or two word
943-- registers. "Fx2dq" matches an st0 operand plus an index operand
944-- pointing to a dword (float) or qword (double).
945--
946-- Every character after the ":" is part of the pattern string:
947--   Hex chars are accumulated to form the opcode (left to right).
948--   "n"       disables the standard opcode mods
949--             (otherwise: -1 for "b", o16 prefix for "w", rex.w for "q")
950--   "X"       Force REX.W.
951--   "r"/"R"   adds the reg. number from the 1st/2nd operand to the opcode.
952--   "m"/"M"   generates ModRM/SIB from the 1st/2nd operand.
953--             The spare 3 bits are either filled with the last hex digit or
954--             the result from a previous "r"/"R". The opcode is restored.
955--   "u"       Use VEX encoding, vvvv unused.
956--   "v"/"V"   Use VEX encoding, vvvv from 1st/2nd operand (the operand is
957--             removed from the list used by future characters).
958--   "w"       Use VEX encoding, vvvv from 3rd operand.
959--   "L"       Force VEX.L
960--
961-- All of the following characters force a flush of the opcode:
962--   "o"/"O"   stores a pure 32 bit disp (offset) from the 1st/2nd operand.
963--   "s"       stores a 4 bit immediate from the last register operand,
964--             followed by 4 zero bits.
965--   "S"       stores a signed 8 bit immediate from the last operand.
966--   "U"       stores an unsigned 8 bit immediate from the last operand.
967--   "W"       stores an unsigned 16 bit immediate from the last operand.
968--   "i"       stores an operand sized immediate from the last operand.
969--   "I"       dito, but generates an action code to optionally modify
970--             the opcode (+2) for a signed 8 bit immediate.
971--   "J"       generates one of the REL action codes from the last operand.
972--
973------------------------------------------------------------------------------
974
975-- Template strings for x86 instructions. Ordered by first opcode byte.
976-- Unimplemented opcodes (deliberate omissions) are marked with *.
977local map_op = {
978  -- 00-05: add...
979  -- 06: *push es
980  -- 07: *pop es
981  -- 08-0D: or...
982  -- 0E: *push cs
983  -- 0F: two byte opcode prefix
984  -- 10-15: adc...
985  -- 16: *push ss
986  -- 17: *pop ss
987  -- 18-1D: sbb...
988  -- 1E: *push ds
989  -- 1F: *pop ds
990  -- 20-25: and...
991  es_0 =	"26",
992  -- 27: *daa
993  -- 28-2D: sub...
994  cs_0 =	"2E",
995  -- 2F: *das
996  -- 30-35: xor...
997  ss_0 =	"36",
998  -- 37: *aaa
999  -- 38-3D: cmp...
1000  ds_0 =	"3E",
1001  -- 3F: *aas
1002  inc_1 =	x64 and "m:FF0m" or "rdw:40r|m:FF0m",
1003  dec_1 =	x64 and "m:FF1m" or "rdw:48r|m:FF1m",
1004  push_1 =	(x64 and "rq:n50r|rw:50r|mq:nFF6m|mw:FF6m" or
1005			 "rdw:50r|mdw:FF6m").."|S.:6AS|ib:n6Ai|i.:68i",
1006  pop_1 =	x64 and "rq:n58r|rw:58r|mq:n8F0m|mw:8F0m" or "rdw:58r|mdw:8F0m",
1007  -- 60: *pusha, *pushad, *pushaw
1008  -- 61: *popa, *popad, *popaw
1009  -- 62: *bound rdw,x
1010  -- 63: x86: *arpl mw,rw
1011  movsxd_2 =	x64 and "rm/qd:63rM",
1012  fs_0 =	"64",
1013  gs_0 =	"65",
1014  o16_0 =	"66",
1015  a16_0 =	not x64 and "67" or nil,
1016  a32_0 =	x64 and "67",
1017  -- 68: push idw
1018  -- 69: imul rdw,mdw,idw
1019  -- 6A: push ib
1020  -- 6B: imul rdw,mdw,S
1021  -- 6C: *insb
1022  -- 6D: *insd, *insw
1023  -- 6E: *outsb
1024  -- 6F: *outsd, *outsw
1025  -- 70-7F: jcc lb
1026  -- 80: add... mb,i
1027  -- 81: add... mdw,i
1028  -- 82: *undefined
1029  -- 83: add... mdw,S
1030  test_2 =	"mr:85Rm|rm:85rM|Ri:A9ri|mi:F70mi",
1031  -- 86: xchg rb,mb
1032  -- 87: xchg rdw,mdw
1033  -- 88: mov mb,r
1034  -- 89: mov mdw,r
1035  -- 8A: mov r,mb
1036  -- 8B: mov r,mdw
1037  -- 8C: *mov mdw,seg
1038  lea_2 =	"rx1dq:8DrM",
1039  -- 8E: *mov seg,mdw
1040  -- 8F: pop mdw
1041  nop_0 =	"90",
1042  xchg_2 =	"Rrqdw:90R|rRqdw:90r|rm:87rM|mr:87Rm",
1043  cbw_0 =	"6698",
1044  cwde_0 =	"98",
1045  cdqe_0 =	"4898",
1046  cwd_0 =	"6699",
1047  cdq_0 =	"99",
1048  cqo_0 =	"4899",
1049  -- 9A: *call iw:idw
1050  wait_0 =	"9B",
1051  fwait_0 =	"9B",
1052  pushf_0 =	"9C",
1053  pushfd_0 =	not x64 and "9C",
1054  pushfq_0 =	x64 and "9C",
1055  popf_0 =	"9D",
1056  popfd_0 =	not x64 and "9D",
1057  popfq_0 =	x64 and "9D",
1058  sahf_0 =	"9E",
1059  lahf_0 =	"9F",
1060  mov_2 =	"OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi",
1061  movsb_0 =	"A4",
1062  movsw_0 =	"66A5",
1063  movsd_0 =	"A5",
1064  cmpsb_0 =	"A6",
1065  cmpsw_0 =	"66A7",
1066  cmpsd_0 =	"A7",
1067  -- A8: test Rb,i
1068  -- A9: test Rdw,i
1069  stosb_0 =	"AA",
1070  stosw_0 =	"66AB",
1071  stosd_0 =	"AB",
1072  lodsb_0 =	"AC",
1073  lodsw_0 =	"66AD",
1074  lodsd_0 =	"AD",
1075  scasb_0 =	"AE",
1076  scasw_0 =	"66AF",
1077  scasd_0 =	"AF",
1078  -- B0-B7: mov rb,i
1079  -- B8-BF: mov rdw,i
1080  -- C0: rol... mb,i
1081  -- C1: rol... mdw,i
1082  ret_1 =	"i.:nC2W",
1083  ret_0 =	"C3",
1084  -- C4: *les rdw,mq
1085  -- C5: *lds rdw,mq
1086  -- C6: mov mb,i
1087  -- C7: mov mdw,i
1088  -- C8: *enter iw,ib
1089  leave_0 =	"C9",
1090  -- CA: *retf iw
1091  -- CB: *retf
1092  int3_0 =	"CC",
1093  int_1 =	"i.:nCDU",
1094  into_0 =	"CE",
1095  -- CF: *iret
1096  -- D0: rol... mb,1
1097  -- D1: rol... mdw,1
1098  -- D2: rol... mb,cl
1099  -- D3: rol... mb,cl
1100  -- D4: *aam ib
1101  -- D5: *aad ib
1102  -- D6: *salc
1103  -- D7: *xlat
1104  -- D8-DF: floating point ops
1105  -- E0: *loopne
1106  -- E1: *loope
1107  -- E2: *loop
1108  -- E3: *jcxz, *jecxz
1109  -- E4: *in Rb,ib
1110  -- E5: *in Rdw,ib
1111  -- E6: *out ib,Rb
1112  -- E7: *out ib,Rdw
1113  call_1 =	x64 and "mq:nFF2m|J.:E8nJ" or "md:FF2m|J.:E8J",
1114  jmp_1 =	x64 and "mq:nFF4m|J.:E9nJ" or "md:FF4m|J.:E9J", -- short: EB
1115  -- EA: *jmp iw:idw
1116  -- EB: jmp ib
1117  -- EC: *in Rb,dx
1118  -- ED: *in Rdw,dx
1119  -- EE: *out dx,Rb
1120  -- EF: *out dx,Rdw
1121  lock_0 =	"F0",
1122  int1_0 =	"F1",
1123  repne_0 =	"F2",
1124  repnz_0 =	"F2",
1125  rep_0 =	"F3",
1126  repe_0 =	"F3",
1127  repz_0 =	"F3",
1128  -- F4: *hlt
1129  cmc_0 =	"F5",
1130  -- F6: test... mb,i; div... mb
1131  -- F7: test... mdw,i; div... mdw
1132  clc_0 =	"F8",
1133  stc_0 =	"F9",
1134  -- FA: *cli
1135  cld_0 =	"FC",
1136  std_0 =	"FD",
1137  -- FE: inc... mb
1138  -- FF: inc... mdw
1139
1140  -- misc ops
1141  not_1 =	"m:F72m",
1142  neg_1 =	"m:F73m",
1143  mul_1 =	"m:F74m",
1144  imul_1 =	"m:F75m",
1145  div_1 =	"m:F76m",
1146  idiv_1 =	"m:F77m",
1147
1148  imul_2 =	"rmqdw:0FAFrM|rIqdw:69rmI|rSqdw:6BrmS|riqdw:69rmi",
1149  imul_3 =	"rmIqdw:69rMI|rmSqdw:6BrMS|rmiqdw:69rMi",
1150
1151  movzx_2 =	"rm/db:0FB6rM|rm/qb:|rm/wb:0FB6rM|rm/dw:0FB7rM|rm/qw:",
1152  movsx_2 =	"rm/db:0FBErM|rm/qb:|rm/wb:0FBErM|rm/dw:0FBFrM|rm/qw:",
1153
1154  bswap_1 =	"rqd:0FC8r",
1155  bsf_2 =	"rmqdw:0FBCrM",
1156  bsr_2 =	"rmqdw:0FBDrM",
1157  bt_2 =	"mrqdw:0FA3Rm|miqdw:0FBA4mU",
1158  btc_2 =	"mrqdw:0FBBRm|miqdw:0FBA7mU",
1159  btr_2 =	"mrqdw:0FB3Rm|miqdw:0FBA6mU",
1160  bts_2 =	"mrqdw:0FABRm|miqdw:0FBA5mU",
1161
1162  shld_3 =	"mriqdw:0FA4RmU|mrC/qq:0FA5Rm|mrC/dd:|mrC/ww:",
1163  shrd_3 =	"mriqdw:0FACRmU|mrC/qq:0FADRm|mrC/dd:|mrC/ww:",
1164
1165  rdtsc_0 =	"0F31", -- P1+
1166  rdpmc_0 =	"0F33", -- P6+
1167  cpuid_0 =	"0FA2", -- P1+
1168
1169  -- floating point ops
1170  fst_1 =	"ff:DDD0r|xd:D92m|xq:nDD2m",
1171  fstp_1 =	"ff:DDD8r|xd:D93m|xq:nDD3m|xt:DB7m",
1172  fld_1 =	"ff:D9C0r|xd:D90m|xq:nDD0m|xt:DB5m",
1173
1174  fpop_0 =	"DDD8", -- Alias for fstp st0.
1175
1176  fist_1 =	"xw:nDF2m|xd:DB2m",
1177  fistp_1 =	"xw:nDF3m|xd:DB3m|xq:nDF7m",
1178  fild_1 =	"xw:nDF0m|xd:DB0m|xq:nDF5m",
1179
1180  fxch_0 =	"D9C9",
1181  fxch_1 =	"ff:D9C8r",
1182  fxch_2 =	"fFf:D9C8r|Fff:D9C8R",
1183
1184  fucom_1 =	"ff:DDE0r",
1185  fucom_2 =	"Fff:DDE0R",
1186  fucomp_1 =	"ff:DDE8r",
1187  fucomp_2 =	"Fff:DDE8R",
1188  fucomi_1 =	"ff:DBE8r", -- P6+
1189  fucomi_2 =	"Fff:DBE8R", -- P6+
1190  fucomip_1 =	"ff:DFE8r", -- P6+
1191  fucomip_2 =	"Fff:DFE8R", -- P6+
1192  fcomi_1 =	"ff:DBF0r", -- P6+
1193  fcomi_2 =	"Fff:DBF0R", -- P6+
1194  fcomip_1 =	"ff:DFF0r", -- P6+
1195  fcomip_2 =	"Fff:DFF0R", -- P6+
1196  fucompp_0 =	"DAE9",
1197  fcompp_0 =	"DED9",
1198
1199  fldenv_1 =	"x.:D94m",
1200  fnstenv_1 =	"x.:D96m",
1201  fstenv_1 =	"x.:9BD96m",
1202  fldcw_1 =	"xw:nD95m",
1203  fstcw_1 =	"xw:n9BD97m",
1204  fnstcw_1 =	"xw:nD97m",
1205  fstsw_1 =	"Rw:n9BDFE0|xw:n9BDD7m",
1206  fnstsw_1 =	"Rw:nDFE0|xw:nDD7m",
1207  fclex_0 =	"9BDBE2",
1208  fnclex_0 =	"DBE2",
1209
1210  fnop_0 =	"D9D0",
1211  -- D9D1-D9DF: unassigned
1212
1213  fchs_0 =	"D9E0",
1214  fabs_0 =	"D9E1",
1215  -- D9E2: unassigned
1216  -- D9E3: unassigned
1217  ftst_0 =	"D9E4",
1218  fxam_0 =	"D9E5",
1219  -- D9E6: unassigned
1220  -- D9E7: unassigned
1221  fld1_0 =	"D9E8",
1222  fldl2t_0 =	"D9E9",
1223  fldl2e_0 =	"D9EA",
1224  fldpi_0 =	"D9EB",
1225  fldlg2_0 =	"D9EC",
1226  fldln2_0 =	"D9ED",
1227  fldz_0 =	"D9EE",
1228  -- D9EF: unassigned
1229
1230  f2xm1_0 =	"D9F0",
1231  fyl2x_0 =	"D9F1",
1232  fptan_0 =	"D9F2",
1233  fpatan_0 =	"D9F3",
1234  fxtract_0 =	"D9F4",
1235  fprem1_0 =	"D9F5",
1236  fdecstp_0 =	"D9F6",
1237  fincstp_0 =	"D9F7",
1238  fprem_0 =	"D9F8",
1239  fyl2xp1_0 =	"D9F9",
1240  fsqrt_0 =	"D9FA",
1241  fsincos_0 =	"D9FB",
1242  frndint_0 =	"D9FC",
1243  fscale_0 =	"D9FD",
1244  fsin_0 =	"D9FE",
1245  fcos_0 =	"D9FF",
1246
1247  -- SSE, SSE2
1248  andnpd_2 =	"rmo:660F55rM",
1249  andnps_2 =	"rmo:0F55rM",
1250  andpd_2 =	"rmo:660F54rM",
1251  andps_2 =	"rmo:0F54rM",
1252  clflush_1 =	"x.:0FAE7m",
1253  cmppd_3 =	"rmio:660FC2rMU",
1254  cmpps_3 =	"rmio:0FC2rMU",
1255  cmpsd_3 =	"rrio:F20FC2rMU|rxi/oq:",
1256  cmpss_3 =	"rrio:F30FC2rMU|rxi/od:",
1257  comisd_2 =	"rro:660F2FrM|rx/oq:",
1258  comiss_2 =	"rro:0F2FrM|rx/od:",
1259  cvtdq2pd_2 =	"rro:F30FE6rM|rx/oq:",
1260  cvtdq2ps_2 =	"rmo:0F5BrM",
1261  cvtpd2dq_2 =	"rmo:F20FE6rM",
1262  cvtpd2ps_2 =	"rmo:660F5ArM",
1263  cvtpi2pd_2 =	"rx/oq:660F2ArM",
1264  cvtpi2ps_2 =	"rx/oq:0F2ArM",
1265  cvtps2dq_2 =	"rmo:660F5BrM",
1266  cvtps2pd_2 =	"rro:0F5ArM|rx/oq:",
1267  cvtsd2si_2 =	"rr/do:F20F2DrM|rr/qo:|rx/dq:|rxq:",
1268  cvtsd2ss_2 =	"rro:F20F5ArM|rx/oq:",
1269  cvtsi2sd_2 =	"rm/od:F20F2ArM|rm/oq:F20F2ArXM",
1270  cvtsi2ss_2 =	"rm/od:F30F2ArM|rm/oq:F30F2ArXM",
1271  cvtss2sd_2 =	"rro:F30F5ArM|rx/od:",
1272  cvtss2si_2 =	"rr/do:F30F2DrM|rr/qo:|rxd:|rx/qd:",
1273  cvttpd2dq_2 =	"rmo:660FE6rM",
1274  cvttps2dq_2 =	"rmo:F30F5BrM",
1275  cvttsd2si_2 =	"rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:",
1276  cvttss2si_2 =	"rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:",
1277  fxsave_1 =	"x.:0FAE0m",
1278  fxrstor_1 =	"x.:0FAE1m",
1279  ldmxcsr_1 =	"xd:0FAE2m",
1280  lfence_0 =	"0FAEE8",
1281  maskmovdqu_2 = "rro:660FF7rM",
1282  mfence_0 =	"0FAEF0",
1283  movapd_2 =	"rmo:660F28rM|mro:660F29Rm",
1284  movaps_2 =	"rmo:0F28rM|mro:0F29Rm",
1285  movd_2 =	"rm/od:660F6ErM|rm/oq:660F6ErXM|mr/do:660F7ERm|mr/qo:",
1286  movdqa_2 =	"rmo:660F6FrM|mro:660F7FRm",
1287  movdqu_2 =	"rmo:F30F6FrM|mro:F30F7FRm",
1288  movhlps_2 =	"rro:0F12rM",
1289  movhpd_2 =	"rx/oq:660F16rM|xr/qo:n660F17Rm",
1290  movhps_2 =	"rx/oq:0F16rM|xr/qo:n0F17Rm",
1291  movlhps_2 =	"rro:0F16rM",
1292  movlpd_2 =	"rx/oq:660F12rM|xr/qo:n660F13Rm",
1293  movlps_2 =	"rx/oq:0F12rM|xr/qo:n0F13Rm",
1294  movmskpd_2 =	"rr/do:660F50rM",
1295  movmskps_2 =	"rr/do:0F50rM",
1296  movntdq_2 =	"xro:660FE7Rm",
1297  movnti_2 =	"xrqd:0FC3Rm",
1298  movntpd_2 =	"xro:660F2BRm",
1299  movntps_2 =	"xro:0F2BRm",
1300  movq_2 =	"rro:F30F7ErM|rx/oq:|xr/qo:n660FD6Rm",
1301  movsd_2 =	"rro:F20F10rM|rx/oq:|xr/qo:nF20F11Rm",
1302  movss_2 =	"rro:F30F10rM|rx/od:|xr/do:F30F11Rm",
1303  movupd_2 =	"rmo:660F10rM|mro:660F11Rm",
1304  movups_2 =	"rmo:0F10rM|mro:0F11Rm",
1305  orpd_2 =	"rmo:660F56rM",
1306  orps_2 =	"rmo:0F56rM",
1307  pause_0 =	"F390",
1308  pextrw_3 =	"rri/do:660FC5rMU|xri/wo:660F3A15nRmU", -- Mem op: SSE4.1 only.
1309  pinsrw_3 =	"rri/od:660FC4rMU|rxi/ow:",
1310  pmovmskb_2 =	"rr/do:660FD7rM",
1311  prefetchnta_1 = "xb:n0F180m",
1312  prefetcht0_1 = "xb:n0F181m",
1313  prefetcht1_1 = "xb:n0F182m",
1314  prefetcht2_1 = "xb:n0F183m",
1315  pshufd_3 =	"rmio:660F70rMU",
1316  pshufhw_3 =	"rmio:F30F70rMU",
1317  pshuflw_3 =	"rmio:F20F70rMU",
1318  pslld_2 =	"rmo:660FF2rM|rio:660F726mU",
1319  pslldq_2 =	"rio:660F737mU",
1320  psllq_2 =	"rmo:660FF3rM|rio:660F736mU",
1321  psllw_2 =	"rmo:660FF1rM|rio:660F716mU",
1322  psrad_2 =	"rmo:660FE2rM|rio:660F724mU",
1323  psraw_2 =	"rmo:660FE1rM|rio:660F714mU",
1324  psrld_2 =	"rmo:660FD2rM|rio:660F722mU",
1325  psrldq_2 =	"rio:660F733mU",
1326  psrlq_2 =	"rmo:660FD3rM|rio:660F732mU",
1327  psrlw_2 =	"rmo:660FD1rM|rio:660F712mU",
1328  rcpps_2 =	"rmo:0F53rM",
1329  rcpss_2 =	"rro:F30F53rM|rx/od:",
1330  rsqrtps_2 =	"rmo:0F52rM",
1331  rsqrtss_2 =	"rmo:F30F52rM",
1332  sfence_0 =	"0FAEF8",
1333  shufpd_3 =	"rmio:660FC6rMU",
1334  shufps_3 =	"rmio:0FC6rMU",
1335  stmxcsr_1 =   "xd:0FAE3m",
1336  ucomisd_2 =	"rro:660F2ErM|rx/oq:",
1337  ucomiss_2 =	"rro:0F2ErM|rx/od:",
1338  unpckhpd_2 =	"rmo:660F15rM",
1339  unpckhps_2 =	"rmo:0F15rM",
1340  unpcklpd_2 =	"rmo:660F14rM",
1341  unpcklps_2 =	"rmo:0F14rM",
1342  xorpd_2 =	"rmo:660F57rM",
1343  xorps_2 =	"rmo:0F57rM",
1344
1345  -- SSE3 ops
1346  fisttp_1 =	"xw:nDF1m|xd:DB1m|xq:nDD1m",
1347  addsubpd_2 =	"rmo:660FD0rM",
1348  addsubps_2 =	"rmo:F20FD0rM",
1349  haddpd_2 =	"rmo:660F7CrM",
1350  haddps_2 =	"rmo:F20F7CrM",
1351  hsubpd_2 =	"rmo:660F7DrM",
1352  hsubps_2 =	"rmo:F20F7DrM",
1353  lddqu_2 =	"rxo:F20FF0rM",
1354  movddup_2 =	"rmo:F20F12rM",
1355  movshdup_2 =	"rmo:F30F16rM",
1356  movsldup_2 =	"rmo:F30F12rM",
1357
1358  -- SSSE3 ops
1359  pabsb_2 =	"rmo:660F381CrM",
1360  pabsd_2 =	"rmo:660F381ErM",
1361  pabsw_2 =	"rmo:660F381DrM",
1362  palignr_3 =	"rmio:660F3A0FrMU",
1363  phaddd_2 =	"rmo:660F3802rM",
1364  phaddsw_2 =	"rmo:660F3803rM",
1365  phaddw_2 =	"rmo:660F3801rM",
1366  phsubd_2 =	"rmo:660F3806rM",
1367  phsubsw_2 =	"rmo:660F3807rM",
1368  phsubw_2 =	"rmo:660F3805rM",
1369  pmaddubsw_2 =	"rmo:660F3804rM",
1370  pmulhrsw_2 =	"rmo:660F380BrM",
1371  pshufb_2 =	"rmo:660F3800rM",
1372  psignb_2 =	"rmo:660F3808rM",
1373  psignd_2 =	"rmo:660F380ArM",
1374  psignw_2 =	"rmo:660F3809rM",
1375
1376  -- SSE4.1 ops
1377  blendpd_3 =	"rmio:660F3A0DrMU",
1378  blendps_3 =	"rmio:660F3A0CrMU",
1379  blendvpd_3 =	"rmRo:660F3815rM",
1380  blendvps_3 =	"rmRo:660F3814rM",
1381  dppd_3 =	"rmio:660F3A41rMU",
1382  dpps_3 =	"rmio:660F3A40rMU",
1383  extractps_3 =	"mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
1384  insertps_3 =	"rrio:660F3A41rMU|rxi/od:",
1385  movntdqa_2 =	"rxo:660F382ArM",
1386  mpsadbw_3 =	"rmio:660F3A42rMU",
1387  packusdw_2 =	"rmo:660F382BrM",
1388  pblendvb_3 =	"rmRo:660F3810rM",
1389  pblendw_3 =	"rmio:660F3A0ErMU",
1390  pcmpeqq_2 =	"rmo:660F3829rM",
1391  pextrb_3 =	"rri/do:660F3A14nRmU|rri/qo:|xri/bo:",
1392  pextrd_3 =	"mri/do:660F3A16RmU",
1393  pextrq_3 =	"mri/qo:660F3A16RmU",
1394  -- pextrw is SSE2, mem operand is SSE4.1 only
1395  phminposuw_2 = "rmo:660F3841rM",
1396  pinsrb_3 =	"rri/od:660F3A20nrMU|rxi/ob:",
1397  pinsrd_3 =	"rmi/od:660F3A22rMU",
1398  pinsrq_3 =	"rmi/oq:660F3A22rXMU",
1399  pmaxsb_2 =	"rmo:660F383CrM",
1400  pmaxsd_2 =	"rmo:660F383DrM",
1401  pmaxud_2 =	"rmo:660F383FrM",
1402  pmaxuw_2 =	"rmo:660F383ErM",
1403  pminsb_2 =	"rmo:660F3838rM",
1404  pminsd_2 =	"rmo:660F3839rM",
1405  pminud_2 =	"rmo:660F383BrM",
1406  pminuw_2 =	"rmo:660F383ArM",
1407  pmovsxbd_2 =	"rro:660F3821rM|rx/od:",
1408  pmovsxbq_2 =	"rro:660F3822rM|rx/ow:",
1409  pmovsxbw_2 =	"rro:660F3820rM|rx/oq:",
1410  pmovsxdq_2 =	"rro:660F3825rM|rx/oq:",
1411  pmovsxwd_2 =	"rro:660F3823rM|rx/oq:",
1412  pmovsxwq_2 =	"rro:660F3824rM|rx/od:",
1413  pmovzxbd_2 =	"rro:660F3831rM|rx/od:",
1414  pmovzxbq_2 =	"rro:660F3832rM|rx/ow:",
1415  pmovzxbw_2 =	"rro:660F3830rM|rx/oq:",
1416  pmovzxdq_2 =	"rro:660F3835rM|rx/oq:",
1417  pmovzxwd_2 =	"rro:660F3833rM|rx/oq:",
1418  pmovzxwq_2 =	"rro:660F3834rM|rx/od:",
1419  pmuldq_2 =	"rmo:660F3828rM",
1420  pmulld_2 =	"rmo:660F3840rM",
1421  ptest_2 =	"rmo:660F3817rM",
1422  roundpd_3 =	"rmio:660F3A09rMU",
1423  roundps_3 =	"rmio:660F3A08rMU",
1424  roundsd_3 =	"rrio:660F3A0BrMU|rxi/oq:",
1425  roundss_3 =	"rrio:660F3A0ArMU|rxi/od:",
1426
1427  -- SSE4.2 ops
1428  crc32_2 =	"rmqd:F20F38F1rM|rm/dw:66F20F38F1rM|rm/db:F20F38F0rM|rm/qb:",
1429  pcmpestri_3 =	"rmio:660F3A61rMU",
1430  pcmpestrm_3 =	"rmio:660F3A60rMU",
1431  pcmpgtq_2 =	"rmo:660F3837rM",
1432  pcmpistri_3 =	"rmio:660F3A63rMU",
1433  pcmpistrm_3 =	"rmio:660F3A62rMU",
1434  popcnt_2 =	"rmqdw:F30FB8rM",
1435
1436  -- SSE4a
1437  extrq_2 =	"rro:660F79rM",
1438  extrq_3 =	"riio:660F780mUU",
1439  insertq_2 =	"rro:F20F79rM",
1440  insertq_4 =	"rriio:F20F78rMUU",
1441  lzcnt_2 =	"rmqdw:F30FBDrM",
1442  movntsd_2 =	"xr/qo:nF20F2BRm",
1443  movntss_2 =	"xr/do:F30F2BRm",
1444  -- popcnt is also in SSE4.2
1445
1446  -- AES-NI
1447  aesdec_2 =	"rmo:660F38DErM",
1448  aesdeclast_2 = "rmo:660F38DFrM",
1449  aesenc_2 =	"rmo:660F38DCrM",
1450  aesenclast_2 = "rmo:660F38DDrM",
1451  aesimc_2 =	"rmo:660F38DBrM",
1452  aeskeygenassist_3 = "rmio:660F3ADFrMU",
1453  pclmulqdq_3 =	"rmio:660F3A44rMU",
1454
1455   -- AVX FP ops
1456  vaddsubpd_3 =	"rrmoy:660FVD0rM",
1457  vaddsubps_3 =	"rrmoy:F20FVD0rM",
1458  vandpd_3 =	"rrmoy:660FV54rM",
1459  vandps_3 =	"rrmoy:0FV54rM",
1460  vandnpd_3 =	"rrmoy:660FV55rM",
1461  vandnps_3 =	"rrmoy:0FV55rM",
1462  vblendpd_4 =	"rrmioy:660F3AV0DrMU",
1463  vblendps_4 =	"rrmioy:660F3AV0CrMU",
1464  vblendvpd_4 =	"rrmroy:660F3AV4BrMs",
1465  vblendvps_4 =	"rrmroy:660F3AV4ArMs",
1466  vbroadcastf128_2 = "rx/yo:660F38u1ArM",
1467  vcmppd_4 =	"rrmioy:660FVC2rMU",
1468  vcmpps_4 =	"rrmioy:0FVC2rMU",
1469  vcmpsd_4 =	"rrrio:F20FVC2rMU|rrxi/ooq:",
1470  vcmpss_4 =	"rrrio:F30FVC2rMU|rrxi/ood:",
1471  vcomisd_2 =	"rro:660Fu2FrM|rx/oq:",
1472  vcomiss_2 =	"rro:0Fu2FrM|rx/od:",
1473  vcvtdq2pd_2 =	"rro:F30FuE6rM|rx/oq:|rm/yo:",
1474  vcvtdq2ps_2 =	"rmoy:0Fu5BrM",
1475  vcvtpd2dq_2 =	"rmoy:F20FuE6rM",
1476  vcvtpd2ps_2 =	"rmoy:660Fu5ArM",
1477  vcvtps2dq_2 =	"rmoy:660Fu5BrM",
1478  vcvtps2pd_2 =	"rro:0Fu5ArM|rx/oq:|rm/yo:",
1479  vcvtsd2si_2 =	"rr/do:F20Fu2DrM|rx/dq:|rr/qo:|rxq:",
1480  vcvtsd2ss_3 =	"rrro:F20FV5ArM|rrx/ooq:",
1481  vcvtsi2sd_3 =	"rrm/ood:F20FV2ArM|rrm/ooq:F20FVX2ArM",
1482  vcvtsi2ss_3 =	"rrm/ood:F30FV2ArM|rrm/ooq:F30FVX2ArM",
1483  vcvtss2sd_3 =	"rrro:F30FV5ArM|rrx/ood:",
1484  vcvtss2si_2 =	"rr/do:F30Fu2DrM|rxd:|rr/qo:|rx/qd:",
1485  vcvttpd2dq_2 = "rmo:660FuE6rM|rm/oy:660FuLE6rM",
1486  vcvttps2dq_2 = "rmoy:F30Fu5BrM",
1487  vcvttsd2si_2 = "rr/do:F20Fu2CrM|rx/dq:|rr/qo:|rxq:",
1488  vcvttss2si_2 = "rr/do:F30Fu2CrM|rxd:|rr/qo:|rx/qd:",
1489  vdppd_4 =	"rrmio:660F3AV41rMU",
1490  vdpps_4 =	"rrmioy:660F3AV40rMU",
1491  vextractf128_3 = "mri/oy:660F3AuL19RmU",
1492  vextractps_3 = "mri/do:660F3Au17RmU",
1493  vhaddpd_3 =	"rrmoy:660FV7CrM",
1494  vhaddps_3 =	"rrmoy:F20FV7CrM",
1495  vhsubpd_3 =	"rrmoy:660FV7DrM",
1496  vhsubps_3 =	"rrmoy:F20FV7DrM",
1497  vinsertf128_4 = "rrmi/yyo:660F3AV18rMU",
1498  vinsertps_4 =	"rrrio:660F3AV21rMU|rrxi/ood:",
1499  vldmxcsr_1 =	"xd:0FuAE2m",
1500  vmaskmovps_3 = "rrxoy:660F38V2CrM|xrroy:660F38V2ERm",
1501  vmaskmovpd_3 = "rrxoy:660F38V2DrM|xrroy:660F38V2FRm",
1502  vmovapd_2 =	"rmoy:660Fu28rM|mroy:660Fu29Rm",
1503  vmovaps_2 =	"rmoy:0Fu28rM|mroy:0Fu29Rm",
1504  vmovd_2 =	"rm/od:660Fu6ErM|rm/oq:660FuX6ErM|mr/do:660Fu7ERm|mr/qo:",
1505  vmovq_2 =	"rro:F30Fu7ErM|rx/oq:|xr/qo:660FuD6Rm",
1506  vmovddup_2 =	"rmy:F20Fu12rM|rro:|rx/oq:",
1507  vmovhlps_3 =	"rrro:0FV12rM",
1508  vmovhpd_2 =	"xr/qo:660Fu17Rm",
1509  vmovhpd_3 =	"rrx/ooq:660FV16rM",
1510  vmovhps_2 =	"xr/qo:0Fu17Rm",
1511  vmovhps_3 =	"rrx/ooq:0FV16rM",
1512  vmovlhps_3 =	"rrro:0FV16rM",
1513  vmovlpd_2 =	"xr/qo:660Fu13Rm",
1514  vmovlpd_3 =	"rrx/ooq:660FV12rM",
1515  vmovlps_2 =	"xr/qo:0Fu13Rm",
1516  vmovlps_3 =	"rrx/ooq:0FV12rM",
1517  vmovmskpd_2 =	"rr/do:660Fu50rM|rr/dy:660FuL50rM",
1518  vmovmskps_2 =	"rr/do:0Fu50rM|rr/dy:0FuL50rM",
1519  vmovntpd_2 =	"xroy:660Fu2BRm",
1520  vmovntps_2 =	"xroy:0Fu2BRm",
1521  vmovsd_2 =	"rx/oq:F20Fu10rM|xr/qo:F20Fu11Rm",
1522  vmovsd_3 =	"rrro:F20FV10rM",
1523  vmovshdup_2 =	"rmoy:F30Fu16rM",
1524  vmovsldup_2 =	"rmoy:F30Fu12rM",
1525  vmovss_2 =	"rx/od:F30Fu10rM|xr/do:F30Fu11Rm",
1526  vmovss_3 =	"rrro:F30FV10rM",
1527  vmovupd_2 =	"rmoy:660Fu10rM|mroy:660Fu11Rm",
1528  vmovups_2 =	"rmoy:0Fu10rM|mroy:0Fu11Rm",
1529  vorpd_3 =	"rrmoy:660FV56rM",
1530  vorps_3 =	"rrmoy:0FV56rM",
1531  vpermilpd_3 =	"rrmoy:660F38V0DrM|rmioy:660F3Au05rMU",
1532  vpermilps_3 =	"rrmoy:660F38V0CrM|rmioy:660F3Au04rMU",
1533  vperm2f128_4 = "rrmiy:660F3AV06rMU",
1534  vptestpd_2 =	"rmoy:660F38u0FrM",
1535  vptestps_2 =	"rmoy:660F38u0ErM",
1536  vrcpps_2 =	"rmoy:0Fu53rM",
1537  vrcpss_3 =	"rrro:F30FV53rM|rrx/ood:",
1538  vrsqrtps_2 =	"rmoy:0Fu52rM",
1539  vrsqrtss_3 =	"rrro:F30FV52rM|rrx/ood:",
1540  vroundpd_3 =	"rmioy:660F3Au09rMU",
1541  vroundps_3 =	"rmioy:660F3Au08rMU",
1542  vroundsd_4 =	"rrrio:660F3AV0BrMU|rrxi/ooq:",
1543  vroundss_4 =	"rrrio:660F3AV0ArMU|rrxi/ood:",
1544  vshufpd_4 =	"rrmioy:660FVC6rMU",
1545  vshufps_4 =	"rrmioy:0FVC6rMU",
1546  vsqrtps_2 =	"rmoy:0Fu51rM",
1547  vsqrtss_2 =	"rro:F30Fu51rM|rx/od:",
1548  vsqrtpd_2 =	"rmoy:660Fu51rM",
1549  vsqrtsd_2 =	"rro:F20Fu51rM|rx/oq:",
1550  vstmxcsr_1 =	"xd:0FuAE3m",
1551  vucomisd_2 =	"rro:660Fu2ErM|rx/oq:",
1552  vucomiss_2 =	"rro:0Fu2ErM|rx/od:",
1553  vunpckhpd_3 =	"rrmoy:660FV15rM",
1554  vunpckhps_3 =	"rrmoy:0FV15rM",
1555  vunpcklpd_3 =	"rrmoy:660FV14rM",
1556  vunpcklps_3 =	"rrmoy:0FV14rM",
1557  vxorpd_3 =	"rrmoy:660FV57rM",
1558  vxorps_3 =	"rrmoy:0FV57rM",
1559  vzeroall_0 =	"0FuL77",
1560  vzeroupper_0 = "0Fu77",
1561
1562  -- AVX2 FP ops
1563  vbroadcastss_2 = "rx/od:660F38u18rM|rx/yd:|rro:|rr/yo:",
1564  vbroadcastsd_2 = "rx/yq:660F38u19rM|rr/yo:",
1565  -- *vgather* (!vsib)
1566  vpermpd_3 =	"rmiy:660F3AuX01rMU",
1567  vpermps_3 =	"rrmy:660F38V16rM",
1568
1569  -- AVX, AVX2 integer ops
1570  -- In general, xmm requires AVX, ymm requires AVX2.
1571  vaesdec_3 =  "rrmo:660F38VDErM",
1572  vaesdeclast_3 = "rrmo:660F38VDFrM",
1573  vaesenc_3 =  "rrmo:660F38VDCrM",
1574  vaesenclast_3 = "rrmo:660F38VDDrM",
1575  vaesimc_2 =  "rmo:660F38uDBrM",
1576  vaeskeygenassist_3 = "rmio:660F3AuDFrMU",
1577  vlddqu_2 =	"rxoy:F20FuF0rM",
1578  vmaskmovdqu_2 = "rro:660FuF7rM",
1579  vmovdqa_2 =	"rmoy:660Fu6FrM|mroy:660Fu7FRm",
1580  vmovdqu_2 =	"rmoy:F30Fu6FrM|mroy:F30Fu7FRm",
1581  vmovntdq_2 =	"xroy:660FuE7Rm",
1582  vmovntdqa_2 =	"rxoy:660F38u2ArM",
1583  vmpsadbw_4 =	"rrmioy:660F3AV42rMU",
1584  vpabsb_2 =	"rmoy:660F38u1CrM",
1585  vpabsd_2 =	"rmoy:660F38u1ErM",
1586  vpabsw_2 =	"rmoy:660F38u1DrM",
1587  vpackusdw_3 =	"rrmoy:660F38V2BrM",
1588  vpalignr_4 =	"rrmioy:660F3AV0FrMU",
1589  vpblendvb_4 =	"rrmroy:660F3AV4CrMs",
1590  vpblendw_4 =	"rrmioy:660F3AV0ErMU",
1591  vpclmulqdq_4 = "rrmio:660F3AV44rMU",
1592  vpcmpeqq_3 =	"rrmoy:660F38V29rM",
1593  vpcmpestri_3 = "rmio:660F3Au61rMU",
1594  vpcmpestrm_3 = "rmio:660F3Au60rMU",
1595  vpcmpgtq_3 =	"rrmoy:660F38V37rM",
1596  vpcmpistri_3 = "rmio:660F3Au63rMU",
1597  vpcmpistrm_3 = "rmio:660F3Au62rMU",
1598  vpextrb_3 =	"rri/do:660F3Au14nRmU|rri/qo:|xri/bo:",
1599  vpextrw_3 =	"rri/do:660FuC5rMU|xri/wo:660F3Au15nRmU",
1600  vpextrd_3 =	"mri/do:660F3Au16RmU",
1601  vpextrq_3 =	"mri/qo:660F3Au16RmU",
1602  vphaddw_3 =	"rrmoy:660F38V01rM",
1603  vphaddd_3 =	"rrmoy:660F38V02rM",
1604  vphaddsw_3 =	"rrmoy:660F38V03rM",
1605  vphminposuw_2 = "rmo:660F38u41rM",
1606  vphsubw_3 =	"rrmoy:660F38V05rM",
1607  vphsubd_3 =	"rrmoy:660F38V06rM",
1608  vphsubsw_3 =	"rrmoy:660F38V07rM",
1609  vpinsrb_4 =	"rrri/ood:660F3AV20rMU|rrxi/oob:",
1610  vpinsrw_4 =	"rrri/ood:660FVC4rMU|rrxi/oow:",
1611  vpinsrd_4 =	"rrmi/ood:660F3AV22rMU",
1612  vpinsrq_4 =	"rrmi/ooq:660F3AVX22rMU",
1613  vpmaddubsw_3 = "rrmoy:660F38V04rM",
1614  vpmaxsb_3 =	"rrmoy:660F38V3CrM",
1615  vpmaxsd_3 =	"rrmoy:660F38V3DrM",
1616  vpmaxuw_3 =	"rrmoy:660F38V3ErM",
1617  vpmaxud_3 =	"rrmoy:660F38V3FrM",
1618  vpminsb_3 =	"rrmoy:660F38V38rM",
1619  vpminsd_3 =	"rrmoy:660F38V39rM",
1620  vpminuw_3 =	"rrmoy:660F38V3ArM",
1621  vpminud_3 =	"rrmoy:660F38V3BrM",
1622  vpmovmskb_2 =	"rr/do:660FuD7rM|rr/dy:660FuLD7rM",
1623  vpmovsxbw_2 =	"rroy:660F38u20rM|rx/oq:|rx/yo:",
1624  vpmovsxbd_2 =	"rroy:660F38u21rM|rx/od:|rx/yq:",
1625  vpmovsxbq_2 =	"rroy:660F38u22rM|rx/ow:|rx/yd:",
1626  vpmovsxwd_2 =	"rroy:660F38u23rM|rx/oq:|rx/yo:",
1627  vpmovsxwq_2 =	"rroy:660F38u24rM|rx/od:|rx/yq:",
1628  vpmovsxdq_2 =	"rroy:660F38u25rM|rx/oq:|rx/yo:",
1629  vpmovzxbw_2 =	"rroy:660F38u30rM|rx/oq:|rx/yo:",
1630  vpmovzxbd_2 =	"rroy:660F38u31rM|rx/od:|rx/yq:",
1631  vpmovzxbq_2 =	"rroy:660F38u32rM|rx/ow:|rx/yd:",
1632  vpmovzxwd_2 =	"rroy:660F38u33rM|rx/oq:|rx/yo:",
1633  vpmovzxwq_2 =	"rroy:660F38u34rM|rx/od:|rx/yq:",
1634  vpmovzxdq_2 =	"rroy:660F38u35rM|rx/oq:|rx/yo:",
1635  vpmuldq_3 =	"rrmoy:660F38V28rM",
1636  vpmulhrsw_3 =	"rrmoy:660F38V0BrM",
1637  vpmulld_3 =	"rrmoy:660F38V40rM",
1638  vpshufb_3 =	"rrmoy:660F38V00rM",
1639  vpshufd_3 =	"rmioy:660Fu70rMU",
1640  vpshufhw_3 =	"rmioy:F30Fu70rMU",
1641  vpshuflw_3 =	"rmioy:F20Fu70rMU",
1642  vpsignb_3 =	"rrmoy:660F38V08rM",
1643  vpsignw_3 =	"rrmoy:660F38V09rM",
1644  vpsignd_3 =	"rrmoy:660F38V0ArM",
1645  vpslldq_3 =	"rrioy:660Fv737mU",
1646  vpsllw_3 =	"rrmoy:660FVF1rM|rrioy:660Fv716mU",
1647  vpslld_3 =	"rrmoy:660FVF2rM|rrioy:660Fv726mU",
1648  vpsllq_3 =	"rrmoy:660FVF3rM|rrioy:660Fv736mU",
1649  vpsraw_3 =	"rrmoy:660FVE1rM|rrioy:660Fv714mU",
1650  vpsrad_3 =	"rrmoy:660FVE2rM|rrioy:660Fv724mU",
1651  vpsrldq_3 =	"rrioy:660Fv733mU",
1652  vpsrlw_3 =	"rrmoy:660FVD1rM|rrioy:660Fv712mU",
1653  vpsrld_3 =	"rrmoy:660FVD2rM|rrioy:660Fv722mU",
1654  vpsrlq_3 =	"rrmoy:660FVD3rM|rrioy:660Fv732mU",
1655  vptest_2 =	"rmoy:660F38u17rM",
1656
1657  -- AVX2 integer ops
1658  vbroadcasti128_2 = "rx/yo:660F38u5ArM",
1659  vinserti128_4 = "rrmi/yyo:660F3AV38rMU",
1660  vextracti128_3 = "mri/oy:660F3AuL39RmU",
1661  vpblendd_4 =	"rrmioy:660F3AV02rMU",
1662  vpbroadcastb_2 = "rro:660F38u78rM|rx/ob:|rr/yo:|rx/yb:",
1663  vpbroadcastw_2 = "rro:660F38u79rM|rx/ow:|rr/yo:|rx/yw:",
1664  vpbroadcastd_2 = "rro:660F38u58rM|rx/od:|rr/yo:|rx/yd:",
1665  vpbroadcastq_2 = "rro:660F38u59rM|rx/oq:|rr/yo:|rx/yq:",
1666  vpermd_3 =	"rrmy:660F38V36rM",
1667  vpermq_3 =	"rmiy:660F3AuX00rMU",
1668  -- *vpgather* (!vsib)
1669  vperm2i128_4 = "rrmiy:660F3AV46rMU",
1670  vpmaskmovd_3 = "rrxoy:660F38V8CrM|xrroy:660F38V8ERm",
1671  vpmaskmovq_3 = "rrxoy:660F38VX8CrM|xrroy:660F38VX8ERm",
1672  vpsllvd_3 =	"rrmoy:660F38V47rM",
1673  vpsllvq_3 =	"rrmoy:660F38VX47rM",
1674  vpsravd_3 =	"rrmoy:660F38V46rM",
1675  vpsrlvd_3 =	"rrmoy:660F38V45rM",
1676  vpsrlvq_3 =	"rrmoy:660F38VX45rM",
1677
1678  -- Intel ADX
1679  adcx_2 =	"rmqd:660F38F6rM",
1680  adox_2 =	"rmqd:F30F38F6rM",
1681
1682  -- BMI1
1683  andn_3 =	"rrmqd:0F38VF2rM",
1684  bextr_3 =	"rmrqd:0F38wF7rM",
1685  blsi_2 =	"rmqd:0F38vF33m",
1686  blsmsk_2 =	"rmqd:0F38vF32m",
1687  blsr_2 =	"rmqd:0F38vF31m",
1688  tzcnt_2 =	"rmqdw:F30FBCrM",
1689
1690  -- BMI2
1691  bzhi_3 =	"rmrqd:0F38wF5rM",
1692  mulx_3 =	"rrmqd:F20F38VF6rM",
1693  pdep_3 =	"rrmqd:F20F38VF5rM",
1694  pext_3 =	"rrmqd:F30F38VF5rM",
1695  rorx_3 =	"rmSqd:F20F3AuF0rMS",
1696  sarx_3 =	"rmrqd:F30F38wF7rM",
1697  shrx_3 =	"rmrqd:F20F38wF7rM",
1698  shlx_3 =	"rmrqd:660F38wF7rM",
1699
1700  -- FMA3
1701  vfmaddsub132pd_3 = "rrmoy:660F38VX96rM",
1702  vfmaddsub132ps_3 = "rrmoy:660F38V96rM",
1703  vfmaddsub213pd_3 = "rrmoy:660F38VXA6rM",
1704  vfmaddsub213ps_3 = "rrmoy:660F38VA6rM",
1705  vfmaddsub231pd_3 = "rrmoy:660F38VXB6rM",
1706  vfmaddsub231ps_3 = "rrmoy:660F38VB6rM",
1707
1708  vfmsubadd132pd_3 = "rrmoy:660F38VX97rM",
1709  vfmsubadd132ps_3 = "rrmoy:660F38V97rM",
1710  vfmsubadd213pd_3 = "rrmoy:660F38VXA7rM",
1711  vfmsubadd213ps_3 = "rrmoy:660F38VA7rM",
1712  vfmsubadd231pd_3 = "rrmoy:660F38VXB7rM",
1713  vfmsubadd231ps_3 = "rrmoy:660F38VB7rM",
1714
1715  vfmadd132pd_3 = "rrmoy:660F38VX98rM",
1716  vfmadd132ps_3 = "rrmoy:660F38V98rM",
1717  vfmadd132sd_3 = "rrro:660F38VX99rM|rrx/ooq:",
1718  vfmadd132ss_3 = "rrro:660F38V99rM|rrx/ood:",
1719  vfmadd213pd_3 = "rrmoy:660F38VXA8rM",
1720  vfmadd213ps_3 = "rrmoy:660F38VA8rM",
1721  vfmadd213sd_3 = "rrro:660F38VXA9rM|rrx/ooq:",
1722  vfmadd213ss_3 = "rrro:660F38VA9rM|rrx/ood:",
1723  vfmadd231pd_3 = "rrmoy:660F38VXB8rM",
1724  vfmadd231ps_3 = "rrmoy:660F38VB8rM",
1725  vfmadd231sd_3 = "rrro:660F38VXB9rM|rrx/ooq:",
1726  vfmadd231ss_3 = "rrro:660F38VB9rM|rrx/ood:",
1727
1728  vfmsub132pd_3 = "rrmoy:660F38VX9ArM",
1729  vfmsub132ps_3 = "rrmoy:660F38V9ArM",
1730  vfmsub132sd_3 = "rrro:660F38VX9BrM|rrx/ooq:",
1731  vfmsub132ss_3 = "rrro:660F38V9BrM|rrx/ood:",
1732  vfmsub213pd_3 = "rrmoy:660F38VXAArM",
1733  vfmsub213ps_3 = "rrmoy:660F38VAArM",
1734  vfmsub213sd_3 = "rrro:660F38VXABrM|rrx/ooq:",
1735  vfmsub213ss_3 = "rrro:660F38VABrM|rrx/ood:",
1736  vfmsub231pd_3 = "rrmoy:660F38VXBArM",
1737  vfmsub231ps_3 = "rrmoy:660F38VBArM",
1738  vfmsub231sd_3 = "rrro:660F38VXBBrM|rrx/ooq:",
1739  vfmsub231ss_3 = "rrro:660F38VBBrM|rrx/ood:",
1740
1741  vfnmadd132pd_3 = "rrmoy:660F38VX9CrM",
1742  vfnmadd132ps_3 = "rrmoy:660F38V9CrM",
1743  vfnmadd132sd_3 = "rrro:660F38VX9DrM|rrx/ooq:",
1744  vfnmadd132ss_3 = "rrro:660F38V9DrM|rrx/ood:",
1745  vfnmadd213pd_3 = "rrmoy:660F38VXACrM",
1746  vfnmadd213ps_3 = "rrmoy:660F38VACrM",
1747  vfnmadd213sd_3 = "rrro:660F38VXADrM|rrx/ooq:",
1748  vfnmadd213ss_3 = "rrro:660F38VADrM|rrx/ood:",
1749  vfnmadd231pd_3 = "rrmoy:660F38VXBCrM",
1750  vfnmadd231ps_3 = "rrmoy:660F38VBCrM",
1751  vfnmadd231sd_3 = "rrro:660F38VXBDrM|rrx/ooq:",
1752  vfnmadd231ss_3 = "rrro:660F38VBDrM|rrx/ood:",
1753
1754  vfnmsub132pd_3 = "rrmoy:660F38VX9ErM",
1755  vfnmsub132ps_3 = "rrmoy:660F38V9ErM",
1756  vfnmsub132sd_3 = "rrro:660F38VX9FrM|rrx/ooq:",
1757  vfnmsub132ss_3 = "rrro:660F38V9FrM|rrx/ood:",
1758  vfnmsub213pd_3 = "rrmoy:660F38VXAErM",
1759  vfnmsub213ps_3 = "rrmoy:660F38VAErM",
1760  vfnmsub213sd_3 = "rrro:660F38VXAFrM|rrx/ooq:",
1761  vfnmsub213ss_3 = "rrro:660F38VAFrM|rrx/ood:",
1762  vfnmsub231pd_3 = "rrmoy:660F38VXBErM",
1763  vfnmsub231ps_3 = "rrmoy:660F38VBErM",
1764  vfnmsub231sd_3 = "rrro:660F38VXBFrM|rrx/ooq:",
1765  vfnmsub231ss_3 = "rrro:660F38VBFrM|rrx/ood:",
1766}
1767
1768------------------------------------------------------------------------------
1769
1770-- Arithmetic ops.
1771for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
1772		     ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
1773  local n8 = shl(n, 3)
1774  map_op[name.."_2"] = format(
1775    "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi",
1776    1+n8, 3+n8, n, n, 5+n8, n)
1777end
1778
1779-- Shift ops.
1780for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,
1781		     shl = 4, shr = 5,          sar = 7, sal = 4 } do
1782  map_op[name.."_2"] = format("m1:D1%Xm|mC1qdwb:D3%Xm|mi:C1%XmU", n, n, n)
1783end
1784
1785-- Conditional ops.
1786for cc,n in pairs(map_cc) do
1787  map_op["j"..cc.."_1"] = format("J.:n0F8%XJ", n) -- short: 7%X
1788  map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n)
1789  map_op["cmov"..cc.."_2"] = format("rmqdw:0F4%XrM", n) -- P6+
1790end
1791
1792-- FP arithmetic ops.
1793for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
1794		     sub = 4, subr = 5, div = 6, divr = 7 } do
1795  local nc = 0xc0 + shl(n, 3)
1796  local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
1797  local fn = "f"..name
1798  map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n)
1799  if n == 2 or n == 3 then
1800    map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:nDC%XM", nc, n, n)
1801  else
1802    map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:nDC%XM", nc, nr, n, n)
1803    map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)
1804    map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)
1805  end
1806  map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)
1807end
1808
1809-- FP conditional moves.
1810for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
1811  local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6)
1812  map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
1813  map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
1814end
1815
1816-- SSE / AVX FP arithmetic ops.
1817for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
1818		     sub = 12, min = 13, div = 14, max = 15 } do
1819  map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
1820  map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
1821  map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
1822  map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
1823  if n ~= 1 then
1824    map_op["v"..name.."ps_3"] = format("rrmoy:0FV5%XrM", n)
1825    map_op["v"..name.."ss_3"] = format("rrro:F30FV5%XrM|rrx/ood:", n)
1826    map_op["v"..name.."pd_3"] = format("rrmoy:660FV5%XrM", n)
1827    map_op["v"..name.."sd_3"] = format("rrro:F20FV5%XrM|rrx/ooq:", n)
1828  end
1829end
1830
1831-- SSE2 / AVX / AVX2 integer arithmetic ops (66 0F leaf).
1832for name,n in pairs{
1833  paddb = 0xFC, paddw = 0xFD, paddd = 0xFE, paddq = 0xD4,
1834  paddsb = 0xEC, paddsw = 0xED, packssdw = 0x6B,
1835  packsswb = 0x63, packuswb = 0x67, paddusb = 0xDC,
1836  paddusw = 0xDD, pand = 0xDB, pandn = 0xDF, pavgb = 0xE0,
1837  pavgw = 0xE3, pcmpeqb = 0x74, pcmpeqd = 0x76,
1838  pcmpeqw = 0x75, pcmpgtb = 0x64, pcmpgtd = 0x66,
1839  pcmpgtw = 0x65, pmaddwd = 0xF5, pmaxsw = 0xEE,
1840  pmaxub = 0xDE, pminsw = 0xEA, pminub = 0xDA,
1841  pmulhuw = 0xE4, pmulhw = 0xE5, pmullw = 0xD5,
1842  pmuludq = 0xF4, por = 0xEB, psadbw = 0xF6, psubb = 0xF8,
1843  psubw = 0xF9, psubd = 0xFA, psubq = 0xFB, psubsb = 0xE8,
1844  psubsw = 0xE9, psubusb = 0xD8, psubusw = 0xD9,
1845  punpckhbw = 0x68, punpckhwd = 0x69, punpckhdq = 0x6A,
1846  punpckhqdq = 0x6D, punpcklbw = 0x60, punpcklwd = 0x61,
1847  punpckldq = 0x62, punpcklqdq = 0x6C, pxor = 0xEF
1848} do
1849  map_op[name.."_2"] = format("rmo:660F%02XrM", n)
1850  map_op["v"..name.."_3"] = format("rrmoy:660FV%02XrM", n)
1851end
1852
1853------------------------------------------------------------------------------
1854
1855local map_vexarg = { u = false, v = 1, V = 2, w = 3 }
1856
1857-- Process pattern string.
1858local function dopattern(pat, args, sz, op, needrex)
1859  local digit, addin, vex
1860  local opcode = 0
1861  local szov = sz
1862  local narg = 1
1863  local rex = 0
1864
1865  -- Limit number of section buffer positions used by a single dasm_put().
1866  -- A single opcode needs a maximum of 6 positions.
1867  if secpos+6 > maxsecpos then wflush() end
1868
1869  -- Process each character.
1870  for c in gmatch(pat.."|", ".") do
1871    if match(c, "%x") then	-- Hex digit.
1872      digit = byte(c) - 48
1873      if digit > 48 then digit = digit - 39
1874      elseif digit > 16 then digit = digit - 7 end
1875      opcode = opcode*16 + digit
1876      addin = nil
1877    elseif c == "n" then	-- Disable operand size mods for opcode.
1878      szov = nil
1879    elseif c == "X" then	-- Force REX.W.
1880      rex = 8
1881    elseif c == "L" then	-- Force VEX.L.
1882      vex.l = true
1883    elseif c == "r" then	-- Merge 1st operand regno. into opcode.
1884      addin = args[1]; opcode = opcode + (addin.reg % 8)
1885      if narg < 2 then narg = 2 end
1886    elseif c == "R" then	-- Merge 2nd operand regno. into opcode.
1887      addin = args[2]; opcode = opcode + (addin.reg % 8)
1888      narg = 3
1889    elseif c == "m" or c == "M" then	-- Encode ModRM/SIB.
1890      local s
1891      if addin then
1892	s = addin.reg
1893	opcode = opcode - band(s, 7)	-- Undo regno opcode merge.
1894      else
1895	s = band(opcode, 15)	-- Undo last digit.
1896	opcode = shr(opcode, 4)
1897      end
1898      local nn = c == "m" and 1 or 2
1899      local t = args[nn]
1900      if narg <= nn then narg = nn + 1 end
1901      if szov == "q" and rex == 0 then rex = rex + 8 end
1902      if t.reg and t.reg > 7 then rex = rex + 1 end
1903      if t.xreg and t.xreg > 7 then rex = rex + 2 end
1904      if s > 7 then rex = rex + 4 end
1905      if needrex then rex = rex + 16 end
1906      local psz, sk = wputop(szov, opcode, rex, vex, s < 0, t.vreg or t.vxreg)
1907      opcode = nil
1908      local imark = sub(pat, -1) -- Force a mark (ugly).
1909      -- Put ModRM/SIB with regno/last digit as spare.
1910      wputmrmsib(t, imark, s, addin and addin.vreg, psz, sk)
1911      addin = nil
1912    elseif map_vexarg[c] ~= nil then -- Encode using VEX prefix
1913      local b = band(opcode, 255); opcode = shr(opcode, 8)
1914      local m = 1
1915      if b == 0x38 then m = 2
1916      elseif b == 0x3a then m = 3 end
1917      if m ~= 1 then b = band(opcode, 255); opcode = shr(opcode, 8) end
1918      if b ~= 0x0f then
1919	werror("expected `0F', `0F38', or `0F3A' to precede `"..c..
1920	  "' in pattern `"..pat.."' for `"..op.."'")
1921      end
1922      local v = map_vexarg[c]
1923      if v then v = remove(args, v) end
1924      b = band(opcode, 255)
1925      local p = 0
1926      if b == 0x66 then p = 1
1927      elseif b == 0xf3 then p = 2
1928      elseif b == 0xf2 then p = 3 end
1929      if p ~= 0 then opcode = shr(opcode, 8) end
1930      if opcode ~= 0 then wputop(nil, opcode, 0); opcode = 0 end
1931      vex = { m = m, p = p, v = v }
1932    else
1933      if opcode then -- Flush opcode.
1934	if szov == "q" and rex == 0 then rex = rex + 8 end
1935	if needrex then rex = rex + 16 end
1936	if addin and addin.reg == -1 then
1937	  local psz, sk = wputop(szov, opcode - 7, rex, vex, true)
1938	  wvreg("opcode", addin.vreg, psz, sk)
1939	else
1940	  if addin and addin.reg > 7 then rex = rex + 1 end
1941	  wputop(szov, opcode, rex, vex)
1942	end
1943	opcode = nil
1944      end
1945      if c == "|" then break end
1946      if c == "o" then -- Offset (pure 32 bit displacement).
1947	wputdarg(args[1].disp); if narg < 2 then narg = 2 end
1948      elseif c == "O" then
1949	wputdarg(args[2].disp); narg = 3
1950      else
1951	-- Anything else is an immediate operand.
1952	local a = args[narg]
1953	narg = narg + 1
1954	local mode, imm = a.mode, a.imm
1955	if mode == "iJ" and not match("iIJ", c) then
1956	  werror("bad operand size for label")
1957	end
1958	if c == "S" then
1959	  wputsbarg(imm)
1960	elseif c == "U" then
1961	  wputbarg(imm)
1962	elseif c == "W" then
1963	  wputwarg(imm)
1964	elseif c == "i" or c == "I" then
1965	  if mode == "iJ" then
1966	    wputlabel("IMM_", imm, 1)
1967	  elseif mode == "iI" and c == "I" then
1968	    waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)
1969	  else
1970	    wputszarg(sz, imm)
1971	  end
1972	elseif c == "J" then
1973	  if mode == "iPJ" then
1974	    waction("REL_A", imm) -- !x64 (secpos)
1975	  else
1976	    wputlabel("REL_", imm, 2)
1977	  end
1978	elseif c == "s" then
1979	  local reg = a.reg
1980	  if reg < 0 then
1981	    wputb(0)
1982	    wvreg("imm.hi", a.vreg)
1983	  else
1984	    wputb(shl(reg, 4))
1985	  end
1986	else
1987	  werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
1988	end
1989      end
1990    end
1991  end
1992end
1993
1994------------------------------------------------------------------------------
1995
1996-- Mapping of operand modes to short names. Suppress output with '#'.
1997local map_modename = {
1998  r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",
1999  f = "stx", F = "st0", J = "lbl", ["1"] = "1",
2000  I = "#", S = "#", O = "#",
2001}
2002
2003-- Return a table/string showing all possible operand modes.
2004local function templatehelp(template, nparams)
2005  if nparams == 0 then return "" end
2006  local t = {}
2007  for tm in gmatch(template, "[^%|]+") do
2008    local s = map_modename[sub(tm, 1, 1)]
2009    s = s..gsub(sub(tm, 2, nparams), ".", function(c)
2010      return ", "..map_modename[c]
2011    end)
2012    if not match(s, "#") then t[#t+1] = s end
2013  end
2014  return t
2015end
2016
2017-- Match operand modes against mode match part of template.
2018local function matchtm(tm, args)
2019  for i=1,#args do
2020    if not match(args[i].mode, sub(tm, i, i)) then return end
2021  end
2022  return true
2023end
2024
2025-- Handle opcodes defined with template strings.
2026map_op[".template__"] = function(params, template, nparams)
2027  if not params then return templatehelp(template, nparams) end
2028  local args = {}
2029
2030  -- Zero-operand opcodes have no match part.
2031  if #params == 0 then
2032    dopattern(template, args, "d", params.op, nil)
2033    return
2034  end
2035
2036  -- Determine common operand size (coerce undefined size) or flag as mixed.
2037  local sz, szmix, needrex
2038  for i,p in ipairs(params) do
2039    args[i] = parseoperand(p)
2040    local nsz = args[i].opsize
2041    if nsz then
2042      if sz and sz ~= nsz then szmix = true else sz = nsz end
2043    end
2044    local nrex = args[i].needrex
2045    if nrex ~= nil then
2046      if needrex == nil then
2047	needrex = nrex
2048      elseif needrex ~= nrex then
2049	werror("bad mix of byte-addressable registers")
2050      end
2051    end
2052  end
2053
2054  -- Try all match:pattern pairs (separated by '|').
2055  local gotmatch, lastpat
2056  for tm in gmatch(template, "[^%|]+") do
2057    -- Split off size match (starts after mode match) and pattern string.
2058    local szm, pat = match(tm, "^(.-):(.*)$", #args+1)
2059    if pat == "" then pat = lastpat else lastpat = pat end
2060    if matchtm(tm, args) then
2061      local prefix = sub(szm, 1, 1)
2062      if prefix == "/" then -- Exactly match leading operand sizes.
2063	for i = #szm,1,-1 do
2064	  if i == 1 then
2065	    dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
2066	    return
2067	  elseif args[i-1].opsize ~= sub(szm, i, i) then
2068	    break
2069	  end
2070	end
2071      else -- Match common operand size.
2072	local szp = sz
2073	if szm == "" then szm = x64 and "qdwb" or "dwb" end -- Default sizes.
2074	if prefix == "1" then szp = args[1].opsize; szmix = nil
2075	elseif prefix == "2" then szp = args[2].opsize; szmix = nil end
2076	if not szmix and (prefix == "." or match(szm, szp or "#")) then
2077	  dopattern(pat, args, szp, params.op, needrex) -- Process pattern.
2078	  return
2079	end
2080      end
2081      gotmatch = true
2082    end
2083  end
2084
2085  local msg = "bad operand mode"
2086  if gotmatch then
2087    if szmix then
2088      msg = "mixed operand size"
2089    else
2090      msg = sz and "bad operand size" or "missing operand size"
2091    end
2092  end
2093
2094  werror(msg.." in `"..opmodestr(params.op, args).."'")
2095end
2096
2097------------------------------------------------------------------------------
2098
2099-- x64-specific opcode for 64 bit immediates and displacements.
2100if x64 then
2101  function map_op.mov64_2(params)
2102    if not params then return { "reg, imm", "reg, [disp]", "[disp], reg" } end
2103    if secpos+2 > maxsecpos then wflush() end
2104    local opcode, op64, sz, rex, vreg
2105    local op64 = match(params[1], "^%[%s*(.-)%s*%]$")
2106    if op64 then
2107      local a = parseoperand(params[2])
2108      if a.mode ~= "rmR" then werror("bad operand mode") end
2109      sz = a.opsize
2110      rex = sz == "q" and 8 or 0
2111      opcode = 0xa3
2112    else
2113      op64 = match(params[2], "^%[%s*(.-)%s*%]$")
2114      local a = parseoperand(params[1])
2115      if op64 then
2116	if a.mode ~= "rmR" then werror("bad operand mode") end
2117	sz = a.opsize
2118	rex = sz == "q" and 8 or 0
2119	opcode = 0xa1
2120      else
2121	if sub(a.mode, 1, 1) ~= "r" or a.opsize ~= "q" then
2122	  werror("bad operand mode")
2123	end
2124	op64 = params[2]
2125	if a.reg == -1 then
2126	  vreg = a.vreg
2127	  opcode = 0xb8
2128	else
2129	  opcode = 0xb8 + band(a.reg, 7)
2130	end
2131	rex = a.reg > 7 and 9 or 8
2132      end
2133    end
2134    local psz, sk = wputop(sz, opcode, rex, nil, vreg)
2135    wvreg("opcode", vreg, psz, sk)
2136    waction("IMM_D", format("(unsigned int)(%s)", op64))
2137    waction("IMM_D", format("(unsigned int)((%s)>>32)", op64))
2138  end
2139end
2140
2141------------------------------------------------------------------------------
2142
2143-- Pseudo-opcodes for data storage.
2144local function op_data(params)
2145  if not params then return "imm..." end
2146  local sz = sub(params.op, 2, 2)
2147  if sz == "a" then sz = addrsize end
2148  for _,p in ipairs(params) do
2149    local a = parseoperand(p)
2150    if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
2151      werror("bad mode or size in `"..p.."'")
2152    end
2153    if a.mode == "iJ" then
2154      wputlabel("IMM_", a.imm, 1)
2155    else
2156      wputszarg(sz, a.imm)
2157    end
2158    if secpos+2 > maxsecpos then wflush() end
2159  end
2160end
2161
2162map_op[".byte_*"] = op_data
2163map_op[".sbyte_*"] = op_data
2164map_op[".word_*"] = op_data
2165map_op[".dword_*"] = op_data
2166map_op[".aword_*"] = op_data
2167
2168------------------------------------------------------------------------------
2169
2170-- Pseudo-opcode to mark the position where the action list is to be emitted.
2171map_op[".actionlist_1"] = function(params)
2172  if not params then return "cvar" end
2173  local name = params[1] -- No syntax check. You get to keep the pieces.
2174  wline(function(out) writeactions(out, name) end)
2175end
2176
2177-- Pseudo-opcode to mark the position where the global enum is to be emitted.
2178map_op[".globals_1"] = function(params)
2179  if not params then return "prefix" end
2180  local prefix = params[1] -- No syntax check. You get to keep the pieces.
2181  wline(function(out) writeglobals(out, prefix) end)
2182end
2183
2184-- Pseudo-opcode to mark the position where the global names are to be emitted.
2185map_op[".globalnames_1"] = function(params)
2186  if not params then return "cvar" end
2187  local name = params[1] -- No syntax check. You get to keep the pieces.
2188  wline(function(out) writeglobalnames(out, name) end)
2189end
2190
2191-- Pseudo-opcode to mark the position where the extern names are to be emitted.
2192map_op[".externnames_1"] = function(params)
2193  if not params then return "cvar" end
2194  local name = params[1] -- No syntax check. You get to keep the pieces.
2195  wline(function(out) writeexternnames(out, name) end)
2196end
2197
2198------------------------------------------------------------------------------
2199
2200-- Label pseudo-opcode (converted from trailing colon form).
2201map_op[".label_2"] = function(params)
2202  if not params then return "[1-9] | ->global | =>pcexpr  [, addr]" end
2203  if secpos+2 > maxsecpos then wflush() end
2204  local a = parseoperand(params[1])
2205  local mode, imm = a.mode, a.imm
2206  if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then
2207    -- Local label (1: ... 9:) or global label (->global:).
2208    waction("LABEL_LG", nil, 1)
2209    wputxb(imm)
2210  elseif mode == "iJ" then
2211    -- PC label (=>pcexpr:).
2212    waction("LABEL_PC", imm)
2213  else
2214    werror("bad label definition")
2215  end
2216  -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.
2217  local addr = params[2]
2218  if addr then
2219    local a = parseoperand(addr)
2220    if a.mode == "iPJ" then
2221      waction("SETLABEL", a.imm)
2222    else
2223      werror("bad label assignment")
2224    end
2225  end
2226end
2227map_op[".label_1"] = map_op[".label_2"]
2228
2229------------------------------------------------------------------------------
2230
2231-- Alignment pseudo-opcode.
2232map_op[".align_1"] = function(params)
2233  if not params then return "numpow2" end
2234  if secpos+1 > maxsecpos then wflush() end
2235  local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]
2236  if align then
2237    local x = align
2238    -- Must be a power of 2 in the range (2 ... 256).
2239    for i=1,8 do
2240      x = x / 2
2241      if x == 1 then
2242	waction("ALIGN", nil, 1)
2243	wputxb(align-1) -- Action byte is 2**n-1.
2244	return
2245      end
2246    end
2247  end
2248  werror("bad alignment")
2249end
2250
2251-- Spacing pseudo-opcode.
2252map_op[".space_2"] = function(params)
2253  if not params then return "num [, filler]" end
2254  if secpos+1 > maxsecpos then wflush() end
2255  waction("SPACE", params[1])
2256  local fill = params[2]
2257  if fill then
2258    fill = tonumber(fill)
2259    if not fill or fill < 0 or fill > 255 then werror("bad filler") end
2260  end
2261  wputxb(fill or 0)
2262end
2263map_op[".space_1"] = map_op[".space_2"]
2264
2265------------------------------------------------------------------------------
2266
2267-- Pseudo-opcode for (primitive) type definitions (map to C types).
2268map_op[".type_3"] = function(params, nparams)
2269  if not params then
2270    return nparams == 2 and "name, ctype" or "name, ctype, reg"
2271  end
2272  local name, ctype, reg = params[1], params[2], params[3]
2273  if not match(name, "^[%a_][%w_]*$") then
2274    werror("bad type name `"..name.."'")
2275  end
2276  local tp = map_type[name]
2277  if tp then
2278    werror("duplicate type `"..name.."'")
2279  end
2280  if reg and not map_reg_valid_base[reg] then
2281    werror("bad base register `"..(map_reg_rev[reg] or reg).."'")
2282  end
2283  -- Add #type to defines. A bit unclean to put it in map_archdef.
2284  map_archdef["#"..name] = "sizeof("..ctype..")"
2285  -- Add new type and emit shortcut define.
2286  local num = ctypenum + 1
2287  map_type[name] = {
2288    ctype = ctype,
2289    ctypefmt = format("Dt%X(%%s)", num),
2290    reg = reg,
2291  }
2292  wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
2293  ctypenum = num
2294end
2295map_op[".type_2"] = map_op[".type_3"]
2296
2297-- Dump type definitions.
2298local function dumptypes(out, lvl)
2299  local t = {}
2300  for name in pairs(map_type) do t[#t+1] = name end
2301  sort(t)
2302  out:write("Type definitions:\n")
2303  for _,name in ipairs(t) do
2304    local tp = map_type[name]
2305    local reg = tp.reg and map_reg_rev[tp.reg] or ""
2306    out:write(format("  %-20s %-20s %s\n", name, tp.ctype, reg))
2307  end
2308  out:write("\n")
2309end
2310
2311------------------------------------------------------------------------------
2312
2313-- Set the current section.
2314function _M.section(num)
2315  waction("SECTION")
2316  wputxb(num)
2317  wflush(true) -- SECTION is a terminal action.
2318end
2319
2320------------------------------------------------------------------------------
2321
2322-- Dump architecture description.
2323function _M.dumparch(out)
2324  out:write(format("DynASM %s version %s, released %s\n\n",
2325    _info.arch, _info.version, _info.release))
2326  dumpregs(out)
2327  dumpactions(out)
2328end
2329
2330-- Dump all user defined elements.
2331function _M.dumpdef(out, lvl)
2332  dumptypes(out, lvl)
2333  dumpglobals(out, lvl)
2334  dumpexterns(out, lvl)
2335end
2336
2337------------------------------------------------------------------------------
2338
2339-- Pass callbacks from/to the DynASM core.
2340function _M.passcb(wl, we, wf, ww)
2341  wline, werror, wfatal, wwarn = wl, we, wf, ww
2342  return wflush
2343end
2344
2345-- Setup the arch-specific module.
2346function _M.setup(arch, opt)
2347  g_arch, g_opt = arch, opt
2348end
2349
2350-- Merge the core maps and the arch-specific maps.
2351function _M.mergemaps(map_coreop, map_def)
2352  setmetatable(map_op, { __index = map_coreop })
2353  setmetatable(map_def, { __index = map_archdef })
2354  return map_op, map_def
2355end
2356
2357return _M
2358
2359------------------------------------------------------------------------------
2360
2361