mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-18 16:40:32 +00:00
Improve signal handling and math
- Polyfill ucontext_t on FreeBSD/OpenBSD/NetBSD - Add tests confirming signals can edit CPU state - Work towards supporting ZIP filesystem on bare metal - Add more tinymath unit tests for POSIX conformance - Add X87 and SSE status flags to crash report - Fix some bugs in blinkenlights - Fix llvm build breakage
This commit is contained in:
parent
cdc54ea1fd
commit
40291c9db3
109 changed files with 2316 additions and 520 deletions
|
@ -21,48 +21,6 @@
|
|||
#include "tool/build/lib/machine.h"
|
||||
#include "tool/build/lib/modrm.h"
|
||||
|
||||
uint64_t AluBsr(struct Machine *m, uint32_t rde, uint64_t x) {
|
||||
unsigned i;
|
||||
if (Rexw(rde)) {
|
||||
x &= 0xffffffffffffffff;
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
return 63 ^ __builtin_clzll(x);
|
||||
} else if (!Osz(rde)) {
|
||||
x &= 0xffffffff;
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
return 31 ^ __builtin_clz(x);
|
||||
} else {
|
||||
x &= 0xffff;
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
for (i = 15; !(x & 0x8000); --i) x <<= 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AluBsf(struct Machine *m, uint32_t rde, uint64_t x) {
|
||||
unsigned i;
|
||||
if (Rexw(rde)) {
|
||||
x &= 0xffffffffffffffff;
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
return __builtin_ctzll(x);
|
||||
} else if (!Osz(rde)) {
|
||||
x &= 0xffffffff;
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
return __builtin_ctz(x);
|
||||
} else {
|
||||
x &= 0xffff;
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
for (i = 0; !(x & 1); ++i) x >>= 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AluPopcnt(struct Machine *m, uint32_t rde, uint64_t x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
|
@ -77,3 +35,111 @@ uint64_t AluPopcnt(struct Machine *m, uint32_t rde, uint64_t x) {
|
|||
x = (x + (x >> 8)) & 0x7f;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t AluBsr(struct Machine *m, uint32_t rde, uint64_t x) {
|
||||
unsigned i;
|
||||
if (Rexw(rde)) {
|
||||
x &= 0xffffffffffffffff;
|
||||
if (Rep(rde) == 3) {
|
||||
if (!x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, false);
|
||||
return 64;
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, x == 1);
|
||||
}
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
}
|
||||
return 63 ^ __builtin_clzll(x);
|
||||
} else if (!Osz(rde)) {
|
||||
x &= 0xffffffff;
|
||||
if (Rep(rde) == 3) {
|
||||
if (!x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, false);
|
||||
return 32;
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, x == 1);
|
||||
}
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
}
|
||||
return 31 ^ __builtin_clz(x);
|
||||
} else {
|
||||
x &= 0xffff;
|
||||
if (Rep(rde) == 3) {
|
||||
if (!x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, false);
|
||||
return 16;
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, x == 1);
|
||||
}
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
}
|
||||
for (i = 15; !(x & 0x8000); --i) x <<= 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AluBsf(struct Machine *m, uint32_t rde, uint64_t x) {
|
||||
unsigned i;
|
||||
if (Rexw(rde)) {
|
||||
x &= 0xffffffffffffffff;
|
||||
if (Rep(rde) == 3) {
|
||||
if (!x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, false);
|
||||
return 64;
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, x & 1);
|
||||
}
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
}
|
||||
return __builtin_ctzll(x);
|
||||
} else if (!Osz(rde)) {
|
||||
x &= 0xffffffff;
|
||||
if (Rep(rde) == 3) {
|
||||
if (!x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, false);
|
||||
return 32;
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, x & 1);
|
||||
}
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
}
|
||||
return __builtin_ctz(x);
|
||||
} else {
|
||||
x &= 0xffff;
|
||||
if (Rep(rde) == 3) {
|
||||
if (!x) {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, true);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, false);
|
||||
return 16;
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_CF, false);
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, x & 1);
|
||||
}
|
||||
} else {
|
||||
m->flags = SetFlag(m->flags, FLAGS_ZF, !x);
|
||||
if (!x) return 0;
|
||||
}
|
||||
for (i = 0; !(x & 1); ++i) x >>= 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,6 +503,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
|
|||
RCASE(0x74, DisOpPqQqVdqWdq(x, p, "pcmpeqb"));
|
||||
RCASE(0x75, DisOpPqQqVdqWdq(x, p, "pcmpeqw"));
|
||||
RCASE(0x76, DisOpPqQqVdqWdq(x, p, "pcmpeqd"));
|
||||
RCASE(0x77, "emms");
|
||||
RCASE(0x80 ... 0x8f, "jCC Jvds");
|
||||
RCASE(0x90 ... 0x9f, "setCC Jvds");
|
||||
RCASE(0xA0, "push %fs");
|
||||
|
@ -524,8 +525,6 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
|
|||
RCASE(0xB7, "movzwWLQ %Gvqp Ew");
|
||||
RCASE(0xB9, "ud %Gvqp Evqp");
|
||||
RCASE(0xBB, "btc Evqp %Gvqp");
|
||||
RCASE(0xBC, "bsf %Gvqp Evqp");
|
||||
RCASE(0xBD, "bsr %Gvqp Evqp");
|
||||
RCASE(0xBE, "movsbWLQ %Gvqp Eb");
|
||||
RCASE(0xBF, "movswWLQ %Gvqp Ew");
|
||||
RCASE(0xC0, "xadd Eb %Gb");
|
||||
|
@ -577,6 +576,18 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
|
|||
RCASE(0xFD, DisOpPqQqVdqWdq(x, p, "paddw"));
|
||||
RCASE(0xFE, DisOpPqQqVdqWdq(x, p, "paddd"));
|
||||
RCASE(0xFF, "ud0 %Gvqp Evqp");
|
||||
case 0xBC:
|
||||
if (Rep(x->op.rde) == 3) {
|
||||
return "tzcnt %Gvqp Evqp";
|
||||
} else {
|
||||
return "bsf %Gvqp Evqp";
|
||||
}
|
||||
case 0xBD:
|
||||
if (Rep(x->op.rde) == 3) {
|
||||
return "lzcnt %Gvqp Evqp";
|
||||
} else {
|
||||
return "bsr %Gvqp Evqp";
|
||||
}
|
||||
case 0x01:
|
||||
switch (ModrmReg(x->op.rde)) {
|
||||
case 0:
|
||||
|
|
|
@ -1664,6 +1664,17 @@ static void OpRdmsr(struct Machine *m, uint32_t rde) {
|
|||
Write32(m->ax, 0);
|
||||
}
|
||||
|
||||
static void OpVzeroupper(struct Machine *m, uint32_t rde) {
|
||||
}
|
||||
|
||||
static void OpEmms(struct Machine *m, uint32_t rde) {
|
||||
if (m->xedd->op.vexvalid) {
|
||||
OpVzeroupper(m, rde);
|
||||
} else {
|
||||
m->fpu.tw = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static const nexgen32e_f kNexgen32e[] = {
|
||||
[0x000] = OpAlubAdd,
|
||||
[0x001] = OpAluw,
|
||||
|
@ -2040,7 +2051,7 @@ static const nexgen32e_f kNexgen32e[] = {
|
|||
[0x174] = OpSsePcmpeqb,
|
||||
[0x175] = OpSsePcmpeqw,
|
||||
[0x176] = OpSsePcmpeqd,
|
||||
[0x177] = OpUd,
|
||||
[0x177] = OpEmms,
|
||||
[0x178] = OpUd,
|
||||
[0x179] = OpUd,
|
||||
[0x17A] = OpUd,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue