mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Make more improvements
This change includes many bug fixes, for the NT polyfills, strings, memory, boot, and math libraries which were discovered by adding more tools for recreational programming, such as PC emulation. Lemon has also been vendored because it works so well at parsing languages.
This commit is contained in:
parent
416fd86676
commit
23d333c090
201 changed files with 14558 additions and 3082 deletions
|
@ -24,23 +24,27 @@
|
|||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/build/lib/demangle.h"
|
||||
#include "tool/build/lib/dis.h"
|
||||
#include "tool/build/lib/endian.h"
|
||||
#include "tool/build/lib/high.h"
|
||||
#include "tool/build/lib/modrm.h"
|
||||
|
||||
static const char kScale[4][4] = {"", ",2", ",4", ",8"};
|
||||
static const char kSegName[8][3] = {"es", "cs", "ss", "ds", "fs", "gs"};
|
||||
static const char kPuttingOnTheRiz[2][4] = {"eiz", "riz"};
|
||||
static const char kPuttingOnTheRip[2][4] = {"eip", "rip"};
|
||||
static const char kRiz[2][4] = {"eiz", "riz"};
|
||||
static const char kRip[2][4] = {"eip", "rip"};
|
||||
static const char kSka[4][4] = {"", ",2", ",4", ",8"};
|
||||
static const char kSeg[8][3] = {"es", "cs", "ss", "ds", "fs", "gs"};
|
||||
static const char kCtl[8][4] = {"cr0", "wut", "cr2", "cr3",
|
||||
"cr4", "wut", "wut", "wut"};
|
||||
|
||||
static const char kRegisterName8[2][2][8][5] = {
|
||||
static const char kBreg[2][2][8][5] = {
|
||||
{{"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"},
|
||||
{"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil"}},
|
||||
{{"wut", "wut", "wut", "wut", "wut", "wut", "wut", "wut"},
|
||||
{"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"}},
|
||||
};
|
||||
|
||||
static const char kRegisterName[2][2][2][8][5] = {
|
||||
static const char kGreg[2][2][2][8][5] = {
|
||||
{{{"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"},
|
||||
{"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"}},
|
||||
{{"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"},
|
||||
|
@ -51,43 +55,39 @@ static const char kRegisterName[2][2][2][8][5] = {
|
|||
{"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}},
|
||||
};
|
||||
|
||||
static const char kControlName[8][4] = {
|
||||
"cr0", "wut", "cr2", "cr3", "cr4", "wut", "wut", "wut",
|
||||
};
|
||||
|
||||
static int64_t RipRelative(struct DisBuilder b, int64_t d) {
|
||||
return b.addr + b.xedd->length + d;
|
||||
static int64_t RipRelative(struct Dis *d, int64_t i) {
|
||||
return d->addr + d->xedd->length + i;
|
||||
}
|
||||
|
||||
static const char *GetAddrReg(struct DisBuilder b, uint32_t rde, uint8_t x,
|
||||
static const char *GetAddrReg(struct Dis *d, uint32_t rde, uint8_t x,
|
||||
uint8_t r) {
|
||||
return kRegisterName[Eamode(rde) == XED_MODE_REAL]
|
||||
[Eamode(rde) == XED_MODE_LONG][x & 1][r & 7];
|
||||
return kGreg[Eamode(rde) == XED_MODE_REAL][Eamode(rde) == XED_MODE_LONG]
|
||||
[x & 1][r & 7];
|
||||
}
|
||||
|
||||
static char *DisRegister(char *p, const char *s) {
|
||||
if (g_dis_high) p = DisHigh(p, g_dis_high->reg);
|
||||
p = HighStart(p, g_high.reg);
|
||||
*p++ = '%';
|
||||
p = stpcpy(p, s);
|
||||
if (g_dis_high) p = DisHigh(p, -1);
|
||||
p = HighEnd(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisComment(char *p, const char *s) {
|
||||
if (g_dis_high) p = DisHigh(p, g_dis_high->comment);
|
||||
p = HighStart(p, g_high.comment);
|
||||
p = stpcpy(p, s);
|
||||
if (g_dis_high) p = DisHigh(p, -1);
|
||||
p = HighEnd(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisRegisterByte(struct DisBuilder b, uint32_t rde, char *p, bool g,
|
||||
static char *DisRegisterByte(struct Dis *d, uint32_t rde, char *p, bool g,
|
||||
int r) {
|
||||
return DisRegister(p, kRegisterName8[g][Rex(rde)][r]);
|
||||
return DisRegister(p, kBreg[g][Rex(rde)][r]);
|
||||
}
|
||||
|
||||
static char *DisRegisterWord(struct DisBuilder b, uint32_t rde, char *p, bool g,
|
||||
static char *DisRegisterWord(struct Dis *d, uint32_t rde, char *p, bool g,
|
||||
int r) {
|
||||
return DisRegister(p, kRegisterName[Osz(rde)][Rexw(rde)][g][r]);
|
||||
return DisRegister(p, kGreg[Osz(rde)][Rexw(rde)][g][r]);
|
||||
}
|
||||
|
||||
static char *DisInt(char *p, int64_t x) {
|
||||
|
@ -106,14 +106,14 @@ static char *DisInt(char *p, int64_t x) {
|
|||
return p;
|
||||
}
|
||||
|
||||
static char *DisSym(struct DisBuilder b, char *p, int64_t addr) {
|
||||
static char *DisSym(struct Dis *d, char *p, int64_t addr) {
|
||||
long sym;
|
||||
int64_t addend;
|
||||
const char *name;
|
||||
if ((sym = DisFindSym(b.dis, addr)) != -1 && b.dis->syms.p[sym].name) {
|
||||
addend = addr - b.dis->syms.p[sym].addr;
|
||||
name = b.dis->syms.stab + b.dis->syms.p[sym].name;
|
||||
p = stpcpy(p, name);
|
||||
if ((sym = DisFindSym(d, addr)) != -1 && d->syms.p[sym].name) {
|
||||
addend = addr - d->syms.p[sym].addr;
|
||||
name = d->syms.stab + d->syms.p[sym].name;
|
||||
p = Demangle(p, name);
|
||||
if (addend) {
|
||||
*p++ = '+';
|
||||
p = DisInt(p, addend);
|
||||
|
@ -124,79 +124,69 @@ static char *DisSym(struct DisBuilder b, char *p, int64_t addr) {
|
|||
}
|
||||
}
|
||||
|
||||
static char *DisSymLiteral(struct DisBuilder b, char *p, uint64_t x) {
|
||||
static char *DisSymLiteral(struct Dis *d, char *p, uint64_t x) {
|
||||
*p++ = '$';
|
||||
if (g_dis_high) p = DisHigh(p, g_dis_high->literal);
|
||||
p = DisSym(b, p, x);
|
||||
if (g_dis_high) p = DisHigh(p, -1);
|
||||
p = HighStart(p, g_high.literal);
|
||||
p = DisSym(d, p, x);
|
||||
p = HighEnd(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisXmm(struct DisBuilder b, uint32_t rde, char *p, const char *s,
|
||||
int reg) {
|
||||
if (g_dis_high) p = DisHigh(p, g_dis_high->reg);
|
||||
*p++ = '%';
|
||||
p = stpcpy(p, s);
|
||||
p += uint64toarray_radix10(Rexr(rde) << 3 | reg, p);
|
||||
if (g_dis_high) p = DisHigh(p, -1);
|
||||
return p;
|
||||
static char *DisGvqp(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegisterWord(d, rde, p, Rexr(rde), ModrmReg(rde));
|
||||
}
|
||||
|
||||
static char *DisGvqp(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegisterWord(b, rde, p, Rexr(rde), ModrmReg(rde));
|
||||
static char *DisGdqp(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[0][Rexw(rde)][Rexr(rde)][ModrmReg(rde)]);
|
||||
}
|
||||
|
||||
static char *DisGdqp(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kRegisterName[0][Rexw(rde)][Rexr(rde)][ModrmReg(rde)]);
|
||||
static char *DisGb(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegisterByte(d, rde, p, Rexr(rde), ModrmReg(rde));
|
||||
}
|
||||
|
||||
static char *DisGb(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegisterByte(b, rde, p, Rexr(rde), ModrmReg(rde));
|
||||
}
|
||||
|
||||
static char *DisSego(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisSego(struct Dis *d, uint32_t rde, char *p) {
|
||||
int seg;
|
||||
seg = Sego(rde) ? Sego(rde) : b.xedd->op.hint;
|
||||
seg = Sego(rde) ? Sego(rde) : d->xedd->op.hint;
|
||||
if (seg) {
|
||||
p = DisRegister(p, kSegName[seg - 1]);
|
||||
p = DisRegister(p, kSeg[seg - 1]);
|
||||
*p++ = ':';
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisM(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisM(struct Dis *d, uint32_t rde, char *p) {
|
||||
int64_t disp;
|
||||
const char *base, *index, *scale;
|
||||
p = DisSego(b, rde, p);
|
||||
p = DisSego(d, rde, p);
|
||||
base = index = scale = NULL;
|
||||
if (ModrmMod(rde) == 0b01 || ModrmMod(rde) == 0b10 || IsRipRelative(rde) ||
|
||||
(Eamode(rde) == XED_MODE_REAL && ModrmRm(rde) == 6 && !ModrmMod(rde)) ||
|
||||
(ModrmMod(rde) == 0b00 && ModrmRm(rde) == 0b100 &&
|
||||
SibBase(b.xedd) == 0b101)) {
|
||||
disp = b.xedd->op.disp;
|
||||
if (IsRipRelative(rde)) disp = RipRelative(b, disp);
|
||||
p = DisSym(b, p, disp);
|
||||
SibBase(d->xedd) == 0b101)) {
|
||||
disp = d->xedd->op.disp;
|
||||
if (IsRipRelative(rde)) disp = RipRelative(d, disp);
|
||||
p = DisSym(d, p, disp);
|
||||
}
|
||||
if (Eamode(rde) != XED_MODE_REAL) {
|
||||
if (!SibExists(rde)) {
|
||||
DCHECK(!b.xedd->op.has_sib);
|
||||
DCHECK(!d->xedd->op.has_sib);
|
||||
if (IsRipRelative(rde)) {
|
||||
if (Mode(rde) == XED_MODE_LONG) {
|
||||
base = kPuttingOnTheRip[Eamode(rde) == XED_MODE_LONG];
|
||||
base = kRip[Eamode(rde) == XED_MODE_LONG];
|
||||
}
|
||||
} else {
|
||||
base = GetAddrReg(b, rde, Rexb(rde), ModrmRm(rde));
|
||||
base = GetAddrReg(d, rde, Rexb(rde), ModrmRm(rde));
|
||||
}
|
||||
} else if (!SibIsAbsolute(b.xedd, rde)) {
|
||||
if (SibHasBase(b.xedd, rde)) {
|
||||
base = GetAddrReg(b, rde, Rexb(rde), SibBase(b.xedd));
|
||||
} else if (!SibIsAbsolute(d->xedd, rde)) {
|
||||
if (SibHasBase(d->xedd, rde)) {
|
||||
base = GetAddrReg(d, rde, Rexb(rde), SibBase(d->xedd));
|
||||
}
|
||||
if (SibHasIndex(b.xedd)) {
|
||||
index = GetAddrReg(b, rde, Rexx(b.xedd), SibIndex(b.xedd));
|
||||
} else if (b.xedd->op.scale) {
|
||||
index = kPuttingOnTheRiz[Eamode(rde) == XED_MODE_LONG];
|
||||
if (SibHasIndex(d->xedd)) {
|
||||
index = GetAddrReg(d, rde, Rexx(d->xedd), SibIndex(d->xedd));
|
||||
} else if (d->xedd->op.scale) {
|
||||
index = kRiz[Eamode(rde) == XED_MODE_LONG];
|
||||
}
|
||||
scale = kScale[b.xedd->op.scale];
|
||||
scale = kSka[d->xedd->op.scale];
|
||||
}
|
||||
} else {
|
||||
switch (ModrmRm(rde)) {
|
||||
|
@ -250,206 +240,235 @@ static char *DisM(struct DisBuilder b, uint32_t rde, char *p) {
|
|||
return p;
|
||||
}
|
||||
|
||||
static char *DisEb(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisRegMem(struct Dis *d, uint32_t rde, char *p,
|
||||
char *f(struct Dis *, uint32_t, char *)) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisRegisterByte(b, rde, p, Rexb(rde), ModrmRm(rde));
|
||||
return f(d, rde, p);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
return DisM(d, rde, p);
|
||||
}
|
||||
}
|
||||
|
||||
static char *DisEvqp(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static noinline char *DisE(struct Dis *d, uint32_t rde, char *p,
|
||||
char *f(struct Dis *, uint32_t, char *, bool, int)) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisRegisterWord(b, rde, p, Rexb(rde), ModrmRm(rde));
|
||||
return f(d, rde, p, Rexb(rde), ModrmRm(rde));
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
return DisM(d, rde, p);
|
||||
}
|
||||
}
|
||||
|
||||
static char *DisEdqp(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisRegister(p, kRegisterName[0][Rexw(rde)][Rexb(rde)][ModrmRm(rde)]);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisEb(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisE(d, rde, p, DisRegisterByte);
|
||||
}
|
||||
|
||||
static char *DisEv(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
const char *s;
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisRegister(p, kRegisterName[Osz(rde)][0][Rexb(rde)][ModrmRm(rde)]);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisEvqp(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisE(d, rde, p, DisRegisterWord);
|
||||
}
|
||||
|
||||
static char *DisGvq(struct DisBuilder b, uint32_t rde, char *p, int r) {
|
||||
static char *DisEdqpReg(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[0][Rexw(rde)][Rexb(rde)][ModrmRm(rde)]);
|
||||
}
|
||||
|
||||
static char *DisEdqp(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisEdqpReg);
|
||||
}
|
||||
|
||||
static char *DisEvReg(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[Osz(rde)][0][Rexb(rde)][ModrmRm(rde)]);
|
||||
}
|
||||
|
||||
static char *DisEv(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisEvReg);
|
||||
}
|
||||
|
||||
static char *DisGvq(struct Dis *d, uint32_t rde, char *p, int r) {
|
||||
const char *s;
|
||||
if (Mode(rde) == XED_MODE_LONG) {
|
||||
s = kRegisterName[Osz(rde)][!Osz(rde)][Rexb(rde)][r];
|
||||
s = kGreg[Osz(rde)][!Osz(rde)][Rexb(rde)][r];
|
||||
} else {
|
||||
s = kRegisterName[Osz(rde)][0][Rexb(rde)][r];
|
||||
s = kGreg[Osz(rde)][0][Rexb(rde)][r];
|
||||
}
|
||||
return DisRegister(p, s);
|
||||
}
|
||||
|
||||
static char *DisZvq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisGvq(b, rde, p, ModrmSrm(rde));
|
||||
static char *DisZvq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisGvq(d, rde, p, ModrmSrm(rde));
|
||||
}
|
||||
|
||||
static char *DisEvq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisGvq(b, rde, p, ModrmRm(rde));
|
||||
static char *DisEvqReg(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisGvq(d, rde, p, ModrmRm(rde));
|
||||
}
|
||||
|
||||
static char *DisEvq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisEvqReg);
|
||||
}
|
||||
|
||||
static char *DisEdReg(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[0][0][Rexb(rde)][ModrmRm(rde)]);
|
||||
}
|
||||
|
||||
static char *DisEd(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisEdReg);
|
||||
}
|
||||
|
||||
static char *DisEqReg(struct Dis *d, uint32_t rde, char *p) {
|
||||
const char *r;
|
||||
if (Mode(rde) == XED_MODE_LONG) {
|
||||
r = kGreg[0][1][Rexb(rde)][ModrmRm(rde)];
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
r = kGreg[Osz(rde)][0][Rexb(rde)][ModrmRm(rde)];
|
||||
}
|
||||
return DisRegister(p, r);
|
||||
}
|
||||
|
||||
static char *DisEd(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisRegister(p, kRegisterName[0][0][Rexb(rde)][ModrmRm(rde)]);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisEq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisEqReg);
|
||||
}
|
||||
|
||||
static char *DisEq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisRegister(p, kRegisterName[0][1][Rexb(rde)][ModrmRm(rde)]);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisZvqp(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegisterWord(d, rde, p, Rexb(rde), ModrmSrm(rde));
|
||||
}
|
||||
|
||||
static char *DisZvqp(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegisterWord(b, rde, p, Rexb(rde), ModrmSrm(rde));
|
||||
static char *DisZb(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegisterByte(d, rde, p, Rexb(rde), ModrmSrm(rde));
|
||||
}
|
||||
|
||||
static char *DisZb(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegisterByte(b, rde, p, Rexb(rde), ModrmSrm(rde));
|
||||
static char *DisEax(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[Osz(rde)][0][0][0]);
|
||||
}
|
||||
|
||||
static char *DisEax(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kRegisterName[Osz(rde)][0][0][0]);
|
||||
static char *DisRax(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[Osz(rde)][Rexw(rde)][0][0]);
|
||||
}
|
||||
|
||||
static char *DisRax(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kRegisterName[Osz(rde)][Rexw(rde)][0][0]);
|
||||
static char *DisRdx(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[Osz(rde)][Rexw(rde)][0][2]);
|
||||
}
|
||||
|
||||
static char *DisRdx(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kRegisterName[Osz(rde)][Rexw(rde)][0][2]);
|
||||
static char *DisCd(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kCtl[ModrmReg(rde)]);
|
||||
}
|
||||
|
||||
static char *DisCd(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kControlName[ModrmReg(rde)]);
|
||||
static char *DisHd(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegister(p, kGreg[0][Mode(rde) == XED_MODE_LONG][0][ModrmRm(rde)]);
|
||||
}
|
||||
|
||||
static char *DisHd(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisRegister(
|
||||
p, kRegisterName[0][Mode(rde) == XED_MODE_LONG][0][ModrmRm(rde)]);
|
||||
static char *DisImm(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisSymLiteral(d, p, d->xedd->op.uimm0);
|
||||
}
|
||||
|
||||
static char *DisImm(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisSymLiteral(b, p, b.xedd->op.uimm0);
|
||||
static char *DisRvds(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisSymLiteral(d, p, d->xedd->op.disp);
|
||||
}
|
||||
|
||||
static char *DisRvds(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisSymLiteral(b, p, b.xedd->op.disp);
|
||||
}
|
||||
|
||||
static char *DisKvds(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisKpvds(struct Dis *d, uint32_t rde, char *p, uint64_t x) {
|
||||
*p++ = '$';
|
||||
if (g_dis_high) p = DisHigh(p, g_dis_high->literal);
|
||||
p = DisInt(p, b.xedd->op.uimm0);
|
||||
if (g_dis_high) p = DisHigh(p, -1);
|
||||
p = HighStart(p, g_high.literal);
|
||||
p = DisInt(p, x);
|
||||
p = HighEnd(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisOne(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisKvds(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisKpvds(d, rde, p, d->xedd->op.uimm0);
|
||||
}
|
||||
|
||||
static char *DisPvds(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisKpvds(d, rde, p,
|
||||
d->xedd->op.disp & (Osz(rde) ? 0xffff : 0xffffffff));
|
||||
}
|
||||
|
||||
static char *DisOne(struct Dis *d, uint32_t rde, char *p) {
|
||||
*p++ = '$';
|
||||
if (g_dis_high) p = DisHigh(p, g_dis_high->literal);
|
||||
p = HighStart(p, g_high.literal);
|
||||
p = stpcpy(p, "1");
|
||||
if (g_dis_high) p = DisHigh(p, -1);
|
||||
p = HighEnd(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisJbs(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (b.xedd->op.disp > 0) *p++ = '+';
|
||||
p += int64toarray_radix10(b.xedd->op.disp, p);
|
||||
static char *DisJbs(struct Dis *d, uint32_t rde, char *p) {
|
||||
if (d->xedd->op.disp > 0) *p++ = '+';
|
||||
p += int64toarray_radix10(d->xedd->op.disp, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisJb(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (b.xedd->op.disp > 0) *p++ = '+';
|
||||
p += uint64toarray_radix10(b.xedd->op.disp & 0xff, p);
|
||||
static char *DisJb(struct Dis *d, uint32_t rde, char *p) {
|
||||
if (d->xedd->op.disp > 0) *p++ = '+';
|
||||
p += uint64toarray_radix10(d->xedd->op.disp & 0xff, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisJvds(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisSym(b, p, RipRelative(b, b.xedd->op.disp));
|
||||
static char *DisJvds(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisSym(d, p, RipRelative(d, d->xedd->op.disp));
|
||||
}
|
||||
|
||||
static char *DisAbs(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisSym(b, p, b.xedd->op.disp);
|
||||
static char *DisAbs(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisSym(d, p, d->xedd->op.disp);
|
||||
}
|
||||
|
||||
static char *DisSw(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (kSegName[ModrmReg(rde)][0]) p = DisRegister(p, kSegName[ModrmReg(rde)]);
|
||||
static char *DisSw(struct Dis *d, uint32_t rde, char *p) {
|
||||
if (kSeg[ModrmReg(rde)][0]) p = DisRegister(p, kSeg[ModrmReg(rde)]);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisSpecialAddr(struct DisBuilder b, uint32_t rde, char *p, int r) {
|
||||
static char *DisSpecialAddr(struct Dis *d, uint32_t rde, char *p, int r) {
|
||||
*p++ = '(';
|
||||
p = DisRegister(p, GetAddrReg(b, rde, 0, r));
|
||||
p = DisRegister(p, GetAddrReg(d, rde, 0, r));
|
||||
*p++ = ')';
|
||||
*p = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisY(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisSpecialAddr(b, rde, p, 7); // es:di
|
||||
static char *DisY(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisSpecialAddr(d, rde, p, 7); // es:di
|
||||
}
|
||||
|
||||
static char *DisX(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
DisSego(b, rde, p);
|
||||
return DisSpecialAddr(b, rde, p, 6); // ds:si
|
||||
static char *DisX(struct Dis *d, uint32_t rde, char *p) {
|
||||
DisSego(d, rde, p);
|
||||
return DisSpecialAddr(d, rde, p, 6); // ds:si
|
||||
}
|
||||
|
||||
static char *DisBBb(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
DisSego(b, rde, p);
|
||||
return DisSpecialAddr(b, rde, p, 3); // ds:bx
|
||||
static char *DisBBb(struct Dis *d, uint32_t rde, char *p) {
|
||||
DisSego(d, rde, p);
|
||||
return DisSpecialAddr(d, rde, p, 3); // ds:bx
|
||||
}
|
||||
|
||||
static char *DisNq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisXmm(b, rde, p, "mm", ModrmRm(rde));
|
||||
static char *DisXmm(struct Dis *d, uint32_t rde, char *p, const char *s,
|
||||
int reg) {
|
||||
p = HighStart(p, g_high.reg);
|
||||
*p++ = '%';
|
||||
p = stpcpy(p, s);
|
||||
p += uint64toarray_radix10(reg, p);
|
||||
p = HighEnd(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisUq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisXmm(b, rde, p, "mm", ModrmRm(rde));
|
||||
static char *DisNq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisXmm(d, rde, p, "mm", ModrmRm(rde));
|
||||
}
|
||||
|
||||
static char *DisPq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisXmm(b, rde, p, "mm", ModrmReg(rde));
|
||||
static char *DisPq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisXmm(d, rde, p, "mm", ModrmReg(rde));
|
||||
}
|
||||
|
||||
static char *DisUdq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisXmm(b, rde, p, "xmm", ModrmRm(rde));
|
||||
static char *DisUq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisXmm(d, rde, p, "xmm", RexbRm(rde));
|
||||
}
|
||||
|
||||
static char *DisVdq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
return DisXmm(b, rde, p, "xmm", ModrmReg(rde));
|
||||
static char *DisUdq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisXmm(d, rde, p, "xmm", RexbRm(rde));
|
||||
}
|
||||
|
||||
static char *DisQq(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisNq(b, rde, p);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisVdq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisXmm(d, rde, p, "xmm", RexrReg(rde));
|
||||
}
|
||||
|
||||
static char *DisEst(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisQq(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisNq);
|
||||
}
|
||||
|
||||
static char *DisEst(struct Dis *d, uint32_t rde, char *p) {
|
||||
p = DisRegister(p, "st");
|
||||
if (ModrmRm(rde) != 0) {
|
||||
*p++ = '(';
|
||||
|
@ -460,29 +479,21 @@ static char *DisEst(struct DisBuilder b, uint32_t rde, char *p) {
|
|||
return p;
|
||||
}
|
||||
|
||||
static char *DisEst1(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
static char *DisEst1(struct Dis *d, uint32_t rde, char *p) {
|
||||
if (ModrmRm(rde) != 1) {
|
||||
p = DisEst(b, rde, p);
|
||||
p = DisEst(d, rde, p);
|
||||
} else {
|
||||
*p = '\0';
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *DisEssr(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisEst(b, rde, p);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisEssr(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisEst);
|
||||
}
|
||||
|
||||
static char *DisWps(struct DisBuilder b, uint32_t rde, char *p) {
|
||||
if (IsModrmRegister(rde)) {
|
||||
return DisUdq(b, rde, p);
|
||||
} else {
|
||||
return DisM(b, rde, p);
|
||||
}
|
||||
static char *DisWps(struct Dis *d, uint32_t rde, char *p) {
|
||||
return DisRegMem(d, rde, p, DisUdq);
|
||||
}
|
||||
|
||||
#define DisEdr DisM
|
||||
|
@ -537,7 +548,7 @@ static char *DisWps(struct DisBuilder b, uint32_t rde, char *p) {
|
|||
|
||||
static const struct DisArg {
|
||||
char s[8];
|
||||
char *(*f)(struct DisBuilder, uint32_t, char *);
|
||||
char *(*f)(struct Dis *, uint32_t, char *);
|
||||
} kDisArgs[] = /* <sorted> */ {
|
||||
{"$1", DisOne}, //
|
||||
{"%Cd", DisCd}, //
|
||||
|
@ -610,6 +621,7 @@ static const struct DisArg {
|
|||
{"Mwi", DisMwi}, //
|
||||
{"Ob", DisOb}, //
|
||||
{"Ovqp", DisOvqp}, //
|
||||
{"Pvds", DisPvds}, //
|
||||
{"Qpi", DisQpi}, //
|
||||
{"Qq", DisQq}, //
|
||||
{"Rvds", DisRvds}, //
|
||||
|
@ -635,7 +647,7 @@ static int CompareString8(const char a[8], const char b[8]) {
|
|||
return x > y ? 1 : x < y ? -1 : 0;
|
||||
}
|
||||
|
||||
char *DisArg(struct DisBuilder b, char *p, const char *s) {
|
||||
char *DisArg(struct Dis *d, char *p, const char *s) {
|
||||
char key[8];
|
||||
int c, m, l, r;
|
||||
l = 0;
|
||||
|
@ -649,7 +661,7 @@ char *DisArg(struct DisBuilder b, char *p, const char *s) {
|
|||
} else if (c > 0) {
|
||||
r = m - 1;
|
||||
} else {
|
||||
return kDisArgs[m].f(b, b.xedd->op.rde, p);
|
||||
return kDisArgs[m].f(d, d->xedd->op.rde, p);
|
||||
}
|
||||
}
|
||||
if (*s == '%') {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue