diff --git a/build/package b/build/package index dcbcf95b..082ac816 100755 --- a/build/package +++ b/build/package @@ -18,14 +18,15 @@ else fi fi -if [ "$SILENT" = "0" ]; then - COLUMNS=${COLUMNS:-80} - COLUMNS=$((COLUMNS - 4)) - printf "%s\n" "$*" | - /usr/bin/fold -s -w $COLUMNS | - sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 -else - printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 -fi +printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 +# if [ "$SILENT" = "0" ]; then +# COLUMNS=${COLUMNS:-80} +# COLUMNS=$((COLUMNS - 4)) +# printf "%s\n" "$*" | +# /usr/bin/fold -s -w $COLUMNS | +# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 +# else +# printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 +# fi exec "$@" diff --git a/build/zipobj b/build/zipobj index 54f9b200..f2f61f27 100755 --- a/build/zipobj +++ b/build/zipobj @@ -42,11 +42,7 @@ else fi if [ "$SILENT" = "0" ]; then - COLUMNS=${COLUMNS:-80} - COLUMNS=$((COLUMNS - 4)) - printf "%s\n" "$*" | - /usr/bin/fold -s -w $COLUMNS | - $SED -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 + printf "%s\n" "$*" >&2 else printf "$LOGFMT" "${ACTION:-ZIPOBJ}" "$3" >&2 fi diff --git a/libc/bits/safemacros.h b/libc/bits/safemacros.h index 00e638b1..f9a3eabc 100644 --- a/libc/bits/safemacros.h +++ b/libc/bits/safemacros.h @@ -1,7 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_ #define COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_ #ifndef __STRICT_ANSI__ -#include "libc/limits.h" #include "libc/macros.h" #include "libc/runtime/runtime.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) diff --git a/libc/dns/resolvedns.c b/libc/dns/resolvedns.c index 7a5b6552..2a9aa74a 100644 --- a/libc/dns/resolvedns.c +++ b/libc/dns/resolvedns.c @@ -17,6 +17,7 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/dns/consts.h" #include "libc/dns/dns.h" @@ -92,8 +93,8 @@ int resolvedns(const struct ResolvConf *resolvconf, int af, const char *name, } if (p + 2 + 2 + 4 + 2 < pe) { uint16_t rtype, rclass, rdlength; - rtype = read16be(p), p += 2; - rclass = read16be(p), p += 2; + rtype = READ16BE(p), p += 2; + rclass = READ16BE(p), p += 2; /* ttl */ p += 4; rdlength = read16be(p), p += 2; if (p + rdlength <= pe && rdlength == 4 && diff --git a/libc/fmt/pflink.h b/libc/fmt/pflink.h index 9cffa7b7..0fcfd8a6 100644 --- a/libc/fmt/pflink.h +++ b/libc/fmt/pflink.h @@ -1,8 +1,8 @@ #ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #define COSMOPOLITAN_LIBC_FMT_PFLINK_H_ -#include "libc/dce.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) #ifndef __STRICT_ANSI__ +#include "libc/dce.h" /** * @fileoverview builtin+preprocessor+linker tricks for printf/scanf. diff --git a/libc/intrin/shufpd.c b/libc/intrin/shufpd.c index fc0aab03..3bb0bef2 100644 --- a/libc/intrin/shufpd.c +++ b/libc/intrin/shufpd.c @@ -18,16 +18,16 @@ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/shufpd.h" +#include "libc/str/str.h" /** * Shuffles double vector. * @param 𝑚 needs to be a literal, constexpr, or embedding * @mayalias */ -void(shufpd)(double b[2], const double a[2], uint8_t m) { +void(shufpd)(double c[2], const double b[2], const double a[2], uint8_t m) { double t[2]; t[0] = a[(m & 0b0000001) >> 0]; - t[1] = a[(m & 0b0000010) >> 1]; - b[0] = t[0]; - b[1] = t[1]; + t[1] = b[(m & 0b0000010) >> 1]; + memcpy(c, t, 16); } diff --git a/libc/intrin/shufpd.h b/libc/intrin/shufpd.h index 62cf5a0b..44806d46 100644 --- a/libc/intrin/shufpd.h +++ b/libc/intrin/shufpd.h @@ -3,7 +3,7 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -void shufpd(double[2], const double[2], uint8_t); +void shufpd(double[2], const double[2], const double[2], uint8_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/intrin/shufps.c b/libc/intrin/shufps.c index 350584f2..7f636a83 100644 --- a/libc/intrin/shufps.c +++ b/libc/intrin/shufps.c @@ -18,20 +18,18 @@ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/shufps.h" +#include "libc/str/str.h" /** * Shuffles float vector. * @param 𝑚 needs to be a literal, constexpr, or embedding * @mayalias */ -void(shufps)(float b[4], const float a[4], uint8_t m) { +void(shufps)(float c[4], const float b[4], const float a[4], uint8_t m) { float t[4]; - t[0] = a[(m & 0b00000011) >> 0]; - t[1] = a[(m & 0b00001100) >> 2]; + t[0] = b[(m & 0b00000011) >> 0]; + t[1] = b[(m & 0b00001100) >> 2]; t[2] = a[(m & 0b00110000) >> 4]; t[3] = a[(m & 0b11000000) >> 6]; - b[0] = t[0]; - b[1] = t[1]; - b[2] = t[2]; - b[3] = t[3]; + memcpy(c, t, 16); } diff --git a/libc/intrin/shufps.h b/libc/intrin/shufps.h index bb5e824f..2c04e38c 100644 --- a/libc/intrin/shufps.h +++ b/libc/intrin/shufps.h @@ -3,7 +3,7 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -void shufps(float[4], const float[4], uint8_t); +void shufps(float[4], const float[4], const float[4], uint8_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/log/log.h b/libc/log/log.h index 39fadaf8..57d70807 100644 --- a/libc/log/log.h +++ b/libc/log/log.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_ #define COSMOPOLITAN_LIBC_LOG_LOG_H_ -#include "libc/dce.h" /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § liblog ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ diff --git a/libc/math.h b/libc/math.h index 0bf498b5..66952089 100644 --- a/libc/math.h +++ b/libc/math.h @@ -80,11 +80,20 @@ typedef float float_t; typedef double double_t; #endif -#define isinf(x) __builtin_isinf(x) -#define isnan(x) __builtin_isnan(x) -#define isfinite(x) __builtin_isfinite(x) -#define isnormal(x) __builtin_isnormal(x) -#define signbit(x) __builtin_signbit(x) +#define isinf(x) __builtin_isinf(x) +#define isnan(x) __builtin_isnan(x) +#define isfinite(x) __builtin_isfinite(x) +#define isnormal(x) __builtin_isnormal(x) +#define signbit(x) __builtin_signbit(x) +#define isgreater(x, y) __builtin_isgreater(x, y) +#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y) +#define isless(x, y) __builtin_isless(x, y) +#define islessequal(x, y) __builtin_islessequal(x, y) +#define islessgreater(x, y) __builtin_islessgreater(x, y) +#define isunordered(x, y) __builtin_isunordered(x, y) + +#define fpclassify(x) \ + __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x) double acos(double); double acosh(double); @@ -276,13 +285,6 @@ void sincos(double, double *, double *); void sincosf(float, float *, float *); void sincosl(long double, long double *, long double *); -int __fpclassify(double); -int __fpclassifyf(float); -int __fpclassifyl(long double); -#define fpclassify(X) \ - (sizeof(X) == 8 ? __fpclassify(X) \ - : sizeof(X) == 4 ? __fpclassifyf(X) : __fpclassifyl(X)) - /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § mathematics » x87 ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ diff --git a/libc/nt/thunk/msabi.h b/libc/nt/thunk/msabi.h index 0ac5526e..69edc9ee 100644 --- a/libc/nt/thunk/msabi.h +++ b/libc/nt/thunk/msabi.h @@ -9,7 +9,7 @@ * generate code that calls MS ABI functions directly, without needing * to jump through the assembly thunks. */ -#if __GNUC__ * 100 + __GNUC_MINOR_ >= 408 || \ +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 408 || \ (__has_attribute(__ms_abi__) || defined(__llvm__)) #define __msabi __attribute__((__ms_abi__)) #endif diff --git a/libc/nt/winsock.h b/libc/nt/winsock.h index f20cce11..08047881 100644 --- a/libc/nt/winsock.h +++ b/libc/nt/winsock.h @@ -45,15 +45,15 @@ COSMOPOLITAN_C_START_ #endif #define kNtSioSocketCloseNotify 0x9800000Du -#define kNtSioUdpConnreset 0x9800000Cu -#define kNtSioUdpNetreset 0x9800000F +#define kNtSioUdpConnreset 0x9800000Cu +#define kNtSioUdpNetreset 0x9800000F -#define kNtTfDisconnect 0x01 -#define kNtTfReuseSocket 0x02 -#define kNtTfWriteBehind 0x04 +#define kNtTfDisconnect 0x01 +#define kNtTfReuseSocket 0x02 +#define kNtTfWriteBehind 0x04 #define kNtTfUseDefaultWorker 0x00 -#define kNtTfUseSystemThread 0x10 -#define kNtTfUseKernelApc 0x20 +#define kNtTfUseSystemThread 0x10 +#define kNtTfUseKernelApc 0x20 struct sockaddr; struct sockaddr_in; @@ -295,8 +295,8 @@ struct NtWsaCompletion { * functions are declared within their respective wrappers. */ -nodiscard int32_t WSAStartup(uint16_t wVersionRequested, - struct NtWsaData *lpWSAData) paramsnonnull(); +int32_t WSAStartup(uint16_t wVersionRequested, struct NtWsaData *lpWSAData) + paramsnonnull() nodiscard; int WSACleanup(void); int WSAGetLastError(void); @@ -312,9 +312,9 @@ int __listen$nt(uint64_t, int); int __setsockopt$nt(uint64_t, int, int, const void *, int); int __shutdown$nt(uint64_t, int); -nodiscard uint64_t WSASocket(int af, int type, int protocol, - const struct NtWsaProtocolInfo *opt_lpProtocolInfo, - const uint32_t opt_group, uint32_t dwFlags); +uint64_t WSASocket(int af, int type, int protocol, + const struct NtWsaProtocolInfo *opt_lpProtocolInfo, + const uint32_t opt_group, uint32_t dwFlags) nodiscard; int WSAConnect(uint64_t s, const struct sockaddr *name, const int namelen, const struct iovec$nt *opt_lpCallerData, @@ -340,11 +340,11 @@ bool32 WSAConnectByList(uint64_t s, const struct timeval$nt *opt_timeout, struct NtOverlapped *__Reserved) paramsnonnull((2)); -nodiscard int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr, - int32_t *opt_inout_addrlen, - const NtConditionProc opt_lpfnCondition, - const uint32_t *opt_dwCallbackData) - paramsnonnull((2)); +int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr, + int32_t *opt_inout_addrlen, + const NtConditionProc opt_lpfnCondition, + const uint32_t *opt_dwCallbackData) + paramsnonnull((2)) nodiscard; int WSASend(uint64_t s, const struct iovec$nt *lpBuffers, uint32_t dwBufferCount, uint32_t *opt_out_lpNumberOfBytesSent, @@ -406,7 +406,7 @@ int WSANSPIoctl(int64_t hLookup, uint32_t dwControlCode, const struct NtWsaCompletion *opt_lpCompletion) paramsnonnull((3, 5, 7)); -nodiscard int64_t WSACreateEvent(void); +int64_t WSACreateEvent(void) nodiscard; bool32 WSACloseEvent(const int64_t hEvent); bool32 WSAResetEvent(const int64_t hEvent); bool32 WSASetEvent(const int64_t hEvent); diff --git a/libc/runtime/describeos.c b/libc/runtime/describeos.c index e485a563..d0e0a5fe 100644 --- a/libc/runtime/describeos.c +++ b/libc/runtime/describeos.c @@ -17,6 +17,7 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" diff --git a/libc/runtime/hook.greg.c b/libc/runtime/hook.greg.c index a1820e59..03ce50c1 100644 --- a/libc/runtime/hook.greg.c +++ b/libc/runtime/hook.greg.c @@ -17,6 +17,7 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/sigset.h" @@ -71,7 +72,7 @@ privileged void __hook(void ifunc(void), struct SymbolTable *symbols) { pe = (unsigned char *)(symbols->addr_base + symbols->symbols[i + 1].addr_rva); p < pe - 8; ++p) { - code = read64le(p); + code = READ64LE(p); /* * Test for -mrecord-mcount (w/ -fpie or -fpic) diff --git a/libc/runtime/memtrack.c b/libc/runtime/memtrack.c index 33fc2944..953d8691 100644 --- a/libc/runtime/memtrack.c +++ b/libc/runtime/memtrack.c @@ -18,6 +18,7 @@ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" +#include "libc/dce.h" #include "libc/macros.h" #include "libc/runtime/memtrack.h" #include "libc/runtime/runtime.h" diff --git a/libc/runtime/memtrack.h b/libc/runtime/memtrack.h index 507ab768..8f233e50 100644 --- a/libc/runtime/memtrack.h +++ b/libc/runtime/memtrack.h @@ -4,7 +4,7 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define kMappingsSize 0x100000000000 /* 16TB */ +#define kMappingsSize 0x0000100000000000 /* 16TB */ #define kMappingsStart (IsGenuineCosmo() ? 0x300000000000 : 0x200000000000) #define kFixedMappingsStart 0x0000100000000000 #define kFixedMappingsSize kMappingsSize diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c index e18028fe..357401ea 100644 --- a/libc/runtime/mmap.c +++ b/libc/runtime/mmap.c @@ -129,7 +129,7 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { if (!CANONICAL(addr)) return VIP(einval()); if (!(!!(flags & MAP_ANONYMOUS) ^ (fd != -1))) return VIP(einval()); if (!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED))) return VIP(einval()); - if (fd != -1) size = ROUNDUP(size, FRAMESIZE); + if (fd == -1) size = ROUNDUP(size, FRAMESIZE); if (flags & MAP_FIXED) { if (UntrackMemoryIntervals(addr, size) == -1) { return MAP_FAILED; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 51ff12fc..2dcd9846 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_ #define COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_ -#include "libc/dce.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ /*───────────────────────────────────────────────────────────────────────────│─╗ diff --git a/libc/str/str.h b/libc/str/str.h index e08e112b..37babf1b 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_STR_STR_H_ #define COSMOPOLITAN_LIBC_STR_STR_H_ -#include "libc/bits/bits.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ /*───────────────────────────────────────────────────────────────────────────│─╗ diff --git a/libc/tinymath/acosl.S b/libc/tinymath/acosl.S index 80b39bb7..526a0e19 100644 --- a/libc/tinymath/acosl.S +++ b/libc/tinymath/acosl.S @@ -46,7 +46,7 @@ tinymath_acosl: fsqrt fabs # needed in downward rounding mode #endif - fxch %st(1) + fxch fpatan pop %rbp ret diff --git a/libc/tinymath/asinl.S b/libc/tinymath/asinl.S index d656ca51..d83199eb 100644 --- a/libc/tinymath/asinl.S +++ b/libc/tinymath/asinl.S @@ -51,5 +51,4 @@ tinymath_asinl: .alias tinymath_asinl,asinl .rodata.cst4 - .align 4 .Lone: .float 1.0 diff --git a/libc/tinymath/cabsl.S b/libc/tinymath/cabsl.S index de6639b5..01be1ec3 100644 --- a/libc/tinymath/cabsl.S +++ b/libc/tinymath/cabsl.S @@ -27,7 +27,7 @@ tinymath_cabsl: fldt 32(%rbp) fldt 16(%rbp) fmul %st,%st - fxch %st(1) + fxch fmul %st,%st faddp %st,%st(1) fsqrt diff --git a/libc/tinymath/carg.S b/libc/tinymath/carg.S index 5320c058..8bbe4f0e 100644 --- a/libc/tinymath/carg.S +++ b/libc/tinymath/carg.S @@ -29,7 +29,7 @@ tinymath_carg: fldl -16(%rbp) movsd %xmm1,-16(%rbp) fldl -16(%rbp) - fxch %st(1) + fxch fpatan fstpl -16(%rbp) movsd -16(%rbp),%xmm0 diff --git a/libc/tinymath/exp10l.S b/libc/tinymath/exp10l.S index 904f51a7..1e6ed7da 100644 --- a/libc/tinymath/exp10l.S +++ b/libc/tinymath/exp10l.S @@ -34,7 +34,7 @@ tinymath_exp10l: fld %st frndint fsubr %st,%st(1) - fxch %st(1) + fxch f2xm1 fld1 faddp diff --git a/libc/tinymath/exp2l.S b/libc/tinymath/exp2l.S index 6ced34b5..42c0abb6 100644 --- a/libc/tinymath/exp2l.S +++ b/libc/tinymath/exp2l.S @@ -32,7 +32,7 @@ tinymath_exp2l: fld %st frndint fsubr %st,%st(1) - fxch %st(1) + fxch f2xm1 fadds .Lone(%rip) fscale diff --git a/libc/tinymath/expl.S b/libc/tinymath/expl.S index c25ac607..e3268432 100644 --- a/libc/tinymath/expl.S +++ b/libc/tinymath/expl.S @@ -34,7 +34,7 @@ tinymath_expl: fld %st frndint fsubr %st,%st(1) - fxch %st(1) + fxch f2xm1 fld1 faddp diff --git a/libc/tinymath/floor.S b/libc/tinymath/floor.S index 7b52aa0f..b8df1dc7 100644 --- a/libc/tinymath/floor.S +++ b/libc/tinymath/floor.S @@ -25,14 +25,14 @@ tinymath_floor: .leafprologue .profilable - movsd .LC6(%rip),%xmm1 - movsd .LC5(%rip),%xmm2 + movsd 4f(%rip),%xmm1 + movsd 3f(%rip),%xmm2 andpd %xmm0,%xmm1 comisd %xmm1,%xmm2 jbe 1f cvttsd2siq %xmm0,%rax pxor %xmm1,%xmm1 - movsd .LC4(%rip),%xmm2 + movsd 2f(%rip),%xmm2 cvtsi2sdq %rax,%xmm1 movapd %xmm1,%xmm3 cmpnlesd %xmm0,%xmm3 @@ -45,13 +45,6 @@ tinymath_floor: .alias tinymath_floor,floor .rodata.cst8 -.LC4: .long 0 - .long 1072693248 -.LC5: .long 0 - .long 1127219200 - - .rodata.cst16 -.LC6: .long 4294967295 - .long 2147483647 - .long 0 - .long 0 +2: .double 1 +3: .double 0x0010000000000000 +4: .double nan diff --git a/libc/tinymath/fpclassifyl.S b/libc/tinymath/fpclassifyl.S deleted file mode 100644 index a872f4eb..00000000 --- a/libc/tinymath/fpclassifyl.S +++ /dev/null @@ -1,54 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/math.h" -#include "libc/macros.h" -.source __FILE__ - -tinymath_fpclassifyl: - push %rbp - mov %rsp,%rbp - mov 24(%rbp),%rax - mov 16(%rbp),%rdx - and $0x7fff,%ax - mov %rdx,%rcx - shr $63,%rcx - movzwl %ax,%esi - or %ecx,%esi - jne 2f - cmp $1,%rdx - sbb %eax,%eax - add $3,%eax - jmp 1f -2: cmp $0x7fff,%ax - jne 4f - xor %eax,%eax - test %rcx,%rcx - je 1f - xor %eax,%eax - add %rdx,%rdx - sete %al - jmp 1f -4: mov %ecx,%eax - neg %eax - and $FP_NORMAL,%eax -1: pop %rbp - ret - .endfn tinymath_fpclassifyl,globl - .alias tinymath_fpclassifyl,__fpclassifyl diff --git a/libc/tinymath/hypotl.S b/libc/tinymath/hypotl.S index 2d4ee651..b3569b54 100644 --- a/libc/tinymath/hypotl.S +++ b/libc/tinymath/hypotl.S @@ -28,7 +28,7 @@ tinymath_hypotl: fldt 32(%rbp) fldt 16(%rbp) fmul %st,%st - fxch %st(1) + fxch fmul %st,%st faddp pop %rbp diff --git a/libc/tinymath/ilogb.S b/libc/tinymath/ilogb.S index 985874f0..5541197d 100644 --- a/libc/tinymath/ilogb.S +++ b/libc/tinymath/ilogb.S @@ -19,7 +19,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" -/ Returns log₂ₓ exponent part of double. +/ Returns log₂𝑥 exponent part of double. / / @param 𝑥 is double passed in %xmm0 / @return result in %eax diff --git a/libc/tinymath/ilogbf.S b/libc/tinymath/ilogbf.S index 9b92cddd..a6317a43 100644 --- a/libc/tinymath/ilogbf.S +++ b/libc/tinymath/ilogbf.S @@ -19,7 +19,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" -/ Returns log₂ₓ exponent part of float. +/ Returns log₂x exponent part of float. / / @param 𝑥 is float passed in %xmm0 / @return result in %eax diff --git a/libc/tinymath/ilogbl.S b/libc/tinymath/ilogbl.S index 97535971..f1e407ab 100644 --- a/libc/tinymath/ilogbl.S +++ b/libc/tinymath/ilogbl.S @@ -19,7 +19,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" -/ Returns log₂ₓ exponent part of long double. +/ Returns log₂x exponent part of long double. / / @param 𝑥 is long double passed on stack / @return result in %eax diff --git a/libc/tinymath/isgreater.S b/libc/tinymath/isgreater.S deleted file mode 100644 index 3df0551f..00000000 --- a/libc/tinymath/isgreater.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isgreaterf: - .leafprologue - .profilable - xor %eax,%eax - comiss %xmm1,%xmm0 - seta %al - .leafepilogue - .endfn tinymath_isgreaterf,globl - .alias tinymath_isgreaterf,isgreaterf diff --git a/libc/tinymath/isgreaterequal.S b/libc/tinymath/isgreaterequal.S deleted file mode 100644 index 6889f781..00000000 --- a/libc/tinymath/isgreaterequal.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isgreaterequal: - .leafprologue - .profilable - xor %eax,%eax - comisd %xmm1,%xmm0 - setnb %al - .leafepilogue - .endfn tinymath_isgreaterequal,globl - .alias tinymath_isgreaterequal,isgreaterequal diff --git a/libc/tinymath/isgreaterequalf.S b/libc/tinymath/isgreaterequalf.S deleted file mode 100644 index ed53038b..00000000 --- a/libc/tinymath/isgreaterequalf.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isgreaterequalf: - .leafprologue - .profilable - xor %eax,%eax - comiss %xmm1,%xmm0 - setnb %al - .leafepilogue - .endfn tinymath_isgreaterequalf,globl - .alias tinymath_isgreaterequalf,isgreaterequalf diff --git a/libc/tinymath/isgreaterequall.S b/libc/tinymath/isgreaterequall.S deleted file mode 100644 index 1e8b5632..00000000 --- a/libc/tinymath/isgreaterequall.S +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isgreaterequall: - push %rbp - mov %rsp,%rbp - .profilable - fldt 32(%rbp) - fldt 16(%rbp) - xor %eax,%eax - fcomip %st(1),%st - fstp %st - setnb %al - pop %rbp - ret - .endfn tinymath_isgreaterequall,globl - .alias tinymath_isgreaterequall,isgreaterequall diff --git a/libc/tinymath/isgreaterf.S b/libc/tinymath/isgreaterf.S deleted file mode 100644 index 3f332b68..00000000 --- a/libc/tinymath/isgreaterf.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isgreater: - .leafprologue - .profilable - xor %eax,%eax - comisd %xmm1,%xmm0 - seta %al - .leafepilogue - .endfn tinymath_isgreater,globl - .alias tinymath_isgreater,isgreater diff --git a/libc/tinymath/isgreaterl.S b/libc/tinymath/isgreaterl.S deleted file mode 100644 index 46c41966..00000000 --- a/libc/tinymath/isgreaterl.S +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isgreaterl: - push %rbp - mov %rsp,%rbp - .profilable - fldt 32(%rbp) - fldt 16(%rbp) - xor %eax,%eax - fcomip %st(1),%st - fstp %st - seta %al - pop %rbp - ret - .endfn tinymath_isgreaterl,globl - .alias tinymath_isgreaterl,isgreaterl diff --git a/libc/tinymath/isless.S b/libc/tinymath/isless.S deleted file mode 100644 index f91efc1c..00000000 --- a/libc/tinymath/isless.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isless: - .leafprologue - .profilable - xor %eax,%eax - comisd %xmm0,%xmm1 - seta %al - .leafepilogue - .endfn tinymath_isless,globl - .alias tinymath_isless,isless diff --git a/libc/tinymath/islessequal.S b/libc/tinymath/islessequal.S deleted file mode 100644 index 51cba664..00000000 --- a/libc/tinymath/islessequal.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessequal: - .leafprologue - .profilable - xor %eax,%eax - comisd %xmm0,%xmm1 - setnb %al - .leafepilogue - .endfn tinymath_islessequal,globl - .alias tinymath_islessequal,islessequal diff --git a/libc/tinymath/islessequalf.S b/libc/tinymath/islessequalf.S deleted file mode 100644 index d314546c..00000000 --- a/libc/tinymath/islessequalf.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessequalf: - .leafprologue - .profilable - xor %eax,%eax - comiss %xmm0,%xmm1 - setnb %al - .leafepilogue - .endfn tinymath_islessequalf,globl - .alias tinymath_islessequalf,islessequalf diff --git a/libc/tinymath/islessequall.S b/libc/tinymath/islessequall.S deleted file mode 100644 index 08ce494d..00000000 --- a/libc/tinymath/islessequall.S +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessequall: - push %rbp - mov %rsp,%rbp - .profilable - fldt 16(%rbp) - xor %eax,%eax - fldt 32(%rbp) - fcomip %st(1),%st - fstp %st - setnb %al - pop %rbp - ret - .endfn tinymath_islessequall,globl - .alias tinymath_islessequall,islessequall diff --git a/libc/tinymath/islessf.S b/libc/tinymath/islessf.S deleted file mode 100644 index 3bb0d15f..00000000 --- a/libc/tinymath/islessf.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessf: - .leafprologue - .profilable - xor %eax,%eax - comiss %xmm0,%xmm1 - seta %al - .leafepilogue - .endfn tinymath_islessf,globl - .alias tinymath_islessf,islessf diff --git a/libc/tinymath/islessgreater.S b/libc/tinymath/islessgreater.S deleted file mode 100644 index 75deb94b..00000000 --- a/libc/tinymath/islessgreater.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessgreater: - .leafprologue - .profilable - xor %eax,%eax - comisd %xmm1,%xmm0 - setne %al - .leafepilogue - .endfn tinymath_islessgreater,globl - .alias tinymath_islessgreater,islessgreater diff --git a/libc/tinymath/islessgreaterf.S b/libc/tinymath/islessgreaterf.S deleted file mode 100644 index 88d04eff..00000000 --- a/libc/tinymath/islessgreaterf.S +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessgreaterf: - .leafprologue - .profilable - xor %eax,%eax - comiss %xmm1,%xmm0 - setne %al - .leafepilogue - .endfn tinymath_islessgreaterf,globl - .alias tinymath_islessgreaterf,islessgreaterf diff --git a/libc/tinymath/islessgreaterl.S b/libc/tinymath/islessgreaterl.S deleted file mode 100644 index df4191f3..00000000 --- a/libc/tinymath/islessgreaterl.S +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessgreaterl: - push %rbp - mov %rsp,%rbp - .profilable - fldt 16(%rbp) - xor %eax,%eax - fldt 32(%rbp) - fcomip %st(1),%st - fstp %st - setne %al - pop %rbp - ret - .endfn tinymath_islessgreaterl,globl - .alias tinymath_islessgreaterl,islessgreaterl diff --git a/libc/tinymath/islessl.S b/libc/tinymath/islessl.S deleted file mode 100644 index df07ef67..00000000 --- a/libc/tinymath/islessl.S +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_islessl: - push %rbp - mov %rsp,%rbp - .profilable - fldt 16(%rbp) - xor %eax,%eax - fldt 32(%rbp) - fcomip %st(1),%st - fstp %st - seta %al - pop %rbp - ret - .endfn tinymath_islessl,globl - .alias tinymath_islessl,islessl diff --git a/libc/tinymath/isunordered.S b/libc/tinymath/isunordered.S deleted file mode 100644 index f065ced9..00000000 --- a/libc/tinymath/isunordered.S +++ /dev/null @@ -1,29 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isunordered: - .leafprologue - .profilable - xor %eax,%eax - .leafepilogue - .endfn tinymath_isunordered,globl - .alias tinymath_isunordered,isunordered diff --git a/libc/tinymath/isunorderedf.S b/libc/tinymath/isunorderedf.S deleted file mode 100644 index 061d485a..00000000 --- a/libc/tinymath/isunorderedf.S +++ /dev/null @@ -1,29 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isunorderedf: - .leafprologue - .profilable - xor %eax,%eax - .leafepilogue - .endfn tinymath_isunorderedf,globl - .alias tinymath_isunorderedf,isunorderedf diff --git a/libc/tinymath/isunorderedl.S b/libc/tinymath/isunorderedl.S deleted file mode 100644 index 620c1023..00000000 --- a/libc/tinymath/isunorderedl.S +++ /dev/null @@ -1,29 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_isunorderedl: - .leafprologue - .profilable - xor %eax,%eax - .leafepilogue - .endfn tinymath_isunorderedl,globl - .alias tinymath_isunorderedl,isunorderedl diff --git a/libc/tinymath/ldexp.S b/libc/tinymath/ldexp.S index 8d337c85..d1d4a11c 100644 --- a/libc/tinymath/ldexp.S +++ b/libc/tinymath/ldexp.S @@ -20,21 +20,26 @@ #include "libc/macros.h" .source __FILE__ +/ Returns 𝑥 × 2ʸ. +/ +/ @param 𝑥 is double passed in %xmm0 +/ @param 𝑦 is exponent via %edi +/ @return double in %xmm0 tinymath_ldexp: push %rbp mov %rsp,%rbp .profilable - push %rax - movsd %xmm0,-8(%rbp) - fldl -8(%rbp) - mov %edi,-8(%rbp) - fildl -8(%rbp) - fxch %st(1) + push %rdi + fildl (%rsp) + movsd %xmm0,(%rsp) + fldl (%rsp) fscale fstp %st(1) - fstpl -8(%rbp) - movsd -8(%rbp),%xmm0 + fstpl (%rsp) + movsd (%rsp),%xmm0 leave ret .endfn tinymath_ldexp,globl .alias tinymath_ldexp,ldexp + .alias tinymath_ldexp,scalbn + .alias tinymath_ldexp,scalbln diff --git a/libc/tinymath/ldexpf.S b/libc/tinymath/ldexpf.S index 2c058dad..f41129b1 100644 --- a/libc/tinymath/ldexpf.S +++ b/libc/tinymath/ldexpf.S @@ -20,21 +20,26 @@ #include "libc/macros.h" .source __FILE__ +/ Returns 𝑥 × 2ʸ. +/ +/ @param 𝑥 is float passed in %xmm0 +/ @param 𝑦 is exponent via %edi +/ @return float in %xmm0 tinymath_ldexpf: push %rbp mov %rsp,%rbp .profilable - push %rax - movss %xmm0,-4(%rbp) - flds -4(%rbp) - movl %edi,-4(%rbp) - fildl -4(%rbp) - fxch %st(1) + push %rdi + fildl (%rsp) + movss %xmm0,(%rsp) + flds (%rsp) fscale fstp %st(1) - fstps -4(%rbp) - movss -4(%rbp),%xmm0 + fstps (%rsp) + movss (%rsp),%xmm0 leave ret .endfn tinymath_ldexpf,globl .alias tinymath_ldexpf,ldexpf + .alias tinymath_ldexpf,scalbnf + .alias tinymath_ldexpf,scalblnf diff --git a/libc/tinymath/ldexpl.S b/libc/tinymath/ldexpl.S index 2c79e399..11a77827 100644 --- a/libc/tinymath/ldexpl.S +++ b/libc/tinymath/ldexpl.S @@ -20,16 +20,23 @@ #include "libc/macros.h" .source __FILE__ +/ Returns 𝑥 × 2ʸ. +/ +/ @param 𝑥 is long double passed on stack +/ @param 𝑦 is exponent via %edi +/ @return result in %st0 tinymath_ldexpl: + push %rbp + mov %rsp,%rbp .profilable - sub $24,%rsp - fldt 32(%rsp) - movl %edi,12(%rsp) - fildl 12(%rsp) - fxch %st(1) - add $24,%rsp + push %rdi + fildl (%rsp) + fldt 16(%rbp) fscale fstp %st(1) + leave ret .endfn tinymath_ldexpl,globl .alias tinymath_ldexpl,ldexpl + .alias tinymath_ldexpl,scalbnl + .alias tinymath_ldexpl,scalblnl diff --git a/libc/tinymath/log1p.S b/libc/tinymath/log1p.S index cd67d530..c0a5e68a 100644 --- a/libc/tinymath/log1p.S +++ b/libc/tinymath/log1p.S @@ -34,12 +34,12 @@ tinymath_log1p: fld %st fabs fldt .LC16(%rip) - fxch %st(1) + fxch fcomip %st(1),%st fstp %st jnb 1f fldln2 - fxch %st(1) + fxch fyl2xp1 fstpl (%rsp) vmovsd (%rsp),%xmm0 @@ -48,7 +48,7 @@ tinymath_log1p: 1: fld1 faddp %st,%st(1) fldln2 - fxch %st(1) + fxch fyl2x fstpl (%rsp) vmovsd (%rsp),%xmm0 diff --git a/libc/tinymath/log1pf.S b/libc/tinymath/log1pf.S index ee5c6bed..0f94c396 100644 --- a/libc/tinymath/log1pf.S +++ b/libc/tinymath/log1pf.S @@ -34,12 +34,12 @@ tinymath_log1pf: fld %st fabs fldt .LC16(%rip) - fxch %st(1) + fxch fcomip %st(1),%st fstp %st jnb 2f fldln2 - fxch %st(1) + fxch fyl2xp1 1: fstps -4(%rbp) vmovss -4(%rbp),%xmm0 @@ -48,7 +48,7 @@ tinymath_log1pf: 2: fld1 faddp %st,%st(1) fldln2 - fxch %st(1) + fxch fyl2x jmp 1b .endfn tinymath_log1pf,globl diff --git a/libc/tinymath/log1pl.S b/libc/tinymath/log1pl.S index 2eb8ba66..7626e5aa 100644 --- a/libc/tinymath/log1pl.S +++ b/libc/tinymath/log1pl.S @@ -32,19 +32,19 @@ tinymath_log1pl: fld %st fabs fldt .LC16(%rip) - fxch %st(1) + fxch fcomip %st(1),%st fstp %st jnb 1f fldln2 - fxch %st(1) + fxch fyl2xp1 0: pop %rbp ret 1: fld1 faddp %st,%st(1) fldln2 - fxch %st(1) + fxch fyl2x jmp 0b .endfn tinymath_log1pl,globl diff --git a/libc/tinymath/powl.S b/libc/tinymath/powl.S index c45cac47..91a503ba 100644 --- a/libc/tinymath/powl.S +++ b/libc/tinymath/powl.S @@ -39,7 +39,7 @@ tinymath_powl: f2xm1 faddp fscale - fxch %st(1) + fxch fstp %st pop %rbp ret diff --git a/libc/tinymath/scalb.S b/libc/tinymath/scalb.S index 5cba7d85..37254dd7 100644 --- a/libc/tinymath/scalb.S +++ b/libc/tinymath/scalb.S @@ -20,21 +20,14 @@ #include "libc/macros.h" .source __FILE__ +/ Returns 𝑥 × 2ʸ. +/ +/ @param 𝑥 is double passed in %xmm0 +/ @param 𝑦 is double passed in %xmm1, which is truncated +/ @return result in %xmm0 +/ @see ldexp() tinymath_scalb: - push %rbp - mov %rsp,%rbp - .profilable - push %rax - movsd %xmm0,(%rsp) - fldl (%rsp) - movsd %xmm1,(%rsp) - fldl (%rsp) - fxch %st(1) - fscale - fstp %st(1) - fstpl (%rsp) - movsd (%rsp),%xmm0 - leave - ret + cvttsd2si %xmm1,%edi + jmp tinymath_ldexp .endfn tinymath_scalb,globl .alias tinymath_scalb,scalb diff --git a/libc/tinymath/scalbf.S b/libc/tinymath/scalbf.S index 27b8d706..fbbbd5d2 100644 --- a/libc/tinymath/scalbf.S +++ b/libc/tinymath/scalbf.S @@ -20,21 +20,14 @@ #include "libc/macros.h" .source __FILE__ +/ Returns 𝑥 × 2ʸ. +/ +/ @param 𝑥 is float passed in %xmm0 +/ @param 𝑦 is float passed in %xmm1, which is truncated +/ @return result in %xmm0 +/ @see ldexpf() tinymath_scalbf: - push %rbp - mov %rsp,%rbp - .profilable - push %rax - movss %xmm0,-4(%rbp) - flds -4(%rbp) - movss %xmm1,-4(%rbp) - flds -4(%rbp) - fxch %st(1) - fscale - fstp %st(1) - fstps -4(%rbp) - movss -4(%rbp),%xmm0 - leave - ret + cvttss2si %xmm1,%edi + jmp tinymath_ldexpf .endfn tinymath_scalbf,globl .alias tinymath_scalbf,scalbf diff --git a/libc/tinymath/scalbl.S b/libc/tinymath/scalbl.S index fcf343e2..b99d87cb 100644 --- a/libc/tinymath/scalbl.S +++ b/libc/tinymath/scalbl.S @@ -20,6 +20,12 @@ #include "libc/macros.h" .source __FILE__ +/ Returns 𝑥 × 2ʸ. +/ +/ @param 𝑥 is long double passed on stack +/ @param 𝑦 is long double passed on stack +/ @return result in %st0 +/ @see ldexpl() tinymath_scalbl: push %rbp mov %rsp,%rbp diff --git a/libc/tinymath/scalbln.S b/libc/tinymath/scalbln.S deleted file mode 100644 index 1703d48a..00000000 --- a/libc/tinymath/scalbln.S +++ /dev/null @@ -1,40 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_scalbln: - push %rbp - mov %rsp,%rbp - .profilable - push %rax - movsd %xmm0,-8(%rbp) - fldl -8(%rbp) - movq %rdi,-8(%rbp) - fildl -8(%rbp) - fxch %st(1) - fscale - fstp %st(1) - fstpl -8(%rbp) - movsd -8(%rbp),%xmm0 - leave - ret - .endfn tinymath_scalbln,globl - .alias tinymath_scalbln,scalbln diff --git a/libc/tinymath/scalblnl.S b/libc/tinymath/scalblnl.S deleted file mode 100644 index 963b8b91..00000000 --- a/libc/tinymath/scalblnl.S +++ /dev/null @@ -1,40 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -tinymath_scalblnf: - push %rbp - mov %rsp,%rbp - .profilable - push %rax - movss %xmm0,(%rsp) - flds (%rsp) - movq %rdi,(%rsp) - fildl (%rsp) - fxch %st(1) - fscale - fstp %st(1) - fstps (%rsp) - movss (%rsp),%xmm0 - leave - ret - .endfn tinymath_scalblnf,globl - .alias tinymath_scalblnf,scalblnf diff --git a/libc/tinymath/scalbn.S b/libc/tinymath/scalbn.S deleted file mode 100644 index 164e1569..00000000 --- a/libc/tinymath/scalbn.S +++ /dev/null @@ -1,44 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -/ Returns 𝑥 × 2ʸ. -/ -/ @param 𝑥 is double passed in %xmm0 -/ @param 𝑦 is exponent via %edi -tinymath_scalbn: - push %rbp - mov %rsp,%rbp - .profilable - push %rax - movsd %xmm0,-8(%rbp) - fldl -8(%rbp) - movl %edi,-8(%rbp) - fildl -8(%rbp) - fxch %st(1) - fscale - fstp %st(1) - fstpl -8(%rbp) - movsd -8(%rbp),%xmm0 - leave - ret - .endfn tinymath_scalbn,globl - .alias tinymath_scalbn,scalbn diff --git a/libc/tinymath/scalbnf.S b/libc/tinymath/scalbnf.S deleted file mode 100644 index 9ea55181..00000000 --- a/libc/tinymath/scalbnf.S +++ /dev/null @@ -1,44 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -/ Returns 𝑥 × 2ʸ. -/ -/ @param 𝑥 is float passed in %xmm0 -/ @param 𝑦 is exponent via %edi -tinymath_scalbnf: - push %rbp - mov %rsp,%rbp - .profilable - push %rax - movss %xmm0,-4(%rbp) - flds -4(%rbp) - movl %edi,-4(%rbp) - fildl -4(%rbp) - fxch %st(1) - fscale - fstp %st(1) - fstps -4(%rbp) - movss -4(%rbp),%xmm0 - leave - ret - .endfn tinymath_scalbnf,globl - .alias tinymath_scalbnf,scalbnf diff --git a/libc/tinymath/scalbnl.S b/libc/tinymath/scalbnl.S deleted file mode 100644 index ea7135fe..00000000 --- a/libc/tinymath/scalbnl.S +++ /dev/null @@ -1,40 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 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 "libc/macros.h" -.source __FILE__ - -/ Returns 𝑥 × 2ʸ. -/ -/ @param 𝑥 is long double passed on stack -/ @param 𝑦 is exponent via %edi -tinymath_scalbnl: - push %rbp - mov %rsp,%rbp - .profilable - fldt 16(%rsp) - push %rdi - fildl (%rsp) - fxch - fscale - fstp %st(1) - leave - ret - .endfn tinymath_scalbnl,globl - .alias tinymath_scalbnl,scalbnl diff --git a/libc/tinymath/sincos.S b/libc/tinymath/sincos.S index 487d2156..ec196019 100644 --- a/libc/tinymath/sincos.S +++ b/libc/tinymath/sincos.S @@ -34,7 +34,7 @@ tinymath_sincos: movsd %xmm0,-8(%rbp) fldl -8(%rbp) fsincos - fxch %st(1) + fxch fstpl (%rdi) fstpl (%rsi) leave diff --git a/libc/tinymath/sincosf.S b/libc/tinymath/sincosf.S index a1089332..9e7db427 100644 --- a/libc/tinymath/sincosf.S +++ b/libc/tinymath/sincosf.S @@ -34,7 +34,7 @@ tinymath_sincosf: movss %xmm0,4(%rsp) flds 4(%rsp) fsincos - fxch %st(1) + fxch fstps (%rdi) fstps (%rsi) leave diff --git a/libc/tinymath/sqrt.S b/libc/tinymath/sqrt.S index 23452c07..ff6fa9bd 100644 --- a/libc/tinymath/sqrt.S +++ b/libc/tinymath/sqrt.S @@ -20,6 +20,10 @@ #include "libc/macros.h" .source __FILE__ +/ Returns square root of 𝑥. +/ +/ @param 𝑥 is an double passed in %xmm0 +/ @return result in %xmm0 tinymath_sqrt: .leafprologue .profilable diff --git a/libc/tinymath/sqrtf.S b/libc/tinymath/sqrtf.S index 468f771f..2bf54828 100644 --- a/libc/tinymath/sqrtf.S +++ b/libc/tinymath/sqrtf.S @@ -20,6 +20,10 @@ #include "libc/macros.h" .source __FILE__ +/ Returns square root of 𝑥. +/ +/ @param 𝑥 is an float passed in %xmm0 +/ @return result in %xmm0 tinymath_sqrtf: .leafprologue .profilable diff --git a/libc/tinymath/trunc.S b/libc/tinymath/trunc.S index 628e00a4..de76e2e4 100644 --- a/libc/tinymath/trunc.S +++ b/libc/tinymath/trunc.S @@ -43,11 +43,5 @@ tinymath_trunc: .alias tinymath_trunc,trunc .rodata.cst8 -2: .long 0 - .long 1127219200 - - .rodata.cst16 -3: .long 4294967295 - .long 2147483647 - .long 0 - .long 0 +2: .double 0x0010000000000000 +3: .double nan diff --git a/test/libc/conv/test.mk b/test/libc/conv/test.mk index 920c733b..0309f708 100644 --- a/test/libc/conv/test.mk +++ b/test/libc/conv/test.mk @@ -27,6 +27,9 @@ TEST_LIBC_CONV_DIRECTDEPS = \ LIBC_CONV \ LIBC_NEXGEN32E \ LIBC_STUBS \ + LIBC_TINYMATH \ + LIBC_RUNTIME \ + LIBC_X \ LIBC_TESTLIB TEST_LIBC_CONV_DEPS := \ diff --git a/test/libc/fmt/strerror_test.c b/test/libc/fmt/strerror_test.c index 6b87c7f3..7fe5a0f0 100644 --- a/test/libc/fmt/strerror_test.c +++ b/test/libc/fmt/strerror_test.c @@ -40,6 +40,11 @@ TEST(strerror, enosys) { EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS)); } +TEST(strerror, einval) { + if (IsTiny()) return; + EXPECT_STARTSWITH("EINVAL", strerror(EINVAL)); +} + TEST(strerror, symbolizingTheseNumbersAsErrorsIsHeresyInUnixStyle) { EXPECT_STARTSWITH("E?/err=0/errno:0/GetLastError:0", strerror(0)); EXPECT_STARTSWITH("E?", strerror(-1)); diff --git a/test/libc/intrin/intrin_test.c b/test/libc/intrin/intrin_test.c index fade3aa0..58c8cf37 100644 --- a/test/libc/intrin/intrin_test.c +++ b/test/libc/intrin/intrin_test.c @@ -97,8 +97,6 @@ #include "libc/intrin/punpcklqdq.h" #include "libc/intrin/punpcklwd.h" #include "libc/intrin/pxor.h" -#include "libc/intrin/shufpd.h" -#include "libc/intrin/shufps.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/nexgen32e/kcpuids.h" @@ -1674,50 +1672,6 @@ TEST(pshufhw, fuzz) { } } -TEST(shufps, fuzz) { - int i, j; - float x[4], a[4], b[4]; - for (i = 0; i < 100; ++i) { - for (j = 0; j < 4; ++j) x[j] = Rando() % INT_MAX; -#define T(IMM) \ - shufps(a, x, IMM); \ - (shufps)(b, x, IMM); \ - ASSERT_EQ(0, memcmp(a, b, 16)); \ - shufps(a, (void *)a, IMM); \ - (shufps)(b, (void *)b, IMM); \ - ASSERT_EQ(0, memcmp(a, b, 16)) - T(0b00000011); - T(0b00000110); - T(0b00001100); - T(0b00011000); - T(0b00110000); - T(0b01100000); - T(0b11000000); - T(0b10000000); -#undef T - } -} - -TEST(shufpd, fuzz) { - int i, j; - double x[2], a[2], b[2]; - for (i = 0; i < 100; ++i) { - for (j = 0; j < 2; ++j) x[j] = Rando() % INT_MAX; -#define T(IMM) \ - shufpd(a, x, IMM); \ - (shufpd)(b, x, IMM); \ - ASSERT_EQ(0, memcmp(a, b, 16)); \ - shufpd(a, (void *)a, IMM); \ - (shufpd)(b, (void *)b, IMM); \ - ASSERT_EQ(0, memcmp(a, b, 16)) - T(0b00000000); - T(0b00000001); - T(0b00000010); - T(0b00000011); -#undef T - } -} - TEST(packuswb, test) { const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0}; unsigned char B[16] = {0}; diff --git a/libc/tinymath/fpclassify.S b/test/libc/tinymath/ldexp_test.c similarity index 60% rename from libc/tinymath/fpclassify.S rename to test/libc/tinymath/ldexp_test.c index 05a646bc..67295a1d 100644 --- a/libc/tinymath/fpclassify.S +++ b/test/libc/tinymath/ldexp_test.c @@ -1,5 +1,5 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- 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 │ │ │ @@ -18,28 +18,24 @@ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/math.h" -#include "libc/macros.h" -.source __FILE__ +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" -tinymath_fpclassify: - .leafprologue - movd %xmm0,%rax - movd %xmm0,%rdx - shr $52,%rax - mov %eax,%ecx - and $0x7ff,%ecx - jne 2f - add %rdx,%rdx - cmp $1,%rdx - sbb %eax,%eax - add $3,%eax - jmp 1f -2: mov $FP_NORMAL,%eax - cmp $0x7ff,%ecx - jne 1f - xor %eax,%eax - sal $12,%rdx - sete %al -1: .leafepilogue - .endfn tinymath_fpclassify,globl - .alias tinymath_fpclassify,__fpclassify +TEST(ldexp, test) { + volatile int twopow = 5; + volatile double pi = 3.14; + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", ldexp(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", ldexpf(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", ldexpl(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalb(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbf(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", scalbl(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbn(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbnf(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", scalbnl(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbln(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalblnf(pi, twopow)))); + ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", scalblnl(pi, twopow)))); +} diff --git a/test/tool/build/lib/pml4t_test.c b/test/tool/build/lib/pml4t_test.c index fd3d5bb6..8191f88b 100644 --- a/test/tool/build/lib/pml4t_test.c +++ b/test/tool/build/lib/pml4t_test.c @@ -120,8 +120,8 @@ TEST(pml4t, testOverlapsExistingRegistration_overwritesRegistration) { TEST(pml4t, testFindPml4t_holeTooSmall_skipsOver) { ASSERT_NE(-1, RegisterPml4t(cr3, 0x700000000, 0, 0x1000, NewPage)); ASSERT_NE(-1, RegisterPml4t(cr3, 0x700005000, 0, 0x1000, NewPage)); - ASSERT_EQ(0x700001000, FindPml4t(cr3, 0x700000000, 0x01000, NewPage)); - ASSERT_EQ(0x700006000, FindPml4t(cr3, 0x700000000, 0x10000, NewPage)); + ASSERT_EQ(0x700001000, FindPml4t(cr3, 0x700000000, 0x01000)); + ASSERT_EQ(0x700006000, FindPml4t(cr3, 0x700000000, 0x10000)); } TEST(pml4t, testFreePmlt) { diff --git a/third_party/stb/stb_vorbis.c b/third_party/stb/stb_vorbis.c index 0257d452..bf99d198 100644 --- a/third_party/stb/stb_vorbis.c +++ b/third_party/stb/stb_vorbis.c @@ -34,6 +34,7 @@ // #include "libc/alg/alg.h" #include "libc/assert.h" +#include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/conv/conv.h" #include "libc/limits.h" diff --git a/third_party/xed/x86.h b/third_party/xed/x86.h index 07c8d267..e71a37d1 100644 --- a/third_party/xed/x86.h +++ b/third_party/xed/x86.h @@ -364,6 +364,9 @@ struct XedOperands { /* uint8_t opcode; uint8_t srm : 3; }; + uint8_t map : 4; // enum XedIldMap + uint8_t rep : 2; // 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe) + uint8_t hint : 2; // static branch prediction union { uint8_t sib; struct { @@ -380,12 +383,9 @@ struct XedOperands { /* uint8_t mod : 2; }; }; - uint8_t map : 4; // enum XedIldMap - uint8_t hint : 2; // static branch prediction uint8_t seg_ovd : 3; // XED_SEG_xx uint8_t error : 5; // enum XedError uint8_t mode : 3; // real,legacy,long - uint8_t rep : 2; // 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe) bool lock : 1; // prefix bool imm_signed : 1; // internal int64_t disp; // displacement(%xxx) sign-extended diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c index b879cbab..0370b368 100644 --- a/third_party/zlib/deflate.c +++ b/third_party/zlib/deflate.c @@ -5,6 +5,7 @@ │ Use of this source code is governed by the BSD-style licenses that can │ │ be found in the third_party/zlib/LICENSE file. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" #include "libc/dce.h" #include "libc/macros.h" #include "libc/mem/mem.h" @@ -223,7 +224,7 @@ static inline Pos insert_string_sse(struct DeflateState *const s, Pos ret; unsigned *ip, val, h = 0; ip = (unsigned *)&s->window[str]; - val = read32le(ip); /* XXX: val = *ip; */ + val = READ32LE(ip); /* XXX: val = *ip; */ if (s->level >= 6) val &= 0xFFFFFF; asm("crc32\t%1,%0" : "+r"(h) : "r"(val)); ret = s->head[h & s->hash_mask]; diff --git a/tool/build/calculator.inc b/tool/build/calculator.inc index e5fabee0..5b38f9bd 100644 --- a/tool/build/calculator.inc +++ b/tool/build/calculator.inc @@ -17,7 +17,7 @@ M(1, i, "!", LogicalNot, !x, "logical not") M(2, i, "||", LogicalOr, x || y, "logical or") M(2, i, "&&", LogicalAnd, x &&y, "logical and") -M(2, g, "=", Equal1, x == y && fpclassify(x) == fpclassify(y), "equal to") +M(2, g, "=", Equal1, x == y, "equal to") M(2, g, "!=", Notequal, x != y, "not equal to") M(2, g, "<", LessThan, x < y, "less than") M(2, g, ">", GreaterThan, x > y, "greater than") diff --git a/tool/build/emubin/mips.c b/tool/build/emubin/mips.c index d177b150..114dd63e 100644 --- a/tool/build/emubin/mips.c +++ b/tool/build/emubin/mips.c @@ -28,7 +28,7 @@ static void Print(uint8_t c) { int main(int argc, char *argv[]) { int i; #ifdef DISINGENUOUS - for (i = 0; i < 1400 * 1000 * 1000 / 3; ++i) asm("nop"); + for (i = 0; i < 100 * 1000 * 1000 / 3; ++i) asm("nop"); #else size_t size; struct MetalSha256Ctx ctx; diff --git a/tool/build/emucrt/emucrt.mk b/tool/build/emucrt/emucrt.mk index 84d3248a..436103f4 100644 --- a/tool/build/emucrt/emucrt.mk +++ b/tool/build/emucrt/emucrt.mk @@ -9,4 +9,4 @@ TOOL_BUILD_EMUCRT = \ .PHONY: o/$(MODE)/tool/build/emucrt o/$(MODE)/tool/build/emucrt: \ - o/$(MODE)/tool/build/emucrt/emucrt.o + $(TOOL_BUILD_EMUCRT) diff --git a/tool/build/emulator.c b/tool/build/emulator.c index cb6b7362..009028b8 100644 --- a/tool/build/emulator.c +++ b/tool/build/emulator.c @@ -105,17 +105,15 @@ ARGUMENTS\n\ \n\ PERFORMANCE\n\ \n\ - 1500 MIPS w/ NOP loop\n\ + 1000 MIPS w/ NOP loop\n\ Over 9000 MIPS w/ SIMD & Algorithms\n\ \n\ -PROTIP\n\ -\n\ - Fix SSH keyboard latency for debugger TUI in CONTINUE mode:\n\ -\n\ - sudo sh -c 'echo -n 8192 >/proc/sys/net/core/rmem_default'\n\ - sudo sh -c 'echo -n 8192 >/proc/sys/net/core/wmem_default'\n\ -\n\ +COMPLETENESS\n\ \n\ + Long user mode is supported in addition to SSE3 and SSSE3.\n\ + Integer ops are implemented rigorously with lots of tests.\n\ + Floating point instructions are yolo, and tunable more so.\n\ + Loading, virtual memory management, and syscall need work.\n\ \n" #define DUMPWIDTH 64 @@ -274,7 +272,6 @@ static uint8_t CycleSseWidth(uint8_t w) { } static void OnBusted(void) { - LOGF("OnBusted"); CHECK(onbusted); longjmp(onbusted, 1); } @@ -621,15 +618,10 @@ static void DrawTerminal(struct Panel *p) { } } -static void DrawFlag(struct Panel *p, long i, char *name, bool value, - bool previous) { - AppendPanel(p, i, " "); - if (value) { - AppendPanel(p, i, name); - } else { - AppendPanel(p, i, " "); - } - AppendPanel(p, i, " "); +static void DrawFlag(struct Panel *p, long i, char name, bool value) { + char str[] = " "; + if (value) str[1] = name; + AppendPanel(p, i, str); } static void DrawRegister(struct Panel *p, long i, long r) { @@ -649,13 +641,12 @@ static void DrawRegister(struct Panel *p, long i, long r) { static void DrawSt(struct Panel *p, long i, long r) { char buf[32]; + long double value; bool isempty, changed; - long double value, previous; isempty = FpuGetTag(m, r) == kFpuTagEmpty; if (isempty) AppendPanel(p, i, "\e[2m"); - value = *FpuSt(&m[0], r); - previous = *FpuSt(&m[1], r); - changed = value != previous; + value = m[0].fpu.st[(r + m[0].fpu.sp) & 0b111]; + changed = value != m[1].fpu.st[(r + m[0].fpu.sp) & 0b111]; if (!isempty && changed) AppendPanel(p, i, "\e[7m"); snprintf(buf, sizeof(buf), "ST%d ", r); AppendPanel(p, i, buf); @@ -689,20 +680,27 @@ static void DrawCpu(struct Panel *p) { DrawRegister(p, 7, 11), DrawRegister(p, 7, 15), DrawSt(p, 7, 7); snprintf(buf, sizeof(buf), "RIP 0x%016x FLG", m[0].ip); AppendPanel(p, 8, buf); - DrawFlag(p, 8, "C", GetFlag(m[0].flags, FLAGS_CF), - GetFlag(m[1].flags, FLAGS_CF)); - DrawFlag(p, 8, "Z", GetFlag(m[0].flags, FLAGS_ZF), - GetFlag(m[1].flags, FLAGS_ZF)); - DrawFlag(p, 8, "S", GetFlag(m[0].flags, FLAGS_SF), - GetFlag(m[1].flags, FLAGS_SF)); - DrawFlag(p, 8, "O", GetFlag(m[0].flags, FLAGS_OF), - GetFlag(m[1].flags, FLAGS_OF)); - DrawFlag(p, 8, "P", GetFlag(m[0].flags, FLAGS_PF), - GetFlag(m[1].flags, FLAGS_PF)); - DrawFlag(p, 8, "I", GetFlag(m[0].flags, FLAGS_IF), - GetFlag(m[1].flags, FLAGS_IF)); - DrawFlag(p, 8, "D", GetFlag(m[0].flags, FLAGS_DF), - GetFlag(m[1].flags, FLAGS_DF)); + DrawFlag(p, 8, 'C', GetFlag(m[0].flags, FLAGS_CF)); + DrawFlag(p, 8, 'P', GetFlag(m[0].flags, FLAGS_PF)); + DrawFlag(p, 8, 'A', GetFlag(m[0].flags, FLAGS_AF)); + DrawFlag(p, 8, 'Z', GetFlag(m[0].flags, FLAGS_ZF)); + DrawFlag(p, 8, 'S', GetFlag(m[0].flags, FLAGS_SF)); + DrawFlag(p, 8, 'I', GetFlag(m[0].flags, FLAGS_IF)); + DrawFlag(p, 8, 'D', GetFlag(m[0].flags, FLAGS_DF)); + DrawFlag(p, 8, 'O', GetFlag(m[0].flags, FLAGS_OF)); + AppendPanel(p, 8, " "); + if (m->fpu.ie) AppendPanel(p, 8, " IE"); + if (m->fpu.de) AppendPanel(p, 8, " DE"); + if (m->fpu.ze) AppendPanel(p, 8, " ZE"); + if (m->fpu.oe) AppendPanel(p, 8, " OE"); + if (m->fpu.ue) AppendPanel(p, 8, " UE"); + if (m->fpu.pe) AppendPanel(p, 8, " PE"); + if (m->fpu.sf) AppendPanel(p, 8, " SF"); + if (m->fpu.es) AppendPanel(p, 8, " ES"); + if (m->fpu.c0) AppendPanel(p, 8, " C0"); + if (m->fpu.c1) AppendPanel(p, 8, " C1"); + if (m->fpu.c2) AppendPanel(p, 8, " C2"); + if (m->fpu.bf) AppendPanel(p, 8, " BF"); } static void DrawXmm(struct Panel *p, long i, long r) { diff --git a/tool/build/lib/alu.c b/tool/build/lib/alu.c index 746a506f..be150b16 100644 --- a/tool/build/lib/alu.c +++ b/tool/build/lib/alu.c @@ -25,8 +25,8 @@ * NexGen32e Arithmetic Unit. */ int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) { - bool zf, sf, c, o, cf; uint64_t t, z, s, m, k; + bool cf, of, zf, sf, af, carry; assert(w < 4); k = 8; k <<= w; @@ -35,9 +35,10 @@ int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) { m = s; m |= s - 1; t = x; - c = 0; - o = 0; - cf = GetFlag(*flags, FLAGS_CF); + cf = 0; + of = 0; + af = 0; + carry = GetFlag(*flags, FLAGS_CF); switch (h & 7) { case ALU_OR: z = x | y; @@ -50,22 +51,26 @@ int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) { break; case ALU_CMP: h |= 8; - cf = 0; + carry = 0; case ALU_SBB: - t = (x & m) - cf; - c = (x & m) < (t & m); + t = (x & m) - carry; + cf = (x & m) < (t & m); + af = (x & 15) < (t & 15); case ALU_SUB: z = (t & m) - (y & m); - c |= (t & m) < (z & m); - o = !!((z ^ x) & (x ^ y) & s); + cf |= (t & m) < (z & m); + af |= (t & 15) < (z & 15); + of = !!((z ^ x) & (x ^ y) & s); break; case ALU_ADC: - t = (x & m) + cf; - c = (t & m) < (x & m); + t = (x & m) + carry; + cf = (t & m) < (x & m); + af = (t & 15) < (x & 15); case ALU_ADD: z = (t & m) + (y & m); - c |= (z & m) < (y & m); - o = !!((z ^ x) & (z ^ y) & s); + cf |= (z & m) < (y & m); + af |= (z & 15) < (y & 15); + of = !!((z ^ x) & (z ^ y) & s); break; default: unreachable; @@ -73,8 +78,10 @@ int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) { z &= m; zf = !z; sf = !!(z & s); - *flags &= ~(1 << FLAGS_CF | 1 << FLAGS_ZF | 1 << FLAGS_SF | 1 << FLAGS_OF); - *flags |= c << FLAGS_CF | zf << FLAGS_ZF | sf << FLAGS_SF | o << FLAGS_OF; + *flags = (*flags & ~(1 << FLAGS_CF | 1 << FLAGS_ZF | 1 << FLAGS_SF | + 1 << FLAGS_OF | 1 << FLAGS_AF)) | + cf << FLAGS_CF | zf << FLAGS_ZF | sf << FLAGS_SF | of << FLAGS_OF | + af << FLAGS_AF; *flags = SetLazyParityByte(*flags, x); if (h & ALU_TEST) z = x; return z; diff --git a/tool/build/lib/alu.h b/tool/build/lib/alu.h index c09e71ea..42b08756 100644 --- a/tool/build/lib/alu.h +++ b/tool/build/lib/alu.h @@ -11,7 +11,6 @@ #define ALU_XOR 6 #define ALU_CMP 7 #define ALU_TEST 8 -#define ALU_FLIP 16 #define BSU_ROL 0 #define BSU_ROR 1 diff --git a/tool/build/lib/buildlib.mk b/tool/build/lib/buildlib.mk index 60516f4c..30bb45c5 100644 --- a/tool/build/lib/buildlib.mk +++ b/tool/build/lib/buildlib.mk @@ -63,6 +63,8 @@ $(TOOL_BUILD_LIB_A).pkg: \ $(TOOL_BUILD_LIB_A_OBJS) \ $(foreach x,$(TOOL_BUILD_LIB_A_DIRECTDEPS),$($(x)_A).pkg) +o/$(MODE)/tool/build/lib/fpu.o: OVERRIDE_CFLAGS += -ffast-math + TOOL_BUILD_LIB_LIBS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x))) TOOL_BUILD_LIB_SRCS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)_SRCS)) TOOL_BUILD_LIB_HDRS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)_HDRS)) diff --git a/tool/build/lib/case.h b/tool/build/lib/case.h index d1204964..6d393fcd 100644 --- a/tool/build/lib/case.h +++ b/tool/build/lib/case.h @@ -7,5 +7,10 @@ CODE; \ break +#define CASR(OP, CODE) \ + case OP: \ + CODE; \ + return + #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_TOOL_BUILD_LIB_CASE_H_ */ diff --git a/tool/build/lib/cvt.c b/tool/build/lib/cvt.c index 51839d4c..679b1c0c 100644 --- a/tool/build/lib/cvt.c +++ b/tool/build/lib/cvt.c @@ -26,6 +26,21 @@ #include "tool/build/lib/modrm.h" #include "tool/build/lib/throw.h" +static double SseRoundDouble(struct Machine *m, double x) { + switch (m->sse.rc) { + case 0: + return nearbyint(x); + case 1: + return floor(x); + case 2: + return ceil(x); + case 3: + return trunc(x); + default: + unreachable; + } +} + static void OpGdqpWssCvttss2si(struct Machine *m, uint32_t rde) { float f; int64_t n; @@ -57,7 +72,7 @@ static void OpGdqpWsdCvtsd2si(struct Machine *m, uint32_t rde) { double d; int64_t n; memcpy(&d, GetModrmRegisterXmmPointerRead8(m, rde), 8); - n = nearbyint(d); + n = SseRoundDouble(m, d); if (!Rexw(rde)) n &= 0xffffffff; Write64(RegRexrReg(m, rde), n); } @@ -113,11 +128,26 @@ static void OpVpdQpiCvtpi2pd(struct Machine *m, uint32_t rde) { } static void OpPpiWpsqCvtps2pi(struct Machine *m, uint32_t rde) { + unsigned i; float f[2]; int32_t n[2]; memcpy(f, GetModrmRegisterXmmPointerRead8(m, rde), 8); - n[0] = nearbyintf(f[0]); - n[1] = nearbyintf(f[1]); + switch (m->sse.rc) { + case 0: + for (i = 0; i < 2; ++i) n[i] = nearbyintf(f[i]); + break; + case 1: + for (i = 0; i < 2; ++i) n[i] = floorf(f[i]); + break; + case 2: + for (i = 0; i < 2; ++i) n[i] = ceilf(f[i]); + break; + case 3: + for (i = 0; i < 2; ++i) n[i] = truncf(f[i]); + break; + default: + unreachable; + } Write32(MmReg(m, rde) + 0, n[0]); Write32(MmReg(m, rde) + 4, n[1]); } @@ -133,11 +163,11 @@ static void OpPpiWpsqCvttps2pi(struct Machine *m, uint32_t rde) { } static void OpPpiWpdCvtpd2pi(struct Machine *m, uint32_t rde) { + unsigned i; double d[2]; int32_t n[2]; memcpy(d, GetModrmRegisterXmmPointerRead16(m, rde), 16); - n[0] = nearbyint(d[0]); - n[1] = nearbyint(d[1]); + for (i = 0; i < 2; ++i) n[i] = SseRoundDouble(m, d[i]); Write32(MmReg(m, rde) + 0, n[0]); Write32(MmReg(m, rde) + 4, n[1]); } @@ -218,7 +248,22 @@ static void OpVdqWpsCvtps2dq(struct Machine *m, uint32_t rde) { float f[4]; int32_t n[4]; memcpy(f, GetModrmRegisterXmmPointerRead16(m, rde), 16); - for (i = 0; i < 4; ++i) n[i] = nearbyintf(f[i]); + switch (m->sse.rc) { + case 0: + for (i = 0; i < 4; ++i) n[i] = nearbyintf(f[i]); + break; + case 1: + for (i = 0; i < 4; ++i) n[i] = floorf(f[i]); + break; + case 2: + for (i = 0; i < 4; ++i) n[i] = ceilf(f[i]); + break; + case 3: + for (i = 0; i < 4; ++i) n[i] = truncf(f[i]); + break; + default: + unreachable; + } memcpy(XmmRexrReg(m, rde), n, 16); } @@ -236,7 +281,7 @@ static void OpVdqWpdCvtpd2dq(struct Machine *m, uint32_t rde) { double d[2]; int32_t n[2]; memcpy(d, GetModrmRegisterXmmPointerRead16(m, rde), 16); - for (i = 0; i < 2; ++i) n[i] = nearbyintf(d[i]); + for (i = 0; i < 2; ++i) n[i] = SseRoundDouble(m, d[i]); memcpy(XmmRexrReg(m, rde), n, 8); } diff --git a/tool/build/lib/dis.c b/tool/build/lib/dis.c index 76a22e7e..189de010 100644 --- a/tool/build/lib/dis.c +++ b/tool/build/lib/dis.c @@ -23,6 +23,7 @@ #include "libc/conv/itoa.h" #include "libc/fmt/bing.h" #include "libc/fmt/fmt.h" +#include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.h" diff --git a/tool/build/lib/disarg.c b/tool/build/lib/disarg.c index 45c4c72a..9eda298c 100644 --- a/tool/build/lib/disarg.c +++ b/tool/build/lib/disarg.c @@ -17,6 +17,7 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" #include "libc/conv/itoa.h" #include "libc/limits.h" #include "libc/log/check.h" diff --git a/tool/build/lib/fpu.c b/tool/build/lib/fpu.c index a2dc50e8..37256a75 100644 --- a/tool/build/lib/fpu.c +++ b/tool/build/lib/fpu.c @@ -30,6 +30,7 @@ #include "tool/build/lib/memory.h" #include "tool/build/lib/modrm.h" #include "tool/build/lib/throw.h" +#include "tool/build/lib/word.h" #include "tool/build/lib/x87.h" #define FPUREG 0 @@ -92,90 +93,142 @@ static void FpuSetStRmPop(struct Machine *m, long double x) { FpuSetStPop(m, ModrmRm(m->xedd->op.rde), x); } -static int16_t GetMemoryShort(struct Machine *m) { +static int16_t FpuGetMemoryShort(struct Machine *m) { uint8_t b[2]; return Read16(Load(m, m->fpu.dp, 2, b)); } -static int32_t GetMemoryInt(struct Machine *m) { +static int32_t FpuGetMemoryInt(struct Machine *m) { uint8_t b[4]; return Read32(Load(m, m->fpu.dp, 4, b)); } -static int64_t GetMemoryLong(struct Machine *m) { +static int64_t FpuGetMemoryLong(struct Machine *m) { uint8_t b[8]; return Read64(Load(m, m->fpu.dp, 8, b)); } -static float GetMemoryFloat(struct Machine *m) { +static float FpuGetMemoryFloat(struct Machine *m) { float f; uint8_t b[4]; memcpy(&f, Load(m, m->fpu.dp, 4, b), 4); return f; } -static double GetMemoryDouble(struct Machine *m) { +static double FpuGetMemoryDouble(struct Machine *m) { double f; uint8_t b[8]; memcpy(&f, Load(m, m->fpu.dp, 8, b), 8); return f; } -static long double GetMemoryLongDouble(struct Machine *m) { +static long double FpuGetMemoryLongDouble(struct Machine *m) { long double f; uint8_t b[10]; memcpy(&f, Load(m, m->fpu.dp, 10, b), 10); return f; } -static void SetMemoryShort(struct Machine *m, int16_t i) { - void *p[2]; - uint8_t b[2]; - Write16(BeginStore(m, m->fpu.dp, 2, p, b), i); - EndStore(m, m->fpu.dp, 2, p, b); +static void FpuSetMemoryShort(struct Machine *m, int16_t i) { + SetMemoryShort(m, m->fpu.dp, i); } -static void SetMemoryInt(struct Machine *m, int32_t i) { - void *p[2]; - uint8_t b[4]; - Write32(BeginStore(m, m->fpu.dp, 4, p, b), i); - EndStore(m, m->fpu.dp, 4, p, b); +static void FpuSetMemoryInt(struct Machine *m, int32_t i) { + SetMemoryInt(m, m->fpu.dp, i); } -static void SetMemoryLong(struct Machine *m, int64_t i) { - void *p[2]; - uint8_t b[8]; - Write64(BeginStore(m, m->fpu.dp, 8, p, b), i); - EndStore(m, m->fpu.dp, 8, p, b); +static void FpuSetMemoryLong(struct Machine *m, int64_t i) { + SetMemoryLong(m, m->fpu.dp, i); } -static void SetMemoryFloat(struct Machine *m, float f) { - void *p[2]; - uint8_t b[4]; - memcpy(BeginStore(m, m->fpu.dp, 4, p, b), &f, 4); - EndStore(m, m->fpu.dp, 4, p, b); +static void FpuSetMemoryFloat(struct Machine *m, float f) { + SetMemoryFloat(m, m->fpu.dp, f); } -static void SetMemoryDouble(struct Machine *m, double f) { - void *p[2]; - uint8_t b[8]; - memcpy(BeginStore(m, m->fpu.dp, 8, p, b), &f, 8); - EndStore(m, m->fpu.dp, 8, p, b); +static void FpuSetMemoryDouble(struct Machine *m, double f) { + SetMemoryDouble(m, m->fpu.dp, f); } -static void SetMemoryLdbl(struct Machine *m, long double f) { - void *p[2]; - uint8_t b[10]; - memcpy(BeginStore(m, m->fpu.dp, 10, p, b), &f, 10); - EndStore(m, m->fpu.dp, 10, p, b); +static void FpuSetMemoryLdbl(struct Machine *m, long double f) { + SetMemoryLdbl(m, m->fpu.dp, f); } -static long double FpuDivide(struct Machine *m, long double x, long double y) { - if (y) { - return x / y; +static long double FpuAdd(struct Machine *m, long double x, long double y) { + if (!isunordered(x, y)) { + switch (isinf(y) << 1 | isinf(x)) { + case 0b00: + return x + y; + case 0b01: + return x; + case 0b10: + return y; + case 0b11: + if (signbit(x) == signbit(y)) { + return x; + } else { + m->fpu.ie = true; + return copysign(NAN, x); + } + default: + unreachable; + } } else { - m->fpu.ze = true; - return signbit(x) ? -INFINITY : INFINITY; + return NAN; + } +} + +static long double FpuSub(struct Machine *m, long double x, long double y) { + if (!isunordered(x, y)) { + switch (isinf(y) << 1 | isinf(x)) { + case 0b00: + return x - y; + case 0b01: + return -x; + case 0b10: + return y; + case 0b11: + if (signbit(x) == signbit(y)) { + m->fpu.ie = true; + return copysign(NAN, x); + } else { + return y; + } + default: + unreachable; + } + } else { + return NAN; + } +} + +static long double FpuMul(struct Machine *m, long double x, long double y) { + if (!isunordered(x, y)) { + if (!((isinf(x) && !y) || (isinf(y) && !x))) { + return x * y; + } else { + m->fpu.ie = true; + return -NAN; + } + } else { + return NAN; + } +} + +static long double FpuDiv(struct Machine *m, long double x, long double y) { + if (!isunordered(x, y)) { + if (x || y) { + if (y) { + return x / y; + } else { + m->fpu.ze = true; + return copysign(INFINITY, x); + } + } else { + m->fpu.ie = true; + return copysign(NAN, x); + } + } else { + return NAN; } } @@ -198,7 +251,7 @@ static void FpuCompare(struct Machine *m, long double y) { long double x; x = St0(m); m->fpu.c1 = false; - if (!isnan(x) && !isnan(y)) { + if (!isunordered(x, y)) { m->fpu.c0 = x < y; m->fpu.c2 = false; m->fpu.c3 = x == y; @@ -210,7 +263,7 @@ static void FpuCompare(struct Machine *m, long double y) { } } -static void OpFxam(struct Machine *m) { +void OpFxam(struct Machine *m) { long double x; x = *FpuSt(m, 0); m->fpu.c1 = !!signbit(x); @@ -362,59 +415,59 @@ static void OpFcomp(struct Machine *m) { } static void OpFaddStEst(struct Machine *m) { - FpuSetSt0(m, St0(m) + StRm(m)); + FpuSetSt0(m, FpuAdd(m, St0(m), StRm(m))); } static void OpFmulStEst(struct Machine *m) { - FpuSetSt0(m, St0(m) * StRm(m)); + FpuSetSt0(m, FpuMul(m, St0(m), StRm(m))); } static void OpFsubStEst(struct Machine *m) { - FpuSetSt0(m, St0(m) - StRm(m)); + FpuSetSt0(m, FpuSub(m, St0(m), StRm(m))); } static void OpFsubrStEst(struct Machine *m) { - FpuSetSt0(m, StRm(m) - St0(m)); + FpuSetSt0(m, FpuSub(m, StRm(m), St0(m))); } static void OpFdivStEst(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, St0(m), StRm(m))); + FpuSetSt0(m, FpuDiv(m, St0(m), StRm(m))); } static void OpFdivrStEst(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, StRm(m), St0(m))); + FpuSetSt0(m, FpuDiv(m, StRm(m), St0(m))); } static void OpFaddEstSt(struct Machine *m) { - FpuSetStRm(m, StRm(m) + St0(m)); + FpuSetStRm(m, FpuAdd(m, StRm(m), St0(m))); } static void OpFmulEstSt(struct Machine *m) { - FpuSetStRm(m, StRm(m) * St0(m)); + FpuSetStRm(m, FpuMul(m, StRm(m), St0(m))); } static void OpFsubEstSt(struct Machine *m) { - FpuSetStRm(m, St0(m) - StRm(m)); + FpuSetStRm(m, FpuSub(m, St0(m), StRm(m))); } static void OpFsubrEstSt(struct Machine *m) { - FpuSetStRm(m, StRm(m) - St0(m)); + FpuSetStRm(m, FpuSub(m, StRm(m), St0(m))); } static void OpFdivEstSt(struct Machine *m) { - FpuSetStRm(m, FpuDivide(m, StRm(m), St0(m))); + FpuSetStRm(m, FpuDiv(m, StRm(m), St0(m))); } static void OpFdivrEstSt(struct Machine *m) { - FpuSetStRm(m, FpuDivide(m, St0(m), StRm(m))); + FpuSetStRm(m, FpuDiv(m, St0(m), StRm(m))); } static void OpFaddp(struct Machine *m) { - FpuSetStRmPop(m, St0(m) + StRm(m)); + FpuSetStRmPop(m, FpuAdd(m, St0(m), StRm(m))); } static void OpFmulp(struct Machine *m) { - FpuSetStRmPop(m, St0(m) * StRm(m)); + FpuSetStRmPop(m, FpuMul(m, St0(m), StRm(m))); } static void OpFcompp(struct Machine *m) { @@ -423,31 +476,31 @@ static void OpFcompp(struct Machine *m) { } static void OpFsubp(struct Machine *m) { - FpuSetStRmPop(m, St0(m) - StRm(m)); + FpuSetStRmPop(m, FpuSub(m, St0(m), StRm(m))); } static void OpFsubrp(struct Machine *m) { - FpuSetStPop(m, 1, StRm(m) - St0(m)); + FpuSetStPop(m, 1, FpuSub(m, StRm(m), St0(m))); } static void OpFdivp(struct Machine *m) { - FpuSetStRmPop(m, FpuDivide(m, St0(m), StRm(m))); + FpuSetStRmPop(m, FpuDiv(m, St0(m), StRm(m))); } static void OpFdivrp(struct Machine *m) { - FpuSetStRmPop(m, FpuDivide(m, StRm(m), St0(m))); + FpuSetStRmPop(m, FpuDiv(m, StRm(m), St0(m))); } static void OpFadds(struct Machine *m) { - FpuSetSt0(m, St0(m) + GetMemoryFloat(m)); + FpuSetSt0(m, FpuAdd(m, St0(m), FpuGetMemoryFloat(m))); } static void OpFmuls(struct Machine *m) { - FpuSetSt0(m, St0(m) * GetMemoryFloat(m)); + FpuSetSt0(m, FpuMul(m, St0(m), FpuGetMemoryFloat(m))); } static void OpFcoms(struct Machine *m) { - FpuCompare(m, GetMemoryFloat(m)); + FpuCompare(m, FpuGetMemoryFloat(m)); } static void OpFcomps(struct Machine *m) { @@ -456,64 +509,64 @@ static void OpFcomps(struct Machine *m) { } static void OpFsubs(struct Machine *m) { - FpuSetSt0(m, St0(m) - GetMemoryFloat(m)); + FpuSetSt0(m, FpuSub(m, St0(m), FpuGetMemoryFloat(m))); } static void OpFsubrs(struct Machine *m) { - FpuSetSt0(m, GetMemoryFloat(m) - St0(m)); + FpuSetSt0(m, FpuSub(m, FpuGetMemoryFloat(m), St0(m))); } static void OpFdivs(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, St0(m), GetMemoryFloat(m))); + FpuSetSt0(m, FpuDiv(m, St0(m), FpuGetMemoryFloat(m))); } static void OpFdivrs(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, GetMemoryFloat(m), St0(m))); + FpuSetSt0(m, FpuDiv(m, FpuGetMemoryFloat(m), St0(m))); } static void OpFaddl(struct Machine *m) { - FpuSetSt0(m, St0(m) + GetMemoryDouble(m)); + FpuSetSt0(m, FpuAdd(m, St0(m), FpuGetMemoryDouble(m))); } static void OpFmull(struct Machine *m) { - FpuSetSt0(m, St0(m) * GetMemoryDouble(m)); + FpuSetSt0(m, FpuMul(m, St0(m), FpuGetMemoryDouble(m))); } static void OpFcoml(struct Machine *m) { - FpuCompare(m, GetMemoryDouble(m)); + FpuCompare(m, FpuGetMemoryDouble(m)); } static void OpFcompl(struct Machine *m) { - FpuCompare(m, GetMemoryDouble(m)); + FpuCompare(m, FpuGetMemoryDouble(m)); FpuPop(m); } static void OpFsubl(struct Machine *m) { - FpuSetSt0(m, St0(m) - GetMemoryDouble(m)); + FpuSetSt0(m, FpuSub(m, St0(m), FpuGetMemoryDouble(m))); } static void OpFsubrl(struct Machine *m) { - FpuSetSt0(m, GetMemoryDouble(m) - St0(m)); + FpuSetSt0(m, FpuSub(m, FpuGetMemoryDouble(m), St0(m))); } static void OpFdivl(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, St0(m), GetMemoryDouble(m))); + FpuSetSt0(m, FpuDiv(m, St0(m), FpuGetMemoryDouble(m))); } static void OpFdivrl(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, GetMemoryDouble(m), St0(m))); + FpuSetSt0(m, FpuDiv(m, FpuGetMemoryDouble(m), St0(m))); } static void OpFiaddl(struct Machine *m) { - FpuSetSt0(m, St0(m) + GetMemoryInt(m)); + FpuSetSt0(m, FpuAdd(m, St0(m), FpuGetMemoryInt(m))); } static void OpFimull(struct Machine *m) { - FpuSetSt0(m, St0(m) * GetMemoryInt(m)); + FpuSetSt0(m, FpuMul(m, St0(m), FpuGetMemoryInt(m))); } static void OpFicoml(struct Machine *m) { - FpuCompare(m, GetMemoryInt(m)); + FpuCompare(m, FpuGetMemoryInt(m)); } static void OpFicompl(struct Machine *m) { @@ -522,31 +575,31 @@ static void OpFicompl(struct Machine *m) { } static void OpFisubl(struct Machine *m) { - FpuSetSt0(m, St0(m) - GetMemoryInt(m)); + FpuSetSt0(m, FpuSub(m, St0(m), FpuGetMemoryInt(m))); } static void OpFisubrl(struct Machine *m) { - FpuSetSt0(m, GetMemoryInt(m) - St0(m)); + FpuSetSt0(m, FpuSub(m, FpuGetMemoryInt(m), St0(m))); } static void OpFidivl(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, St0(m), GetMemoryInt(m))); + FpuSetSt0(m, FpuDiv(m, St0(m), FpuGetMemoryInt(m))); } static void OpFidivrl(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, GetMemoryInt(m), St0(m))); + FpuSetSt0(m, FpuDiv(m, FpuGetMemoryInt(m), St0(m))); } static void OpFiadds(struct Machine *m) { - FpuSetSt0(m, St0(m) + GetMemoryShort(m)); + FpuSetSt0(m, FpuAdd(m, St0(m), FpuGetMemoryShort(m))); } static void OpFimuls(struct Machine *m) { - FpuSetSt0(m, St0(m) * GetMemoryShort(m)); + FpuSetSt0(m, FpuMul(m, St0(m), FpuGetMemoryShort(m))); } static void OpFicoms(struct Machine *m) { - FpuCompare(m, GetMemoryShort(m)); + FpuCompare(m, FpuGetMemoryShort(m)); } static void OpFicomps(struct Machine *m) { @@ -555,19 +608,19 @@ static void OpFicomps(struct Machine *m) { } static void OpFisubs(struct Machine *m) { - FpuSetSt0(m, St0(m) - GetMemoryShort(m)); + FpuSetSt0(m, FpuSub(m, St0(m), FpuGetMemoryShort(m))); } static void OpFisubrs(struct Machine *m) { - FpuSetSt0(m, GetMemoryShort(m) - St0(m)); + FpuSetSt0(m, FpuSub(m, FpuGetMemoryShort(m), St0(m))); } static void OpFidivs(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, St0(m), GetMemoryShort(m))); + FpuSetSt0(m, FpuDiv(m, St0(m), FpuGetMemoryShort(m))); } static void OpFidivrs(struct Machine *m) { - FpuSetSt0(m, FpuDivide(m, GetMemoryShort(m), St0(m))); + FpuSetSt0(m, FpuDiv(m, FpuGetMemoryShort(m), St0(m))); } static void OpFsqrt(struct Machine *m) { @@ -612,11 +665,11 @@ static void OpFld(struct Machine *m) { } static void OpFlds(struct Machine *m) { - FpuPush(m, GetMemoryFloat(m)); + FpuPush(m, FpuGetMemoryFloat(m)); } static void OpFsts(struct Machine *m) { - SetMemoryFloat(m, St0(m)); + FpuSetMemoryFloat(m, St0(m)); } static void OpFstps(struct Machine *m) { @@ -625,11 +678,11 @@ static void OpFstps(struct Machine *m) { } static void OpFstpt(struct Machine *m) { - SetMemoryLdbl(m, FpuPop(m)); + FpuSetMemoryLdbl(m, FpuPop(m)); } static void OpFstl(struct Machine *m) { - SetMemoryDouble(m, St0(m)); + FpuSetMemoryDouble(m, St0(m)); } static void OpFstpl(struct Machine *m) { @@ -652,15 +705,15 @@ static void OpFxch(struct Machine *m) { } static void OpFldcw(struct Machine *m) { - m->fpu.cw = GetMemoryShort(m); + m->fpu.cw = FpuGetMemoryShort(m); } static void OpFldt(struct Machine *m) { - FpuPush(m, GetMemoryLongDouble(m)); + FpuPush(m, FpuGetMemoryLongDouble(m)); } static void OpFldl(struct Machine *m) { - FpuPush(m, GetMemoryDouble(m)); + FpuPush(m, FpuGetMemoryDouble(m)); } static void OpFldConstant(struct Machine *m) { @@ -694,43 +747,43 @@ static void OpFldConstant(struct Machine *m) { } static void OpFstcw(struct Machine *m) { - SetMemoryShort(m, m->fpu.cw); + FpuSetMemoryShort(m, m->fpu.cw); } static void OpFilds(struct Machine *m) { - FpuPush(m, GetMemoryShort(m)); + FpuPush(m, FpuGetMemoryShort(m)); } static void OpFildl(struct Machine *m) { - FpuPush(m, GetMemoryInt(m)); + FpuPush(m, FpuGetMemoryInt(m)); } static void OpFildll(struct Machine *m) { - FpuPush(m, GetMemoryLong(m)); + FpuPush(m, FpuGetMemoryLong(m)); } static void OpFisttpl(struct Machine *m) { - SetMemoryInt(m, FpuPop(m)); + FpuSetMemoryInt(m, FpuPop(m)); } static void OpFisttpll(struct Machine *m) { - SetMemoryLong(m, FpuPop(m)); + FpuSetMemoryLong(m, FpuPop(m)); } static void OpFisttps(struct Machine *m) { - SetMemoryShort(m, FpuPop(m)); + FpuSetMemoryShort(m, FpuPop(m)); } static void OpFists(struct Machine *m) { - SetMemoryShort(m, FpuRound(m, St0(m))); + FpuSetMemoryShort(m, FpuRound(m, St0(m))); } static void OpFistl(struct Machine *m) { - SetMemoryInt(m, FpuRound(m, St0(m))); + FpuSetMemoryInt(m, FpuRound(m, St0(m))); } static void OpFistll(struct Machine *m) { - SetMemoryLong(m, FpuRound(m, St0(m))); + FpuSetMemoryLong(m, FpuRound(m, St0(m))); } static void OpFistpl(struct Machine *m) { @@ -752,7 +805,7 @@ static void OpFcomi(struct Machine *m) { long double x, y; x = St0(m); y = StRm(m); - if (!isnan(x) && !isnan(y)) { + if (!isunordered(x, y)) { m->flags = SetFlag(m->flags, FLAGS_ZF, x == y); m->flags = SetFlag(m->flags, FLAGS_CF, x < y); m->flags = SetFlag(m->flags, FLAGS_PF, false); @@ -796,7 +849,7 @@ static void OpFfreep(struct Machine *m) { } static void OpFstswMw(struct Machine *m) { - SetMemoryShort(m, m->fpu.sw); + FpuSetMemoryShort(m, m->fpu.sw); } static void OpFstswAx(struct Machine *m) { @@ -975,83 +1028,83 @@ void OpFpu(struct Machine *m) { CASE(DISP(0xDA, FPUREG, 2), OpFcmovbe(m)); CASE(DISP(0xDA, FPUREG, 3), OpFcmovu(m)); CASE(DISP(0xDA, MEMORY, 0), OpFiaddl(m)); - CASE(DISP(0xDa, MEMORY, 1), OpFimull(m)); - CASE(DISP(0xDa, MEMORY, 2), OpFicoml(m)); - CASE(DISP(0xDa, MEMORY, 3), OpFicompl(m)); - CASE(DISP(0xDa, MEMORY, 4), OpFisubl(m)); - CASE(DISP(0xDa, MEMORY, 5), OpFisubrl(m)); - CASE(DISP(0xDa, MEMORY, 6), OpFidivl(m)); - CASE(DISP(0xDa, MEMORY, 7), OpFidivrl(m)); - CASE(DISP(0xDb, FPUREG, 0), OpFcmovnb(m)); - CASE(DISP(0xDb, FPUREG, 1), OpFcmovne(m)); - CASE(DISP(0xDb, FPUREG, 2), OpFcmovnbe(m)); - CASE(DISP(0xDb, FPUREG, 3), OpFcmovnu(m)); - CASE(DISP(0xDb, FPUREG, 5), OpFucomi(m)); - CASE(DISP(0xDb, FPUREG, 6), OpFcomi(m)); - CASE(DISP(0xDb, MEMORY, 0), OpFildl(m)); - CASE(DISP(0xDb, MEMORY, 1), OpFisttpl(m)); - CASE(DISP(0xDb, MEMORY, 2), OpFistl(m)); - CASE(DISP(0xDb, MEMORY, 3), OpFistpl(m)); - CASE(DISP(0xDb, MEMORY, 5), OpFldt(m)); - CASE(DISP(0xDb, MEMORY, 7), OpFstpt(m)); - CASE(DISP(0xDc, FPUREG, 0), OpFaddEstSt(m)); - CASE(DISP(0xDc, FPUREG, 1), OpFmulEstSt(m)); - CASE(DISP(0xDc, FPUREG, 2), OpFcom(m)); - CASE(DISP(0xDc, FPUREG, 3), OpFcomp(m)); - CASE(DISP(0xDc, FPUREG, 4), OpFsubEstSt(m)); - CASE(DISP(0xDc, FPUREG, 5), OpFsubrEstSt(m)); - CASE(DISP(0xDc, FPUREG, 6), OpFdivEstSt(m)); - CASE(DISP(0xDc, FPUREG, 7), OpFdivrEstSt(m)); - CASE(DISP(0xDc, MEMORY, 0), OpFaddl(m)); - CASE(DISP(0xDc, MEMORY, 1), OpFmull(m)); - CASE(DISP(0xDc, MEMORY, 2), OpFcoml(m)); - CASE(DISP(0xDc, MEMORY, 3), OpFcompl(m)); - CASE(DISP(0xDc, MEMORY, 4), OpFsubl(m)); - CASE(DISP(0xDc, MEMORY, 5), OpFsubrl(m)); - CASE(DISP(0xDc, MEMORY, 6), OpFdivl(m)); - CASE(DISP(0xDc, MEMORY, 7), OpFdivrl(m)); - CASE(DISP(0xDd, FPUREG, 0), OpFfree(m)); - CASE(DISP(0xDd, FPUREG, 1), OpFxch(m)); - CASE(DISP(0xDd, FPUREG, 2), OpFst(m)); - CASE(DISP(0xDd, FPUREG, 3), OpFstp(m)); - CASE(DISP(0xDd, FPUREG, 4), OpFucom(m)); - CASE(DISP(0xDd, FPUREG, 5), OpFucomp(m)); - CASE(DISP(0xDd, MEMORY, 0), OpFldl(m)); - CASE(DISP(0xDd, MEMORY, 1), OpFisttpll(m)); - CASE(DISP(0xDd, MEMORY, 2), OpFstl(m)); - CASE(DISP(0xDd, MEMORY, 3), OpFstpl(m)); - CASE(DISP(0xDd, MEMORY, 4), OpFrstor(m)); - CASE(DISP(0xDd, MEMORY, 6), OpFsave(m)); - CASE(DISP(0xDd, MEMORY, 7), OpFstswMw(m)); - CASE(DISP(0xDe, FPUREG, 0), OpFaddp(m)); - CASE(DISP(0xDe, FPUREG, 1), OpFmulp(m)); - CASE(DISP(0xDe, FPUREG, 2), OpFcomp(m)); - CASE(DISP(0xDe, FPUREG, 3), OpFcompp(m)); - CASE(DISP(0xDe, FPUREG, 4), OpFsubp(m)); - CASE(DISP(0xDe, FPUREG, 5), OpFsubrp(m)); - CASE(DISP(0xDe, FPUREG, 6), OpFdivp(m)); - CASE(DISP(0xDe, FPUREG, 7), OpFdivrp(m)); - CASE(DISP(0xDe, MEMORY, 0), OpFiadds(m)); - CASE(DISP(0xDe, MEMORY, 1), OpFimuls(m)); - CASE(DISP(0xDe, MEMORY, 2), OpFicoms(m)); - CASE(DISP(0xDe, MEMORY, 3), OpFicomps(m)); - CASE(DISP(0xDe, MEMORY, 4), OpFisubs(m)); - CASE(DISP(0xDe, MEMORY, 5), OpFisubrs(m)); - CASE(DISP(0xDe, MEMORY, 6), OpFidivs(m)); - CASE(DISP(0xDe, MEMORY, 7), OpFidivrs(m)); - CASE(DISP(0xDf, FPUREG, 0), OpFfreep(m)); - CASE(DISP(0xDf, FPUREG, 1), OpFxch(m)); - CASE(DISP(0xDf, FPUREG, 2), OpFstp(m)); - CASE(DISP(0xDf, FPUREG, 3), OpFstp(m)); - CASE(DISP(0xDf, FPUREG, 4), OpFstswAx(m)); - CASE(DISP(0xDf, FPUREG, 5), OpFucomip(m)); - CASE(DISP(0xDf, FPUREG, 6), OpFcomip(m)); - CASE(DISP(0xDf, MEMORY, 0), OpFilds(m)); - CASE(DISP(0xDf, MEMORY, 1), OpFisttps(m)); - CASE(DISP(0xDf, MEMORY, 2), OpFists(m)); - CASE(DISP(0xDf, MEMORY, 3), OpFistps(m)); - CASE(DISP(0xDf, MEMORY, 5), OpFildll(m)); - CASE(DISP(0xDf, MEMORY, 7), OpFistpll(m)); + CASE(DISP(0xDA, MEMORY, 1), OpFimull(m)); + CASE(DISP(0xDA, MEMORY, 2), OpFicoml(m)); + CASE(DISP(0xDA, MEMORY, 3), OpFicompl(m)); + CASE(DISP(0xDA, MEMORY, 4), OpFisubl(m)); + CASE(DISP(0xDA, MEMORY, 5), OpFisubrl(m)); + CASE(DISP(0xDA, MEMORY, 6), OpFidivl(m)); + CASE(DISP(0xDA, MEMORY, 7), OpFidivrl(m)); + CASE(DISP(0xDB, FPUREG, 0), OpFcmovnb(m)); + CASE(DISP(0xDB, FPUREG, 1), OpFcmovne(m)); + CASE(DISP(0xDB, FPUREG, 2), OpFcmovnbe(m)); + CASE(DISP(0xDB, FPUREG, 3), OpFcmovnu(m)); + CASE(DISP(0xDB, FPUREG, 5), OpFucomi(m)); + CASE(DISP(0xDB, FPUREG, 6), OpFcomi(m)); + CASE(DISP(0xDB, MEMORY, 0), OpFildl(m)); + CASE(DISP(0xDB, MEMORY, 1), OpFisttpl(m)); + CASE(DISP(0xDB, MEMORY, 2), OpFistl(m)); + CASE(DISP(0xDB, MEMORY, 3), OpFistpl(m)); + CASE(DISP(0xDB, MEMORY, 5), OpFldt(m)); + CASE(DISP(0xDB, MEMORY, 7), OpFstpt(m)); + CASE(DISP(0xDC, FPUREG, 0), OpFaddEstSt(m)); + CASE(DISP(0xDC, FPUREG, 1), OpFmulEstSt(m)); + CASE(DISP(0xDC, FPUREG, 2), OpFcom(m)); + CASE(DISP(0xDC, FPUREG, 3), OpFcomp(m)); + CASE(DISP(0xDC, FPUREG, 4), OpFsubEstSt(m)); + CASE(DISP(0xDC, FPUREG, 5), OpFsubrEstSt(m)); + CASE(DISP(0xDC, FPUREG, 6), OpFdivEstSt(m)); + CASE(DISP(0xDC, FPUREG, 7), OpFdivrEstSt(m)); + CASE(DISP(0xDC, MEMORY, 0), OpFaddl(m)); + CASE(DISP(0xDC, MEMORY, 1), OpFmull(m)); + CASE(DISP(0xDC, MEMORY, 2), OpFcoml(m)); + CASE(DISP(0xDC, MEMORY, 3), OpFcompl(m)); + CASE(DISP(0xDC, MEMORY, 4), OpFsubl(m)); + CASE(DISP(0xDC, MEMORY, 5), OpFsubrl(m)); + CASE(DISP(0xDC, MEMORY, 6), OpFdivl(m)); + CASE(DISP(0xDC, MEMORY, 7), OpFdivrl(m)); + CASE(DISP(0xDD, FPUREG, 0), OpFfree(m)); + CASE(DISP(0xDD, FPUREG, 1), OpFxch(m)); + CASE(DISP(0xDD, FPUREG, 2), OpFst(m)); + CASE(DISP(0xDD, FPUREG, 3), OpFstp(m)); + CASE(DISP(0xDD, FPUREG, 4), OpFucom(m)); + CASE(DISP(0xDD, FPUREG, 5), OpFucomp(m)); + CASE(DISP(0xDD, MEMORY, 0), OpFldl(m)); + CASE(DISP(0xDD, MEMORY, 1), OpFisttpll(m)); + CASE(DISP(0xDD, MEMORY, 2), OpFstl(m)); + CASE(DISP(0xDD, MEMORY, 3), OpFstpl(m)); + CASE(DISP(0xDD, MEMORY, 4), OpFrstor(m)); + CASE(DISP(0xDD, MEMORY, 6), OpFsave(m)); + CASE(DISP(0xDD, MEMORY, 7), OpFstswMw(m)); + CASE(DISP(0xDE, FPUREG, 0), OpFaddp(m)); + CASE(DISP(0xDE, FPUREG, 1), OpFmulp(m)); + CASE(DISP(0xDE, FPUREG, 2), OpFcomp(m)); + CASE(DISP(0xDE, FPUREG, 3), OpFcompp(m)); + CASE(DISP(0xDE, FPUREG, 4), OpFsubp(m)); + CASE(DISP(0xDE, FPUREG, 5), OpFsubrp(m)); + CASE(DISP(0xDE, FPUREG, 6), OpFdivp(m)); + CASE(DISP(0xDE, FPUREG, 7), OpFdivrp(m)); + CASE(DISP(0xDE, MEMORY, 0), OpFiadds(m)); + CASE(DISP(0xDE, MEMORY, 1), OpFimuls(m)); + CASE(DISP(0xDE, MEMORY, 2), OpFicoms(m)); + CASE(DISP(0xDE, MEMORY, 3), OpFicomps(m)); + CASE(DISP(0xDE, MEMORY, 4), OpFisubs(m)); + CASE(DISP(0xDE, MEMORY, 5), OpFisubrs(m)); + CASE(DISP(0xDE, MEMORY, 6), OpFidivs(m)); + CASE(DISP(0xDE, MEMORY, 7), OpFidivrs(m)); + CASE(DISP(0xDF, FPUREG, 0), OpFfreep(m)); + CASE(DISP(0xDF, FPUREG, 1), OpFxch(m)); + CASE(DISP(0xDF, FPUREG, 2), OpFstp(m)); + CASE(DISP(0xDF, FPUREG, 3), OpFstp(m)); + CASE(DISP(0xDF, FPUREG, 4), OpFstswAx(m)); + CASE(DISP(0xDF, FPUREG, 5), OpFucomip(m)); + CASE(DISP(0xDF, FPUREG, 6), OpFcomip(m)); + CASE(DISP(0xDF, MEMORY, 0), OpFilds(m)); + CASE(DISP(0xDF, MEMORY, 1), OpFisttps(m)); + CASE(DISP(0xDF, MEMORY, 2), OpFists(m)); + CASE(DISP(0xDF, MEMORY, 3), OpFistps(m)); + CASE(DISP(0xDF, MEMORY, 5), OpFildll(m)); + CASE(DISP(0xDF, MEMORY, 7), OpFistpll(m)); case DISP(0xD9, FPUREG, 4): switch (ModrmRm(m->xedd->op.rde)) { CASE(0, OpFchs(m)); diff --git a/tool/build/lib/instruction.c b/tool/build/lib/instruction.c index f4290b6c..437a33d1 100644 --- a/tool/build/lib/instruction.c +++ b/tool/build/lib/instruction.c @@ -26,8 +26,15 @@ #include "tool/build/lib/throw.h" static bool IsOpcodeEqual(uint8_t *a, uint8_t b[16], size_t size) { - if (likely(size)) { - return memcmp(a, b, size) == 0; + unsigned i; + if (size) { + i = 0; + do { + if (a[i] != b[i]) { + return false; + } + } while (++i < size); + return true; } else { return false; } diff --git a/tool/build/lib/loader.c b/tool/build/lib/loader.c index 9aa69fc7..b3fb8cf8 100644 --- a/tool/build/lib/loader.c +++ b/tool/build/lib/loader.c @@ -49,8 +49,8 @@ static void LoadElfLoadSegment(struct Machine *m, void *code, size_t codesize, vstart = ROUNDDOWN(phdr->p_vaddr, align); vbss = ROUNDUP(phdr->p_vaddr + phdr->p_filesz, align); vend = ROUNDUP(phdr->p_vaddr + phdr->p_memsz, align); - fstart = ROUNDDOWN(felf + phdr->p_offset, align); - fend = ROUNDUP(felf + phdr->p_offset + phdr->p_filesz, align); + fstart = felf + ROUNDDOWN(phdr->p_offset, align); + fend = felf + ROUNDUP(phdr->p_offset + phdr->p_filesz, align); bsssize = vend - vbss; CHECK_GE(vend, vstart); CHECK_GE(fend, fstart); @@ -112,9 +112,11 @@ static void LoadBin(struct Machine *m, intptr_t base, const char *prog, void LoadProgram(struct Machine *m, const char *prog, char **args, char **vars, struct Elf *elf) { int fd; + char *real; + ssize_t rc; struct stat st; void *code, *stack; - size_t codesize, stacksize; + size_t i, codesize, mappedsize, extrasize, stacksize; DCHECK_NOTNULL(prog); elf->prog = prog; if ((fd = open(prog, O_RDONLY)) == -1 || @@ -123,16 +125,30 @@ void LoadProgram(struct Machine *m, const char *prog, char **args, char **vars, fputs(": not found\n", stderr); exit(1); } - codesize = st.st_size; stacksize = STACKSIZE; + codesize = st.st_size; + mappedsize = ROUNDDOWN(codesize, FRAMESIZE); + extrasize = codesize - mappedsize; CHECK_NE(MAP_FAILED, (stack = mmap(NULL, stacksize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - CHECK_NE(MAP_FAILED, (code = mmap(NULL, codesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE, fd, 0))); + code = real = (char *)0x0000400000000000; + if (mappedsize) { + CHECK_NE(MAP_FAILED, mmap(real, mappedsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0)); + real += mappedsize; + } + if (extrasize) { + CHECK_NE(MAP_FAILED, + mmap(real, ROUNDUP(extrasize, FRAMESIZE), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)); + for (i = 0; i < extrasize; i += (size_t)rc) { + CHECK_NE(-1, (rc = pread(fd, real + i, extrasize - i, mappedsize + i))); + } + } CHECK_NE(-1, close(fd)); ResetCpu(m); - Write64(m->sp, 0x800000000000); - RegisterMemory(m, 0x800000000000 - stacksize, stack, stacksize); + Write64(m->sp, 0x0000800000000000); + RegisterMemory(m, 0x0000800000000000 - stacksize, stack, stacksize); LoadArgv(m, prog, args, vars); if (memcmp(code, "\177ELF", 4) == 0) { elf->ehdr = code; diff --git a/tool/build/lib/machine.c b/tool/build/lib/machine.c index bd4f4b0a..9cbefd45 100644 --- a/tool/build/lib/machine.c +++ b/tool/build/lib/machine.c @@ -59,14 +59,11 @@ #define MUTATING true #define READONLY false #define UNCONDITIONAL true -#define REG ModrmReg(rde) -#define UIMM0 m->xedd->op.uimm0 #define BITS (8 << RegLog2(rde)) #define SIGN (1ull << (BITS - 1)) #define MASK (SIGN | (SIGN - 1)) #define SHIFTMASK (BITS - 1) #define TEST ALU_TEST | ALU_AND -#define ZF GetFlag(m->flags, FLAGS_ZF) typedef int int_v _Vector_size(16) aligned(16); typedef long long_v _Vector_size(16) aligned(16); @@ -139,7 +136,7 @@ static void ImportFlags(struct Machine *m, uint64_t flags) { m->flags = SetLazyParityByte(m->flags, !((m->flags >> FLAGS_PF) & 1)); } -static uint64_t ReadMemory(uint32_t rde, uint8_t p[8]) { +forceinline uint64_t ReadMemory(uint32_t rde, uint8_t p[8]) { if (Rexw(rde)) { return Read64(p); } else if (!Osz(rde)) { @@ -149,7 +146,7 @@ static uint64_t ReadMemory(uint32_t rde, uint8_t p[8]) { } } -static int64_t ReadMemorySigned(uint32_t rde, uint8_t p[8]) { +forceinline int64_t ReadMemorySigned(uint32_t rde, uint8_t p[8]) { if (Rexw(rde)) { return (int64_t)Read64(p); } else if (!Osz(rde)) { @@ -159,7 +156,7 @@ static int64_t ReadMemorySigned(uint32_t rde, uint8_t p[8]) { } } -static void WriteRegister(uint32_t rde, uint8_t p[8], uint64_t x) { +forceinline void WriteRegister(uint32_t rde, uint8_t p[8], uint64_t x) { if (Rexw(rde)) { Write64(p, x); } else if (!Osz(rde)) { @@ -169,7 +166,7 @@ static void WriteRegister(uint32_t rde, uint8_t p[8], uint64_t x) { } } -static void WriteMemory(uint32_t rde, uint8_t p[8], uint64_t x) { +forceinline void WriteMemory(uint32_t rde, uint8_t p[8], uint64_t x) { if (Rexw(rde)) { Write64(p, x); } else if (!Osz(rde)) { @@ -179,7 +176,7 @@ static void WriteMemory(uint32_t rde, uint8_t p[8], uint64_t x) { } } -static void WriteRegisterOrMemory(uint32_t rde, uint8_t p[8], uint64_t x) { +forceinline void WriteRegisterOrMemory(uint32_t rde, uint8_t p[8], uint64_t x) { if (IsModrmRegister(rde)) { WriteRegister(rde, p, x); } else { @@ -925,11 +922,10 @@ static void OpMovlpdVqMq(struct Machine *m, uint32_t rde) { } static void OpMovddupVqWq(struct Machine *m, uint32_t rde) { - uint8_t *dst, *src; - dst = XmmRexrReg(m, rde); + uint8_t *src; src = GetModrmRegisterXmmPointerRead8(m, rde); - memcpy(dst + 0, src, 8); - memcpy(dst + 8, src, 8); + memcpy(XmmRexrReg(m, rde) + 0, src, 8); + memcpy(XmmRexrReg(m, rde) + 8, src, 8); } static void OpMovsldupVqWq(struct Machine *m, uint32_t rde) { @@ -1285,17 +1281,21 @@ static void OpShuffle(struct Machine *m, uint32_t rde) { } } +static void OpShufps(struct Machine *m, uint32_t rde) { + shufps((void *)XmmRexrReg(m, rde), (void *)XmmRexrReg(m, rde), + (void *)GetModrmRegisterXmmPointerRead16(m, rde), m->xedd->op.uimm0); +} + +static void OpShufpd(struct Machine *m, uint32_t rde) { + shufpd((void *)XmmRexrReg(m, rde), (void *)XmmRexrReg(m, rde), + (void *)GetModrmRegisterXmmPointerRead16(m, rde), m->xedd->op.uimm0); +} + static void OpShufpsd(struct Machine *m, uint32_t rde) { - float s[4]; - double d[2]; if (Osz(rde)) { - memcpy(d, GetModrmRegisterXmmPointerRead16(m, rde), 16); - (shufpd)(d, d, m->xedd->op.uimm0); - memcpy(XmmRexrReg(m, rde), d, 16); + OpShufpd(m, rde); } else { - memcpy(s, GetModrmRegisterXmmPointerRead16(m, rde), 16); - (shufps)(s, s, m->xedd->op.uimm0); - memcpy(XmmRexrReg(m, rde), s, 16); + OpShufps(m, rde); } } @@ -1698,136 +1698,82 @@ static void OpAddsubpsd(struct Machine *m, uint32_t rde) { OpVpsdWpsd66f2(m, rde, OpAddsubps, OpAddsubpd); } -static void OpAluw(struct Machine *m, uint32_t rde, - int64_t f(int, int, uint64_t, uint64_t, uint32_t *), int h) { - int64_t v; - void *p[2]; - bool readonly; - uint64_t x, y, z; - uint8_t w, *a, *b, *c, split[8]; - w = RegLog2(rde); - readonly = (h & ALU_TEST) || (h & 7) == ALU_CMP; - if (IsModrmRegister(rde)) { - v = 0; - a = RegRexbRm(m, rde); - } else { - v = ComputeAddress(m, rde); - if (h & ALU_FLIP) { - a = Load(m, v, 1 << w, split); - } else { - a = AccessRam(m, v, 1 << w, p, split, true); - if (readonly) { - SetReadAddr(m, v, 1); - } else { - SetWriteAddr(m, v, 1); - } - } - } - b = RegRexrReg(m, rde); - if (h & ALU_FLIP) { - c = b; - b = a; - a = c; - } - y = Read64(b); - x = Read64(a); - z = f(w, h, x, y, &m->flags); - if (!readonly) { - WriteRegisterOrMemory(rde, a, z); - EndStore(m, v, 1 << w, p, split); - } +static void OpAlub(struct Machine *m, uint32_t rde, int h) { + uint8_t *a; + a = GetModrmRegisterBytePointerWrite(m, rde); + Write8(a, Alu(0, h, Read8(a), Read8(ByteRexrReg(m, rde)), &m->flags)); } -static void OpAlub(struct Machine *m, uint32_t rde, - int64_t f(int, int, uint64_t, uint64_t, uint32_t *), int h) { - int64_t v; - bool readonly; - uint64_t x, y, z; - uint8_t *a, *b, *c; - readonly = (h & ALU_TEST) || (h & 7) == ALU_CMP; - if (!m->xedd->op.has_modrm || IsModrmRegister(rde)) { - a = ByteRexbRm(m, rde); - } else { - v = ComputeAddress(m, rde); - a = ResolveAddress(m, v); - if ((h & ALU_FLIP) || readonly) { - SetReadAddr(m, v, 1); - } else { - SetWriteAddr(m, v, 1); - } - } - b = ByteRexrReg(m, rde); - if (h & ALU_FLIP) { - c = b; - b = a; - a = c; - } - y = Read8(b); - x = Read8(a); - z = f(0, h, x, y, &m->flags); - if (!readonly) Write8(a, z); +static void OpAlubRo(struct Machine *m, uint32_t rde, int h) { + Alu(0, h, Read8(GetModrmRegisterBytePointerWrite(m, rde)), + Read8(ByteRexrReg(m, rde)), &m->flags); } -static void OpAluwi(struct Machine *m, uint32_t rde, - int64_t f(int, int, uint64_t, uint64_t, uint32_t *), int h, - uint64_t yimm) { - int64_t v; - void *p[2]; - bool readonly; - uint64_t x, y, z; - uint8_t w, *a, *c, split[8]; - w = RegLog2(rde); - readonly = (h & ALU_TEST) || (h & 7) == ALU_CMP; - if (!m->xedd->op.has_modrm || IsModrmRegister(rde)) { - v = 0; - a = RegRexbRm(m, rde); - } else { - v = ComputeAddress(m, rde); - a = AccessRam(m, v, 1 << w, p, split, true); - if (readonly) { - SetReadAddr(m, v, 1 << w); - } else { - SetWriteAddr(m, v, 1 << w); - } - } - y = yimm; - x = Read64(a); - z = f(w, h, x, y, &m->flags); - if (!readonly) { - WriteRegisterOrMemory(rde, a, z); - EndStore(m, v, 1 << w, p, split); - } +static void OpAlubFlip(struct Machine *m, uint32_t rde, int h) { + Write8(ByteRexrReg(m, rde), + Alu(0, h, Read8(ByteRexrReg(m, rde)), + Read8(GetModrmRegisterBytePointerRead(m, rde)), &m->flags)); } -static void OpAlubi(struct Machine *m, uint32_t rde, - int64_t f(int, int, uint64_t, uint64_t, uint32_t *), int h, - uint64_t yimm) { - int64_t v; - bool readonly; - uint64_t x, y, z; - uint8_t *a, *b, *c; - readonly = (h & ALU_TEST) || (h & 7) == ALU_CMP; - if (!m->xedd->op.has_modrm || IsModrmRegister(rde)) { - a = ByteRexbRm(m, rde); - } else { - v = ComputeAddress(m, rde); - a = ResolveAddress(m, v); - if (readonly) { - SetReadAddr(m, v, 1); - } else { - SetWriteAddr(m, v, 1); - } - } - y = yimm; - b = NULL; - x = Read8(a); - z = f(0, h, x, y, &m->flags); - if (!readonly) Write8(a, z); +static void OpAlubFlipRo(struct Machine *m, uint32_t rde, int h) { + Alu(0, h, Read8(ByteRexrReg(m, rde)), + Read8(GetModrmRegisterBytePointerRead(m, rde)), &m->flags); } -static void OpBsuwi(struct Machine *m, uint32_t rde, - int64_t f(int, int, uint64_t, uint64_t, uint32_t *), int h, - uint64_t yimm) { +static void OpAlubi(struct Machine *m, uint32_t rde, int h) { + uint8_t *a; + a = GetModrmRegisterBytePointerWrite(m, rde); + Write8(a, Alu(0, h, Read8(a), m->xedd->op.uimm0, &m->flags)); +} + +static void OpAlubiRo(struct Machine *m, uint32_t rde, int h) { + Alu(0, h, Read8(GetModrmRegisterBytePointerWrite(m, rde)), m->xedd->op.uimm0, + &m->flags); +} + +static void OpAluw(struct Machine *m, uint32_t rde, int h) { + uint8_t *a; + a = GetModrmRegisterWordPointerWriteOszRexw(m, rde); + WriteRegisterOrMemory(rde, a, + Alu(RegLog2(rde), h, ReadMemory(rde, a), + Read64(RegRexrReg(m, rde)), &m->flags)); +} + +static void OpAluwRo(struct Machine *m, uint32_t rde, int h) { + Alu(RegLog2(rde), h, + ReadMemory(rde, GetModrmRegisterWordPointerWriteOszRexw(m, rde)), + Read64(RegRexrReg(m, rde)), &m->flags); +} + +static void OpAluwFlip(struct Machine *m, uint32_t rde, int h) { + WriteRegister( + rde, RegRexrReg(m, rde), + Alu(RegLog2(rde), h, Read64(RegRexrReg(m, rde)), + ReadMemory(rde, GetModrmRegisterWordPointerReadOszRexw(m, rde)), + &m->flags)); +} + +static void OpAluwFlipRo(struct Machine *m, uint32_t rde, int h) { + Alu(RegLog2(rde), h, Read64(RegRexrReg(m, rde)), + ReadMemory(rde, GetModrmRegisterWordPointerReadOszRexw(m, rde)), + &m->flags); +} + +static void OpAluwi(struct Machine *m, uint32_t rde, int h) { + uint8_t *a; + a = GetModrmRegisterWordPointerWriteOszRexw(m, rde); + WriteRegisterOrMemory( + rde, a, + Alu(RegLog2(rde), h, ReadMemory(rde, a), m->xedd->op.uimm0, &m->flags)); +} + +static void OpAluwiRo(struct Machine *m, uint32_t rde, int h) { + Alu(RegLog2(rde), h, + ReadMemory(rde, GetModrmRegisterWordPointerWriteOszRexw(m, rde)), + m->xedd->op.uimm0, &m->flags); +} + +static void OpBsuwi(struct Machine *m, uint32_t rde, int h, uint64_t yimm) { int64_t v; void *p[2]; uint8_t w, *a, split[8]; @@ -1839,204 +1785,419 @@ static void OpBsuwi(struct Machine *m, uint32_t rde, v = ComputeAddress(m, rde); a = BeginLoadStore(m, v, 1 << w, p, split); } - WriteRegisterOrMemory(rde, a, f(w, h, Read64(a), yimm, &m->flags)); + WriteRegisterOrMemory(rde, a, Bsu(w, h, Read64(a), yimm, &m->flags)); EndStore(m, v, 1 << w, p, split); } -static void OpBsubi(struct Machine *m, uint32_t rde, - int64_t f(int, int, uint64_t, uint64_t, uint32_t *), int h, - uint64_t yimm) { +static void OpBsubi(struct Machine *m, uint32_t rde, int h, uint64_t yimm) { uint8_t *a; a = GetModrmRegisterBytePointerWrite(m, rde); - Write8(a, f(0, h, Read8(a), yimm, &m->flags)); + Write8(a, Bsu(0, h, Read8(a), yimm, &m->flags)); } -void ExecuteInstructionMap0(struct Machine *m, uint32_t rde) { - switch (m->xedd->op.opcode) { - CASE(/*0120 0x50*/ 0b01010000 ... 0x57, OpPushZvq(m, rde)); - CASE(/*0130 0x58*/ 0b01011000 ... 0x5f, OpPopZvq(m, rde)); - CASE(/*0143 0x63*/ 0b01100011, OpMovsxdGdqpEd(m, rde)); - CASE(/*0150 0x68*/ 0b01101000, PushOsz(m, rde, m->xedd->op.uimm0)); - CASE(/*0151 0x69*/ 0b01101001, OpImulGvqpEvqpImm(m, rde)); - CASE(/*0152 0x6A*/ 0b01101010, PushOsz(m, rde, m->xedd->op.uimm0)); - CASE(/*0153 0x6B*/ 0b01101011, OpImulGvqpEvqpImm(m, rde)); - CASE(/*0154 0x6C*/ 0b01101100, OpString(m, rde, STRING_INS)); - CASE(/*0155 0x6D*/ 0b01101101, OpString(m, rde, STRING_INS)); - CASE(/*0156 0x6E*/ 0b01101110, OpString(m, rde, STRING_OUTS)); - CASE(/*0157 0x6F*/ 0b01101111, OpString(m, rde, STRING_OUTS)); - CASE(/*0160 0x70*/ 0b01110000, if (GetCond(m, 0x0)) OpJmp(m)); - CASE(/*0161 0x71*/ 0b01110001, if (GetCond(m, 0x1)) OpJmp(m)); - CASE(/*0162 0x72*/ 0b01110010, if (GetCond(m, 0x2)) OpJmp(m)); - CASE(/*0163 0x73*/ 0b01110011, if (GetCond(m, 0x3)) OpJmp(m)); - CASE(/*0164 0x74*/ 0b01110100, if (GetCond(m, 0x4)) OpJmp(m)); - CASE(/*0165 0x75*/ 0b01110101, if (GetCond(m, 0x5)) OpJmp(m)); - CASE(/*0166 0x76*/ 0b01110110, if (GetCond(m, 0x6)) OpJmp(m)); - CASE(/*0167 0x77*/ 0b01110111, if (GetCond(m, 0x7)) OpJmp(m)); - CASE(/*0170 0x78*/ 0b01111000, if (GetCond(m, 0x8)) OpJmp(m)); - CASE(/*0171 0x79*/ 0b01111001, if (GetCond(m, 0x9)) OpJmp(m)); - CASE(/*0172 0x7A*/ 0b01111010, if (GetCond(m, 0xa)) OpJmp(m)); - CASE(/*0173 0x7B*/ 0b01111011, if (GetCond(m, 0xb)) OpJmp(m)); - CASE(/*0174 0x7C*/ 0b01111100, if (GetCond(m, 0xc)) OpJmp(m)); - CASE(/*0175 0x7D*/ 0b01111101, if (GetCond(m, 0xd)) OpJmp(m)); - CASE(/*0176 0x7E*/ 0b01111110, if (GetCond(m, 0xe)) OpJmp(m)); - CASE(/*0177 0x7F*/ 0b01111111, if (GetCond(m, 0xf)) OpJmp(m)); - CASE(/*0200 0x80*/ 0b10000000, OpAlubi(m, rde, Alu, ModrmReg(rde), UIMM0)); - CASE(/*0201 0x81*/ 0b10000001, OpAluwi(m, rde, Alu, ModrmReg(rde), UIMM0)); - CASE(/*0202 0x82*/ 0b10000010, OpAlubi(m, rde, Alu, ModrmReg(rde), UIMM0)); - CASE(/*0203 0x83*/ 0b10000011, OpAluwi(m, rde, Alu, ModrmReg(rde), UIMM0)); - CASE(/*0204 0x84*/ 0b10000100, OpAlub(m, rde, Alu, TEST)); - CASE(/*0205 0x85*/ 0b10000101, OpAluw(m, rde, Alu, TEST)); - CASE(/*0206 0x86*/ 0b10000110, OpXchgGbEb(m, rde)); - CASE(/*0207 0x87*/ 0b10000111, OpXchgGvqpEvqp(m, rde)); - CASE(/*0210 0x88*/ 0b10001000, OpMovEbGb(m, rde)); - CASE(/*0211 0x89*/ 0b10001001, OpMovEvqpGvqp(m, rde)); - CASE(/*0212 0x8A*/ 0b10001010, OpMovGbEb(m, rde)); - CASE(/*0213 0x8B*/ 0b10001011, OpMovGvqpEvqp(m, rde)); - CASE(/*0214 0x8C*/ 0b10001100, OpMovEvqpSw(m)); - CASE(/*0215 0x8D*/ 0b10001101, OpLeaGvqpM(m, rde)); - CASE(/*0216 0x8E*/ 0b10001110, OpMovSwEvqp(m)); - CASE(/*0217 0x8F*/ 0b10001111, OpPopEvq(m, rde)); - CASE(/*0220 0x90*/ 0b10010000, OpNop(m, rde)); - CASE(/*0221 0x91*/ 0b10010001 ... 0x97, OpXchgZvqp(m, rde)); - CASE(/*0230 0x98*/ 0b10011000, OpConvert1(m, rde)); - CASE(/*0231 0x99*/ 0b10011001, OpConvert2(m, rde)); - CASE(/*0234 0x9C*/ 0b10011100, OpPushf(m, rde)); - CASE(/*0235 0x9D*/ 0b10011101, OpPopf(m, rde)); - CASE(/*0236 0x9E*/ 0b10011110, OpSahf(m)); - CASE(/*0237 0x9F*/ 0b10011111, OpLahf(m)); - CASE(/*0233 0x9b*/ 0b10011011, OpFwait(m)); - CASE(/*0240 0xA0*/ 0b10100000, OpMovAlOb(m)); - CASE(/*0241 0xA1*/ 0b10100001, OpMovRaxOvqp(m, rde)); - CASE(/*0242 0xA2*/ 0b10100010, OpMovObAl(m)); - CASE(/*0243 0xA3*/ 0b10100011, OpMovOvqpRax(m, rde)); - CASE(/*0244 0xA4*/ 0b10100100, OpMovsb(m, rde)); - CASE(/*0245 0xA5*/ 0b10100101, OpString(m, rde, STRING_MOVS)); - CASE(/*0246 0xA6*/ 0b10100110, OpString(m, rde, STRING_CMPS)); - CASE(/*0247 0xA7*/ 0b10100111, OpString(m, rde, STRING_CMPS)); - CASE(/*0250 0xA8*/ 0b10101000, OpAlubi(m, rde, Alu, TEST, UIMM0)); - CASE(/*0251 0xA9*/ 0b10101001, OpAluwi(m, rde, Alu, TEST, UIMM0)); - CASE(/*0252 0xAA*/ 0b10101010, OpStosb(m, rde)); - CASE(/*0253 0xAB*/ 0b10101011, OpString(m, rde, STRING_STOS)); - CASE(/*0254 0xAC*/ 0b10101100, OpString(m, rde, STRING_LODS)); - CASE(/*0255 0xAD*/ 0b10101101, OpString(m, rde, STRING_LODS)); - CASE(/*0256 0xAE*/ 0b10101110, OpString(m, rde, STRING_SCAS)); - CASE(/*0257 0xAF*/ 0b10101111, OpString(m, rde, STRING_SCAS)); - CASE(/*0260 0xB0*/ 0b10110000 ... 0b10110111, OpMovZbIb(m, rde)); - CASE(/*0270 0xB8*/ 0b10111000 ... 0b10111111, OpMovZvqpIvqp(m, rde)); - CASE(/*0300 0xC0*/ 0b11000000, OpBsubi(m, rde, Bsu, ModrmReg(rde), UIMM0)); - CASE(/*0301 0xC1*/ 0b11000001, OpBsuwi(m, rde, Bsu, ModrmReg(rde), UIMM0)); - CASE(/*0302 0xC2*/ 0b11000010, OpRet(m, m->xedd->op.uimm0)); - CASE(/*0303 0xC3*/ 0b11000011, OpRet(m, 0)); - CASE(/*0306 0xC6*/ 0b11000110, OpMovEbIb(m, rde)); - CASE(/*0307 0xC7*/ 0b11000111, OpMovEvqpIvds(m, rde)); - CASE(/*0311 0xC9*/ 0b11001001, OpLeave(m)); - CASE(/*0314 0xCC*/ 0b11001100, OpInterrupt(m, 3)); - CASE(/*0315 0xCD*/ 0b11001101, OpInterrupt(m, m->xedd->op.uimm0)); - CASE(/*0320 0xD0*/ 0b11010000, OpBsubi(m, rde, Bsu, ModrmReg(rde), 1)); - CASE(/*0321 0xD1*/ 0b11010001, OpBsuwi(m, rde, Bsu, ModrmReg(rde), 1)); - CASE(/*0322 0xD2*/ 0b11010010, OpBsubi(m, rde, Bsu, REG, m->cx[0])); - CASE(/*0323 0xD3*/ 0b11010011, OpBsuwi(m, rde, Bsu, REG, m->cx[0])); - CASE(/*0327 0xD7*/ 0b11010111, OpXlat(m, rde)); - CASE(/*0340 0xE0*/ 0b11100000, OpLoop(m, rde, !ZF)); - CASE(/*0341 0xE1*/ 0b11100001, OpLoop(m, rde, ZF)); - CASE(/*0342 0xE2*/ 0b11100010, OpLoop(m, rde, 1)); - CASE(/*0343 0xE3*/ 0b11100011, OpJcxz(m, rde)); - CASE(/*0344 0xE4*/ 0b11100100, Write8(m->ax, OpIn(m, UIMM0))); - CASE(/*0345 0xE5*/ 0b11100101, Write32(m->ax, OpIn(m, UIMM0))); - CASE(/*0346 0xE6*/ 0b11100110, OpOut(m, UIMM0, Read8(m->ax))); - CASE(/*0347 0xE7*/ 0b11100111, OpOut(m, UIMM0, Read32(m->ax))); - CASE(/*0350 0xE8*/ 0b11101000, OpCallJvds(m)); - CASE(/*0351 0xE9*/ 0b11101001, OpJmp(m)); - CASE(/*0353 0xEB*/ 0b11101011, OpJmp(m)); - CASE(/*0354 0xEC*/ 0b11101100, Write8(m->ax, OpIn(m, Read16(m->dx)))); - CASE(/*0355 0xED*/ 0b11101101, Write32(m->ax, OpIn(m, Read16(m->dx)))); - CASE(/*0356 0xEE*/ 0b11101110, OpOut(m, Read16(m->dx), Read8(m->ax))); - CASE(/*0357 0xEF*/ 0b11101111, OpOut(m, Read16(m->dx), Read32(m->ax))); - CASE(/*0361 0xF1*/ 0b11110001, OpInterrupt(m, 1)); - CASE(/*0364 0xF4*/ 0b11110100, OpHlt(m)); - CASE(/*0365 0xF5*/ 0b11110101, OpCmc(m)); - CASE(/*0370 0xF8*/ 0b11111000, OpClc(m)); - CASE(/*0371 0xF9*/ 0b11111001, OpStc(m)); - CASE(/*0372 0xFA*/ 0b11111010, OpCli(m)); - CASE(/*0373 0xFB*/ 0b11111011, OpSti(m)); - CASE(/*0374 0xFC*/ 0b11111100, OpCld(m)); - CASE(/*0375 0xFD*/ 0b11111101, OpStd(m)); - case /*0004 0x04*/ 0b00000100: - case /*0014 0x0C*/ 0b00001100: - case /*0024 0x14*/ 0b00010100: - case /*0034 0x1C*/ 0b00011100: - case /*0044 0x24*/ 0b00100100: - case /*0054 0x2C*/ 0b00101100: - case /*0064 0x34*/ 0b00110100: - case /*0074 0x3C*/ 0b00111100: - OpAlubi(m, rde, Alu, (m->xedd->op.opcode & 070) >> 3, m->xedd->op.uimm0); - break; - case /*0005 0x05*/ 0b00000101: - case /*0015 0x0D*/ 0b00001101: - case /*0025 0x15*/ 0b00010101: - case /*0035 0x1D*/ 0b00011101: - case /*0045 0x25*/ 0b00100101: - case /*0055 0x2D*/ 0b00101101: - case /*0065 0x35*/ 0b00110101: - case /*0075 0x3D*/ 0b00111101: - OpAluwi(m, rde, Alu, (m->xedd->op.opcode & 070) >> 3, m->xedd->op.uimm0); - break; - case /*0000 0x00*/ 0b00000000: - case /*0002 0x02*/ 0b00000010: - case /*0010 0x08*/ 0b00001000: - case /*0012 0x0A*/ 0b00001010: - case /*0020 0x10*/ 0b00010000: - case /*0022 0x12*/ 0b00010010: - case /*0030 0x18*/ 0b00011000: - case /*0032 0x1A*/ 0b00011010: - case /*0040 0x20*/ 0b00100000: - case /*0042 0x22*/ 0b00100010: - case /*0050 0x28*/ 0b00101000: - case /*0052 0x2A*/ 0b00101010: - case /*0060 0x30*/ 0b00110000: - case /*0062 0x32*/ 0b00110010: - case /*0070 0x38*/ 0b00111000: - case /*0072 0x3A*/ 0b00111010: - OpAlub(m, rde, Alu, - ((m->xedd->op.opcode & 070) >> 3 | - (m->xedd->op.opcode & 0b010 ? ALU_FLIP : 0))); - break; - case /*0001 0x01*/ 0b00000001: - case /*0003 0x03*/ 0b00000011: - case /*0011 0x09*/ 0b00001001: - case /*0013 0x0B*/ 0b00001011: - case /*0021 0x11*/ 0b00010001: - case /*0023 0x13*/ 0b00010011: - case /*0031 0x19*/ 0b00011001: - case /*0033 0x1B*/ 0b00011011: - case /*0041 0x21*/ 0b00100001: - case /*0043 0x23*/ 0b00100011: - case /*0051 0x29*/ 0b00101001: - case /*0053 0x2B*/ 0b00101011: - case /*0061 0x31*/ 0b00110001: - case /*0063 0x33*/ 0b00110011: - case /*0071 0x39*/ 0b00111001: - case /*0073 0x3B*/ 0b00111011: - OpAluw(m, rde, Alu, - ((m->xedd->op.opcode & 070) >> 3 | - (m->xedd->op.opcode & 0b010 ? ALU_FLIP : 0))); - break; - case /*0330 0xD8*/ 0b11011000: - case /*0331 0xD9*/ 0b11011001: - case /*0332 0xDA*/ 0b11011010: - case /*0333 0xDB*/ 0b11011011: - case /*0334 0xDC*/ 0b11011100: - case /*0335 0xDD*/ 0b11011101: - case /*0336 0xDE*/ 0b11011110: - case /*0337 0xDF*/ 0b11011111: +static void OpAluAlIb(struct Machine *m, int h) { + Write8(m->ax, Alu(0, h, Read8(m->ax), m->xedd->op.uimm0, &m->flags)); +} + +static void OpAluRaxIvds(struct Machine *m, uint32_t rde, int h) { + WriteRegister(rde, m->ax, + Alu(RegLog2(rde), h, ReadMemory(rde, m->ax), m->xedd->op.uimm0, + &m->flags)); +} + +static void OpCmpAlIb(struct Machine *m) { + Alu(0, ALU_SUB, Read8(m->ax), m->xedd->op.uimm0, &m->flags); +} + +static void OpCmpRaxIvds(struct Machine *m, uint32_t rde) { + Alu(RegLog2(rde), ALU_SUB, ReadMemory(rde, m->ax), m->xedd->op.uimm0, + &m->flags); +} + +static void OpTestAlIb(struct Machine *m) { + Alu(0, ALU_AND, Read8(m->ax), m->xedd->op.uimm0, &m->flags); +} + +static void OpTestRaxIvds(struct Machine *m, uint32_t rde) { + Alu(RegLog2(rde), ALU_AND, ReadMemory(rde, m->ax), m->xedd->op.uimm0, + &m->flags); +} + +void ExecuteInstruction(struct Machine *m) { + uint32_t rde; + m->ip += m->xedd->length; + rde = m->xedd->op.rde; + switch (m->xedd->op.map << 8 | m->xedd->op.opcode) { + CASR(0x0B0 ... 0x0B7, OpMovZbIb(m, rde)); + CASR(0x0B8 ... 0x0BF, OpMovZvqpIvqp(m, rde)); + CASR(0x050 ... 0x057, OpPushZvq(m, rde)); + CASR(0x058 ... 0x05F, OpPopZvq(m, rde)); + CASR(0x091 ... 0x097, OpXchgZvqp(m, rde)); + CASR(0x1C8 ... 0x1CF, OpBswapZvqp(m, rde)); + CASR(0x000, OpAlub(m, rde, ALU_ADD)); + CASE(0x001, OpAluw(m, rde, ALU_ADD)); + CASR(0x002, OpAlubFlip(m, rde, ALU_ADD)); + CASE(0x003, OpAluwFlip(m, rde, ALU_ADD)); + CASR(0x004, OpAluAlIb(m, ALU_ADD)); + CASR(0x005, OpAluRaxIvds(m, rde, ALU_ADD)); + CASR(0x008, OpAlub(m, rde, ALU_OR)); + CASE(0x009, OpAluw(m, rde, ALU_OR)); + CASR(0x00A, OpAlubFlip(m, rde, ALU_OR)); + CASE(0x00B, OpAluwFlip(m, rde, ALU_OR)); + CASR(0x00C, OpAluAlIb(m, ALU_OR)); + CASR(0x00D, OpAluRaxIvds(m, rde, ALU_OR)); + CASR(0x010, OpAlub(m, rde, ALU_ADC)); + CASE(0x011, OpAluw(m, rde, ALU_ADC)); + CASR(0x012, OpAlubFlip(m, rde, ALU_ADC)); + CASE(0x013, OpAluwFlip(m, rde, ALU_ADC)); + CASR(0x014, OpAluAlIb(m, ALU_ADC)); + CASR(0x015, OpAluRaxIvds(m, rde, ALU_ADC)); + CASR(0x018, OpAlub(m, rde, ALU_SBB)); + CASE(0x019, OpAluw(m, rde, ALU_SBB)); + CASR(0x01A, OpAlubFlip(m, rde, ALU_SBB)); + CASE(0x01B, OpAluwFlip(m, rde, ALU_SBB)); + CASR(0x01C, OpAluAlIb(m, ALU_SBB)); + CASR(0x01D, OpAluRaxIvds(m, rde, ALU_SBB)); + CASR(0x020, OpAlub(m, rde, ALU_AND)); + CASE(0x021, OpAluw(m, rde, ALU_AND)); + CASR(0x022, OpAlubFlip(m, rde, ALU_AND)); + CASE(0x023, OpAluwFlip(m, rde, ALU_AND)); + CASR(0x024, OpAluAlIb(m, ALU_AND)); + CASR(0x025, OpAluRaxIvds(m, rde, ALU_AND)); + CASR(0x028, OpAlub(m, rde, ALU_SUB)); + CASE(0x029, OpAluw(m, rde, ALU_SUB)); + CASR(0x02A, OpAlubFlip(m, rde, ALU_SUB)); + CASE(0x02B, OpAluwFlip(m, rde, ALU_SUB)); + CASR(0x02C, OpAluAlIb(m, ALU_SUB)); + CASR(0x02D, OpAluRaxIvds(m, rde, ALU_SUB)); + CASR(0x030, OpAlub(m, rde, ALU_XOR)); + CASE(0x031, OpAluw(m, rde, ALU_XOR)); + CASR(0x032, OpAlubFlip(m, rde, ALU_XOR)); + CASE(0x033, OpAluwFlip(m, rde, ALU_XOR)); + CASR(0x034, OpAluAlIb(m, ALU_XOR)); + CASR(0x035, OpAluRaxIvds(m, rde, ALU_XOR)); + CASR(0x038, OpAlubRo(m, rde, ALU_CMP)); + CASE(0x039, OpAluwRo(m, rde, ALU_CMP)); + CASR(0x03A, OpAlubFlipRo(m, rde, ALU_CMP)); + CASE(0x03B, OpAluwFlipRo(m, rde, ALU_CMP)); + CASR(0x03C, OpCmpAlIb(m)); + CASR(0x03D, OpCmpRaxIvds(m, rde)); + CASE(0x063, OpMovsxdGdqpEd(m, rde)); + CASE(0x068, PushOsz(m, rde, m->xedd->op.uimm0)); + CASE(0x069, OpImulGvqpEvqpImm(m, rde)); + CASE(0x06A, PushOsz(m, rde, m->xedd->op.uimm0)); + CASE(0x06B, OpImulGvqpEvqpImm(m, rde)); + CASE(0x06C, OpString(m, rde, STRING_INS)); + CASE(0x06D, OpString(m, rde, STRING_INS)); + CASE(0x06E, OpString(m, rde, STRING_OUTS)); + CASE(0x06F, OpString(m, rde, STRING_OUTS)); + CASR(0x070, if (GetCond(m, 0x0)) OpJmp(m)); + CASR(0x071, if (GetCond(m, 0x1)) OpJmp(m)); + CASR(0x072, if (GetCond(m, 0x2)) OpJmp(m)); + CASR(0x073, if (GetCond(m, 0x3)) OpJmp(m)); + CASR(0x074, if (GetCond(m, 0x4)) OpJmp(m)); + CASR(0x075, if (GetCond(m, 0x5)) OpJmp(m)); + CASR(0x076, if (GetCond(m, 0x6)) OpJmp(m)); + CASR(0x077, if (GetCond(m, 0x7)) OpJmp(m)); + CASR(0x078, if (GetCond(m, 0x8)) OpJmp(m)); + CASR(0x079, if (GetCond(m, 0x9)) OpJmp(m)); + CASR(0x07A, if (GetCond(m, 0xa)) OpJmp(m)); + CASR(0x07B, if (GetCond(m, 0xb)) OpJmp(m)); + CASR(0x07C, if (GetCond(m, 0xc)) OpJmp(m)); + CASR(0x07D, if (GetCond(m, 0xd)) OpJmp(m)); + CASR(0x07E, if (GetCond(m, 0xe)) OpJmp(m)); + CASR(0x07F, if (GetCond(m, 0xf)) OpJmp(m)); + CASR(0x080, OpAlubi(m, rde, ModrmReg(rde))); + CASE(0x081, OpAluwi(m, rde, ModrmReg(rde))); + CASR(0x082, OpAlubi(m, rde, ModrmReg(rde))); + CASE(0x083, OpAluwi(m, rde, ModrmReg(rde))); + CASR(0x084, OpAlubRo(m, rde, TEST)); + CASE(0x085, OpAluwRo(m, rde, TEST)); + CASE(0x086, OpXchgGbEb(m, rde)); + CASE(0x087, OpXchgGvqpEvqp(m, rde)); + CASE(0x088, OpMovEbGb(m, rde)); + CASE(0x089, OpMovEvqpGvqp(m, rde)); + CASE(0x08A, OpMovGbEb(m, rde)); + CASE(0x08B, OpMovGvqpEvqp(m, rde)); + CASE(0x08C, OpMovEvqpSw(m)); + CASE(0x08D, OpLeaGvqpM(m, rde)); + CASE(0x08E, OpMovSwEvqp(m)); + CASE(0x08F, OpPopEvq(m, rde)); + CASE(0x090, OpNop(m, rde)); + CASE(0x098, OpConvert1(m, rde)); + CASE(0x099, OpConvert2(m, rde)); + CASE(0x09C, OpPushf(m, rde)); + CASE(0x09D, OpPopf(m, rde)); + CASE(0x09E, OpSahf(m)); + CASE(0x09F, OpLahf(m)); + CASE(0x09B, OpFwait(m)); + CASE(0x0A0, OpMovAlOb(m)); + CASE(0x0A1, OpMovRaxOvqp(m, rde)); + CASE(0x0A2, OpMovObAl(m)); + CASE(0x0A3, OpMovOvqpRax(m, rde)); + CASE(0x0A4, OpMovsb(m, rde)); + CASE(0x0A5, OpString(m, rde, STRING_MOVS)); + CASE(0x0A6, OpString(m, rde, STRING_CMPS)); + CASE(0x0A7, OpString(m, rde, STRING_CMPS)); + CASE(0x0A8, OpTestAlIb(m)); + CASE(0x0A9, OpTestRaxIvds(m, rde)); + CASE(0x0AA, OpStosb(m, rde)); + CASE(0x0AB, OpString(m, rde, STRING_STOS)); + CASE(0x0AC, OpString(m, rde, STRING_LODS)); + CASE(0x0AD, OpString(m, rde, STRING_LODS)); + CASE(0x0AE, OpString(m, rde, STRING_SCAS)); + CASE(0x0AF, OpString(m, rde, STRING_SCAS)); + CASR(0x0C0, OpBsubi(m, rde, ModrmReg(rde), m->xedd->op.uimm0)); + CASR(0x0C1, OpBsuwi(m, rde, ModrmReg(rde), m->xedd->op.uimm0)); + CASE(0x0C2, OpRet(m, m->xedd->op.uimm0)); + CASE(0x0C3, OpRet(m, 0)); + CASE(0x0C6, OpMovEbIb(m, rde)); + CASE(0x0C7, OpMovEvqpIvds(m, rde)); + CASE(0x0C9, OpLeave(m)); + CASE(0x0CC, OpInterrupt(m, 3)); + CASE(0x0CD, OpInterrupt(m, m->xedd->op.uimm0)); + CASR(0x0D0, OpBsubi(m, rde, ModrmReg(rde), 1)); + CASR(0x0D1, OpBsuwi(m, rde, ModrmReg(rde), 1)); + CASR(0x0D2, OpBsubi(m, rde, ModrmReg(rde), m->cx[0])); + CASR(0x0D3, OpBsuwi(m, rde, ModrmReg(rde), m->cx[0])); + CASE(0x0D7, OpXlat(m, rde)); + CASE(0x0E0, OpLoop(m, rde, !GetFlag(m->flags, FLAGS_ZF))); + CASE(0x0E1, OpLoop(m, rde, GetFlag(m->flags, FLAGS_ZF))); + CASE(0x0E2, OpLoop(m, rde, 1)); + CASE(0x0E3, OpJcxz(m, rde)); + CASE(0x0E4, Write8(m->ax, OpIn(m, m->xedd->op.uimm0))); + CASE(0x0E5, Write32(m->ax, OpIn(m, m->xedd->op.uimm0))); + CASE(0x0E6, OpOut(m, m->xedd->op.uimm0, Read8(m->ax))); + CASE(0x0E7, OpOut(m, m->xedd->op.uimm0, Read32(m->ax))); + CASE(0x0E8, OpCallJvds(m)); + CASE(0x0E9, OpJmp(m)); + CASE(0x0EB, OpJmp(m)); + CASE(0x0EC, Write8(m->ax, OpIn(m, Read16(m->dx)))); + CASE(0x0ED, Write32(m->ax, OpIn(m, Read16(m->dx)))); + CASE(0x0EE, OpOut(m, Read16(m->dx), Read8(m->ax))); + CASE(0x0EF, OpOut(m, Read16(m->dx), Read32(m->ax))); + CASE(0x0F1, OpInterrupt(m, 1)); + CASE(0x0F4, OpHlt(m)); + CASE(0x0F5, OpCmc(m)); + CASE(0x0F8, OpClc(m)); + CASE(0x0F9, OpStc(m)); + CASE(0x0FA, OpCli(m)); + CASE(0x0FB, OpSti(m)); + CASE(0x0FC, OpCld(m)); + CASE(0x0FD, OpStd(m)); + CASE(0x105, OpSyscall(m)); + CASE(0x110, OpMov0f10(m, rde)); + CASE(0x111, OpMovWpsVps(m, rde)); + CASE(0x112, OpMov0f12(m, rde)); + CASE(0x113, OpMov0f13(m, rde)); + CASE(0x114, OpUnpcklpsd(m, rde)); + CASE(0x115, OpUnpckhpsd(m, rde)); + CASE(0x116, OpMov0f16(m, rde)); + CASE(0x117, OpMov0f17(m, rde)); + CASE(0x128, OpMov0f28(m, rde)); + CASE(0x129, OpMovWpsVps(m, rde)); + CASE(0x12A, OpCvt(m, rde, kOpCvt0f2a)); + CASE(0x12B, OpMov0f2b(m, rde)); + CASE(0x12C, OpCvt(m, rde, kOpCvtt0f2c)); + CASE(0x12D, OpCvt(m, rde, kOpCvt0f2d)); + CASE(0x12E, OpComissVsWs(m, rde)); + CASE(0x12F, OpComissVsWs(m, rde)); + CASE(0x131, OpRdtsc(m)); + CASE(0x140, if (GetCond(m, 0x0)) OpMovGvqpEvqp(m, rde)); + CASE(0x141, if (GetCond(m, 0x1)) OpMovGvqpEvqp(m, rde)); + CASE(0x142, if (GetCond(m, 0x2)) OpMovGvqpEvqp(m, rde)); + CASE(0x143, if (GetCond(m, 0x3)) OpMovGvqpEvqp(m, rde)); + CASE(0x144, if (GetCond(m, 0x4)) OpMovGvqpEvqp(m, rde)); + CASE(0x145, if (GetCond(m, 0x5)) OpMovGvqpEvqp(m, rde)); + CASE(0x146, if (GetCond(m, 0x6)) OpMovGvqpEvqp(m, rde)); + CASE(0x147, if (GetCond(m, 0x7)) OpMovGvqpEvqp(m, rde)); + CASE(0x148, if (GetCond(m, 0x8)) OpMovGvqpEvqp(m, rde)); + CASE(0x149, if (GetCond(m, 0x9)) OpMovGvqpEvqp(m, rde)); + CASE(0x14A, if (GetCond(m, 0xa)) OpMovGvqpEvqp(m, rde)); + CASE(0x14B, if (GetCond(m, 0xb)) OpMovGvqpEvqp(m, rde)); + CASE(0x14C, if (GetCond(m, 0xc)) OpMovGvqpEvqp(m, rde)); + CASE(0x14D, if (GetCond(m, 0xd)) OpMovGvqpEvqp(m, rde)); + CASE(0x14E, if (GetCond(m, 0xe)) OpMovGvqpEvqp(m, rde)); + CASE(0x14F, if (GetCond(m, 0xf)) OpMovGvqpEvqp(m, rde)); + CASE(0x151, OpSqrtpsd(m, rde)); + CASE(0x152, OpRsqrtps(m, rde)); + CASE(0x153, OpRcpps(m, rde)); + CASE(0x154, OpAndpsd(m, rde)); + CASE(0x155, OpAndnpsd(m, rde)); + CASE(0x156, OpOrpsd(m, rde)); + CASE(0x157, OpXorpsd(m, rde)); + CASE(0x158, OpAddpsd(m, rde)); + CASE(0x159, OpMulpsd(m, rde)); + CASE(0x15A, OpCvt(m, rde, kOpCvt0f5a)); + CASE(0x15B, OpCvt(m, rde, kOpCvt0f5b)); + CASE(0x15C, OpSubpsd(m, rde)); + CASE(0x15D, OpMinpsd(m, rde)); + CASE(0x15E, OpDivpsd(m, rde)); + CASE(0x15F, OpMaxpsd(m, rde)); + CASR(0x160, OpSse(m, rde, kOpSsePunpcklbw)); + CASR(0x161, OpSse(m, rde, kOpSsePunpcklwd)); + CASR(0x162, OpSse(m, rde, kOpSsePunpckldq)); + CASR(0x163, OpSse(m, rde, kOpSsePacksswb)); + CASR(0x164, OpSse(m, rde, kOpSsePcmpgtb)); + CASR(0x165, OpSse(m, rde, kOpSsePcmpgtw)); + CASR(0x166, OpSse(m, rde, kOpSsePcmpgtd)); + CASR(0x167, OpSse(m, rde, kOpSsePackuswb)); + CASR(0x168, OpSse(m, rde, kOpSsePunpckhbw)); + CASR(0x169, OpSse(m, rde, kOpSsePunpckhwd)); + CASR(0x16A, OpSse(m, rde, kOpSsePunpckhdq)); + CASR(0x16B, OpSse(m, rde, kOpSsePackssdw)); + CASR(0x16C, OpSse(m, rde, kOpSsePunpcklqdq)); + CASR(0x16D, OpSse(m, rde, kOpSsePunpckhqdq)); + CASE(0x16E, OpMov0f6e(m, rde)); + CASE(0x16F, OpMov0f6f(m, rde)); + CASE(0x170, OpShuffle(m, rde)); + CASR(0x174, OpSse(m, rde, kOpSsePcmpeqb)); + CASR(0x175, OpSse(m, rde, kOpSsePcmpeqw)); + CASR(0x176, OpSse(m, rde, kOpSsePcmpeqd)); + CASE(0x17C, OpHaddpsd(m, rde)); + CASE(0x17D, OpHsubpsd(m, rde)); + CASE(0x17E, OpMov0f7e(m, rde)); + CASE(0x17F, OpMov0f7f(m, rde)); + CASE(0x180, if (GetCond(m, 0x0)) OpJmp(m)); + CASE(0x181, if (GetCond(m, 0x1)) OpJmp(m)); + CASE(0x182, if (GetCond(m, 0x2)) OpJmp(m)); + CASE(0x183, if (GetCond(m, 0x3)) OpJmp(m)); + CASE(0x184, if (GetCond(m, 0x4)) OpJmp(m)); + CASE(0x185, if (GetCond(m, 0x5)) OpJmp(m)); + CASE(0x186, if (GetCond(m, 0x6)) OpJmp(m)); + CASE(0x187, if (GetCond(m, 0x7)) OpJmp(m)); + CASE(0x188, if (GetCond(m, 0x8)) OpJmp(m)); + CASE(0x189, if (GetCond(m, 0x9)) OpJmp(m)); + CASE(0x18A, if (GetCond(m, 0xa)) OpJmp(m)); + CASE(0x18B, if (GetCond(m, 0xb)) OpJmp(m)); + CASE(0x18C, if (GetCond(m, 0xc)) OpJmp(m)); + CASE(0x18D, if (GetCond(m, 0xd)) OpJmp(m)); + CASE(0x18E, if (GetCond(m, 0xe)) OpJmp(m)); + CASE(0x18F, if (GetCond(m, 0xf)) OpJmp(m)); + CASE(0x190, OpEbSetCc(m, rde, GetCond(m, 0x0))); + CASE(0x191, OpEbSetCc(m, rde, GetCond(m, 0x1))); + CASE(0x192, OpEbSetCc(m, rde, GetCond(m, 0x2))); + CASE(0x193, OpEbSetCc(m, rde, GetCond(m, 0x3))); + CASE(0x194, OpEbSetCc(m, rde, GetCond(m, 0x4))); + CASE(0x195, OpEbSetCc(m, rde, GetCond(m, 0x5))); + CASE(0x196, OpEbSetCc(m, rde, GetCond(m, 0x6))); + CASE(0x197, OpEbSetCc(m, rde, GetCond(m, 0x7))); + CASE(0x198, OpEbSetCc(m, rde, GetCond(m, 0x8))); + CASE(0x199, OpEbSetCc(m, rde, GetCond(m, 0x9))); + CASE(0x19A, OpEbSetCc(m, rde, GetCond(m, 0xa))); + CASE(0x19B, OpEbSetCc(m, rde, GetCond(m, 0xb))); + CASE(0x19C, OpEbSetCc(m, rde, GetCond(m, 0xc))); + CASE(0x19D, OpEbSetCc(m, rde, GetCond(m, 0xd))); + CASE(0x19E, OpEbSetCc(m, rde, GetCond(m, 0xe))); + CASE(0x19F, OpEbSetCc(m, rde, GetCond(m, 0xf))); + CASE(0x1A0, OpPushFs(m)); + CASE(0x1A1, OpPopFs(m)); + CASE(0x1A2, OpCpuid(m)); + CASE(0x1A3, OpBit(m, rde)); + CASE(0x1A8, OpPushGs(m)); + CASE(0x1A9, OpPopGs(m)); + CASE(0x1AB, OpBit(m, rde)); + CASE(0x1AF, OpImulGvqpEvqp(m, rde)); + CASE(0x1B0, OpCmpxchgEbAlGb(m, rde)); + CASE(0x1B1, OpCmpxchgEvqpRaxGvqp(m, rde)); + CASE(0x1B3, OpBit(m, rde)); + CASE(0x1B6, OpMovzbGvqpEb(m, rde)); + CASE(0x1B7, OpMovzwGvqpEw(m, rde)); + CASE(0x1BA, OpBit(m, rde)); + CASE(0x1BB, OpBit(m, rde)); + CASE(0x1BC, OpGvqpEvqp(m, rde, AluBsf, MUTATING)); + CASE(0x1BD, OpGvqpEvqp(m, rde, AluBsr, MUTATING)); + CASE(0x1BE, OpMovsbGvqpEb(m, rde)); + CASE(0x1BF, OpMovswGvqpEw(m, rde)); + CASE(0x1C0, OpXaddEbGb(m, rde)); + CASE(0x1C1, OpXaddEvqpGvqp(m, rde)); + CASE(0x1C2, OpCmppsd(m, rde)); + CASE(0x1C3, OpMovntiMdqpGdqp(m, rde)); + CASE(0x1C4, OpPinsrwVdqEwIb(m, rde)); + CASE(0x1C5, OpPextrwGdqpUdqIb(m, rde)); + CASE(0x1C6, OpShufpsd(m, rde)); + CASE(0x1C7, OpCmpxchgDxAx(m, rde)); + CASE(0x1D0, OpAddsubpsd(m, rde)); + CASR(0x1D1, OpSse(m, rde, kOpSsePsrlwv)); + CASR(0x1D2, OpSse(m, rde, kOpSsePsrldv)); + CASR(0x1D3, OpSse(m, rde, kOpSsePsrlqv)); + CASR(0x1D4, OpSse(m, rde, kOpSsePaddq)); + CASR(0x1D5, OpSse(m, rde, kOpSsePmullw)); + CASE(0x1D6, OpMov0fD6(m, rde)); + CASE(0x1D7, OpPmovmskbGdqpNqUdq(m, rde)); + CASR(0x1D8, OpSse(m, rde, kOpSsePsubusb)); + CASR(0x1D9, OpSse(m, rde, kOpSsePsubusw)); + CASR(0x1DA, OpSse(m, rde, kOpSsePminub)); + CASR(0x1DB, OpSse(m, rde, kOpSsePand)); + CASR(0x1DC, OpSse(m, rde, kOpSsePaddusb)); + CASR(0x1DD, OpSse(m, rde, kOpSsePaddusw)); + CASR(0x1DE, OpSse(m, rde, kOpSsePmaxub)); + CASR(0x1DF, OpSse(m, rde, kOpSsePandn)); + CASR(0x1E0, OpSse(m, rde, kOpSsePavgb)); + CASR(0x1E1, OpSse(m, rde, kOpSsePsrawv)); + CASR(0x1E2, OpSse(m, rde, kOpSsePsradv)); + CASR(0x1E3, OpSse(m, rde, kOpSsePavgw)); + CASR(0x1E4, OpSse(m, rde, kOpSsePmulhuw)); + CASR(0x1E5, OpSse(m, rde, kOpSsePmulhw)); + CASE(0x1E6, OpCvt(m, rde, kOpCvt0fE6)); + CASE(0x1E7, OpMov0fE7(m, rde)); + CASR(0x1E8, OpSse(m, rde, kOpSsePsubsb)); + CASR(0x1E9, OpSse(m, rde, kOpSsePsubsw)); + CASR(0x1EA, OpSse(m, rde, kOpSsePminsw)); + CASR(0x1EB, OpSse(m, rde, kOpSsePor)); + CASR(0x1EC, OpSse(m, rde, kOpSsePaddsb)); + CASR(0x1ED, OpSse(m, rde, kOpSsePaddsw)); + CASR(0x1EE, OpSse(m, rde, kOpSsePmaxsw)); + CASR(0x1EF, OpSse(m, rde, kOpSsePxor)); + CASE(0x1F0, OpLddquVdqMdq(m, rde)); + CASR(0x1F1, OpSse(m, rde, kOpSsePsllwv)); + CASR(0x1F2, OpSse(m, rde, kOpSsePslldv)); + CASR(0x1F3, OpSse(m, rde, kOpSsePsllqv)); + CASR(0x1F4, OpSse(m, rde, kOpSsePmuludq)); + CASR(0x1F5, OpSse(m, rde, kOpSsePmaddwd)); + CASR(0x1F6, OpSse(m, rde, kOpSsePsadbw)); + CASE(0x1F7, OpMaskMovDiXmmRegXmmRm(m, rde)); + CASR(0x1F8, OpSse(m, rde, kOpSsePsubb)); + CASR(0x1F9, OpSse(m, rde, kOpSsePsubw)); + CASR(0x1FA, OpSse(m, rde, kOpSsePsubd)); + CASR(0x1FB, OpSse(m, rde, kOpSsePsubq)); + CASR(0x1FC, OpSse(m, rde, kOpSsePaddb)); + CASR(0x1FD, OpSse(m, rde, kOpSsePaddw)); + CASR(0x1FE, OpSse(m, rde, kOpSsePaddd)); + CASR(0x200, OpSse(m, rde, kOpSsePshufb)); + CASR(0x201, OpSse(m, rde, kOpSsePhaddw)); + CASR(0x202, OpSse(m, rde, kOpSsePhaddd)); + CASR(0x203, OpSse(m, rde, kOpSsePhaddsw)); + CASR(0x204, OpSse(m, rde, kOpSsePmaddubsw)); + CASR(0x205, OpSse(m, rde, kOpSsePhsubw)); + CASR(0x206, OpSse(m, rde, kOpSsePhsubd)); + CASR(0x207, OpSse(m, rde, kOpSsePhsubsw)); + CASR(0x208, OpSse(m, rde, kOpSsePsignb)); + CASR(0x209, OpSse(m, rde, kOpSsePsignw)); + CASR(0x20A, OpSse(m, rde, kOpSsePsignd)); + CASR(0x20B, OpSse(m, rde, kOpSsePmulhrsw)); + CASR(0x21C, OpSse(m, rde, kOpSsePabsb)); + CASR(0x21D, OpSse(m, rde, kOpSsePabsw)); + CASR(0x21E, OpSse(m, rde, kOpSsePabsd)); + CASE(0x22A, OpMovntdqaVdqMdq(m, rde)); + CASR(0x240, OpSse(m, rde, kOpSsePmulld)); + CASE(0x30F, OpSsePalignr(m, rde)); + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: OpFpu(m); break; - case /*0366 0xF6*/ 0b11110110: + case 0xF6: switch (ModrmReg(rde)) { - CASE(0, OpAlubi(m, rde, Alu, TEST, UIMM0)); - CASE(1, OpAlubi(m, rde, Alu, TEST, UIMM0)); - CASE(2, OpEb(m, rde, AluNot)); - CASE(3, OpEb(m, rde, AluNeg)); + CASR(0, OpAlubiRo(m, rde, TEST)); + CASR(1, OpAlubiRo(m, rde, TEST)); + CASR(2, OpEb(m, rde, AluNot)); + CASR(3, OpEb(m, rde, AluNeg)); CASE(4, OpMulAxAlEbUnsigned(m, rde)); CASE(5, OpMulAxAlEbSigned(m, rde)); CASE(6, OpDivAlAhAxEbUnsigned(m, rde)); @@ -2045,10 +2206,10 @@ void ExecuteInstructionMap0(struct Machine *m, uint32_t rde) { unreachable; } break; - case /*0367 0xF7*/ 0b11110111: + case 0xF7: switch (ModrmReg(rde)) { - CASE(0, OpAluwi(m, rde, Alu, TEST, UIMM0)); - CASE(1, OpAluwi(m, rde, Alu, TEST, UIMM0)); + CASE(0, OpAluwiRo(m, rde, TEST)); + CASE(1, OpAluwiRo(m, rde, TEST)); CASE(2, OpEvqp(m, rde, AluNot)); CASE(3, OpEvqp(m, rde, AluNeg)); CASE(4, OpMulRdxRaxEvqpUnsigned(m, rde)); @@ -2059,7 +2220,7 @@ void ExecuteInstructionMap0(struct Machine *m, uint32_t rde) { unreachable; } break; - case /*0376 0xFE*/ 0b11111110: + case 0xFE: switch (ModrmReg(rde)) { CASE(0b000, OpEb(m, rde, AluInc)); CASE(0b001, OpEb(m, rde, AluDec)); @@ -2067,7 +2228,7 @@ void ExecuteInstructionMap0(struct Machine *m, uint32_t rde) { OpUd(m); } break; - case /*0377 0xFF*/ 0b11111111: + case 0xFF: switch (ModrmReg(rde)) { CASE(0, OpEvqp(m, rde, AluInc)); CASE(1, OpEvqp(m, rde, AluDec)); @@ -2078,211 +2239,24 @@ void ExecuteInstructionMap0(struct Machine *m, uint32_t rde) { OpUd(m); } break; - default: - OpUd(m); - } -} - -void ExecuteInstructionMap1(struct Machine *m, uint32_t rde) { - switch (m->xedd->op.opcode) { - CASE(/*0005 0x05*/ 0b00000101, OpSyscall(m)); - CASE(/*0020 0x10*/ 0b00010000, OpMov0f10(m, rde)); - CASE(/*0021 0x11*/ 0b00010001, OpMovWpsVps(m, rde)); - CASE(/*0022 0x12*/ 0b00010010, OpMov0f12(m, rde)); - CASE(/*0023 0x13*/ 0b00010011, OpMov0f13(m, rde)); - CASE(/*0024 0x14*/ 0b00010100, OpUnpcklpsd(m, rde)); - CASE(/*0025 0x15*/ 0b00010101, OpUnpckhpsd(m, rde)); - CASE(/*0026 0x16*/ 0b00010110, OpMov0f16(m, rde)); - CASE(/*0027 0x17*/ 0b00010111, OpMov0f17(m, rde)); - CASE(/*0050 0x28*/ 0b00101000, OpMov0f28(m, rde)); - CASE(/*0051 0x29*/ 0b00101001, OpMovWpsVps(m, rde)); - CASE(/*0052 0x2A*/ 0b00101010, OpCvt(m, rde, kOpCvt0f2a)); - CASE(/*0053 0x2B*/ 0b00101011, OpMov0f2b(m, rde)); - CASE(/*0054 0x2C*/ 0b00101100, OpCvt(m, rde, kOpCvtt0f2c)); - CASE(/*0055 0x2D*/ 0b00101101, OpCvt(m, rde, kOpCvt0f2d)); - CASE(/*0056 0x2E*/ 0b00101110, OpComissVsWs(m, rde)); - CASE(/*0057 0x2F*/ 0b00101111, OpComissVsWs(m, rde)); - CASE(/*0061 0x31*/ 0b00110001, OpRdtsc(m)); - CASE(/*0100 0x40*/ 0b01000000, if (GetCond(m, 0x0)) OpMovGvqpEvqp(m, rde)); - CASE(/*0101 0x41*/ 0b01000001, if (GetCond(m, 0x1)) OpMovGvqpEvqp(m, rde)); - CASE(/*0102 0x42*/ 0b01000010, if (GetCond(m, 0x2)) OpMovGvqpEvqp(m, rde)); - CASE(/*0103 0x43*/ 0b01000011, if (GetCond(m, 0x3)) OpMovGvqpEvqp(m, rde)); - CASE(/*0104 0x44*/ 0b01000100, if (GetCond(m, 0x4)) OpMovGvqpEvqp(m, rde)); - CASE(/*0105 0x45*/ 0b01000101, if (GetCond(m, 0x5)) OpMovGvqpEvqp(m, rde)); - CASE(/*0106 0x46*/ 0b01000110, if (GetCond(m, 0x6)) OpMovGvqpEvqp(m, rde)); - CASE(/*0107 0x47*/ 0b01000111, if (GetCond(m, 0x7)) OpMovGvqpEvqp(m, rde)); - CASE(/*0110 0x48*/ 0b01001000, if (GetCond(m, 0x8)) OpMovGvqpEvqp(m, rde)); - CASE(/*0111 0x49*/ 0b01001001, if (GetCond(m, 0x9)) OpMovGvqpEvqp(m, rde)); - CASE(/*0112 0x4a*/ 0b01001010, if (GetCond(m, 0xa)) OpMovGvqpEvqp(m, rde)); - CASE(/*0113 0x4b*/ 0b01001011, if (GetCond(m, 0xb)) OpMovGvqpEvqp(m, rde)); - CASE(/*0114 0x4c*/ 0b01001100, if (GetCond(m, 0xc)) OpMovGvqpEvqp(m, rde)); - CASE(/*0115 0x4d*/ 0b01001101, if (GetCond(m, 0xd)) OpMovGvqpEvqp(m, rde)); - CASE(/*0116 0x4e*/ 0b01001110, if (GetCond(m, 0xe)) OpMovGvqpEvqp(m, rde)); - CASE(/*0117 0x4f*/ 0b01001111, if (GetCond(m, 0xf)) OpMovGvqpEvqp(m, rde)); - CASE(/*0121 0x51*/ 0b01010001, OpSqrtpsd(m, rde)); - CASE(/*0122 0x52*/ 0b01010010, OpRsqrtps(m, rde)); - CASE(/*0123 0x53*/ 0b01010011, OpRcpps(m, rde)); - CASE(/*0124 0x54*/ 0b01010100, OpAndpsd(m, rde)); - CASE(/*0125 0x55*/ 0b01010101, OpAndnpsd(m, rde)); - CASE(/*0126 0x56*/ 0b01010110, OpOrpsd(m, rde)); - CASE(/*0127 0x57*/ 0b01010111, OpXorpsd(m, rde)); - CASE(/*0130 0x58*/ 0b01011000, OpAddpsd(m, rde)); - CASE(/*0131 0x59*/ 0b01011001, OpMulpsd(m, rde)); - CASE(/*0132 0x5A*/ 0b01011010, OpCvt(m, rde, kOpCvt0f5a)); - CASE(/*0133 0x5B*/ 0b01011011, OpCvt(m, rde, kOpCvt0f5b)); - CASE(/*0134 0x5C*/ 0b01011100, OpSubpsd(m, rde)); - CASE(/*0135 0x5D*/ 0b01011101, OpMinpsd(m, rde)); - CASE(/*0136 0x5E*/ 0b01011110, OpDivpsd(m, rde)); - CASE(/*0137 0x5F*/ 0b01011111, OpMaxpsd(m, rde)); - CASE(/*0140 0x60*/ 0b01100000, OpSse(m, rde, kOpSsePunpcklbw)); - CASE(/*0141 0x61*/ 0b01100001, OpSse(m, rde, kOpSsePunpcklwd)); - CASE(/*0142 0x62*/ 0b01100010, OpSse(m, rde, kOpSsePunpckldq)); - CASE(/*0143 0x63*/ 0b01100011, OpSse(m, rde, kOpSsePacksswb)); - CASE(/*0144 0x64*/ 0b01100100, OpSse(m, rde, kOpSsePcmpgtb)); - CASE(/*0145 0x65*/ 0b01100101, OpSse(m, rde, kOpSsePcmpgtw)); - CASE(/*0146 0x66*/ 0b01100110, OpSse(m, rde, kOpSsePcmpgtd)); - CASE(/*0147 0x67*/ 0b01100111, OpSse(m, rde, kOpSsePackuswb)); - CASE(/*0150 0x68*/ 0b01101000, OpSse(m, rde, kOpSsePunpckhbw)); - CASE(/*0151 0x69*/ 0b01101001, OpSse(m, rde, kOpSsePunpckhwd)); - CASE(/*0152 0x6A*/ 0b01101010, OpSse(m, rde, kOpSsePunpckhdq)); - CASE(/*0153 0x6B*/ 0b01101011, OpSse(m, rde, kOpSsePackssdw)); - CASE(/*0154 0x6C*/ 0b01101100, OpSse(m, rde, kOpSsePunpcklqdq)); - CASE(/*0155 0x6D*/ 0b01101101, OpSse(m, rde, kOpSsePunpckhqdq)); - CASE(/*0156 0x6E*/ 0b01101110, OpMov0f6e(m, rde)); - CASE(/*0157 0x6F*/ 0b01101111, OpMov0f6f(m, rde)); - CASE(/*0160 0x70*/ 0b01110000, OpShuffle(m, rde)); - CASE(/*0164 0x74*/ 0b01110100, OpSse(m, rde, kOpSsePcmpeqb)); - CASE(/*0165 0x75*/ 0b01110101, OpSse(m, rde, kOpSsePcmpeqw)); - CASE(/*0166 0x76*/ 0b01110110, OpSse(m, rde, kOpSsePcmpeqd)); - CASE(/*0174 0x7C*/ 0b01111100, OpHaddpsd(m, rde)); - CASE(/*0175 0x7D*/ 0b01111101, OpHsubpsd(m, rde)); - CASE(/*0176 0x7E*/ 0b01111110, OpMov0f7e(m, rde)); - CASE(/*0177 0x7F*/ 0b01111111, OpMov0f7f(m, rde)); - CASE(/*0200 0x80*/ 0b10000000, if (GetCond(m, 0x0)) OpJmp(m)); - CASE(/*0201 0x81*/ 0b10000001, if (GetCond(m, 0x1)) OpJmp(m)); - CASE(/*0202 0x82*/ 0b10000010, if (GetCond(m, 0x2)) OpJmp(m)); - CASE(/*0203 0x83*/ 0b10000011, if (GetCond(m, 0x3)) OpJmp(m)); - CASE(/*0204 0x84*/ 0b10000100, if (GetCond(m, 0x4)) OpJmp(m)); - CASE(/*0205 0x85*/ 0b10000101, if (GetCond(m, 0x5)) OpJmp(m)); - CASE(/*0206 0x86*/ 0b10000110, if (GetCond(m, 0x6)) OpJmp(m)); - CASE(/*0207 0x87*/ 0b10000111, if (GetCond(m, 0x7)) OpJmp(m)); - CASE(/*0210 0x88*/ 0b10001000, if (GetCond(m, 0x8)) OpJmp(m)); - CASE(/*0211 0x89*/ 0b10001001, if (GetCond(m, 0x9)) OpJmp(m)); - CASE(/*0212 0x8a*/ 0b10001010, if (GetCond(m, 0xa)) OpJmp(m)); - CASE(/*0213 0x8b*/ 0b10001011, if (GetCond(m, 0xb)) OpJmp(m)); - CASE(/*0214 0x8c*/ 0b10001100, if (GetCond(m, 0xc)) OpJmp(m)); - CASE(/*0215 0x8d*/ 0b10001101, if (GetCond(m, 0xd)) OpJmp(m)); - CASE(/*0216 0x8e*/ 0b10001110, if (GetCond(m, 0xe)) OpJmp(m)); - CASE(/*0217 0x8f*/ 0b10001111, if (GetCond(m, 0xf)) OpJmp(m)); - CASE(/*0220 0x90*/ 0b10010000, OpEbSetCc(m, rde, GetCond(m, 0x0))); - CASE(/*0221 0x91*/ 0b10010001, OpEbSetCc(m, rde, GetCond(m, 0x1))); - CASE(/*0222 0x92*/ 0b10010010, OpEbSetCc(m, rde, GetCond(m, 0x2))); - CASE(/*0223 0x93*/ 0b10010011, OpEbSetCc(m, rde, GetCond(m, 0x3))); - CASE(/*0224 0x94*/ 0b10010100, OpEbSetCc(m, rde, GetCond(m, 0x4))); - CASE(/*0225 0x95*/ 0b10010101, OpEbSetCc(m, rde, GetCond(m, 0x5))); - CASE(/*0226 0x96*/ 0b10010110, OpEbSetCc(m, rde, GetCond(m, 0x6))); - CASE(/*0227 0x97*/ 0b10010111, OpEbSetCc(m, rde, GetCond(m, 0x7))); - CASE(/*0230 0x98*/ 0b10011000, OpEbSetCc(m, rde, GetCond(m, 0x8))); - CASE(/*0231 0x99*/ 0b10011001, OpEbSetCc(m, rde, GetCond(m, 0x9))); - CASE(/*0232 0x9A*/ 0b10011010, OpEbSetCc(m, rde, GetCond(m, 0xa))); - CASE(/*0233 0x9B*/ 0b10011011, OpEbSetCc(m, rde, GetCond(m, 0xb))); - CASE(/*0234 0x9C*/ 0b10011100, OpEbSetCc(m, rde, GetCond(m, 0xc))); - CASE(/*0235 0x9D*/ 0b10011101, OpEbSetCc(m, rde, GetCond(m, 0xd))); - CASE(/*0236 0x9E*/ 0b10011110, OpEbSetCc(m, rde, GetCond(m, 0xe))); - CASE(/*0237 0x9F*/ 0b10011111, OpEbSetCc(m, rde, GetCond(m, 0xf))); - CASE(/*0240 0xA0*/ 0b10100000, OpPushFs(m)); - CASE(/*0241 0xA1*/ 0b10100001, OpPopFs(m)); - CASE(/*0242 0xA2*/ 0b10100010, OpCpuid(m)); - CASE(/*0243 0xA3*/ 0b10100011, OpBit(m, rde)); - CASE(/*0250 0xA8*/ 0b10101000, OpPushGs(m)); - CASE(/*0251 0xA9*/ 0b10101001, OpPopGs(m)); - CASE(/*0253 0xAB*/ 0b10101011, OpBit(m, rde)); - CASE(/*0257 0xAF*/ 0b10101111, OpImulGvqpEvqp(m, rde)); - CASE(/*0260 0xB0*/ 0b10110000, OpCmpxchgEbAlGb(m, rde)); - CASE(/*0261 0xB1*/ 0b10110001, OpCmpxchgEvqpRaxGvqp(m, rde)); - CASE(/*0263 0xB3*/ 0b10110011, OpBit(m, rde)); - CASE(/*0266 0xB6*/ 0b10110110, OpMovzbGvqpEb(m, rde)); - CASE(/*0267 0xB7*/ 0b10110111, OpMovzwGvqpEw(m, rde)); - CASE(/*0272 0xBA*/ 0b10111010, OpBit(m, rde)); - CASE(/*0273 0xBB*/ 0b10111011, OpBit(m, rde)); - CASE(/*0274 0xBC*/ 0b10111100, OpGvqpEvqp(m, rde, AluBsf, MUTATING)); - CASE(/*0275 0xBD*/ 0b10111101, OpGvqpEvqp(m, rde, AluBsr, MUTATING)); - CASE(/*0276 0xBE*/ 0b10111110, OpMovsbGvqpEb(m, rde)); - CASE(/*0277 0xBF*/ 0b10111111, OpMovswGvqpEw(m, rde)); - CASE(/*0300 0xC0*/ 0b11000000, OpXaddEbGb(m, rde)); - CASE(/*0301 0xC1*/ 0b11000001, OpXaddEvqpGvqp(m, rde)); - CASE(/*0302 0xC2*/ 0b11000010, OpCmppsd(m, rde)); - CASE(/*0303 0xC3*/ 0b11000011, OpMovntiMdqpGdqp(m, rde)); - CASE(/*0304 0xC4*/ 0b11000100, OpPinsrwVdqEwIb(m, rde)); - CASE(/*0305 0xC5*/ 0b11000101, OpPextrwGdqpUdqIb(m, rde)); - CASE(/*0306 0xC6*/ 0b11000110, OpShufpsd(m, rde)); - CASE(/*0307 0xC7*/ 0b11000111, OpCmpxchgDxAx(m, rde)); - CASE(/*0310 0xC8*/ 0b11001000 ... 0b11001111, OpBswapZvqp(m, rde)); - CASE(/*0320 0xD0*/ 0b11010000, OpAddsubpsd(m, rde)); - CASE(/*0321 0xD1*/ 0b11010001, OpSse(m, rde, kOpSsePsrlwv)); - CASE(/*0322 0xD2*/ 0b11010010, OpSse(m, rde, kOpSsePsrldv)); - CASE(/*0323 0xD3*/ 0b11010011, OpSse(m, rde, kOpSsePsrlqv)); - CASE(/*0324 0xD4*/ 0b11010100, OpSse(m, rde, kOpSsePaddq)); - CASE(/*0325 0xD5*/ 0b11010101, OpSse(m, rde, kOpSsePmullw)); - CASE(/*0326 0xD6*/ 0b11010110, OpMov0fD6(m, rde)); - CASE(/*0327 0xD7*/ 0b11010111, OpPmovmskbGdqpNqUdq(m, rde)); - CASE(/*0330 0xD8*/ 0b11011000, OpSse(m, rde, kOpSsePsubusb)); - CASE(/*0331 0xD9*/ 0b11011001, OpSse(m, rde, kOpSsePsubusw)); - CASE(/*0332 0xDA*/ 0b11011010, OpSse(m, rde, kOpSsePminub)); - CASE(/*0333 0xDB*/ 0b11011011, OpSse(m, rde, kOpSsePand)); - CASE(/*0334 0xDC*/ 0b11011100, OpSse(m, rde, kOpSsePaddusb)); - CASE(/*0335 0xDD*/ 0b11011101, OpSse(m, rde, kOpSsePaddusw)); - CASE(/*0336 0xDE*/ 0b11011110, OpSse(m, rde, kOpSsePmaxub)); - CASE(/*0337 0xDF*/ 0b11011111, OpSse(m, rde, kOpSsePandn)); - CASE(/*0340 0xE0*/ 0b11100000, OpSse(m, rde, kOpSsePavgb)); - CASE(/*0341 0xE1*/ 0b11100001, OpSse(m, rde, kOpSsePsrawv)); - CASE(/*0342 0xE2*/ 0b11100010, OpSse(m, rde, kOpSsePsradv)); - CASE(/*0343 0xE3*/ 0b11100011, OpSse(m, rde, kOpSsePavgw)); - CASE(/*0344 0xE4*/ 0b11100100, OpSse(m, rde, kOpSsePmulhuw)); - CASE(/*0345 0xE5*/ 0b11100101, OpSse(m, rde, kOpSsePmulhw)); - CASE(/*0346 0xE6*/ 0b11100110, OpCvt(m, rde, kOpCvt0fE6)); - CASE(/*0347 0xE7*/ 0b11100111, OpMov0fE7(m, rde)); - CASE(/*0350 0xE8*/ 0b11101000, OpSse(m, rde, kOpSsePsubsb)); - CASE(/*0351 0xE9*/ 0b11101001, OpSse(m, rde, kOpSsePsubsw)); - CASE(/*0352 0xEA*/ 0b11101010, OpSse(m, rde, kOpSsePminsw)); - CASE(/*0353 0xEB*/ 0b11101011, OpSse(m, rde, kOpSsePor)); - CASE(/*0354 0xEC*/ 0b11101100, OpSse(m, rde, kOpSsePaddsb)); - CASE(/*0355 0xED*/ 0b11101101, OpSse(m, rde, kOpSsePaddsw)); - CASE(/*0356 0xEE*/ 0b11101110, OpSse(m, rde, kOpSsePmaxsw)); - CASE(/*0357 0xEF*/ 0b11101111, OpSse(m, rde, kOpSsePxor)); - CASE(/*0360 0xF0*/ 0b11110000, OpLddquVdqMdq(m, rde)); - CASE(/*0361 0xF1*/ 0b11110001, OpSse(m, rde, kOpSsePsllwv)); - CASE(/*0362 0xF2*/ 0b11110010, OpSse(m, rde, kOpSsePslldv)); - CASE(/*0363 0xF3*/ 0b11110011, OpSse(m, rde, kOpSsePsllqv)); - CASE(/*0364 0xF4*/ 0b11110100, OpSse(m, rde, kOpSsePmuludq)); - CASE(/*0365 0xF5*/ 0b11110101, OpSse(m, rde, kOpSsePmaddwd)); - CASE(/*0366 0xF6*/ 0b11110110, OpSse(m, rde, kOpSsePsadbw)); - CASE(/*0367 0xF7*/ 0b11110111, OpMaskMovDiXmmRegXmmRm(m, rde)); - CASE(/*0370 0xF8*/ 0b11111000, OpSse(m, rde, kOpSsePsubb)); - CASE(/*0371 0xF9*/ 0b11111001, OpSse(m, rde, kOpSsePsubw)); - CASE(/*0372 0xFA*/ 0b11111010, OpSse(m, rde, kOpSsePsubd)); - CASE(/*0373 0xFB*/ 0b11111011, OpSse(m, rde, kOpSsePsubq)); - CASE(/*0374 0xFC*/ 0b11111100, OpSse(m, rde, kOpSsePaddb)); - CASE(/*0375 0xFD*/ 0b11111101, OpSse(m, rde, kOpSsePaddw)); - CASE(/*0376 0xFE*/ 0b11111110, OpSse(m, rde, kOpSsePaddd)); - case /*0013 0x0B*/ 0b00001011: - case /*0271 0xB9*/ 0b10111001: - case /*0377 0xFF*/ 0b11111111: + case 0x10B: + case 0x1B9: + case 0x1FF: OpUd(m); break; - case /*0015 0x0D*/ 0b00001101: - case /*0030 0x18*/ 0b00011000: - case /*0031 0x19*/ 0b00011001: - case /*0032 0x1A*/ 0b00011010: - case /*0033 0x1B*/ 0b00011011: - case /*0034 0x1C*/ 0b00011100: - case /*0035 0x1D*/ 0b00011101: + case 0x10D: + case 0x118: + case 0x119: + case 0x11A: + case 0x11B: + case 0x11C: + case 0x11D: OpWutNopEv(m); break; - case /*0037 0x1F*/ 0b00011111: + case 0x11F: OpNopEv(m); break; - case /*0161 0x71*/ 0b01110001: + case 0x171: switch (ModrmReg(rde)) { CASE(2, OpSseUdqIb(m, rde, kOpSseUdqIbPsrlw)); CASE(4, OpSseUdqIb(m, rde, kOpSseUdqIbPsraw)); @@ -2291,7 +2265,7 @@ void ExecuteInstructionMap1(struct Machine *m, uint32_t rde) { OpUd(m); } break; - case /*0162 0x72*/ 0b01110010: + case 0x172: switch (ModrmReg(rde)) { CASE(2, OpSseUdqIb(m, rde, kOpSseUdqIbPsrld)); CASE(4, OpSseUdqIb(m, rde, kOpSseUdqIbPsrad)); @@ -2300,7 +2274,7 @@ void ExecuteInstructionMap1(struct Machine *m, uint32_t rde) { OpUd(m); } break; - case /*0163 0x73*/ 0b01110011: + case 0x173: switch (ModrmReg(rde)) { CASE(2, OpSseUdqIb(m, rde, kOpSseUdqIbPsrlq)); CASE(3, OpSseUdqIb(m, rde, kOpSseUdqIbPsrldq)); @@ -2310,13 +2284,13 @@ void ExecuteInstructionMap1(struct Machine *m, uint32_t rde) { OpUd(m); } break; - case /*0244 0xA4*/ 0b10100100: - case /*0245 0xA5*/ 0b10100101: - case /*0254 0xAC*/ 0b10101100: - case /*0255 0xAD*/ 0b10101101: + case 0x1A4: + case 0x1A5: + case 0x1AC: + case 0x1AD: OpEvqpGvqp(m, rde, OpDoubleShift, MUTATING); break; - case /*0256 0xAE*/ 0b10101110: + case 0x1AE: switch (ModrmReg(rde)) { CASE(5, OpLfence(m)); CASE(6, OpMfence(m)); @@ -2331,7 +2305,7 @@ void ExecuteInstructionMap1(struct Machine *m, uint32_t rde) { OpUd(m); } break; - case 0xB8: + case 0x1B8: if (Rep(rde) == 3) { OpGvqpEvqp(m, rde, AluPopcnt, MUTATING); } else { @@ -2341,59 +2315,6 @@ void ExecuteInstructionMap1(struct Machine *m, uint32_t rde) { default: OpUd(m); } -} - -void ExecuteInstructionMap2(struct Machine *m, uint32_t rde) { - switch (m->xedd->op.opcode) { - CASE(0x00, OpSse(m, rde, kOpSsePshufb)); - CASE(0x01, OpSse(m, rde, kOpSsePhaddw)); - CASE(0x02, OpSse(m, rde, kOpSsePhaddd)); - CASE(0x03, OpSse(m, rde, kOpSsePhaddsw)); - CASE(0x04, OpSse(m, rde, kOpSsePmaddubsw)); - CASE(0x05, OpSse(m, rde, kOpSsePhsubw)); - CASE(0x06, OpSse(m, rde, kOpSsePhsubd)); - CASE(0x07, OpSse(m, rde, kOpSsePhsubsw)); - CASE(0x08, OpSse(m, rde, kOpSsePsignb)); - CASE(0x09, OpSse(m, rde, kOpSsePsignw)); - CASE(0x0A, OpSse(m, rde, kOpSsePsignd)); - CASE(0x0B, OpSse(m, rde, kOpSsePmulhrsw)); - CASE(0x1C, OpSse(m, rde, kOpSsePabsb)); - CASE(0x1D, OpSse(m, rde, kOpSsePabsw)); - CASE(0x1E, OpSse(m, rde, kOpSsePabsd)); - CASE(0x2A, OpMovntdqaVdqMdq(m, rde)); - CASE(0x40, OpSse(m, rde, kOpSsePmulld)); - default: - OpUd(m); - } -} - -void ExecuteInstructionMap3(struct Machine *m, uint32_t rde) { - switch (m->xedd->op.opcode) { - CASE(0x0F, OpSsePalignr(m, rde)); - default: - OpUd(m); - } -} - -void ExecuteInstructionMapUndefined(struct Machine *m, uint32_t rde) { - OpUd(m); -} - -static const map_f kExecuteInstructionMap[16] = { - ExecuteInstructionMap0, ExecuteInstructionMap1, - ExecuteInstructionMap2, ExecuteInstructionMap3, - ExecuteInstructionMapUndefined, ExecuteInstructionMapUndefined, - ExecuteInstructionMapUndefined, ExecuteInstructionMapUndefined, - ExecuteInstructionMapUndefined, ExecuteInstructionMapUndefined, - ExecuteInstructionMapUndefined, ExecuteInstructionMapUndefined, - ExecuteInstructionMapUndefined, ExecuteInstructionMapUndefined, - ExecuteInstructionMapUndefined, ExecuteInstructionMapUndefined, -}; - -void ExecuteInstruction(struct Machine *m) { - uint8_t *p; - m->ip += m->xedd->length; - kExecuteInstructionMap[m->xedd->op.map & 15](m, m->xedd->op.rde); if (m->stashaddr) { VirtualRecv(m, m->stashaddr, m->stash, m->stashsize); m->stashaddr = 0; diff --git a/tool/build/lib/machine.h b/tool/build/lib/machine.h index d26c884f..55334dae 100644 --- a/tool/build/lib/machine.h +++ b/tool/build/lib/machine.h @@ -60,7 +60,7 @@ struct Machine { struct TlbEntry { int64_t v; void *r; - } tlb[4]; + } tlb[16]; uint8_t *veg[2 * 8]; uint8_t *beg[2 * 2 * 8]; struct MachineFpu { diff --git a/tool/build/lib/pml4t.c b/tool/build/lib/pml4t.c index 3957e465..f7a48c4a 100644 --- a/tool/build/lib/pml4t.c +++ b/tool/build/lib/pml4t.c @@ -52,6 +52,40 @@ static uint64_t *GetPageTable(pml4t_t p, long i, void *NewPhysicalPage(void)) { return res; } +static void PtFinder(uint64_t *a, uint64_t *b, uint64_t n, pml4t_t pd, int k) { + uint64_t e, c; + unsigned start; + for (start = (*b >> k) & 511; *b - *a < n && ((*b >> k) & 511) >= start;) { + e = pd[(*b >> k) & 511]; + c = ROUNDUP(*b + 1, 1 << k); + if (!IsValidPage(e)) { + *b = c; + } else if (k && *b - *a + (c - *b) > n) { + PtFinder(a, b, n, UnmaskPageAddr(e), k - 9); + } else { + *a = *b = c; + } + } +} + +/** + * Locates free memory range. + * + * @param h specifies signedness and around where to start searching + * @return virtual page address with size bytes free, or -1 w/ errno + */ +int64_t FindPml4t(pml4t_t pml4t, uint64_t h, uint64_t n) { + uint64_t a, b; + n = ROUNDUP(n, 4096) >> 12; + a = b = (h & 0x0000fffffffff000) >> 12; + if (!n || n > 0x10000000) return einval(); + PtFinder(&a, &b, n, pml4t, 9 * 3); + if (b > 0x0000001000000000) return eoverflow(); + if (h < 0x0000800000000000 && b > 0x0000000800000000) return eoverflow(); + if (b - a < n) return enomem(); + return a << 12; +} + /** * Maps virtual page region to system memory region. * @@ -95,70 +129,6 @@ int RegisterPml4t(pml4t_t pml4t, int64_t v, int64_t r, size_t n, return enomem(); } -/** - * Locates free memory range. - * - * @param hint specifies signedness and around where to start searching - * @return virtual page address with size bytes free, or -1 w/ errno - */ -int64_t FindPml4t(pml4t_t pml4t, int64_t hint, uint64_t size, - void *NewPhysicalPage(void)) { - int64_t res; - unsigned short a[4], b[4]; - uint64_t *pdpt, *pdt, *pd, have; - if (!size) return einval(); - have = 0; - size = ROUNDUP(size, 4096) >> 12; - b[0] = a[0] = (hint >> 39) & 511; - b[1] = a[1] = (hint >> 30) & 511; - b[2] = a[2] = (hint >> 21) & 511; - a[3] = 0; - for (; b[0] < 512; ++b[0]) { - if (!(pdpt = GetPageTable(pml4t, b[0], NewPhysicalPage))) return -1; - for (; b[1] < 512; ++b[1]) { - if (!(pdt = GetPageTable(pdpt, b[1], NewPhysicalPage))) return -1; - for (; b[2] < 512; ++b[2]) { - if (!IsValidPage(pdt[b[2]])) { - if ((have += 512) >= size) { - return MakeAddress(a); - } - } else if (size < 0x200) { - pd = UnmaskPageAddr(pdt[b[2]]); - for (b[3] = 0; b[3] < 512; ++b[3]) { - if (!IsValidPage(pd[b[3]])) { - if ((have += 1) >= size) { - return MakeAddress(a); - } - } else { - have = 0; - a[0] = b[0]; - a[1] = b[1]; - a[2] = b[2]; - a[3] = b[3]; - if ((a[3] += 1) == 512) { - a[3] = 0; - if ((a[2] += 1) == 512) { - a[2] = 0; - if ((a[1] += 1) == 512) { - a[1] = 0; - a[0] += 1; - if (a[0] == 256 || a[0] == 512) { - return eoverflow(); - } - } - } - } - } - } - } - } - a[2] = 0; - } - a[1] = 0; - } - return enomem(); -} - /** * Unmaps pages and frees page tables. */ diff --git a/tool/build/lib/pml4t.h b/tool/build/lib/pml4t.h index b410aca6..349e98f5 100644 --- a/tool/build/lib/pml4t.h +++ b/tool/build/lib/pml4t.h @@ -13,7 +13,7 @@ typedef uint64_t pml4t_t[512] aligned(4096); int FreePml4t(pml4t_t, int64_t, uint64_t, void (*)(void *), int (*)(void *, size_t)); int RegisterPml4t(pml4t_t, int64_t, int64_t, size_t, void *(*)(void)); -int64_t FindPml4t(pml4t_t, int64_t, uint64_t, void *(*)(void)); +int64_t FindPml4t(pml4t_t, uint64_t, uint64_t); char *FormatPml4t(pml4t_t) nodiscard; COSMOPOLITAN_C_END_ diff --git a/tool/build/lib/reset.c b/tool/build/lib/reset.c index f767e14b..3192c4ef 100644 --- a/tool/build/lib/reset.c +++ b/tool/build/lib/reset.c @@ -68,10 +68,6 @@ static void ResetTlb(struct Machine *m) { memset(m->tlb, 0, sizeof(m->tlb)); } -static void ResetMem(struct Machine *m) { - FreePml4t(m->cr3, -0x800000000000, 0x800000000000, free, munmap); -} - void ResetCpu(struct Machine *m) { m->codevirt = 0; m->codereal = NULL; @@ -96,5 +92,4 @@ void ResetCpu(struct Machine *m) { ResetTlb(m); ResetSse(m); ResetFpu(m); - ResetMem(m); } diff --git a/tool/build/lib/string.c b/tool/build/lib/string.c index 0e49593d..13522b2d 100644 --- a/tool/build/lib/string.c +++ b/tool/build/lib/string.c @@ -67,16 +67,14 @@ static void WriteInt(uint8_t p[8], uint64_t x, unsigned long w) { void OpString(struct Machine *m, uint32_t rde, int op) { void *p[2]; + unsigned n; + uint64_t asz; bool compare; int64_t sgn, v; uint8_t s[3][8]; - unsigned n, lg2; - uint64_t asz, seg; sgn = GetFlag(m->flags, FLAGS_DF) ? -1 : 1; asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff; - seg = GetSegment(m); - lg2 = RegLog2(rde); - n = 1 << lg2; + n = 1 << RegLog2(rde); for (;;) { if (Rep(rde) && !Read64(m->cx)) break; v = 0; @@ -84,16 +82,18 @@ void OpString(struct Machine *m, uint32_t rde, int op) { compare = false; switch (op) { case STRING_CMPS: - Alu(lg2, ALU_SUB, - ReadInt(Load(m, (Read64(m->si) + seg) & asz, n, s[2]), lg2), - ReadInt(Load(m, Read64(m->di) & asz, n, s[1]), lg2), &m->flags); + Alu(RegLog2(rde), ALU_SUB, + ReadInt(Load(m, (Read64(m->si) + GetSegment(m)) & asz, n, s[2]), + RegLog2(rde)), + ReadInt(Load(m, Read64(m->di) & asz, n, s[1]), RegLog2(rde)), + &m->flags); Write64(m->di, (Read64(m->di) + sgn * n) & asz); Write64(m->si, (Read64(m->si) + sgn * n) & asz); compare = true; break; case STRING_MOVS: memcpy(BeginStore(m, (v = Read64(m->di) & asz), n, p, s[0]), - Load(m, (Read64(m->si) + seg) & asz, n, s[1]), n); + Load(m, (Read64(m->si) + GetSegment(m)) & asz, n, s[1]), n); Write64(m->di, (Read64(m->di) + sgn * n) & asz); Write64(m->si, (Read64(m->si) + sgn * n) & asz); break; @@ -102,23 +102,26 @@ void OpString(struct Machine *m, uint32_t rde, int op) { Write64(m->di, (Read64(m->di) + sgn * n) & asz); break; case STRING_LODS: - memcpy(m->ax, Load(m, (Read64(m->si) + seg) & asz, n, s[1]), n); + memcpy(m->ax, Load(m, (Read64(m->si) + GetSegment(m)) & asz, n, s[1]), + n); Write64(m->si, (Read64(m->si) + sgn * n) & asz); break; case STRING_SCAS: - Alu(lg2, ALU_SUB, ReadInt(Load(m, Read64(m->di) & asz, n, s[1]), lg2), - ReadInt(m->ax, lg2), &m->flags); + Alu(RegLog2(rde), ALU_SUB, + ReadInt(Load(m, Read64(m->di) & asz, n, s[1]), RegLog2(rde)), + ReadInt(m->ax, RegLog2(rde)), &m->flags); Write64(m->di, (Read64(m->di) + sgn * n) & asz); compare = true; break; case STRING_OUTS: OpOut(m, Read16(m->dx), - ReadInt(Load(m, (Read64(m->si) + seg) & asz, n, s[1]), lg2)); + ReadInt(Load(m, (Read64(m->si) + GetSegment(m)) & asz, n, s[1]), + RegLog2(rde))); Write64(m->si, (Read64(m->si) + sgn * n) & asz); break; case STRING_INS: WriteInt(BeginStore(m, (v = Read64(m->di) & asz), n, p, s[0]), - OpIn(m, Read16(m->dx)), lg2); + OpIn(m, Read16(m->dx)), RegLog2(rde)); Write64(m->di, (Read64(m->di) + sgn * n) & asz); break; default: @@ -138,19 +141,18 @@ void OpRepMovsbEnhanced(struct Machine *m, uint32_t rde) { bool failed; uint8_t *direal, *sireal; unsigned diremain, siremain, i, n; - uint64_t divirtual, sivirtual, diactual, siactual, failaddr, seg, asz, cx; + uint64_t divirtual, sivirtual, diactual, siactual, failaddr, asz, cx; if (!(cx = Read64(m->cx))) return; failed = false; failaddr = 0; - seg = GetSegment(m); asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff; divirtual = Read64(m->di) & asz; sivirtual = Read64(m->si) & asz; - SetWriteAddr(m, (seg + divirtual) & asz, cx); - SetReadAddr(m, (seg + sivirtual) & asz, cx); + SetWriteAddr(m, (GetSegment(m) + divirtual) & asz, cx); + SetReadAddr(m, (GetSegment(m) + sivirtual) & asz, cx); do { - diactual = (seg + divirtual) & asz; - siactual = (seg + sivirtual) & asz; + diactual = (GetSegment(m) + divirtual) & asz; + siactual = (GetSegment(m) + sivirtual) & asz; if (!(direal = FindReal(m, diactual))) { failaddr = diactual; failed = true; @@ -181,17 +183,16 @@ void OpRepStosbEnhanced(struct Machine *m, uint32_t rde) { bool failed; uint8_t *direal, al; unsigned diremain, i, n; - uint64_t divirtual, diactual, failaddr, seg, asz, cx; + uint64_t divirtual, diactual, failaddr, asz, cx; if (!(cx = Read64(m->cx))) return; failaddr = 0; failed = false; al = Read8(m->ax); - seg = GetSegment(m); asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff; divirtual = Read64(m->di) & asz; - SetWriteAddr(m, (seg + divirtual) & asz, cx); + SetWriteAddr(m, (GetSegment(m) + divirtual) & asz, cx); do { - diactual = (seg + divirtual) & asz; + diactual = (GetSegment(m) + divirtual) & asz; if (!(direal = FindReal(m, diactual))) { failaddr = diactual; failed = true; diff --git a/tool/build/lib/syscall.c b/tool/build/lib/syscall.c index 5eec8c45..50457dc0 100644 --- a/tool/build/lib/syscall.c +++ b/tool/build/lib/syscall.c @@ -66,7 +66,7 @@ #define P(x) ((x) ? PNN(x) : 0) #define ASSIGN(D, S) memcpy(&D, &S, MIN(sizeof(S), sizeof(D))) -static const struct MachineFdCb kMachineFdCbHost = { +const struct MachineFdCb kMachineFdCbHost = { .close = close, .read = read, .write = write, @@ -282,7 +282,7 @@ static int64_t OpMmap(struct Machine *m, int64_t virt, size_t size, int prot, if (real == MAP_FAILED) return -1; if (!(flags & MAP_FIXED)) { if (0 <= virt && virt < 0x400000) virt = 0x400000; - if ((virt = FindPml4t(m->cr3, virt, size, MallocPage)) == -1) return -1; + if ((virt = FindPml4t(m->cr3, virt, size)) == -1) return -1; } CHECK_NE(-1, RegisterMemory(m, virt, real, size)); return virt; diff --git a/tool/build/lib/syscall.h b/tool/build/lib/syscall.h index 6227e4b3..4a4429ea 100644 --- a/tool/build/lib/syscall.h +++ b/tool/build/lib/syscall.h @@ -1,9 +1,12 @@ #ifndef COSMOPOLITAN_TOOL_BUILD_LIB_SYSCALL_H_ #define COSMOPOLITAN_TOOL_BUILD_LIB_SYSCALL_H_ +#include "tool/build/lib/fds.h" #include "tool/build/lib/machine.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +extern const struct MachineFdCb kMachineFdCbHost; + void OpSyscall(struct Machine *); COSMOPOLITAN_C_END_ diff --git a/libc/tinymath/fpclassifyf.S b/tool/build/lib/word.c similarity index 58% rename from libc/tinymath/fpclassifyf.S rename to tool/build/lib/word.c index d1eb15fc..2c4d08cf 100644 --- a/libc/tinymath/fpclassifyf.S +++ b/tool/build/lib/word.c @@ -1,5 +1,5 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- 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 │ │ │ @@ -17,30 +17,48 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/math.h" -#include "libc/macros.h" -.source __FILE__ +#include "tool/build/lib/endian.h" +#include "tool/build/lib/memory.h" +#include "tool/build/lib/word.h" -tinymath_fpclassifyf: - .leafprologue - movd %xmm0,%edx - movd %xmm0,%eax - shr $23,%eax - and $255,%eax - je 7f - cmp $255,%eax - je 8f - mov $FP_NORMAL,%eax - jmp 1f -7: add %edx,%edx - je 5f - mov $FP_SUBNORMAL,%eax - jmp 1f -5: mov $FP_ZERO,%eax - jmp 1f -8: sal $9,%edx - sete %al - movzbl %al,%eax -1: .leafepilogue - .endfn tinymath_fpclassifyf,globl - .alias tinymath_fpclassifyf,__fpclassifyf +void SetMemoryShort(struct Machine *m, int64_t v, int16_t i) { + void *p[2]; + uint8_t b[2]; + Write16(BeginStore(m, v, 2, p, b), i); + EndStore(m, v, 2, p, b); +} + +void SetMemoryInt(struct Machine *m, int64_t v, int32_t i) { + void *p[2]; + uint8_t b[4]; + Write32(BeginStore(m, v, 4, p, b), i); + EndStore(m, v, 4, p, b); +} + +void SetMemoryLong(struct Machine *m, int64_t v, int64_t i) { + void *p[2]; + uint8_t b[8]; + Write64(BeginStore(m, v, 8, p, b), i); + EndStore(m, v, 8, p, b); +} + +void SetMemoryFloat(struct Machine *m, int64_t v, float f) { + void *p[2]; + uint8_t b[4]; + memcpy(BeginStore(m, v, 4, p, b), &f, 4); + EndStore(m, v, 4, p, b); +} + +void SetMemoryDouble(struct Machine *m, int64_t v, double f) { + void *p[2]; + uint8_t b[8]; + memcpy(BeginStore(m, v, 8, p, b), &f, 8); + EndStore(m, v, 8, p, b); +} + +void SetMemoryLdbl(struct Machine *m, int64_t v, long double f) { + void *p[2]; + uint8_t b[10]; + memcpy(BeginStore(m, v, 10, p, b), &f, 10); + EndStore(m, v, 10, p, b); +} diff --git a/tool/build/lib/word.h b/tool/build/lib/word.h new file mode 100644 index 00000000..0e148079 --- /dev/null +++ b/tool/build/lib/word.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_TOOL_BUILD_LIB_WORD_H_ +#define COSMOPOLITAN_TOOL_BUILD_LIB_WORD_H_ +#include "tool/build/lib/machine.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void SetMemoryShort(struct Machine *, int64_t, int16_t); +void SetMemoryInt(struct Machine *, int64_t, int32_t); +void SetMemoryLong(struct Machine *, int64_t, int64_t); +void SetMemoryFloat(struct Machine *, int64_t, float); +void SetMemoryDouble(struct Machine *, int64_t, double); +void SetMemoryLdbl(struct Machine *, int64_t, long double); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_TOOL_BUILD_LIB_WORD_H_ */ diff --git a/tool/build/lib/x87.c b/tool/build/lib/x87.c index 277b29f1..33e58c5c 100644 --- a/tool/build/lib/x87.c +++ b/tool/build/lib/x87.c @@ -59,7 +59,7 @@ long double fyl2xp1(long double x, long double y) { } long double fscale(long double significand, long double exponent) { - return scalbnl(significand, exponent); + return scalbl(significand, exponent); } long double fprem(long double dividend, long double modulus, uint32_t *sw) { diff --git a/tool/build/runit.c b/tool/build/runit.c index fd1b9885..fd9ca651 100644 --- a/tool/build/runit.c +++ b/tool/build/runit.c @@ -18,6 +18,7 @@ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/alg/alg.h" +#include "libc/bits/bits.h" #include "libc/bits/safemacros.h" #include "libc/calls/calls.h" #include "libc/calls/hefty/spawn.h" @@ -273,7 +274,7 @@ int ReadResponse(void) { if (!n) break; do { CHECK_GE(n, 4 + 1); - CHECK_EQ(RUNITD_MAGIC, read32be(p)); + CHECK_EQ(RUNITD_MAGIC, READ32BE(p)); p += 4, n -= 4; cmd = *p++, n--; switch (cmd) { diff --git a/tool/build/tinyemu.c b/tool/build/tinyemu.c index 760f36b2..1532d9a9 100644 --- a/tool/build/tinyemu.c +++ b/tool/build/tinyemu.c @@ -20,8 +20,11 @@ #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/sysv/consts/ex.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/x/x.h" #include "tool/build/lib/loader.h" #include "tool/build/lib/machine.h" +#include "tool/build/lib/syscall.h" struct Machine m[1]; @@ -38,6 +41,15 @@ int main(int argc, char *argv[]) { } InitMachine(m); LoadProgram(m, argv[1], argv + 2, environ, &elf); + m->fds.i = 3; + m->fds.n = 8; + m->fds.p = xcalloc(m->fds.n, sizeof(struct MachineFd)); + m->fds.p[0].fd = STDIN_FILENO; + m->fds.p[0].cb = &kMachineFdCbHost; + m->fds.p[1].fd = STDOUT_FILENO; + m->fds.p[1].cb = &kMachineFdCbHost; + m->fds.p[2].fd = STDERR_FILENO; + m->fds.p[2].cb = &kMachineFdCbHost; if (!(rc = setjmp(m->onhalt))) { for (;;) { LoadInstruction(m); diff --git a/tool/emacs/cosmo-c-builtins.el b/tool/emacs/cosmo-c-builtins.el index 95997130..ce3ae5f7 100644 --- a/tool/emacs/cosmo-c-builtins.el +++ b/tool/emacs/cosmo-c-builtins.el @@ -149,7 +149,23 @@ "__builtin_infl" "__builtin_inffn" "__builtin_inffnx" + "__builtin_isnan" + "__builtin_signbit" + "__builtin_signbitf" + "__builtin_signbitl" + "__builtin_isfinite" + "__builtin_isinf" + "__builtin_isinfinite" + "__builtin_isnormal" "__builtin_isinf_sign" + "__builtin_isgreater" + "__builtin_isgreaterequal" + "__builtin_isgreater" + "__builtin_isgreaterequal" + "__builtin_isless" + "__builtin_islessequal" + "__builtin_islessgreater" + "__builtin_isunordered" "__builtin_nan" "__builtin_nand32" "__builtin_nand64" diff --git a/tool/emacs/cosmo-c-keywords.el b/tool/emacs/cosmo-c-keywords.el index 5a626b14..423fc9c0 100644 --- a/tool/emacs/cosmo-c-keywords.el +++ b/tool/emacs/cosmo-c-keywords.el @@ -296,6 +296,7 @@ "__params_nonnull__" "__weak__" "__vector_size__" + "__ms_abi__" "__mode__")) (clang diff --git a/tool/emacs/cosmo-cpp-constants.el b/tool/emacs/cosmo-cpp-constants.el index 15641883..cb0c528d 100644 --- a/tool/emacs/cosmo-cpp-constants.el +++ b/tool/emacs/cosmo-cpp-constants.el @@ -105,6 +105,7 @@ "PAGESIZE" "FRAMESIZE" "BIGPAGESIZE" + "STACKSIZE" "ENV_MAX" "ARG_MAX" "CMD_MAX" diff --git a/tool/viz/generatematrix.c b/tool/viz/generatematrix.c index d4624295..d0471e8e 100644 --- a/tool/viz/generatematrix.c +++ b/tool/viz/generatematrix.c @@ -20,6 +20,7 @@ #include "libc/bits/safemacros.h" #include "libc/conv/conv.h" #include "libc/fmt/fmt.h" +#include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.h" diff --git a/tool/viz/lib/formatstringtable.h b/tool/viz/lib/formatstringtable.h index 77026bbc..c03890fc 100644 --- a/tool/viz/lib/formatstringtable.h +++ b/tool/viz/lib/formatstringtable.h @@ -4,7 +4,7 @@ COSMOPOLITAN_C_START_ typedef void *StringTableFormatter(long yn, long xn, const char *const[yn][xn], - int emit(), void *, const char *, + int (*)(), void *, const char *, const char *, const char *); StringTableFormatter FormatStringTable; @@ -15,28 +15,27 @@ StringTableFormatter FormatStringTableForAssertion; void *FreeStringTableCells(long yn, long xn, char *[yn][xn]); -void FormatMatrixDouble(long yn, long xn, const double[yn][xn], int emit(), +void FormatMatrixDouble(long yn, long xn, const double[yn][xn], int (*)(), void *, StringTableFormatter, const char *, - const char *, const char *, double, - double rounder(double)); -void FormatMatrixFloat(long yn, long xn, const float[yn][xn], int emit(), - void *, StringTableFormatter, const char *, const char *, - const char *, double, double rounder(double)); -void FormatMatrixByte(long yn, long xn, const unsigned char[yn][xn], int emit(), + const char *, const char *, double, double (*)(double)); +void FormatMatrixFloat(long yn, long xn, const float[yn][xn], int (*)(), void *, + StringTableFormatter, const char *, const char *, + const char *, double, double (*)(double)); +void FormatMatrixByte(long yn, long xn, const unsigned char[yn][xn], int (*)(), void *, StringTableFormatter, const char *, const char *, const char *); -void FormatMatrixShort(long yn, long xn, const short[yn][xn], int emit(), - void *, StringTableFormatter, const char *, const char *, +void FormatMatrixShort(long yn, long xn, const short[yn][xn], int (*)(), void *, + StringTableFormatter, const char *, const char *, const char *); char *StringifyMatrixDouble(long yn, long xn, const double[yn][xn], StringTableFormatter, const char *, const char *, const char *, double, - double rounder(double)) mallocesque; + double (*)(double)) mallocesque; char *StringifyMatrixFloat(long yn, long xn, const float[yn][xn], StringTableFormatter, const char *, const char *, const char *, double, - double rounder(double)) mallocesque; + double (*)(double)) mallocesque; char *StringifyMatrixByte(long yn, long xn, const unsigned char[yn][xn], StringTableFormatter, const char *, const char *, const char *) mallocesque;