aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2021-05-02 22:25:16 +0200
committerMike Pall <mike>2021-05-02 22:25:16 +0200
commit1449663ecff3a51b15fe0113b62979b72690178f (patch)
treec4cda077423d534f3634b5194dfe4182ea68f1cd
parent521b367567dc5d91d7f9ae29c257998953e24e53 (diff)
downloadluajit-1449663ecff3a51b15fe0113b62979b72690178f.tar.gz
luajit-1449663ecff3a51b15fe0113b62979b72690178f.tar.bz2
luajit-1449663ecff3a51b15fe0113b62979b72690178f.zip
DynASM/x86: Fix x64 .aword refs. Add .qword, .quad, .addr and .long.
Suggested by Dmitry Stogov.
-rw-r--r--dynasm/dasm_x86.h24
-rw-r--r--dynasm/dasm_x86.lua42
2 files changed, 55 insertions, 11 deletions
diff --git a/dynasm/dasm_x86.h b/dynasm/dasm_x86.h
index 2e2f2334..d8d4928c 100644
--- a/dynasm/dasm_x86.h
+++ b/dynasm/dasm_x86.h
@@ -239,8 +239,11 @@ void dasm_put(Dst_DECL, int start, ...)
239 } 239 }
240 pos++; 240 pos++;
241 ofs += 4; /* Maximum offset needed. */ 241 ofs += 4; /* Maximum offset needed. */
242 if (action == DASM_REL_LG || action == DASM_REL_PC) 242 if (action == DASM_REL_LG || action == DASM_REL_PC) {
243 b[pos++] = ofs; /* Store pass1 offset estimate. */ 243 b[pos++] = ofs; /* Store pass1 offset estimate. */
244 } else if (sizeof(ptrdiff_t) == 8) {
245 ofs += 4;
246 }
244 break; 247 break;
245 case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel; 248 case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
246 case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC); 249 case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
@@ -365,10 +368,22 @@ int dasm_link(Dst_DECL, size_t *szp)
365 do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0) 368 do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
366#define dasmd(x) \ 369#define dasmd(x) \
367 do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0) 370 do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
371#define dasmq(x) \
372 do { *((unsigned long long *)cp) = (unsigned long long)(x); cp+=8; } while (0)
368#else 373#else
369#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0) 374#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
370#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0) 375#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
376#define dasmq(x) do { dasmd(x); dasmd((x)>>32); } while (0)
371#endif 377#endif
378static unsigned char *dasma_(unsigned char *cp, ptrdiff_t x)
379{
380 if (sizeof(ptrdiff_t) == 8)
381 dasmq((unsigned long long)x);
382 else
383 dasmd((unsigned int)x);
384 return cp;
385}
386#define dasma(x) (cp = dasma_(cp, (x)))
372 387
373/* Pass 3: Encode sections. */ 388/* Pass 3: Encode sections. */
374int dasm_encode(Dst_DECL, void *buffer) 389int dasm_encode(Dst_DECL, void *buffer)
@@ -443,12 +458,13 @@ int dasm_encode(Dst_DECL, void *buffer)
443 goto wb; 458 goto wb;
444 } 459 }
445 case DASM_IMM_LG: 460 case DASM_IMM_LG:
446 p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; } 461 p++;
462 if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }
447 /* fallthrough */ 463 /* fallthrough */
448 case DASM_IMM_PC: { 464 case DASM_IMM_PC: {
449 int *pb = DASM_POS2PTR(D, n); 465 int *pb = DASM_POS2PTR(D, n);
450 n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base); 466 dasma(*pb < 0 ? (ptrdiff_t)pb[1] : (*pb + (ptrdiff_t)base));
451 goto wd; 467 break;
452 } 468 }
453 case DASM_LABEL_LG: { 469 case DASM_LABEL_LG: {
454 int idx = *p++; 470 int idx = *p++;
diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua
index bc9a0001..0c803dcd 100644
--- a/dynasm/dasm_x86.lua
+++ b/dynasm/dasm_x86.lua
@@ -484,6 +484,22 @@ local function wputdarg(n)
484 end 484 end
485end 485end
486 486
487-- Put signed or unsigned qword or arg.
488local function wputqarg(n)
489 local tn = type(n)
490 if tn == "number" then -- This is only used for numbers from -2^31..2^32-1.
491 wputb(band(n, 255))
492 wputb(band(shr(n, 8), 255))
493 wputb(band(shr(n, 16), 255))
494 wputb(shr(n, 24))
495 local sign = n < 0 and 255 or 0
496 wputb(sign); wputb(sign); wputb(sign); wputb(sign)
497 else
498 waction("IMM_D", format("(unsigned int)(%s)", n))
499 waction("IMM_D", format("(unsigned int)((unsigned long long)(%s)>>32)", n))
500 end
501end
502
487-- Put operand-size dependent number or arg (defaults to dword). 503-- Put operand-size dependent number or arg (defaults to dword).
488local function wputszarg(sz, n) 504local function wputszarg(sz, n)
489 if not sz or sz == "d" or sz == "q" then wputdarg(n) 505 if not sz or sz == "d" or sz == "q" then wputdarg(n)
@@ -663,10 +679,16 @@ local function opmodestr(op, args)
663end 679end
664 680
665-- Convert number to valid integer or nil. 681-- Convert number to valid integer or nil.
666local function toint(expr) 682local function toint(expr, isqword)
667 local n = tonumber(expr) 683 local n = tonumber(expr)
668 if n then 684 if n then
669 if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then 685 if n % 1 ~= 0 then
686 werror("not an integer number `"..expr.."'")
687 elseif isqword then
688 if n < -2147483648 or n > 2147483647 then
689 n = nil -- Handle it as an expression to avoid precision loss.
690 end
691 elseif n < -2147483648 or n > 4294967295 then
670 werror("bad integer number `"..expr.."'") 692 werror("bad integer number `"..expr.."'")
671 end 693 end
672 return n 694 return n
@@ -749,7 +771,7 @@ local function rtexpr(expr)
749end 771end
750 772
751-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }. 773-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
752local function parseoperand(param) 774local function parseoperand(param, isqword)
753 local t = {} 775 local t = {}
754 776
755 local expr = param 777 local expr = param
@@ -837,7 +859,7 @@ local function parseoperand(param)
837 t.disp = dispexpr(tailx) 859 t.disp = dispexpr(tailx)
838 else 860 else
839 -- imm or opsize*imm 861 -- imm or opsize*imm
840 local imm = toint(expr) 862 local imm = toint(expr, isqword)
841 if not imm and sub(expr, 1, 1) == "*" and t.opsize then 863 if not imm and sub(expr, 1, 1) == "*" and t.opsize then
842 imm = toint(sub(expr, 2)) 864 imm = toint(sub(expr, 2))
843 if imm then 865 if imm then
@@ -1952,7 +1974,7 @@ local function dopattern(pat, args, sz, op, needrex)
1952 local a = args[narg] 1974 local a = args[narg]
1953 narg = narg + 1 1975 narg = narg + 1
1954 local mode, imm = a.mode, a.imm 1976 local mode, imm = a.mode, a.imm
1955 if mode == "iJ" and not match("iIJ", c) then 1977 if mode == "iJ" and not match(x64 and "J" or "iIJ", c) then
1956 werror("bad operand size for label") 1978 werror("bad operand size for label")
1957 end 1979 end
1958 if c == "S" then 1980 if c == "S" then
@@ -2144,14 +2166,16 @@ end
2144local function op_data(params) 2166local function op_data(params)
2145 if not params then return "imm..." end 2167 if not params then return "imm..." end
2146 local sz = sub(params.op, 2, 2) 2168 local sz = sub(params.op, 2, 2)
2147 if sz == "a" then sz = addrsize end 2169 if sz == "l" then sz = "d" elseif sz == "a" then sz = addrsize end
2148 for _,p in ipairs(params) do 2170 for _,p in ipairs(params) do
2149 local a = parseoperand(p) 2171 local a = parseoperand(p, sz == "q")
2150 if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then 2172 if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
2151 werror("bad mode or size in `"..p.."'") 2173 werror("bad mode or size in `"..p.."'")
2152 end 2174 end
2153 if a.mode == "iJ" then 2175 if a.mode == "iJ" then
2154 wputlabel("IMM_", a.imm, 1) 2176 wputlabel("IMM_", a.imm, 1)
2177 elseif sz == "q" then
2178 wputqarg(a.imm)
2155 else 2179 else
2156 wputszarg(sz, a.imm) 2180 wputszarg(sz, a.imm)
2157 end 2181 end
@@ -2163,7 +2187,11 @@ map_op[".byte_*"] = op_data
2163map_op[".sbyte_*"] = op_data 2187map_op[".sbyte_*"] = op_data
2164map_op[".word_*"] = op_data 2188map_op[".word_*"] = op_data
2165map_op[".dword_*"] = op_data 2189map_op[".dword_*"] = op_data
2190map_op[".qword_*"] = op_data
2166map_op[".aword_*"] = op_data 2191map_op[".aword_*"] = op_data
2192map_op[".long_*"] = op_data
2193map_op[".quad_*"] = op_data
2194map_op[".addr_*"] = op_data
2167 2195
2168------------------------------------------------------------------------------ 2196------------------------------------------------------------------------------
2169 2197