/* Action definitions. DASM_STOP must be 255. */
enum {
- DASM_DISP = 232,
+ DASM_DISP = 231,
DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
- DASM_IMM_LG, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
+ DASM_IMM_LG, DASM_IMM_LG64, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
DASM_ALIGN, DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
};
} else {
int *pl, n;
switch (action) {
+ case DASM_IMM_LG64: ofs += 4;
case DASM_REL_LG:
case DASM_IMM_LG:
n = *p++; pl = D->lglabels + n;
pos += 2;
break;
}
- case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
+ case DASM_SPACE: case DASM_IMM_LG: case DASM_IMM_LG64: case DASM_VREG: p++;
case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: case DASM_IMM_PC64:
n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
goto wd;
}
+ case DASM_IMM_LG64: {
+ p++;
+ if (n < 0)
+ dasmq((ptrdiff_t)D->globals[-n]);
+ }
case DASM_IMM_PC64: {
int *pb = DASM_POS2PTR(D, n);
dasmq(*pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base));
"SETLABEL", "REL_A",
-- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
"REL_LG", "REL_PC",
- -- action arg (1 byte) or int arg, 1 buffer pos (link):
- "IMM_LG", "IMM_PC", "IMM_PC64",
+ -- action arg (1 byte) or ptrdiff_t arg, 1 buffer pos (link):
+ "IMM_LG", "IMM_LG64", "IMM_PC", "IMM_PC64",
-- action arg (1 byte) or int arg, 1 buffer pos (offset):
"LABEL_LG", "LABEL_PC",
-- action arg (1 byte), 1 buffer pos (offset):
end
wputxb(imm)
else
- if aprefix == "IMM_" and x64 then
- waction("IMM_PC64", imm, num)
- else
- waction(aprefix.."PC", imm, num)
- end
+ waction(aprefix.."PC", imm, num)
+ end
+end
+
+-- Put action for label arg (IMM_LG64, IMM_PC64, REL_LG, REL_PC).
+local function wputlabel64(aprefix, imm, num)
+ if type(imm) == "number" then
+ waction("IMM_LG64", nil, num);
+ wputxb(imm)
+ else
+ waction("IMM_PC64", imm, num)
end
end
else waction("IMM_W", n) end
end
+-- Put signed or unsigned qword or arg.
+local function wputqarg(n)
+ local tn = type(n)
+ if tn == "number" then
+ wputb(band(n, 255))
+ wputb(band(shr(n, 8), 255))
+ wputb(band(shr(n, 16), 255))
+ wputb(band(shr(n, 24), 255))
+ wputb(band(shr(n, 32), 255))
+ wputb(band(shr(n, 40), 255))
+ wputb(band(shr(n, 48), 255))
+ wputb(shr(n, 56))
+ elseif tn == "table" then
+ wputlabel64("IMM_", n[1], 1)
+ else
+ waction("IMM_D", format("(unsigned int)(%s)", n))
+ waction("IMM_D", format("(unsigned int)((%s)>>32)", n))
+ end
+end
+
-- Put signed or unsigned dword or arg.
local function wputdarg(n)
local tn = type(n)
werror("bad mode or size in `"..p.."'")
end
if a.mode == "iJ" then
- wputlabel("IMM_", a.imm, 1)
+ if sz == 'q' then
+ wputlabel64("IMM_", a.imm, 1)
+ else
+ wputlabel("IMM_", a.imm, 1)
+ end
else
- wputszarg(sz, a.imm)
+ if sz == 'q' then
+ wputqarg(a.imm)
+ else
+ wputszarg(sz, a.imm)
+ end
end
if secpos+2 > maxsecpos then wflush() end
end