aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_x86.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_x86.lua')
-rw-r--r--dynasm/dasm_x86.lua52
1 files changed, 26 insertions, 26 deletions
diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua
index 3bebb83c..a5f5c37d 100644
--- a/dynasm/dasm_x86.lua
+++ b/dynasm/dasm_x86.lua
@@ -28,6 +28,8 @@ local _s = string
28local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char 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 29local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
30local concat, sort = table.concat, table.sort 30local concat, sort = table.concat, table.sort
31local bit = bit or require("bit")
32local band, shl, shr = bit.band, bit.lshift, bit.rshift
31 33
32-- Inherited tables and callbacks. 34-- Inherited tables and callbacks.
33local g_opt, g_arch 35local g_opt, g_arch
@@ -426,10 +428,10 @@ end
426-- Put unsigned word or arg. 428-- Put unsigned word or arg.
427local function wputwarg(n) 429local function wputwarg(n)
428 if type(n) == "number" then 430 if type(n) == "number" then
429 if n < 0 or n > 65535 then 431 if shr(n, 16) ~= 0 then
430 werror("unsigned immediate word out of range") 432 werror("unsigned immediate word out of range")
431 end 433 end
432 local r = n%256; n = (n-r)/256; wputb(r); wputb(n); 434 wputb(band(n, 255)); wputb(shr(n, 8));
433 else waction("IMM_W", n) end 435 else waction("IMM_W", n) end
434end 436end
435 437
@@ -437,10 +439,10 @@ end
437local function wputdarg(n) 439local function wputdarg(n)
438 local tn = type(n) 440 local tn = type(n)
439 if tn == "number" then 441 if tn == "number" then
440 if n < 0 then n = n + 4294967296 end 442 wputb(band(n, 255))
441 local r = n%256; n = (n-r)/256; wputb(r); 443 wputb(band(shr(n, 8), 255))
442 r = n%256; n = (n-r)/256; wputb(r); 444 wputb(band(shr(n, 16), 255))
443 r = n%256; n = (n-r)/256; wputb(r); wputb(n); 445 wputb(shr(n, 24))
444 elseif tn == "table" then 446 elseif tn == "table" then
445 wputlabel("IMM_", n[1], 1) 447 wputlabel("IMM_", n[1], 1)
446 else 448 else
@@ -464,24 +466,23 @@ local function wputop(sz, op, rex)
464 if sz == "w" then wputb(102) end 466 if sz == "w" then wputb(102) end
465 -- Needs >32 bit numbers, but only for crc32 eax, word [ebx] 467 -- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
466 if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end 468 if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
467 if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end 469 if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end
468 if op >= 65536 then 470 if op >= 65536 then
469 if rex ~= 0 then 471 if rex ~= 0 then
470 local opc3 = op - op % 256 472 local opc3 = band(op, 0xffff00)
471 if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then 473 if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
472 wputb(64 + rex % 16); rex = 0 474 wputb(64 + band(rex, 15)); rex = 0
473 end 475 end
474 end 476 end
475 r = op % 65536 wputb((op-r) / 65536) op = r 477 wputb(shr(op, 16)); op = band(op, 0xffff)
476 end 478 end
477 if op >= 256 then 479 if op >= 256 then
478 r = op % 256 480 local b = shr(op, 8)
479 local b = (op-r) / 256 481 if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0 end
480 if b == 15 and rex ~= 0 then wputb(64 + rex % 16); rex = 0 end
481 wputb(b) 482 wputb(b)
482 op = r 483 op = band(op, 255)
483 end 484 end
484 if rex ~= 0 then wputb(64 + rex % 16) end 485 if rex ~= 0 then wputb(64 + band(rex, 15)) end
485 if sz == "b" then op = op - 1 end 486 if sz == "b" then op = op - 1 end
486 wputb(op) 487 wputb(op)
487end 488end
@@ -489,7 +490,7 @@ end
489-- Put ModRM or SIB formatted byte. 490-- Put ModRM or SIB formatted byte.
490local function wputmodrm(m, s, rm, vs, vrm) 491local function wputmodrm(m, s, rm, vs, vrm)
491 assert(m < 4 and s < 16 and rm < 16, "bad modrm operands") 492 assert(m < 4 and s < 16 and rm < 16, "bad modrm operands")
492 wputb(64*m + 8*(s%8) + (rm%8)) 493 wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7))
493end 494end
494 495
495-- Put ModRM/SIB plus optional displacement. 496-- Put ModRM/SIB plus optional displacement.
@@ -548,7 +549,7 @@ local function wputmrmsib(t, imark, s, vsreg)
548 549
549 local m 550 local m
550 if tdisp == "number" then -- Check displacement size at assembly time. 551 if tdisp == "number" then -- Check displacement size at assembly time.
551 if disp == 0 and (reg%8) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too) 552 if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
552 if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0] 553 if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]
553 elseif disp >= -128 and disp <= 127 then m = 1 554 elseif disp >= -128 and disp <= 127 then m = 1
554 else m = 2 end 555 else m = 2 end
@@ -557,7 +558,7 @@ local function wputmrmsib(t, imark, s, vsreg)
557 end 558 end
558 559
559 -- Index register present or esp as base register: need SIB encoding. 560 -- Index register present or esp as base register: need SIB encoding.
560 if xreg or (reg%8) == 4 then 561 if xreg or band(reg, 7) == 4 then
561 wputmodrm(m or 2, s, 4) -- ModRM. 562 wputmodrm(m or 2, s, 4) -- ModRM.
562 if m == nil or imark == "I" then waction("MARK") end 563 if m == nil or imark == "I" then waction("MARK") end
563 if vsreg then waction("VREG", vsreg); wputxb(2) end 564 if vsreg then waction("VREG", vsreg); wputxb(2) end
@@ -1410,7 +1411,7 @@ local map_op = {
1410-- Arithmetic ops. 1411-- Arithmetic ops.
1411for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3, 1412for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
1412 ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do 1413 ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
1413 local n8 = n * 8 1414 local n8 = shl(n, 3)
1414 map_op[name.."_2"] = format( 1415 map_op[name.."_2"] = format(
1415 "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi", 1416 "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi",
1416 1+n8, 3+n8, n, n, 5+n8, n) 1417 1+n8, 3+n8, n, n, 5+n8, n)
@@ -1432,7 +1433,7 @@ end
1432-- FP arithmetic ops. 1433-- FP arithmetic ops.
1433for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3, 1434for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
1434 sub = 4, subr = 5, div = 6, divr = 7 } do 1435 sub = 4, subr = 5, div = 6, divr = 7 } do
1435 local nc = 192 + n * 8 1436 local nc = 0xc0 + shl(n, 3)
1436 local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8)) 1437 local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
1437 local fn = "f"..name 1438 local fn = "f"..name
1438 map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n) 1439 map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n)
@@ -1448,8 +1449,7 @@ end
1448 1449
1449-- FP conditional moves. 1450-- FP conditional moves.
1450for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do 1451for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
1451 local n4 = n % 4 1452 local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6)
1452 local nc = 56000 + n4 * 8 + (n-n4) * 64
1453 map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+ 1453 map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
1454 map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+ 1454 map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
1455end 1455end
@@ -1499,10 +1499,10 @@ local function dopattern(pat, args, sz, op, needrex)
1499 local s 1499 local s
1500 if addin then 1500 if addin then
1501 s = addin.reg 1501 s = addin.reg
1502 opcode = opcode - (s%8) -- Undo regno opcode merge. 1502 opcode = opcode - band(s, 7) -- Undo regno opcode merge.
1503 else 1503 else
1504 s = opcode % 16 -- Undo last digit. 1504 s = band(opcode, 15) -- Undo last digit.
1505 opcode = (opcode - s) / 16 1505 opcode = shr(opcode, 4)
1506 end 1506 end
1507 local nn = c == "m" and 1 or 2 1507 local nn = c == "m" and 1 or 2
1508 local t = args[nn] 1508 local t = args[nn]
@@ -1699,7 +1699,7 @@ if x64 then
1699 werror("bad operand mode") 1699 werror("bad operand mode")
1700 end 1700 end
1701 op64 = params[2] 1701 op64 = params[2]
1702 opcode = 0xb8 + (a.reg%8) -- !x64: no VREG support. 1702 opcode = 0xb8 + band(a.reg, 7) -- !x64: no VREG support.
1703 rex = a.reg > 7 and 9 or 8 1703 rex = a.reg > 7 and 9 or 8
1704 end 1704 end
1705 end 1705 end