Enhance chibicc

This commit is contained in:
Justine Tunney 2020-12-09 04:00:48 -08:00
parent 8da931a7f6
commit 9df2cef4c4
52 changed files with 2606 additions and 2004 deletions

View file

@ -88,12 +88,6 @@ o/$(MODE)/tool/build/emulator.o: \
OVERRIDE_COPTS += \
-fno-sanitize=pointer-overflow
# ifeq (,$(MODE))
# $(TOOL_BUILD_OBJS): \
# OVERRIDE_COPTS += \
# -fsanitize=address
# endif
.PHONY: o/$(MODE)/tool/build
o/$(MODE)/tool/build: \
o/$(MODE)/tool/build/emucrt \

View file

@ -1,230 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/half.h"
#include "dsp/core/q.h"
#include "libc/conv/conv.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/x/x.h"
#include "third_party/gdtoa/gdtoa.h"
#include "third_party/getopt/getopt.h"
#define USAGE \
" [FLAGS] [INT|FLOAT...]\n\
\n\
Example:\n\
\n\
coefficients -n -- 1 4 6 4 1 # Gaussian Blur\n\
coefficients -L16 -H235 -- .299 .587 .114 # BT.601 RGBY\n\
\n\
Flags:\n\
-v verbose\n\
-n normalize\n\
-m FLEX explicit Q(bits)\n\
-L FLEX low data value [default 0]\n\
-H FLEX high data value [default 255]\n\
-? shows this information\n\
\n"
static struct Flags {
bool n;
long L, H, m;
} flags_ = {
.L = 0,
.H = 255,
};
static wontreturn void PrintUsage(int rc, FILE *f) {
fprintf(f, "Usage: %s%s", program_invocation_name, USAGE);
exit(rc);
}
static void GetOpts(int argc, char *argv[]) {
int opt;
while ((opt = getopt(argc, argv, "?nvrL:H:m:")) != -1) {
switch (opt) {
case 'v':
g_loglevel++;
break;
case 'n':
flags_.n = true;
break;
case 'L':
flags_.L = strtol(optarg, NULL, 0);
break;
case 'H':
flags_.H = strtol(optarg, NULL, 0);
break;
case 'm':
flags_.m = strtol(optarg, NULL, 0);
break;
case '?':
PrintUsage(EXIT_SUCCESS, stdout);
default:
PrintUsage(EX_USAGE, stderr);
}
}
}
static void *Normalize(int n, double A[static 8]) {
int i;
double sum, rnorm;
for (sum = i = 0; i < n; ++i) {
sum += A[i];
}
if (fabs(sum - 1) > DBL_MIN * n) {
rnorm = 1 / sum;
for (i = 0; i < n; ++i) {
A[i] *= rnorm;
}
}
return A;
}
static void GetLimits(int n, const long I[static 8], long m, long L, long H,
long res[2][2]) {
int i, j[8];
long x, p[2] = {L, H};
DCHECK(0 < n && n <= 8);
memset(res, 0, sizeof(long) * 2 * 2);
for (j[0] = 0; j[0] < ARRAYLEN(p); ++j[0]) {
for (j[1] = 0; j[1] < ARRAYLEN(p); ++j[1]) {
for (j[2] = 0; j[2] < ARRAYLEN(p); ++j[2]) {
for (j[3] = 0; j[3] < ARRAYLEN(p); ++j[3]) {
for (j[4] = 0; j[4] < ARRAYLEN(p); ++j[4]) {
for (j[5] = 0; j[5] < ARRAYLEN(p); ++j[5]) {
for (j[6] = 0; j[6] < ARRAYLEN(p); ++j[6]) {
for (j[7] = 0; j[7] < ARRAYLEN(p); ++j[7]) {
x = 0;
for (i = 0; i < ARRAYLEN(j); ++i) {
x += p[j[i]] * I[i];
if (x < res[0][0]) res[0][0] = x;
if (x > res[0][1]) res[0][1] = x;
}
x += 1l << (m - 1);
if (x < res[0][0]) res[0][0] = x;
if (x > res[0][1]) res[0][1] = x;
x >>= m;
if (x < res[1][0]) res[1][0] = x;
if (x > res[1][1]) res[1][1] = x;
}
}
}
}
}
}
}
}
}
static const char *GetFittingMachineWord(long L, long H) {
if (-128 <= L && H <= 127) return "int8";
if (0 <= L && H <= 255) return "uint8";
if (-0x8000 <= L && H <= 0x7fff) return "int16";
if (~0x7fffffff <= L && H <= 0x7fffffff) return "int32";
if (0 <= L && H <= 0xffffffff) return "uint32";
return "INT64";
}
static char *DescribeMachineWord(long L, long H) {
return xasprintf("%s[%,ld..%,ld]", GetFittingMachineWord(L, H), L, H);
}
static void ShowBetterCoefficients(int n, double C[static 8], long L, long H) {
long err, I[8], lim[2][2];
char buf[32], kAlphabet[] = "abcdefgh";
int i, j, m, emitted, count, indices[8];
CHECK_LT(L, H);
DCHECK(0 < n && n <= 8);
for (m = 2; m < 40; ++m) {
memset(I, 0, sizeof(I));
if (C[6] || C[7]) {
err = GetIntegerCoefficients8(I, C, m, L, H);
} else {
err = GetIntegerCoefficients(I, C, m, L, H);
}
GetLimits(n, I, m, L, H, lim);
for (count = i = 0; i < n; ++i) {
if (I[i]) {
indices[count++] = i;
}
}
if (count) {
emitted = 0;
if (m) emitted += printf("(");
for (i = 0; i < count; ++i) {
if (i) emitted += printf(" + ");
if (I[indices[i]] != 1) {
emitted += printf("%ld*%c", I[indices[i]], kAlphabet[indices[i]]);
} else {
emitted += printf("%c", kAlphabet[indices[i]]);
}
}
if (m) {
if (m > 1) {
emitted += printf(" + %ld", 1l << (m - 1));
}
emitted += printf(")>>%d", m);
}
printf("%*s", MAX(0, 80 - emitted), " ");
printf("/* %s %s %s ε=%,ld */\n", gc(DescribeMachineWord(L, H)),
gc(DescribeMachineWord(lim[0][0], lim[0][1])),
gc(DescribeMachineWord(lim[1][0], lim[1][1])), err);
}
}
}
static int ReadIdealCoefficients(double C[static 8], int sn, char *S[sn]) {
int i, n;
if ((n = MIN(8, sn)) > 0) {
C[0] = C[1] = C[2] = C[3] = C[4] = C[5] = 0;
for (i = 0; i < n; ++i) {
C[i] = strtod(S[i], NULL);
}
}
return n;
}
int ToolBuildCoefficients(int argc, char *argv[]) {
int n;
double C[8];
GetOpts(argc, argv);
setvbuf(stdout, malloc(PAGESIZE), _IOLBF, PAGESIZE);
if ((n = ReadIdealCoefficients(C, argc - optind, argv + optind))) {
if (flags_.n) Normalize(n, C);
ShowBetterCoefficients(n, C, flags_.L, flags_.H);
}
return 0;
}
int main(int argc, char *argv[]) {
g_loglevel = kLogWarn;
showcrashreports();
return ToolBuildCoefficients(argc, argv);
}

View file

@ -1,267 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/scale/scale.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/conv/conv.h"
#include "libc/fmt/bing.internal.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/testlib/testlib.h"
#include "third_party/gdtoa/gdtoa.h"
#include "third_party/getopt/getopt.h"
#include "third_party/stb/stb_image.h"
#include "third_party/xed/x86.h"
#define USAGE \
" [FLAGS] [PATH]\n\
\n\
Example:\n\
\n\
img2code -cw79 -p2 foo.png\n\
\n\
Flags:\n\
-c compress range\n\
-o PATH out\n\
-r FLEX ratio\n\
-w FLEX new width\n\
-h FLEX new height\n\
-p FLEX pixel y ratio\n\
-? shows this information\n\
\n"
static struct Flags {
const char *o;
double r, p;
int w, h;
bool c;
} flags_ = {
.o = "-",
.p = 1,
};
static wontreturn void PrintUsage(int rc, FILE *f) {
fprintf(f, "Usage: %s%s", program_invocation_name, USAGE);
exit(rc);
}
static void GetOpts(int *argc, char *argv[]) {
int opt;
if (*argc == 2 &&
(strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-help") == 0)) {
PrintUsage(EXIT_SUCCESS, stdout);
}
while ((opt = getopt(*argc, argv, "?co:r:w:h:p:")) != -1) {
switch (opt) {
case 'c':
flags_.c = true;
break;
case 'o':
flags_.o = optarg;
break;
case 'r':
flags_.r = strtod(optarg, NULL);
break;
case 'p':
flags_.p = strtod(optarg, NULL);
break;
case 'w':
flags_.w = strtol(optarg, NULL, 0);
break;
case 'h':
flags_.h = strtol(optarg, NULL, 0);
break;
case '?':
PrintUsage(EXIT_SUCCESS, stdout);
default:
PrintUsage(EX_USAGE, stderr);
}
}
if (optind == *argc) {
argv[(*argc)++] = "-";
}
}
static void GetOutputGeometry(long syn, long sxn, long *out_dyn, long *out_dxn,
double *out_ry, double *out_rx) {
double ry, rx;
long dyn, dxn;
if (!flags_.h && !flags_.w) {
if (flags_.r) {
ry = flags_.r * flags_.p;
rx = flags_.r;
} else {
ry = flags_.p;
rx = 1;
}
dyn = round(syn / ry);
dxn = round(sxn / rx);
} else if (flags_.w && !flags_.h) {
if (flags_.r) {
rx = 1. * sxn / flags_.w;
ry = flags_.r * flags_.p;
dxn = flags_.w;
dyn = round(syn / ry);
} else {
rx = 1. * sxn / flags_.w;
ry = flags_.p * rx;
dxn = flags_.w;
dyn = round(syn / ry);
}
} else if (flags_.h && !flags_.w) {
if (flags_.r) {
rx = flags_.r;
ry = flags_.p * syn / flags_.h;
dxn = flags_.w;
dyn = round(syn / ry);
} else {
ry = flags_.p * syn / flags_.h;
rx = ry;
dyn = flags_.h;
dxn = round(syn / rx);
}
} else {
ry = flags_.p;
rx = 1;
dyn = round(flags_.h / ry);
dxn = flags_.w;
}
*out_dyn = dyn;
*out_dxn = dxn;
*out_ry = ry;
*out_rx = rx;
}
static void *Deinterlace(long dcn, long dyn, long dxn,
unsigned char dst[dcn][dyn][dxn], long syw, long sxw,
long scw, const unsigned char src[syw][sxw][scw],
long syn, long sxn, long sy0, long sx0, long sc0) {
long y, x, c;
for (y = 0; y < dyn; ++y) {
for (x = 0; x < dxn; ++x) {
for (c = 0; c < dcn; ++c) {
dst[c][y][x] = src[sy0 + y][sx0 + x][sc0 + c];
}
}
}
return dst;
}
static void CompressRange(long cn, long yn, long xn,
unsigned char img[cn][yn][xn]) {
static const char R[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
double f;
long c, y, x, L, H;
L = R[0], H = R[strlen(R) - 1];
for (c = 0; c < cn; ++c) {
for (y = 0; y < yn; ++y) {
for (x = 0; x < xn; ++x) {
f = img[c][y][x];
f /= 255;
f *= H - L;
f += L;
img[c][y][x] = MIN(H, MAX(L, lround(f)));
}
}
}
}
static void PrintCode(FILE *f, long cn, long yn, long xn,
unsigned char img[cn][yn][xn]) {
long c, y, x;
if (flags_.c) CompressRange(cn, yn, xn, img);
for (c = 0; c < cn; ++c) {
fputc('\n', f);
for (y = 0; y < yn; ++y) {
fputc('\n', f);
for (x = 0; x < xn; ++x) {
fputwc(bing(img[c][y][x], 0), f);
}
}
}
fputc('\n', f);
}
static void ProcessImage(const char *path, long scn, long syn, long sxn,
unsigned char img[syn][sxn][scn], FILE *f) {
double ry, rx;
long dyn, dxn, cn;
GetOutputGeometry(syn, sxn, &dyn, &dxn, &ry, &rx);
if (dyn == syn && dxn == sxn) {
/* TODO(jart): Why doesn't Gyarados no-op? */
PrintCode(f, scn, dyn, dxn,
Deinterlace(scn, syn, sxn, gc(memalign(32, scn * syn * sxn)), syn,
sxn, scn, img, syn, sxn, 0, 0, 0));
} else {
PrintCode(
f, scn, dyn, dxn,
EzGyarados(scn, dyn, dxn, gc(memalign(32, scn * dyn * dxn)), scn, syn,
sxn,
Deinterlace(scn, syn, sxn, gc(memalign(32, scn * syn * sxn)),
syn, sxn, scn, img, syn, sxn, 0, 0, 0),
0, scn, dyn, dxn, syn, sxn, ry, rx, 0, 0));
}
}
static void WithImageFile(const char *path, FILE *f,
void fn(const char *path, long cn, long yn, long xn,
unsigned char src[yn][xn][cn], FILE *f)) {
struct stat st;
void *map, *data;
int fd, yn, xn, cn;
CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path);
CHECK_NE(-1, fstat(fd, &st));
CHECK_GT(st.st_size, 0);
CHECK_LE(st.st_size, INT_MAX);
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
CHECK_NOTNULL(
(data = stbi_load_from_memory(map, st.st_size, &xn, &yn, &cn, 0)), "%s",
path);
CHECK_NE(-1, munmap(map, st.st_size));
CHECK_NE(-1, close(fd));
fn(path, cn, yn, xn, data, f);
free(data);
}
int main(int argc, char *argv[]) {
int i;
FILE *f;
showcrashreports();
GetOpts(&argc, argv);
stbi_set_unpremultiply_on_load(true);
CHECK_NOTNULL((f = fopen(flags_.o, "w")));
for (i = optind; i < argc; ++i) {
WithImageFile(argv[i], f, ProcessImage);
}
return fclose(f);
}

View file

@ -164,8 +164,8 @@ void OpMulAxAlEbSigned(struct Machine *m, uint32_t rde) {
int16_t ax;
uint8_t *p;
p = GetModrmRegisterBytePointerRead(m, rde);
__builtin_mul_overflow((int8_t)Read8(m->ax), (int8_t)Read8(p), &ax);
of = (int)ax != (int8_t)ax;
ax = (int8_t)Read8(m->ax) * (int8_t)Read8(p);
of = ax != (int8_t)ax;
m->flags = SetFlag(m->flags, FLAGS_CF, of);
m->flags = SetFlag(m->flags, FLAGS_OF, of);
Write16(m->ax, ax);
@ -176,8 +176,8 @@ void OpMulAxAlEbUnsigned(struct Machine *m, uint32_t rde) {
bool of;
uint8_t *p;
p = GetModrmRegisterBytePointerRead(m, rde);
__builtin_mul_overflow(Read8(m->ax), Read8(p), &ax);
of = (uint8_t)ax != ax;
ax = Read8(m->ax) * Read8(p);
of = ax != (uint8_t)ax;
m->flags = SetFlag(m->flags, FLAGS_CF, of);
m->flags = SetFlag(m->flags, FLAGS_OF, of);
Write16(m->ax, ax);
@ -256,10 +256,12 @@ static void AluImul(struct Machine *m, uint32_t rde, uint8_t *a, uint8_t *b) {
of = __builtin_mul_overflow(x, y, &z);
Write64(RegRexrReg(m, rde), z & 0xffffffff);
} else {
int16_t x, y, z;
int z;
int16_t x, y;
x = Read16(a);
y = Read16(b);
of = __builtin_mul_overflow(x, y, &z);
z = x * y;
of = z != (int16_t)z;
Write16(RegRexrReg(m, rde), z);
}
m->flags = SetFlag(m->flags, FLAGS_CF, of);

View file

@ -169,7 +169,7 @@ void *ReserveAddress(struct Machine *m, int64_t v, size_t n) {
}
void *AccessRam(struct Machine *m, int64_t v, size_t n, void *p[2],
uint8_t tmp[n], bool copy) {
uint8_t *tmp, bool copy) {
unsigned k;
uint8_t *a, *b;
DCHECK_LE(n, 0x1000);
@ -188,32 +188,31 @@ void *AccessRam(struct Machine *m, int64_t v, size_t n, void *p[2],
return tmp;
}
void *Load(struct Machine *m, int64_t v, size_t n, uint8_t b[n]) {
void *Load(struct Machine *m, int64_t v, size_t n, uint8_t *b) {
void *p[2];
SetReadAddr(m, v, n);
return AccessRam(m, v, n, p, b, true);
}
void *BeginStore(struct Machine *m, int64_t v, size_t n, void *p[2],
uint8_t b[n]) {
uint8_t *b) {
SetWriteAddr(m, v, n);
return AccessRam(m, v, n, p, b, false);
}
void *BeginStoreNp(struct Machine *m, int64_t v, size_t n, void *p[2],
uint8_t b[n]) {
uint8_t *b) {
if (!v) return NULL;
return BeginStore(m, v, n, p, b);
}
void *BeginLoadStore(struct Machine *m, int64_t v, size_t n, void *p[2],
uint8_t b[n]) {
uint8_t *b) {
SetWriteAddr(m, v, n);
return AccessRam(m, v, n, p, b, true);
}
void EndStore(struct Machine *m, int64_t v, size_t n, void *p[2],
uint8_t b[n]) {
void EndStore(struct Machine *m, int64_t v, size_t n, void *p[2], uint8_t *b) {
uint8_t *a;
unsigned k;
DCHECK_LE(n, 0x1000);
@ -228,7 +227,7 @@ void EndStore(struct Machine *m, int64_t v, size_t n, void *p[2],
}
void EndStoreNp(struct Machine *m, int64_t v, size_t n, void *p[2],
uint8_t b[n]) {
uint8_t *b) {
if (v) EndStore(m, v, n, p, b);
}

View file

@ -39,7 +39,7 @@
* @return -1 w/ errno if an error happened
* @see nblack's notcurses project too!
*/
ssize_t PrintPanels(int fd, long pn, struct Panel p[pn], long tyn, long txn) {
ssize_t PrintPanels(int fd, long pn, struct Panel *p, long tyn, long txn) {
wint_t wc;
ssize_t rc;
size_t wrote;

View file

@ -34,173 +34,6 @@
#include "tool/build/lib/ssefloat.h"
#include "tool/build/lib/throw.h"
#define SSE_BUILTINS \
(!IsModeDbg() && __SSE3__ + 0 && \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408)
typedef int int_v _Vector_size(16) forcealign(16);
typedef long long_v _Vector_size(16) forcealign(16);
static float_v Addps(struct Machine *m, float_v x, float_v y) {
return x + y;
}
static double_v Addpd(struct Machine *m, double_v x, double_v y) {
return x + y;
}
static float_v Mulps(struct Machine *m, float_v x, float_v y) {
return x * y;
}
static double_v Mulpd(struct Machine *m, double_v x, double_v y) {
return x * y;
}
static float_v Subps(struct Machine *m, float_v x, float_v y) {
return x - y;
}
static double_v Subpd(struct Machine *m, double_v x, double_v y) {
return x - y;
}
static float_v Divps(struct Machine *m, float_v x, float_v y) {
return x / y;
}
static double_v Divpd(struct Machine *m, double_v x, double_v y) {
return x / y;
}
static float_v Andps(struct Machine *m, float_v x, float_v y) {
return (float_v)((int_v)x & (int_v)y);
}
static double_v Andpd(struct Machine *m, double_v x, double_v y) {
return (double_v)((long_v)x & (long_v)y);
}
static float_v Andnps(struct Machine *m, float_v x, float_v y) {
return (float_v)(~(int_v)x & (int_v)y);
}
static double_v Andnpd(struct Machine *m, double_v x, double_v y) {
return (double_v)(~(long_v)x & (long_v)y);
}
static float_v Orps(struct Machine *m, float_v x, float_v y) {
return (float_v)((int_v)x | (int_v)y);
}
static double_v Orpd(struct Machine *m, double_v x, double_v y) {
return (double_v)((long_v)x | (long_v)y);
}
static float_v Xorps(struct Machine *m, float_v x, float_v y) {
return (float_v)((int_v)x ^ (int_v)y);
}
static double_v Xorpd(struct Machine *m, double_v x, double_v y) {
return (double_v)((long_v)x ^ (long_v)y);
}
static float_v Minps(struct Machine *m, float_v x, float_v y) {
#if SSE_BUILTINS
return __builtin_ia32_minps(x, y);
#else
unsigned i;
for (i = 0; i < 4; ++i) {
x[i] = MIN(x[i], y[i]);
}
return x;
#endif
}
static double_v Minpd(struct Machine *m, double_v x, double_v y) {
#if SSE_BUILTINS
return __builtin_ia32_minpd(x, y);
#else
unsigned i;
for (i = 0; i < 2; ++i) {
x[i] = MIN(x[i], y[i]);
}
return x;
#endif
}
static float_v Maxps(struct Machine *m, float_v x, float_v y) {
#if SSE_BUILTINS
return __builtin_ia32_maxps(x, y);
#else
unsigned i;
for (i = 0; i < 4; ++i) {
x[i] = MAX(x[i], y[i]);
}
return x;
#endif
}
static double_v Maxpd(struct Machine *m, double_v x, double_v y) {
#if SSE_BUILTINS
return __builtin_ia32_maxpd(x, y);
#else
unsigned i;
for (i = 0; i < 2; ++i) {
x[i] = MAX(x[i], y[i]);
}
return x;
#endif
}
static double_v Haddpd(struct Machine *m, double_v x, double_v y) {
#if SSE_BUILTINS
return __builtin_ia32_haddpd(x, y);
#else
return (double_v){x[0] + x[1], y[0] + y[1]};
#endif
}
static float_v Haddps(struct Machine *m, float_v x, float_v y) {
#if SSE_BUILTINS
return __builtin_ia32_haddps(x, y);
#else
return (float_v){x[0] + x[1], x[2] + x[3], y[0] + y[1], y[2] + y[3]};
#endif
}
static double_v Hsubpd(struct Machine *m, double_v x, double_v y) {
#if SSE_BUILTINS
return __builtin_ia32_hsubpd(x, y);
#else
return (double_v){x[0] - x[1], y[0] - y[1]};
#endif
}
static float_v Hsubps(struct Machine *m, float_v x, float_v y) {
#if SSE_BUILTINS
return __builtin_ia32_hsubps(x, y);
#else
return (float_v){x[0] - x[1], x[2] - x[3], y[0] - y[1], y[2] - y[3]};
#endif
}
static double_v Addsubpd(struct Machine *m, double_v x, double_v y) {
#if SSE_BUILTINS
return __builtin_ia32_addsubpd(x, y);
#else
return (double_v){x[0] - y[0], x[1] + y[1]};
#endif
}
static float_v Addsubps(struct Machine *m, float_v x, float_v y) {
#if SSE_BUILTINS
return __builtin_ia32_addsubps(x, y);
#else
return (float_v){x[0] - y[0], x[1] + y[1], x[2] - y[2], x[3] + y[3]};
#endif
}
void OpUnpcklpsd(struct Machine *m, uint32_t rde) {
uint8_t *a, *b;
a = XmmRexrReg(m, rde);
@ -294,28 +127,28 @@ void OpShufpsd(struct Machine *m, uint32_t rde) {
void OpSqrtpsd(struct Machine *m, uint32_t rde) {
long i;
float_v xf;
double_v xd;
float xf[4];
double xd[2];
switch (Rep(rde) | Osz(rde)) {
case 0:
memcpy(&xf, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(xf, GetModrmRegisterXmmPointerRead16(m, rde), 16);
for (i = 0; i < 4; ++i) xf[i] = sqrtf(xf[i]);
memcpy(XmmRexrReg(m, rde), &xf, 16);
memcpy(XmmRexrReg(m, rde), xf, 16);
break;
case 1:
memcpy(&xd, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(xd, GetModrmRegisterXmmPointerRead16(m, rde), 16);
for (i = 0; i < 2; ++i) xd[i] = sqrt(xd[i]);
memcpy(XmmRexrReg(m, rde), &xd, 16);
memcpy(XmmRexrReg(m, rde), xd, 16);
break;
case 2:
memcpy(&xd, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(xd, GetModrmRegisterXmmPointerRead8(m, rde), 8);
xd[0] = sqrt(xd[0]);
memcpy(XmmRexrReg(m, rde), &xd, 8);
memcpy(XmmRexrReg(m, rde), xd, 8);
break;
case 3:
memcpy(&xf, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(xf, GetModrmRegisterXmmPointerRead4(m, rde), 4);
xf[0] = sqrtf(xf[0]);
memcpy(XmmRexrReg(m, rde), &xf, 4);
memcpy(XmmRexrReg(m, rde), xf, 4);
break;
default:
unreachable;
@ -323,91 +156,30 @@ void OpSqrtpsd(struct Machine *m, uint32_t rde) {
}
void OpRsqrtps(struct Machine *m, uint32_t rde) {
float_v x;
float x[4];
unsigned i;
if (Rep(rde) != 3) {
memcpy(&x, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, GetModrmRegisterXmmPointerRead16(m, rde), 16);
for (i = 0; i < 4; ++i) x[i] = 1.f / sqrtf(x[i]);
memcpy(XmmRexrReg(m, rde), &x, 16);
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
memcpy(&x, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(x, GetModrmRegisterXmmPointerRead4(m, rde), 4);
x[0] = 1.f / sqrtf(x[0]);
memcpy(XmmRexrReg(m, rde), &x, 4);
memcpy(XmmRexrReg(m, rde), x, 4);
}
}
void OpRcpps(struct Machine *m, uint32_t rde) {
float_v x;
float x[4];
unsigned i;
if (Rep(rde) != 3) {
memcpy(&x, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, GetModrmRegisterXmmPointerRead16(m, rde), 16);
for (i = 0; i < 4; ++i) x[i] = 1.f / x[i];
memcpy(XmmRexrReg(m, rde), &x, 16);
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
memcpy(&x, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(x, GetModrmRegisterXmmPointerRead4(m, rde), 4);
x[0] = 1.f / x[0];
memcpy(XmmRexrReg(m, rde), &x, 4);
}
}
static void VpsdWpsd(struct Machine *m, uint32_t rde,
float_v opf(struct Machine *, float_v, float_v),
double_v opd(struct Machine *, double_v, double_v),
bool isfloat, bool isdouble) {
float_v xf, yf;
double_v xd, yd;
if (isfloat) {
memcpy(&xf, XmmRexrReg(m, rde), 16);
memcpy(&yf, GetModrmRegisterXmmPointerRead16(m, rde), 16);
xf = opf(m, xf, yf);
memcpy(XmmRexrReg(m, rde), &xf, 16);
} else if (isdouble) {
memcpy(&xd, XmmRexrReg(m, rde), 16);
memcpy(&yd, GetModrmRegisterXmmPointerRead16(m, rde), 16);
xd = opd(m, xd, yd);
memcpy(XmmRexrReg(m, rde), &xd, 16);
} else {
OpUd(m, rde);
}
}
static void VpsdWpsd66(struct Machine *m, uint32_t rde,
float_v opf(struct Machine *, float_v, float_v),
double_v opd(struct Machine *, double_v, double_v)) {
VpsdWpsd(m, rde, opf, opd, !Osz(rde), Osz(rde));
}
static void VpsdWpsd66f2(struct Machine *m, uint32_t rde,
float_v opf(struct Machine *, float_v, float_v),
double_v opd(struct Machine *, double_v, double_v)) {
VpsdWpsd(m, rde, opf, opd, Rep(rde) == 2, Osz(rde));
}
static void VspsdWspsd(struct Machine *m, uint32_t rde,
float_v opf(struct Machine *, float_v, float_v),
double_v opd(struct Machine *, double_v, double_v)) {
float_v xf, yf;
double_v xd, yd;
if (Rep(rde) == 2) {
memcpy(&yd, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&xd, XmmRexrReg(m, rde), 8);
xd = opd(m, xd, yd);
memcpy(XmmRexrReg(m, rde), &xd, 8);
} else if (Rep(rde) == 3) {
memcpy(&yf, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&xf, XmmRexrReg(m, rde), 4);
xf = opf(m, xf, yf);
memcpy(XmmRexrReg(m, rde), &xf, 4);
} else if (Osz(rde)) {
memcpy(&yd, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(&xd, XmmRexrReg(m, rde), 16);
xd = opd(m, xd, yd);
memcpy(XmmRexrReg(m, rde), &xd, 16);
} else {
memcpy(&yf, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(&xf, XmmRexrReg(m, rde), 16);
xf = opf(m, xf, yf);
memcpy(XmmRexrReg(m, rde), &xf, 16);
memcpy(XmmRexrReg(m, rde), x, 4);
}
}
@ -448,118 +220,376 @@ void OpComissVsWs(struct Machine *m, uint32_t rde) {
}
}
static float_v Cmpps(struct Machine *m, float_v x, float_v y) {
long i;
switch (m->xedd->op.uimm0) {
static int Cmps(int imm, float x, float y) {
switch (imm) {
case 0:
return x == y;
return x == y ? -1 : 0;
case 1:
return x < y;
return x < y ? -1 : 0;
case 2:
return x <= y;
return x <= y ? -1 : 0;
case 3:
for (i = 0; i < 4; ++i) {
x[i] = isnan(x[i]) || isnan(y[i]);
}
return x;
return isnan(x) || isnan(y) ? -1 : 0;
case 4:
return x != y;
return x != y ? -1 : 0;
case 5:
return x >= y;
return x >= y ? -1 : 0;
case 6:
return x > y;
return x > y ? -1 : 0;
case 7:
for (i = 0; i < 4; ++i) {
x[i] = !(isnan(x[i]) || isnan(y[i]));
}
return x;
return !(isnan(x) || isnan(y)) ? -1 : 0;
default:
OpUd(m, 0);
return 0;
}
}
static double_v Cmppd(struct Machine *m, double_v x, double_v y) {
static int32_t Cmpd(int imm, double x, double y) {
long i;
switch (m->xedd->op.uimm0) {
switch (imm) {
case 0:
return x == y;
return x == y ? -1 : 0;
case 1:
return x < y;
return x < y ? -1 : 0;
case 2:
return x <= y;
return x <= y ? -1 : 0;
case 3:
for (i = 0; i < 2; ++i) {
x[i] = isnan(x[i]) || isnan(y[i]);
}
return x;
return isnan(x) || isnan(y) ? -1 : 0;
case 4:
return x != y;
return x != y ? -1 : 0;
case 5:
return x >= y;
return x >= y ? -1 : 0;
case 6:
return x > y;
return x > y ? -1 : 0;
case 7:
for (i = 0; i < 2; ++i) {
x[i] = !(isnan(x[i]) || isnan(y[i]));
}
return x;
return !(isnan(x) || isnan(y)) ? -1 : 0;
default:
OpUd(m, 0);
return 0;
}
}
void OpAddpsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Addps, Addpd);
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x += y;
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x += y;
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] += y[0];
x[1] += y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] += y[0];
x[1] += y[1];
x[2] += y[2];
x[3] += y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpMulpsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Mulps, Mulpd);
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x *= y;
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x *= y;
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] *= y[0];
x[1] *= y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] *= y[0];
x[1] *= y[1];
x[2] *= y[2];
x[3] *= y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpSubpsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Subps, Subpd);
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x -= y;
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x -= y;
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] -= y[0];
x[1] -= y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] -= y[0];
x[1] -= y[1];
x[2] -= y[2];
x[3] -= y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpDivpsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Divps, Divpd);
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x /= y;
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x /= y;
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] /= y[0];
x[1] /= y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] /= y[0];
x[1] /= y[1];
x[2] /= y[2];
x[3] /= y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpMinpsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Minps, Minpd);
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x = MIN(x, y);
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x = MIN(x, y);
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] = MIN(x[0], y[0]);
x[1] = MIN(x[1], y[1]);
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] = MIN(x[0], y[0]);
x[1] = MIN(x[1], y[1]);
x[2] = MIN(x[2], y[2]);
x[3] = MIN(x[3], y[3]);
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpMaxpsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Maxps, Maxpd);
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x = MAX(x, y);
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x = MAX(x, y);
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] = MAX(x[0], y[0]);
x[1] = MAX(x[1], y[1]);
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] = MAX(x[0], y[0]);
x[1] = MAX(x[1], y[1]);
x[2] = MAX(x[2], y[2]);
x[3] = MAX(x[3], y[3]);
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpCmppsd(struct Machine *m, uint32_t rde) {
VspsdWspsd(m, rde, Cmpps, Cmppd);
int imm = m->xedd->op.uimm0;
if (Rep(rde) == 2) {
double x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead8(m, rde), 8);
memcpy(&x, XmmRexrReg(m, rde), 8);
x = Cmpd(imm, x, y);
memcpy(XmmRexrReg(m, rde), &x, 8);
} else if (Rep(rde) == 3) {
float x, y;
memcpy(&y, GetModrmRegisterXmmPointerRead4(m, rde), 4);
memcpy(&x, XmmRexrReg(m, rde), 4);
x = Cmps(imm, x, y);
memcpy(XmmRexrReg(m, rde), &x, 4);
} else if (Osz(rde)) {
double x[2], y[2];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] = Cmpd(imm, x[0], y[0]);
x[1] = Cmpd(imm, x[1], y[1]);
memcpy(XmmRexrReg(m, rde), x, 16);
} else {
float x[4], y[4];
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
memcpy(x, XmmRexrReg(m, rde), 16);
x[0] = Cmps(imm, x[0], y[0]);
x[1] = Cmps(imm, x[1], y[1]);
x[2] = Cmps(imm, x[2], y[2]);
x[3] = Cmps(imm, x[3], y[3]);
memcpy(XmmRexrReg(m, rde), x, 16);
}
}
void OpAndpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66(m, rde, Andps, Andpd);
uint64_t x[2], y[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
x[0] &= y[0];
x[1] &= y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
}
void OpAndnpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66(m, rde, Andnps, Andnpd);
uint64_t x[2], y[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
x[0] = ~x[0] & y[0];
x[1] = ~x[1] & y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
}
void OpOrpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66(m, rde, Orps, Orpd);
uint64_t x[2], y[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
x[0] |= y[0];
x[1] |= y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
}
void OpXorpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66(m, rde, Xorps, Xorpd);
uint64_t x[2], y[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
x[0] ^= y[0];
x[1] ^= y[1];
memcpy(XmmRexrReg(m, rde), x, 16);
}
void OpHaddpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66f2(m, rde, Haddps, Haddpd);
if (Rep(rde) == 2) {
float x[4], y[4], z[4];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
z[0] = x[0] + x[1];
z[1] = x[2] + x[3];
z[2] = y[0] + y[1];
z[3] = y[2] + y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
} else if (Osz(rde)) {
double x[2], y[2], z[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
z[0] = x[0] + x[1];
z[1] = y[0] + y[1];
memcpy(XmmRexrReg(m, rde), z, 16);
} else {
OpUd(m, rde);
}
}
void OpHsubpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66f2(m, rde, Hsubps, Hsubpd);
if (Rep(rde) == 2) {
float x[4], y[4], z[4];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
z[0] = x[0] - x[1];
z[1] = x[2] - x[3];
z[2] = y[0] - y[1];
z[3] = y[2] - y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
} else if (Osz(rde)) {
double x[2], y[2], z[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
z[0] = x[0] - x[1];
z[1] = y[0] - y[1];
memcpy(XmmRexrReg(m, rde), z, 16);
} else {
OpUd(m, rde);
}
}
void OpAddsubpsd(struct Machine *m, uint32_t rde) {
VpsdWpsd66f2(m, rde, Addsubps, Addsubpd);
if (Rep(rde) == 2) {
float x[4], y[4], z[4];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
z[0] = x[0] - y[0];
z[1] = x[1] + y[1];
z[2] = x[2] - y[2];
z[3] = x[3] + y[3];
memcpy(XmmRexrReg(m, rde), x, 16);
} else if (Osz(rde)) {
double x[2], y[2], z[2];
memcpy(x, XmmRexrReg(m, rde), 16);
memcpy(y, GetModrmRegisterXmmPointerRead16(m, rde), 16);
z[0] = x[0] - y[0];
z[1] = x[1] + y[1];
memcpy(XmmRexrReg(m, rde), z, 16);
} else {
OpUd(m, rde);
}
}

View file

@ -442,7 +442,7 @@ static int AppendIovsReal(struct Machine *m, struct Iovs *ib, int64_t addr,
static int AppendIovsGuest(struct Machine *m, struct Iovs *iv, int64_t iovaddr,
long iovlen) {
int rc;
long i, iovsize;
size_t i, iovsize;
struct iovec *guestiovs;
if (!__builtin_mul_overflow(iovlen, sizeof(struct iovec), &iovsize) &&
(0 <= iovsize && iovsize <= 0x7ffff000)) {

View file

@ -69,6 +69,9 @@
"__builtin_va_end"
"__builtin_abs"
"__builtin_strcpy"
"__builtin_strstr"
"__builtin_strpbrk"
"__builtin_strchr"
"__builtin_stpcpy"
"__builtin_setjmp"
"__builtin_longjmp"

View file

@ -1,6 +1,6 @@
(defconst cosmo-c-keywords-regex
(let (
;; (kar
;; '("case"
;; "do"
@ -237,6 +237,7 @@
"__aligned__"
"__alloc_align__"
"__alloc_size__"
"__warn_if_not_aligned__"
"__artificial__"
"__assume_aligned__"
"__cold__"