mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-16 05:46:25 +00:00
Fix bugs and have emulator emulate itself
This commit is contained in:
parent
5aabacb361
commit
bd29223891
111 changed files with 1283 additions and 2073 deletions
|
@ -18,14 +18,15 @@ else
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$SILENT" = "0" ]; then
|
printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
||||||
COLUMNS=${COLUMNS:-80}
|
# if [ "$SILENT" = "0" ]; then
|
||||||
COLUMNS=$((COLUMNS - 4))
|
# COLUMNS=${COLUMNS:-80}
|
||||||
printf "%s\n" "$*" |
|
# COLUMNS=$((COLUMNS - 4))
|
||||||
/usr/bin/fold -s -w $COLUMNS |
|
# printf "%s\n" "$*" |
|
||||||
sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2
|
# /usr/bin/fold -s -w $COLUMNS |
|
||||||
else
|
# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2
|
||||||
printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
# else
|
||||||
fi
|
# printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
||||||
|
# fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
@ -42,11 +42,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$SILENT" = "0" ]; then
|
if [ "$SILENT" = "0" ]; then
|
||||||
COLUMNS=${COLUMNS:-80}
|
printf "%s\n" "$*" >&2
|
||||||
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
|
else
|
||||||
printf "$LOGFMT" "${ACTION:-ZIPOBJ}" "$3" >&2
|
printf "$LOGFMT" "${ACTION:-ZIPOBJ}" "$3" >&2
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_
|
#ifndef COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_
|
||||||
#define COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_
|
#define COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_
|
||||||
#ifndef __STRICT_ANSI__
|
#ifndef __STRICT_ANSI__
|
||||||
#include "libc/limits.h"
|
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dns/consts.h"
|
#include "libc/dns/consts.h"
|
||||||
#include "libc/dns/dns.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) {
|
if (p + 2 + 2 + 4 + 2 < pe) {
|
||||||
uint16_t rtype, rclass, rdlength;
|
uint16_t rtype, rclass, rdlength;
|
||||||
rtype = read16be(p), p += 2;
|
rtype = READ16BE(p), p += 2;
|
||||||
rclass = read16be(p), p += 2;
|
rclass = READ16BE(p), p += 2;
|
||||||
/* ttl */ p += 4;
|
/* ttl */ p += 4;
|
||||||
rdlength = read16be(p), p += 2;
|
rdlength = read16be(p), p += 2;
|
||||||
if (p + rdlength <= pe && rdlength == 4 &&
|
if (p + rdlength <= pe && rdlength == 4 &&
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_
|
#ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_
|
||||||
#define COSMOPOLITAN_LIBC_FMT_PFLINK_H_
|
#define COSMOPOLITAN_LIBC_FMT_PFLINK_H_
|
||||||
#include "libc/dce.h"
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
#ifndef __STRICT_ANSI__
|
#ifndef __STRICT_ANSI__
|
||||||
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview builtin+preprocessor+linker tricks for printf/scanf.
|
* @fileoverview builtin+preprocessor+linker tricks for printf/scanf.
|
||||||
|
|
|
@ -18,16 +18,16 @@
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/intrin/shufpd.h"
|
#include "libc/intrin/shufpd.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuffles double vector.
|
* Shuffles double vector.
|
||||||
* @param 𝑚 needs to be a literal, constexpr, or embedding
|
* @param 𝑚 needs to be a literal, constexpr, or embedding
|
||||||
* @mayalias
|
* @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];
|
double t[2];
|
||||||
t[0] = a[(m & 0b0000001) >> 0];
|
t[0] = a[(m & 0b0000001) >> 0];
|
||||||
t[1] = a[(m & 0b0000010) >> 1];
|
t[1] = b[(m & 0b0000010) >> 1];
|
||||||
b[0] = t[0];
|
memcpy(c, t, 16);
|
||||||
b[1] = t[1];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
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_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -18,20 +18,18 @@
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/intrin/shufps.h"
|
#include "libc/intrin/shufps.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuffles float vector.
|
* Shuffles float vector.
|
||||||
* @param 𝑚 needs to be a literal, constexpr, or embedding
|
* @param 𝑚 needs to be a literal, constexpr, or embedding
|
||||||
* @mayalias
|
* @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];
|
float t[4];
|
||||||
t[0] = a[(m & 0b00000011) >> 0];
|
t[0] = b[(m & 0b00000011) >> 0];
|
||||||
t[1] = a[(m & 0b00001100) >> 2];
|
t[1] = b[(m & 0b00001100) >> 2];
|
||||||
t[2] = a[(m & 0b00110000) >> 4];
|
t[2] = a[(m & 0b00110000) >> 4];
|
||||||
t[3] = a[(m & 0b11000000) >> 6];
|
t[3] = a[(m & 0b11000000) >> 6];
|
||||||
b[0] = t[0];
|
memcpy(c, t, 16);
|
||||||
b[1] = t[1];
|
|
||||||
b[2] = t[2];
|
|
||||||
b[3] = t[3];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
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_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
|
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
|
||||||
#define COSMOPOLITAN_LIBC_LOG_LOG_H_
|
#define COSMOPOLITAN_LIBC_LOG_LOG_H_
|
||||||
#include "libc/dce.h"
|
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||||
│ cosmopolitan § liblog ─╬─│┼
|
│ cosmopolitan § liblog ─╬─│┼
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||||
|
|
26
libc/math.h
26
libc/math.h
|
@ -80,11 +80,20 @@ typedef float float_t;
|
||||||
typedef double double_t;
|
typedef double double_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define isinf(x) __builtin_isinf(x)
|
#define isinf(x) __builtin_isinf(x)
|
||||||
#define isnan(x) __builtin_isnan(x)
|
#define isnan(x) __builtin_isnan(x)
|
||||||
#define isfinite(x) __builtin_isfinite(x)
|
#define isfinite(x) __builtin_isfinite(x)
|
||||||
#define isnormal(x) __builtin_isnormal(x)
|
#define isnormal(x) __builtin_isnormal(x)
|
||||||
#define signbit(x) __builtin_signbit(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 acos(double);
|
||||||
double acosh(double);
|
double acosh(double);
|
||||||
|
@ -276,13 +285,6 @@ void sincos(double, double *, double *);
|
||||||
void sincosf(float, float *, float *);
|
void sincosf(float, float *, float *);
|
||||||
void sincosl(long double, long double *, long double *);
|
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 ─╬─│┼
|
│ cosmopolitan § mathematics » x87 ─╬─│┼
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* generate code that calls MS ABI functions directly, without needing
|
* generate code that calls MS ABI functions directly, without needing
|
||||||
* to jump through the assembly thunks.
|
* to jump through the assembly thunks.
|
||||||
*/
|
*/
|
||||||
#if __GNUC__ * 100 + __GNUC_MINOR_ >= 408 || \
|
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 408 || \
|
||||||
(__has_attribute(__ms_abi__) || defined(__llvm__))
|
(__has_attribute(__ms_abi__) || defined(__llvm__))
|
||||||
#define __msabi __attribute__((__ms_abi__))
|
#define __msabi __attribute__((__ms_abi__))
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,15 +45,15 @@ COSMOPOLITAN_C_START_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define kNtSioSocketCloseNotify 0x9800000Du
|
#define kNtSioSocketCloseNotify 0x9800000Du
|
||||||
#define kNtSioUdpConnreset 0x9800000Cu
|
#define kNtSioUdpConnreset 0x9800000Cu
|
||||||
#define kNtSioUdpNetreset 0x9800000F
|
#define kNtSioUdpNetreset 0x9800000F
|
||||||
|
|
||||||
#define kNtTfDisconnect 0x01
|
#define kNtTfDisconnect 0x01
|
||||||
#define kNtTfReuseSocket 0x02
|
#define kNtTfReuseSocket 0x02
|
||||||
#define kNtTfWriteBehind 0x04
|
#define kNtTfWriteBehind 0x04
|
||||||
#define kNtTfUseDefaultWorker 0x00
|
#define kNtTfUseDefaultWorker 0x00
|
||||||
#define kNtTfUseSystemThread 0x10
|
#define kNtTfUseSystemThread 0x10
|
||||||
#define kNtTfUseKernelApc 0x20
|
#define kNtTfUseKernelApc 0x20
|
||||||
|
|
||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
struct sockaddr_in;
|
struct sockaddr_in;
|
||||||
|
@ -295,8 +295,8 @@ struct NtWsaCompletion {
|
||||||
* functions are declared within their respective wrappers.
|
* functions are declared within their respective wrappers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nodiscard int32_t WSAStartup(uint16_t wVersionRequested,
|
int32_t WSAStartup(uint16_t wVersionRequested, struct NtWsaData *lpWSAData)
|
||||||
struct NtWsaData *lpWSAData) paramsnonnull();
|
paramsnonnull() nodiscard;
|
||||||
|
|
||||||
int WSACleanup(void);
|
int WSACleanup(void);
|
||||||
int WSAGetLastError(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 __setsockopt$nt(uint64_t, int, int, const void *, int);
|
||||||
int __shutdown$nt(uint64_t, int);
|
int __shutdown$nt(uint64_t, int);
|
||||||
|
|
||||||
nodiscard uint64_t WSASocket(int af, int type, int protocol,
|
uint64_t WSASocket(int af, int type, int protocol,
|
||||||
const struct NtWsaProtocolInfo *opt_lpProtocolInfo,
|
const struct NtWsaProtocolInfo *opt_lpProtocolInfo,
|
||||||
const uint32_t opt_group, uint32_t dwFlags);
|
const uint32_t opt_group, uint32_t dwFlags) nodiscard;
|
||||||
|
|
||||||
int WSAConnect(uint64_t s, const struct sockaddr *name, const int namelen,
|
int WSAConnect(uint64_t s, const struct sockaddr *name, const int namelen,
|
||||||
const struct iovec$nt *opt_lpCallerData,
|
const struct iovec$nt *opt_lpCallerData,
|
||||||
|
@ -340,11 +340,11 @@ bool32 WSAConnectByList(uint64_t s,
|
||||||
const struct timeval$nt *opt_timeout,
|
const struct timeval$nt *opt_timeout,
|
||||||
struct NtOverlapped *__Reserved) paramsnonnull((2));
|
struct NtOverlapped *__Reserved) paramsnonnull((2));
|
||||||
|
|
||||||
nodiscard int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr,
|
int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr,
|
||||||
int32_t *opt_inout_addrlen,
|
int32_t *opt_inout_addrlen,
|
||||||
const NtConditionProc opt_lpfnCondition,
|
const NtConditionProc opt_lpfnCondition,
|
||||||
const uint32_t *opt_dwCallbackData)
|
const uint32_t *opt_dwCallbackData)
|
||||||
paramsnonnull((2));
|
paramsnonnull((2)) nodiscard;
|
||||||
|
|
||||||
int WSASend(uint64_t s, const struct iovec$nt *lpBuffers,
|
int WSASend(uint64_t s, const struct iovec$nt *lpBuffers,
|
||||||
uint32_t dwBufferCount, uint32_t *opt_out_lpNumberOfBytesSent,
|
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)
|
const struct NtWsaCompletion *opt_lpCompletion)
|
||||||
paramsnonnull((3, 5, 7));
|
paramsnonnull((3, 5, 7));
|
||||||
|
|
||||||
nodiscard int64_t WSACreateEvent(void);
|
int64_t WSACreateEvent(void) nodiscard;
|
||||||
bool32 WSACloseEvent(const int64_t hEvent);
|
bool32 WSACloseEvent(const int64_t hEvent);
|
||||||
bool32 WSAResetEvent(const int64_t hEvent);
|
bool32 WSAResetEvent(const int64_t hEvent);
|
||||||
bool32 WSASetEvent(const int64_t hEvent);
|
bool32 WSASetEvent(const int64_t hEvent);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/struct/sigset.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 +
|
pe = (unsigned char *)(symbols->addr_base +
|
||||||
symbols->symbols[i + 1].addr_rva);
|
symbols->symbols[i + 1].addr_rva);
|
||||||
p < pe - 8; ++p) {
|
p < pe - 8; ++p) {
|
||||||
code = read64le(p);
|
code = READ64LE(p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test for -mrecord-mcount (w/ -fpie or -fpic)
|
* Test for -mrecord-mcount (w/ -fpie or -fpic)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
#include "libc/runtime/memtrack.h"
|
#include "libc/runtime/memtrack.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
#define kMappingsSize 0x100000000000 /* 16TB */
|
#define kMappingsSize 0x0000100000000000 /* 16TB */
|
||||||
#define kMappingsStart (IsGenuineCosmo() ? 0x300000000000 : 0x200000000000)
|
#define kMappingsStart (IsGenuineCosmo() ? 0x300000000000 : 0x200000000000)
|
||||||
#define kFixedMappingsStart 0x0000100000000000
|
#define kFixedMappingsStart 0x0000100000000000
|
||||||
#define kFixedMappingsSize kMappingsSize
|
#define kFixedMappingsSize kMappingsSize
|
||||||
|
|
|
@ -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 (!CANONICAL(addr)) return VIP(einval());
|
||||||
if (!(!!(flags & MAP_ANONYMOUS) ^ (fd != -1))) return VIP(einval());
|
if (!(!!(flags & MAP_ANONYMOUS) ^ (fd != -1))) return VIP(einval());
|
||||||
if (!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED))) 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 (flags & MAP_FIXED) {
|
||||||
if (UntrackMemoryIntervals(addr, size) == -1) {
|
if (UntrackMemoryIntervals(addr, size) == -1) {
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_
|
#ifndef COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_
|
||||||
#define COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_
|
#define COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_
|
||||||
#include "libc/dce.h"
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_STR_STR_H_
|
#ifndef COSMOPOLITAN_LIBC_STR_STR_H_
|
||||||
#define COSMOPOLITAN_LIBC_STR_STR_H_
|
#define COSMOPOLITAN_LIBC_STR_STR_H_
|
||||||
#include "libc/bits/bits.h"
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||||
|
|
|
@ -46,7 +46,7 @@ tinymath_acosl:
|
||||||
fsqrt
|
fsqrt
|
||||||
fabs # needed in downward rounding mode
|
fabs # needed in downward rounding mode
|
||||||
#endif
|
#endif
|
||||||
fxch %st(1)
|
fxch
|
||||||
fpatan
|
fpatan
|
||||||
pop %rbp
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -51,5 +51,4 @@ tinymath_asinl:
|
||||||
.alias tinymath_asinl,asinl
|
.alias tinymath_asinl,asinl
|
||||||
|
|
||||||
.rodata.cst4
|
.rodata.cst4
|
||||||
.align 4
|
|
||||||
.Lone: .float 1.0
|
.Lone: .float 1.0
|
||||||
|
|
|
@ -27,7 +27,7 @@ tinymath_cabsl:
|
||||||
fldt 32(%rbp)
|
fldt 32(%rbp)
|
||||||
fldt 16(%rbp)
|
fldt 16(%rbp)
|
||||||
fmul %st,%st
|
fmul %st,%st
|
||||||
fxch %st(1)
|
fxch
|
||||||
fmul %st,%st
|
fmul %st,%st
|
||||||
faddp %st,%st(1)
|
faddp %st,%st(1)
|
||||||
fsqrt
|
fsqrt
|
||||||
|
|
|
@ -29,7 +29,7 @@ tinymath_carg:
|
||||||
fldl -16(%rbp)
|
fldl -16(%rbp)
|
||||||
movsd %xmm1,-16(%rbp)
|
movsd %xmm1,-16(%rbp)
|
||||||
fldl -16(%rbp)
|
fldl -16(%rbp)
|
||||||
fxch %st(1)
|
fxch
|
||||||
fpatan
|
fpatan
|
||||||
fstpl -16(%rbp)
|
fstpl -16(%rbp)
|
||||||
movsd -16(%rbp),%xmm0
|
movsd -16(%rbp),%xmm0
|
||||||
|
|
|
@ -34,7 +34,7 @@ tinymath_exp10l:
|
||||||
fld %st
|
fld %st
|
||||||
frndint
|
frndint
|
||||||
fsubr %st,%st(1)
|
fsubr %st,%st(1)
|
||||||
fxch %st(1)
|
fxch
|
||||||
f2xm1
|
f2xm1
|
||||||
fld1
|
fld1
|
||||||
faddp
|
faddp
|
||||||
|
|
|
@ -32,7 +32,7 @@ tinymath_exp2l:
|
||||||
fld %st
|
fld %st
|
||||||
frndint
|
frndint
|
||||||
fsubr %st,%st(1)
|
fsubr %st,%st(1)
|
||||||
fxch %st(1)
|
fxch
|
||||||
f2xm1
|
f2xm1
|
||||||
fadds .Lone(%rip)
|
fadds .Lone(%rip)
|
||||||
fscale
|
fscale
|
||||||
|
|
|
@ -34,7 +34,7 @@ tinymath_expl:
|
||||||
fld %st
|
fld %st
|
||||||
frndint
|
frndint
|
||||||
fsubr %st,%st(1)
|
fsubr %st,%st(1)
|
||||||
fxch %st(1)
|
fxch
|
||||||
f2xm1
|
f2xm1
|
||||||
fld1
|
fld1
|
||||||
faddp
|
faddp
|
||||||
|
|
|
@ -25,14 +25,14 @@
|
||||||
tinymath_floor:
|
tinymath_floor:
|
||||||
.leafprologue
|
.leafprologue
|
||||||
.profilable
|
.profilable
|
||||||
movsd .LC6(%rip),%xmm1
|
movsd 4f(%rip),%xmm1
|
||||||
movsd .LC5(%rip),%xmm2
|
movsd 3f(%rip),%xmm2
|
||||||
andpd %xmm0,%xmm1
|
andpd %xmm0,%xmm1
|
||||||
comisd %xmm1,%xmm2
|
comisd %xmm1,%xmm2
|
||||||
jbe 1f
|
jbe 1f
|
||||||
cvttsd2siq %xmm0,%rax
|
cvttsd2siq %xmm0,%rax
|
||||||
pxor %xmm1,%xmm1
|
pxor %xmm1,%xmm1
|
||||||
movsd .LC4(%rip),%xmm2
|
movsd 2f(%rip),%xmm2
|
||||||
cvtsi2sdq %rax,%xmm1
|
cvtsi2sdq %rax,%xmm1
|
||||||
movapd %xmm1,%xmm3
|
movapd %xmm1,%xmm3
|
||||||
cmpnlesd %xmm0,%xmm3
|
cmpnlesd %xmm0,%xmm3
|
||||||
|
@ -45,13 +45,6 @@ tinymath_floor:
|
||||||
.alias tinymath_floor,floor
|
.alias tinymath_floor,floor
|
||||||
|
|
||||||
.rodata.cst8
|
.rodata.cst8
|
||||||
.LC4: .long 0
|
2: .double 1
|
||||||
.long 1072693248
|
3: .double 0x0010000000000000
|
||||||
.LC5: .long 0
|
4: .double nan
|
||||||
.long 1127219200
|
|
||||||
|
|
||||||
.rodata.cst16
|
|
||||||
.LC6: .long 4294967295
|
|
||||||
.long 2147483647
|
|
||||||
.long 0
|
|
||||||
.long 0
|
|
||||||
|
|
|
@ -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
|
|
|
@ -28,7 +28,7 @@ tinymath_hypotl:
|
||||||
fldt 32(%rbp)
|
fldt 32(%rbp)
|
||||||
fldt 16(%rbp)
|
fldt 16(%rbp)
|
||||||
fmul %st,%st
|
fmul %st,%st
|
||||||
fxch %st(1)
|
fxch
|
||||||
fmul %st,%st
|
fmul %st,%st
|
||||||
faddp
|
faddp
|
||||||
pop %rbp
|
pop %rbp
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
|
|
||||||
/ Returns log₂ₓ exponent part of double.
|
/ Returns log₂𝑥 exponent part of double.
|
||||||
/
|
/
|
||||||
/ @param 𝑥 is double passed in %xmm0
|
/ @param 𝑥 is double passed in %xmm0
|
||||||
/ @return result in %eax
|
/ @return result in %eax
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
|
|
||||||
/ Returns log₂ₓ exponent part of float.
|
/ Returns log₂x exponent part of float.
|
||||||
/
|
/
|
||||||
/ @param 𝑥 is float passed in %xmm0
|
/ @param 𝑥 is float passed in %xmm0
|
||||||
/ @return result in %eax
|
/ @return result in %eax
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.h"
|
#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
|
/ @param 𝑥 is long double passed on stack
|
||||||
/ @return result in %eax
|
/ @return result in %eax
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -20,21 +20,26 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.source __FILE__
|
||||||
|
|
||||||
|
/ Returns 𝑥 × 2ʸ.
|
||||||
|
/
|
||||||
|
/ @param 𝑥 is double passed in %xmm0
|
||||||
|
/ @param 𝑦 is exponent via %edi
|
||||||
|
/ @return double in %xmm0
|
||||||
tinymath_ldexp:
|
tinymath_ldexp:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
push %rax
|
push %rdi
|
||||||
movsd %xmm0,-8(%rbp)
|
fildl (%rsp)
|
||||||
fldl -8(%rbp)
|
movsd %xmm0,(%rsp)
|
||||||
mov %edi,-8(%rbp)
|
fldl (%rsp)
|
||||||
fildl -8(%rbp)
|
|
||||||
fxch %st(1)
|
|
||||||
fscale
|
fscale
|
||||||
fstp %st(1)
|
fstp %st(1)
|
||||||
fstpl -8(%rbp)
|
fstpl (%rsp)
|
||||||
movsd -8(%rbp),%xmm0
|
movsd (%rsp),%xmm0
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn tinymath_ldexp,globl
|
.endfn tinymath_ldexp,globl
|
||||||
.alias tinymath_ldexp,ldexp
|
.alias tinymath_ldexp,ldexp
|
||||||
|
.alias tinymath_ldexp,scalbn
|
||||||
|
.alias tinymath_ldexp,scalbln
|
||||||
|
|
|
@ -20,21 +20,26 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.source __FILE__
|
||||||
|
|
||||||
|
/ Returns 𝑥 × 2ʸ.
|
||||||
|
/
|
||||||
|
/ @param 𝑥 is float passed in %xmm0
|
||||||
|
/ @param 𝑦 is exponent via %edi
|
||||||
|
/ @return float in %xmm0
|
||||||
tinymath_ldexpf:
|
tinymath_ldexpf:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
push %rax
|
push %rdi
|
||||||
movss %xmm0,-4(%rbp)
|
fildl (%rsp)
|
||||||
flds -4(%rbp)
|
movss %xmm0,(%rsp)
|
||||||
movl %edi,-4(%rbp)
|
flds (%rsp)
|
||||||
fildl -4(%rbp)
|
|
||||||
fxch %st(1)
|
|
||||||
fscale
|
fscale
|
||||||
fstp %st(1)
|
fstp %st(1)
|
||||||
fstps -4(%rbp)
|
fstps (%rsp)
|
||||||
movss -4(%rbp),%xmm0
|
movss (%rsp),%xmm0
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn tinymath_ldexpf,globl
|
.endfn tinymath_ldexpf,globl
|
||||||
.alias tinymath_ldexpf,ldexpf
|
.alias tinymath_ldexpf,ldexpf
|
||||||
|
.alias tinymath_ldexpf,scalbnf
|
||||||
|
.alias tinymath_ldexpf,scalblnf
|
||||||
|
|
|
@ -20,16 +20,23 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.source __FILE__
|
||||||
|
|
||||||
|
/ Returns 𝑥 × 2ʸ.
|
||||||
|
/
|
||||||
|
/ @param 𝑥 is long double passed on stack
|
||||||
|
/ @param 𝑦 is exponent via %edi
|
||||||
|
/ @return result in %st0
|
||||||
tinymath_ldexpl:
|
tinymath_ldexpl:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
sub $24,%rsp
|
push %rdi
|
||||||
fldt 32(%rsp)
|
fildl (%rsp)
|
||||||
movl %edi,12(%rsp)
|
fldt 16(%rbp)
|
||||||
fildl 12(%rsp)
|
|
||||||
fxch %st(1)
|
|
||||||
add $24,%rsp
|
|
||||||
fscale
|
fscale
|
||||||
fstp %st(1)
|
fstp %st(1)
|
||||||
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn tinymath_ldexpl,globl
|
.endfn tinymath_ldexpl,globl
|
||||||
.alias tinymath_ldexpl,ldexpl
|
.alias tinymath_ldexpl,ldexpl
|
||||||
|
.alias tinymath_ldexpl,scalbnl
|
||||||
|
.alias tinymath_ldexpl,scalblnl
|
||||||
|
|
|
@ -34,12 +34,12 @@ tinymath_log1p:
|
||||||
fld %st
|
fld %st
|
||||||
fabs
|
fabs
|
||||||
fldt .LC16(%rip)
|
fldt .LC16(%rip)
|
||||||
fxch %st(1)
|
fxch
|
||||||
fcomip %st(1),%st
|
fcomip %st(1),%st
|
||||||
fstp %st
|
fstp %st
|
||||||
jnb 1f
|
jnb 1f
|
||||||
fldln2
|
fldln2
|
||||||
fxch %st(1)
|
fxch
|
||||||
fyl2xp1
|
fyl2xp1
|
||||||
fstpl (%rsp)
|
fstpl (%rsp)
|
||||||
vmovsd (%rsp),%xmm0
|
vmovsd (%rsp),%xmm0
|
||||||
|
@ -48,7 +48,7 @@ tinymath_log1p:
|
||||||
1: fld1
|
1: fld1
|
||||||
faddp %st,%st(1)
|
faddp %st,%st(1)
|
||||||
fldln2
|
fldln2
|
||||||
fxch %st(1)
|
fxch
|
||||||
fyl2x
|
fyl2x
|
||||||
fstpl (%rsp)
|
fstpl (%rsp)
|
||||||
vmovsd (%rsp),%xmm0
|
vmovsd (%rsp),%xmm0
|
||||||
|
|
|
@ -34,12 +34,12 @@ tinymath_log1pf:
|
||||||
fld %st
|
fld %st
|
||||||
fabs
|
fabs
|
||||||
fldt .LC16(%rip)
|
fldt .LC16(%rip)
|
||||||
fxch %st(1)
|
fxch
|
||||||
fcomip %st(1),%st
|
fcomip %st(1),%st
|
||||||
fstp %st
|
fstp %st
|
||||||
jnb 2f
|
jnb 2f
|
||||||
fldln2
|
fldln2
|
||||||
fxch %st(1)
|
fxch
|
||||||
fyl2xp1
|
fyl2xp1
|
||||||
1: fstps -4(%rbp)
|
1: fstps -4(%rbp)
|
||||||
vmovss -4(%rbp),%xmm0
|
vmovss -4(%rbp),%xmm0
|
||||||
|
@ -48,7 +48,7 @@ tinymath_log1pf:
|
||||||
2: fld1
|
2: fld1
|
||||||
faddp %st,%st(1)
|
faddp %st,%st(1)
|
||||||
fldln2
|
fldln2
|
||||||
fxch %st(1)
|
fxch
|
||||||
fyl2x
|
fyl2x
|
||||||
jmp 1b
|
jmp 1b
|
||||||
.endfn tinymath_log1pf,globl
|
.endfn tinymath_log1pf,globl
|
||||||
|
|
|
@ -32,19 +32,19 @@ tinymath_log1pl:
|
||||||
fld %st
|
fld %st
|
||||||
fabs
|
fabs
|
||||||
fldt .LC16(%rip)
|
fldt .LC16(%rip)
|
||||||
fxch %st(1)
|
fxch
|
||||||
fcomip %st(1),%st
|
fcomip %st(1),%st
|
||||||
fstp %st
|
fstp %st
|
||||||
jnb 1f
|
jnb 1f
|
||||||
fldln2
|
fldln2
|
||||||
fxch %st(1)
|
fxch
|
||||||
fyl2xp1
|
fyl2xp1
|
||||||
0: pop %rbp
|
0: pop %rbp
|
||||||
ret
|
ret
|
||||||
1: fld1
|
1: fld1
|
||||||
faddp %st,%st(1)
|
faddp %st,%st(1)
|
||||||
fldln2
|
fldln2
|
||||||
fxch %st(1)
|
fxch
|
||||||
fyl2x
|
fyl2x
|
||||||
jmp 0b
|
jmp 0b
|
||||||
.endfn tinymath_log1pl,globl
|
.endfn tinymath_log1pl,globl
|
||||||
|
|
|
@ -39,7 +39,7 @@ tinymath_powl:
|
||||||
f2xm1
|
f2xm1
|
||||||
faddp
|
faddp
|
||||||
fscale
|
fscale
|
||||||
fxch %st(1)
|
fxch
|
||||||
fstp %st
|
fstp %st
|
||||||
pop %rbp
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -20,21 +20,14 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.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:
|
tinymath_scalb:
|
||||||
push %rbp
|
cvttsd2si %xmm1,%edi
|
||||||
mov %rsp,%rbp
|
jmp tinymath_ldexp
|
||||||
.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
|
|
||||||
.endfn tinymath_scalb,globl
|
.endfn tinymath_scalb,globl
|
||||||
.alias tinymath_scalb,scalb
|
.alias tinymath_scalb,scalb
|
||||||
|
|
|
@ -20,21 +20,14 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.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:
|
tinymath_scalbf:
|
||||||
push %rbp
|
cvttss2si %xmm1,%edi
|
||||||
mov %rsp,%rbp
|
jmp tinymath_ldexpf
|
||||||
.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
|
|
||||||
.endfn tinymath_scalbf,globl
|
.endfn tinymath_scalbf,globl
|
||||||
.alias tinymath_scalbf,scalbf
|
.alias tinymath_scalbf,scalbf
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.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:
|
tinymath_scalbl:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -34,7 +34,7 @@ tinymath_sincos:
|
||||||
movsd %xmm0,-8(%rbp)
|
movsd %xmm0,-8(%rbp)
|
||||||
fldl -8(%rbp)
|
fldl -8(%rbp)
|
||||||
fsincos
|
fsincos
|
||||||
fxch %st(1)
|
fxch
|
||||||
fstpl (%rdi)
|
fstpl (%rdi)
|
||||||
fstpl (%rsi)
|
fstpl (%rsi)
|
||||||
leave
|
leave
|
||||||
|
|
|
@ -34,7 +34,7 @@ tinymath_sincosf:
|
||||||
movss %xmm0,4(%rsp)
|
movss %xmm0,4(%rsp)
|
||||||
flds 4(%rsp)
|
flds 4(%rsp)
|
||||||
fsincos
|
fsincos
|
||||||
fxch %st(1)
|
fxch
|
||||||
fstps (%rdi)
|
fstps (%rdi)
|
||||||
fstps (%rsi)
|
fstps (%rsi)
|
||||||
leave
|
leave
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.source __FILE__
|
||||||
|
|
||||||
|
/ Returns square root of 𝑥.
|
||||||
|
/
|
||||||
|
/ @param 𝑥 is an double passed in %xmm0
|
||||||
|
/ @return result in %xmm0
|
||||||
tinymath_sqrt:
|
tinymath_sqrt:
|
||||||
.leafprologue
|
.leafprologue
|
||||||
.profilable
|
.profilable
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
.source __FILE__
|
.source __FILE__
|
||||||
|
|
||||||
|
/ Returns square root of 𝑥.
|
||||||
|
/
|
||||||
|
/ @param 𝑥 is an float passed in %xmm0
|
||||||
|
/ @return result in %xmm0
|
||||||
tinymath_sqrtf:
|
tinymath_sqrtf:
|
||||||
.leafprologue
|
.leafprologue
|
||||||
.profilable
|
.profilable
|
||||||
|
|
|
@ -43,11 +43,5 @@ tinymath_trunc:
|
||||||
.alias tinymath_trunc,trunc
|
.alias tinymath_trunc,trunc
|
||||||
|
|
||||||
.rodata.cst8
|
.rodata.cst8
|
||||||
2: .long 0
|
2: .double 0x0010000000000000
|
||||||
.long 1127219200
|
3: .double nan
|
||||||
|
|
||||||
.rodata.cst16
|
|
||||||
3: .long 4294967295
|
|
||||||
.long 2147483647
|
|
||||||
.long 0
|
|
||||||
.long 0
|
|
||||||
|
|
|
@ -27,6 +27,9 @@ TEST_LIBC_CONV_DIRECTDEPS = \
|
||||||
LIBC_CONV \
|
LIBC_CONV \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
|
LIBC_TINYMATH \
|
||||||
|
LIBC_RUNTIME \
|
||||||
|
LIBC_X \
|
||||||
LIBC_TESTLIB
|
LIBC_TESTLIB
|
||||||
|
|
||||||
TEST_LIBC_CONV_DEPS := \
|
TEST_LIBC_CONV_DEPS := \
|
||||||
|
|
|
@ -40,6 +40,11 @@ TEST(strerror, enosys) {
|
||||||
EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS));
|
EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(strerror, einval) {
|
||||||
|
if (IsTiny()) return;
|
||||||
|
EXPECT_STARTSWITH("EINVAL", strerror(EINVAL));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(strerror, symbolizingTheseNumbersAsErrorsIsHeresyInUnixStyle) {
|
TEST(strerror, symbolizingTheseNumbersAsErrorsIsHeresyInUnixStyle) {
|
||||||
EXPECT_STARTSWITH("E?/err=0/errno:0/GetLastError:0", strerror(0));
|
EXPECT_STARTSWITH("E?/err=0/errno:0/GetLastError:0", strerror(0));
|
||||||
EXPECT_STARTSWITH("E?", strerror(-1));
|
EXPECT_STARTSWITH("E?", strerror(-1));
|
||||||
|
|
|
@ -97,8 +97,6 @@
|
||||||
#include "libc/intrin/punpcklqdq.h"
|
#include "libc/intrin/punpcklqdq.h"
|
||||||
#include "libc/intrin/punpcklwd.h"
|
#include "libc/intrin/punpcklwd.h"
|
||||||
#include "libc/intrin/pxor.h"
|
#include "libc/intrin/pxor.h"
|
||||||
#include "libc/intrin/shufpd.h"
|
|
||||||
#include "libc/intrin/shufps.h"
|
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/nexgen32e/kcpuids.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) {
|
TEST(packuswb, test) {
|
||||||
const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0};
|
const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0};
|
||||||
unsigned char B[16] = {0};
|
unsigned char B[16] = {0};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
|
@ -18,28 +18,24 @@
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/macros.h"
|
#include "libc/runtime/gc.h"
|
||||||
.source __FILE__
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
tinymath_fpclassify:
|
TEST(ldexp, test) {
|
||||||
.leafprologue
|
volatile int twopow = 5;
|
||||||
movd %xmm0,%rax
|
volatile double pi = 3.14;
|
||||||
movd %xmm0,%rdx
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", ldexp(pi, twopow))));
|
||||||
shr $52,%rax
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", ldexpf(pi, twopow))));
|
||||||
mov %eax,%ecx
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", ldexpl(pi, twopow))));
|
||||||
and $0x7ff,%ecx
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalb(pi, twopow))));
|
||||||
jne 2f
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbf(pi, twopow))));
|
||||||
add %rdx,%rdx
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", scalbl(pi, twopow))));
|
||||||
cmp $1,%rdx
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbn(pi, twopow))));
|
||||||
sbb %eax,%eax
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbnf(pi, twopow))));
|
||||||
add $3,%eax
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", scalbnl(pi, twopow))));
|
||||||
jmp 1f
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalbln(pi, twopow))));
|
||||||
2: mov $FP_NORMAL,%eax
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2f", scalblnf(pi, twopow))));
|
||||||
cmp $0x7ff,%ecx
|
ASSERT_STREQ("100.48", gc(xasprintf("%.2Lf", scalblnl(pi, twopow))));
|
||||||
jne 1f
|
}
|
||||||
xor %eax,%eax
|
|
||||||
sal $12,%rdx
|
|
||||||
sete %al
|
|
||||||
1: .leafepilogue
|
|
||||||
.endfn tinymath_fpclassify,globl
|
|
||||||
.alias tinymath_fpclassify,__fpclassify
|
|
|
@ -120,8 +120,8 @@ TEST(pml4t, testOverlapsExistingRegistration_overwritesRegistration) {
|
||||||
TEST(pml4t, testFindPml4t_holeTooSmall_skipsOver) {
|
TEST(pml4t, testFindPml4t_holeTooSmall_skipsOver) {
|
||||||
ASSERT_NE(-1, RegisterPml4t(cr3, 0x700000000, 0, 0x1000, NewPage));
|
ASSERT_NE(-1, RegisterPml4t(cr3, 0x700000000, 0, 0x1000, NewPage));
|
||||||
ASSERT_NE(-1, RegisterPml4t(cr3, 0x700005000, 0, 0x1000, NewPage));
|
ASSERT_NE(-1, RegisterPml4t(cr3, 0x700005000, 0, 0x1000, NewPage));
|
||||||
ASSERT_EQ(0x700001000, FindPml4t(cr3, 0x700000000, 0x01000, NewPage));
|
ASSERT_EQ(0x700001000, FindPml4t(cr3, 0x700000000, 0x01000));
|
||||||
ASSERT_EQ(0x700006000, FindPml4t(cr3, 0x700000000, 0x10000, NewPage));
|
ASSERT_EQ(0x700006000, FindPml4t(cr3, 0x700000000, 0x10000));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(pml4t, testFreePmlt) {
|
TEST(pml4t, testFreePmlt) {
|
||||||
|
|
1
third_party/stb/stb_vorbis.c
vendored
1
third_party/stb/stb_vorbis.c
vendored
|
@ -34,6 +34,7 @@
|
||||||
//
|
//
|
||||||
#include "libc/alg/alg.h"
|
#include "libc/alg/alg.h"
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/conv/conv.h"
|
#include "libc/conv/conv.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
|
|
6
third_party/xed/x86.h
vendored
6
third_party/xed/x86.h
vendored
|
@ -364,6 +364,9 @@ struct XedOperands { /*
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
uint8_t srm : 3;
|
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 {
|
union {
|
||||||
uint8_t sib;
|
uint8_t sib;
|
||||||
struct {
|
struct {
|
||||||
|
@ -380,12 +383,9 @@ struct XedOperands { /*
|
||||||
uint8_t mod : 2;
|
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 seg_ovd : 3; // XED_SEG_xx
|
||||||
uint8_t error : 5; // enum XedError
|
uint8_t error : 5; // enum XedError
|
||||||
uint8_t mode : 3; // real,legacy,long
|
uint8_t mode : 3; // real,legacy,long
|
||||||
uint8_t rep : 2; // 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe)
|
|
||||||
bool lock : 1; // prefix
|
bool lock : 1; // prefix
|
||||||
bool imm_signed : 1; // internal
|
bool imm_signed : 1; // internal
|
||||||
int64_t disp; // displacement(%xxx) sign-extended
|
int64_t disp; // displacement(%xxx) sign-extended
|
||||||
|
|
3
third_party/zlib/deflate.c
vendored
3
third_party/zlib/deflate.c
vendored
|
@ -5,6 +5,7 @@
|
||||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||||
│ be found in the third_party/zlib/LICENSE file. │
|
│ be found in the third_party/zlib/LICENSE file. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
@ -223,7 +224,7 @@ static inline Pos insert_string_sse(struct DeflateState *const s,
|
||||||
Pos ret;
|
Pos ret;
|
||||||
unsigned *ip, val, h = 0;
|
unsigned *ip, val, h = 0;
|
||||||
ip = (unsigned *)&s->window[str];
|
ip = (unsigned *)&s->window[str];
|
||||||
val = read32le(ip); /* XXX: val = *ip; */
|
val = READ32LE(ip); /* XXX: val = *ip; */
|
||||||
if (s->level >= 6) val &= 0xFFFFFF;
|
if (s->level >= 6) val &= 0xFFFFFF;
|
||||||
asm("crc32\t%1,%0" : "+r"(h) : "r"(val));
|
asm("crc32\t%1,%0" : "+r"(h) : "r"(val));
|
||||||
ret = s->head[h & s->hash_mask];
|
ret = s->head[h & s->hash_mask];
|
||||||
|
|
|
@ -17,7 +17,7 @@ M(1, i, "!", LogicalNot, !x, "logical not")
|
||||||
M(2, i, "||", LogicalOr, x || y, "logical or")
|
M(2, i, "||", LogicalOr, x || y, "logical or")
|
||||||
M(2, i, "&&", LogicalAnd, x &&y, "logical and")
|
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, "!=", Notequal, x != y, "not equal to")
|
||||||
M(2, g, "<", LessThan, x < y, "less than")
|
M(2, g, "<", LessThan, x < y, "less than")
|
||||||
M(2, g, ">", GreaterThan, x > y, "greater than")
|
M(2, g, ">", GreaterThan, x > y, "greater than")
|
||||||
|
|
|
@ -28,7 +28,7 @@ static void Print(uint8_t c) {
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int i;
|
int i;
|
||||||
#ifdef DISINGENUOUS
|
#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
|
#else
|
||||||
size_t size;
|
size_t size;
|
||||||
struct MetalSha256Ctx ctx;
|
struct MetalSha256Ctx ctx;
|
||||||
|
|
|
@ -9,4 +9,4 @@ TOOL_BUILD_EMUCRT = \
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/tool/build/emucrt
|
.PHONY: o/$(MODE)/tool/build/emucrt
|
||||||
o/$(MODE)/tool/build/emucrt: \
|
o/$(MODE)/tool/build/emucrt: \
|
||||||
o/$(MODE)/tool/build/emucrt/emucrt.o
|
$(TOOL_BUILD_EMUCRT)
|
||||||
|
|
|
@ -105,17 +105,15 @@ ARGUMENTS\n\
|
||||||
\n\
|
\n\
|
||||||
PERFORMANCE\n\
|
PERFORMANCE\n\
|
||||||
\n\
|
\n\
|
||||||
1500 MIPS w/ NOP loop\n\
|
1000 MIPS w/ NOP loop\n\
|
||||||
Over 9000 MIPS w/ SIMD & Algorithms\n\
|
Over 9000 MIPS w/ SIMD & Algorithms\n\
|
||||||
\n\
|
\n\
|
||||||
PROTIP\n\
|
COMPLETENESS\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\
|
|
||||||
\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"
|
\n"
|
||||||
|
|
||||||
#define DUMPWIDTH 64
|
#define DUMPWIDTH 64
|
||||||
|
@ -274,7 +272,6 @@ static uint8_t CycleSseWidth(uint8_t w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnBusted(void) {
|
static void OnBusted(void) {
|
||||||
LOGF("OnBusted");
|
|
||||||
CHECK(onbusted);
|
CHECK(onbusted);
|
||||||
longjmp(onbusted, 1);
|
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,
|
static void DrawFlag(struct Panel *p, long i, char name, bool value) {
|
||||||
bool previous) {
|
char str[] = " ";
|
||||||
AppendPanel(p, i, " ");
|
if (value) str[1] = name;
|
||||||
if (value) {
|
AppendPanel(p, i, str);
|
||||||
AppendPanel(p, i, name);
|
|
||||||
} else {
|
|
||||||
AppendPanel(p, i, " ");
|
|
||||||
}
|
|
||||||
AppendPanel(p, i, " ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawRegister(struct Panel *p, long i, long r) {
|
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) {
|
static void DrawSt(struct Panel *p, long i, long r) {
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
long double value;
|
||||||
bool isempty, changed;
|
bool isempty, changed;
|
||||||
long double value, previous;
|
|
||||||
isempty = FpuGetTag(m, r) == kFpuTagEmpty;
|
isempty = FpuGetTag(m, r) == kFpuTagEmpty;
|
||||||
if (isempty) AppendPanel(p, i, "\e[2m");
|
if (isempty) AppendPanel(p, i, "\e[2m");
|
||||||
value = *FpuSt(&m[0], r);
|
value = m[0].fpu.st[(r + m[0].fpu.sp) & 0b111];
|
||||||
previous = *FpuSt(&m[1], r);
|
changed = value != m[1].fpu.st[(r + m[0].fpu.sp) & 0b111];
|
||||||
changed = value != previous;
|
|
||||||
if (!isempty && changed) AppendPanel(p, i, "\e[7m");
|
if (!isempty && changed) AppendPanel(p, i, "\e[7m");
|
||||||
snprintf(buf, sizeof(buf), "ST%d ", r);
|
snprintf(buf, sizeof(buf), "ST%d ", r);
|
||||||
AppendPanel(p, i, buf);
|
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);
|
DrawRegister(p, 7, 11), DrawRegister(p, 7, 15), DrawSt(p, 7, 7);
|
||||||
snprintf(buf, sizeof(buf), "RIP 0x%016x FLG", m[0].ip);
|
snprintf(buf, sizeof(buf), "RIP 0x%016x FLG", m[0].ip);
|
||||||
AppendPanel(p, 8, buf);
|
AppendPanel(p, 8, buf);
|
||||||
DrawFlag(p, 8, "C", GetFlag(m[0].flags, FLAGS_CF),
|
DrawFlag(p, 8, 'C', GetFlag(m[0].flags, FLAGS_CF));
|
||||||
GetFlag(m[1].flags, FLAGS_CF));
|
DrawFlag(p, 8, 'P', GetFlag(m[0].flags, FLAGS_PF));
|
||||||
DrawFlag(p, 8, "Z", GetFlag(m[0].flags, FLAGS_ZF),
|
DrawFlag(p, 8, 'A', GetFlag(m[0].flags, FLAGS_AF));
|
||||||
GetFlag(m[1].flags, FLAGS_ZF));
|
DrawFlag(p, 8, 'Z', GetFlag(m[0].flags, FLAGS_ZF));
|
||||||
DrawFlag(p, 8, "S", GetFlag(m[0].flags, FLAGS_SF),
|
DrawFlag(p, 8, 'S', GetFlag(m[0].flags, FLAGS_SF));
|
||||||
GetFlag(m[1].flags, FLAGS_SF));
|
DrawFlag(p, 8, 'I', GetFlag(m[0].flags, FLAGS_IF));
|
||||||
DrawFlag(p, 8, "O", GetFlag(m[0].flags, FLAGS_OF),
|
DrawFlag(p, 8, 'D', GetFlag(m[0].flags, FLAGS_DF));
|
||||||
GetFlag(m[1].flags, FLAGS_OF));
|
DrawFlag(p, 8, 'O', GetFlag(m[0].flags, FLAGS_OF));
|
||||||
DrawFlag(p, 8, "P", GetFlag(m[0].flags, FLAGS_PF),
|
AppendPanel(p, 8, " ");
|
||||||
GetFlag(m[1].flags, FLAGS_PF));
|
if (m->fpu.ie) AppendPanel(p, 8, " IE");
|
||||||
DrawFlag(p, 8, "I", GetFlag(m[0].flags, FLAGS_IF),
|
if (m->fpu.de) AppendPanel(p, 8, " DE");
|
||||||
GetFlag(m[1].flags, FLAGS_IF));
|
if (m->fpu.ze) AppendPanel(p, 8, " ZE");
|
||||||
DrawFlag(p, 8, "D", GetFlag(m[0].flags, FLAGS_DF),
|
if (m->fpu.oe) AppendPanel(p, 8, " OE");
|
||||||
GetFlag(m[1].flags, FLAGS_DF));
|
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) {
|
static void DrawXmm(struct Panel *p, long i, long r) {
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
* NexGen32e Arithmetic Unit.
|
* NexGen32e Arithmetic Unit.
|
||||||
*/
|
*/
|
||||||
int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) {
|
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;
|
uint64_t t, z, s, m, k;
|
||||||
|
bool cf, of, zf, sf, af, carry;
|
||||||
assert(w < 4);
|
assert(w < 4);
|
||||||
k = 8;
|
k = 8;
|
||||||
k <<= w;
|
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;
|
||||||
m |= s - 1;
|
m |= s - 1;
|
||||||
t = x;
|
t = x;
|
||||||
c = 0;
|
cf = 0;
|
||||||
o = 0;
|
of = 0;
|
||||||
cf = GetFlag(*flags, FLAGS_CF);
|
af = 0;
|
||||||
|
carry = GetFlag(*flags, FLAGS_CF);
|
||||||
switch (h & 7) {
|
switch (h & 7) {
|
||||||
case ALU_OR:
|
case ALU_OR:
|
||||||
z = x | y;
|
z = x | y;
|
||||||
|
@ -50,22 +51,26 @@ int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) {
|
||||||
break;
|
break;
|
||||||
case ALU_CMP:
|
case ALU_CMP:
|
||||||
h |= 8;
|
h |= 8;
|
||||||
cf = 0;
|
carry = 0;
|
||||||
case ALU_SBB:
|
case ALU_SBB:
|
||||||
t = (x & m) - cf;
|
t = (x & m) - carry;
|
||||||
c = (x & m) < (t & m);
|
cf = (x & m) < (t & m);
|
||||||
|
af = (x & 15) < (t & 15);
|
||||||
case ALU_SUB:
|
case ALU_SUB:
|
||||||
z = (t & m) - (y & m);
|
z = (t & m) - (y & m);
|
||||||
c |= (t & m) < (z & m);
|
cf |= (t & m) < (z & m);
|
||||||
o = !!((z ^ x) & (x ^ y) & s);
|
af |= (t & 15) < (z & 15);
|
||||||
|
of = !!((z ^ x) & (x ^ y) & s);
|
||||||
break;
|
break;
|
||||||
case ALU_ADC:
|
case ALU_ADC:
|
||||||
t = (x & m) + cf;
|
t = (x & m) + carry;
|
||||||
c = (t & m) < (x & m);
|
cf = (t & m) < (x & m);
|
||||||
|
af = (t & 15) < (x & 15);
|
||||||
case ALU_ADD:
|
case ALU_ADD:
|
||||||
z = (t & m) + (y & m);
|
z = (t & m) + (y & m);
|
||||||
c |= (z & m) < (y & m);
|
cf |= (z & m) < (y & m);
|
||||||
o = !!((z ^ x) & (z ^ y) & s);
|
af |= (z & 15) < (y & 15);
|
||||||
|
of = !!((z ^ x) & (z ^ y) & s);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unreachable;
|
unreachable;
|
||||||
|
@ -73,8 +78,10 @@ int64_t Alu(int w, int h, uint64_t x, uint64_t y, uint32_t *flags) {
|
||||||
z &= m;
|
z &= m;
|
||||||
zf = !z;
|
zf = !z;
|
||||||
sf = !!(z & s);
|
sf = !!(z & s);
|
||||||
*flags &= ~(1 << FLAGS_CF | 1 << FLAGS_ZF | 1 << FLAGS_SF | 1 << FLAGS_OF);
|
*flags = (*flags & ~(1 << FLAGS_CF | 1 << FLAGS_ZF | 1 << FLAGS_SF |
|
||||||
*flags |= c << FLAGS_CF | zf << FLAGS_ZF | sf << FLAGS_SF | o << FLAGS_OF;
|
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);
|
*flags = SetLazyParityByte(*flags, x);
|
||||||
if (h & ALU_TEST) z = x;
|
if (h & ALU_TEST) z = x;
|
||||||
return z;
|
return z;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#define ALU_XOR 6
|
#define ALU_XOR 6
|
||||||
#define ALU_CMP 7
|
#define ALU_CMP 7
|
||||||
#define ALU_TEST 8
|
#define ALU_TEST 8
|
||||||
#define ALU_FLIP 16
|
|
||||||
|
|
||||||
#define BSU_ROL 0
|
#define BSU_ROL 0
|
||||||
#define BSU_ROR 1
|
#define BSU_ROR 1
|
||||||
|
|
|
@ -63,6 +63,8 @@ $(TOOL_BUILD_LIB_A).pkg: \
|
||||||
$(TOOL_BUILD_LIB_A_OBJS) \
|
$(TOOL_BUILD_LIB_A_OBJS) \
|
||||||
$(foreach x,$(TOOL_BUILD_LIB_A_DIRECTDEPS),$($(x)_A).pkg)
|
$(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_LIBS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)))
|
||||||
TOOL_BUILD_LIB_SRCS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)_SRCS))
|
TOOL_BUILD_LIB_SRCS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)_SRCS))
|
||||||
TOOL_BUILD_LIB_HDRS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)_HDRS))
|
TOOL_BUILD_LIB_HDRS = $(foreach x,$(TOOL_BUILD_LIB_ARTIFACTS),$($(x)_HDRS))
|
||||||
|
|
|
@ -7,5 +7,10 @@
|
||||||
CODE; \
|
CODE; \
|
||||||
break
|
break
|
||||||
|
|
||||||
|
#define CASR(OP, CODE) \
|
||||||
|
case OP: \
|
||||||
|
CODE; \
|
||||||
|
return
|
||||||
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_TOOL_BUILD_LIB_CASE_H_ */
|
#endif /* COSMOPOLITAN_TOOL_BUILD_LIB_CASE_H_ */
|
||||||
|
|
|
@ -26,6 +26,21 @@
|
||||||
#include "tool/build/lib/modrm.h"
|
#include "tool/build/lib/modrm.h"
|
||||||
#include "tool/build/lib/throw.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) {
|
static void OpGdqpWssCvttss2si(struct Machine *m, uint32_t rde) {
|
||||||
float f;
|
float f;
|
||||||
int64_t n;
|
int64_t n;
|
||||||
|
@ -57,7 +72,7 @@ static void OpGdqpWsdCvtsd2si(struct Machine *m, uint32_t rde) {
|
||||||
double d;
|
double d;
|
||||||
int64_t n;
|
int64_t n;
|
||||||
memcpy(&d, GetModrmRegisterXmmPointerRead8(m, rde), 8);
|
memcpy(&d, GetModrmRegisterXmmPointerRead8(m, rde), 8);
|
||||||
n = nearbyint(d);
|
n = SseRoundDouble(m, d);
|
||||||
if (!Rexw(rde)) n &= 0xffffffff;
|
if (!Rexw(rde)) n &= 0xffffffff;
|
||||||
Write64(RegRexrReg(m, rde), n);
|
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) {
|
static void OpPpiWpsqCvtps2pi(struct Machine *m, uint32_t rde) {
|
||||||
|
unsigned i;
|
||||||
float f[2];
|
float f[2];
|
||||||
int32_t n[2];
|
int32_t n[2];
|
||||||
memcpy(f, GetModrmRegisterXmmPointerRead8(m, rde), 8);
|
memcpy(f, GetModrmRegisterXmmPointerRead8(m, rde), 8);
|
||||||
n[0] = nearbyintf(f[0]);
|
switch (m->sse.rc) {
|
||||||
n[1] = nearbyintf(f[1]);
|
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) + 0, n[0]);
|
||||||
Write32(MmReg(m, rde) + 4, n[1]);
|
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) {
|
static void OpPpiWpdCvtpd2pi(struct Machine *m, uint32_t rde) {
|
||||||
|
unsigned i;
|
||||||
double d[2];
|
double d[2];
|
||||||
int32_t n[2];
|
int32_t n[2];
|
||||||
memcpy(d, GetModrmRegisterXmmPointerRead16(m, rde), 16);
|
memcpy(d, GetModrmRegisterXmmPointerRead16(m, rde), 16);
|
||||||
n[0] = nearbyint(d[0]);
|
for (i = 0; i < 2; ++i) n[i] = SseRoundDouble(m, d[i]);
|
||||||
n[1] = nearbyint(d[1]);
|
|
||||||
Write32(MmReg(m, rde) + 0, n[0]);
|
Write32(MmReg(m, rde) + 0, n[0]);
|
||||||
Write32(MmReg(m, rde) + 4, n[1]);
|
Write32(MmReg(m, rde) + 4, n[1]);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +248,22 @@ static void OpVdqWpsCvtps2dq(struct Machine *m, uint32_t rde) {
|
||||||
float f[4];
|
float f[4];
|
||||||
int32_t n[4];
|
int32_t n[4];
|
||||||
memcpy(f, GetModrmRegisterXmmPointerRead16(m, rde), 16);
|
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);
|
memcpy(XmmRexrReg(m, rde), n, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +281,7 @@ static void OpVdqWpdCvtpd2dq(struct Machine *m, uint32_t rde) {
|
||||||
double d[2];
|
double d[2];
|
||||||
int32_t n[2];
|
int32_t n[2];
|
||||||
memcpy(d, GetModrmRegisterXmmPointerRead16(m, rde), 16);
|
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);
|
memcpy(XmmRexrReg(m, rde), n, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/conv/itoa.h"
|
#include "libc/conv/itoa.h"
|
||||||
#include "libc/fmt/bing.h"
|
#include "libc/fmt/bing.h"
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
|
#include "libc/limits.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||||
│ 02110-1301 USA │
|
│ 02110-1301 USA │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/conv/itoa.h"
|
#include "libc/conv/itoa.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "tool/build/lib/memory.h"
|
#include "tool/build/lib/memory.h"
|
||||||
#include "tool/build/lib/modrm.h"
|
#include "tool/build/lib/modrm.h"
|
||||||
#include "tool/build/lib/throw.h"
|
#include "tool/build/lib/throw.h"
|
||||||
|
#include "tool/build/lib/word.h"
|
||||||
#include "tool/build/lib/x87.h"
|
#include "tool/build/lib/x87.h"
|
||||||
|
|
||||||
#define FPUREG 0
|
#define FPUREG 0
|
||||||
|
@ -92,90 +93,142 @@ static void FpuSetStRmPop(struct Machine *m, long double x) {
|
||||||
FpuSetStPop(m, ModrmRm(m->xedd->op.rde), 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];
|
uint8_t b[2];
|
||||||
return Read16(Load(m, m->fpu.dp, 2, b));
|
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];
|
uint8_t b[4];
|
||||||
return Read32(Load(m, m->fpu.dp, 4, b));
|
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];
|
uint8_t b[8];
|
||||||
return Read64(Load(m, m->fpu.dp, 8, b));
|
return Read64(Load(m, m->fpu.dp, 8, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
static float GetMemoryFloat(struct Machine *m) {
|
static float FpuGetMemoryFloat(struct Machine *m) {
|
||||||
float f;
|
float f;
|
||||||
uint8_t b[4];
|
uint8_t b[4];
|
||||||
memcpy(&f, Load(m, m->fpu.dp, 4, b), 4);
|
memcpy(&f, Load(m, m->fpu.dp, 4, b), 4);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double GetMemoryDouble(struct Machine *m) {
|
static double FpuGetMemoryDouble(struct Machine *m) {
|
||||||
double f;
|
double f;
|
||||||
uint8_t b[8];
|
uint8_t b[8];
|
||||||
memcpy(&f, Load(m, m->fpu.dp, 8, b), 8);
|
memcpy(&f, Load(m, m->fpu.dp, 8, b), 8);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double GetMemoryLongDouble(struct Machine *m) {
|
static long double FpuGetMemoryLongDouble(struct Machine *m) {
|
||||||
long double f;
|
long double f;
|
||||||
uint8_t b[10];
|
uint8_t b[10];
|
||||||
memcpy(&f, Load(m, m->fpu.dp, 10, b), 10);
|
memcpy(&f, Load(m, m->fpu.dp, 10, b), 10);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetMemoryShort(struct Machine *m, int16_t i) {
|
static void FpuSetMemoryShort(struct Machine *m, int16_t i) {
|
||||||
void *p[2];
|
SetMemoryShort(m, m->fpu.dp, i);
|
||||||
uint8_t b[2];
|
|
||||||
Write16(BeginStore(m, m->fpu.dp, 2, p, b), i);
|
|
||||||
EndStore(m, m->fpu.dp, 2, p, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetMemoryInt(struct Machine *m, int32_t i) {
|
static void FpuSetMemoryInt(struct Machine *m, int32_t i) {
|
||||||
void *p[2];
|
SetMemoryInt(m, m->fpu.dp, i);
|
||||||
uint8_t b[4];
|
|
||||||
Write32(BeginStore(m, m->fpu.dp, 4, p, b), i);
|
|
||||||
EndStore(m, m->fpu.dp, 4, p, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetMemoryLong(struct Machine *m, int64_t i) {
|
static void FpuSetMemoryLong(struct Machine *m, int64_t i) {
|
||||||
void *p[2];
|
SetMemoryLong(m, m->fpu.dp, i);
|
||||||
uint8_t b[8];
|
|
||||||
Write64(BeginStore(m, m->fpu.dp, 8, p, b), i);
|
|
||||||
EndStore(m, m->fpu.dp, 8, p, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetMemoryFloat(struct Machine *m, float f) {
|
static void FpuSetMemoryFloat(struct Machine *m, float f) {
|
||||||
void *p[2];
|
SetMemoryFloat(m, m->fpu.dp, f);
|
||||||
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 SetMemoryDouble(struct Machine *m, double f) {
|
static void FpuSetMemoryDouble(struct Machine *m, double f) {
|
||||||
void *p[2];
|
SetMemoryDouble(m, m->fpu.dp, f);
|
||||||
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 SetMemoryLdbl(struct Machine *m, long double f) {
|
static void FpuSetMemoryLdbl(struct Machine *m, long double f) {
|
||||||
void *p[2];
|
SetMemoryLdbl(m, m->fpu.dp, f);
|
||||||
uint8_t b[10];
|
|
||||||
memcpy(BeginStore(m, m->fpu.dp, 10, p, b), &f, 10);
|
|
||||||
EndStore(m, m->fpu.dp, 10, p, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double FpuDivide(struct Machine *m, long double x, long double y) {
|
static long double FpuAdd(struct Machine *m, long double x, long double y) {
|
||||||
if (y) {
|
if (!isunordered(x, y)) {
|
||||||
return 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 {
|
} else {
|
||||||
m->fpu.ze = true;
|
return NAN;
|
||||||
return signbit(x) ? -INFINITY : INFINITY;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
long double x;
|
||||||
x = St0(m);
|
x = St0(m);
|
||||||
m->fpu.c1 = false;
|
m->fpu.c1 = false;
|
||||||
if (!isnan(x) && !isnan(y)) {
|
if (!isunordered(x, y)) {
|
||||||
m->fpu.c0 = x < y;
|
m->fpu.c0 = x < y;
|
||||||
m->fpu.c2 = false;
|
m->fpu.c2 = false;
|
||||||
m->fpu.c3 = x == y;
|
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;
|
long double x;
|
||||||
x = *FpuSt(m, 0);
|
x = *FpuSt(m, 0);
|
||||||
m->fpu.c1 = !!signbit(x);
|
m->fpu.c1 = !!signbit(x);
|
||||||
|
@ -362,59 +415,59 @@ static void OpFcomp(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFaddStEst(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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
static void OpFcompp(struct Machine *m) {
|
||||||
|
@ -423,31 +476,31 @@ static void OpFcompp(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFsubp(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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
static void OpFcoms(struct Machine *m) {
|
||||||
FpuCompare(m, GetMemoryFloat(m));
|
FpuCompare(m, FpuGetMemoryFloat(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFcomps(struct Machine *m) {
|
static void OpFcomps(struct Machine *m) {
|
||||||
|
@ -456,64 +509,64 @@ static void OpFcomps(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFsubs(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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
static void OpFcoml(struct Machine *m) {
|
||||||
FpuCompare(m, GetMemoryDouble(m));
|
FpuCompare(m, FpuGetMemoryDouble(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFcompl(struct Machine *m) {
|
static void OpFcompl(struct Machine *m) {
|
||||||
FpuCompare(m, GetMemoryDouble(m));
|
FpuCompare(m, FpuGetMemoryDouble(m));
|
||||||
FpuPop(m);
|
FpuPop(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFsubl(struct Machine *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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
static void OpFicoml(struct Machine *m) {
|
||||||
FpuCompare(m, GetMemoryInt(m));
|
FpuCompare(m, FpuGetMemoryInt(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFicompl(struct Machine *m) {
|
static void OpFicompl(struct Machine *m) {
|
||||||
|
@ -522,31 +575,31 @@ static void OpFicompl(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFisubl(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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
static void OpFicoms(struct Machine *m) {
|
||||||
FpuCompare(m, GetMemoryShort(m));
|
FpuCompare(m, FpuGetMemoryShort(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFicomps(struct Machine *m) {
|
static void OpFicomps(struct Machine *m) {
|
||||||
|
@ -555,19 +608,19 @@ static void OpFicomps(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFisubs(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) {
|
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) {
|
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) {
|
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) {
|
static void OpFsqrt(struct Machine *m) {
|
||||||
|
@ -612,11 +665,11 @@ static void OpFld(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFlds(struct Machine *m) {
|
static void OpFlds(struct Machine *m) {
|
||||||
FpuPush(m, GetMemoryFloat(m));
|
FpuPush(m, FpuGetMemoryFloat(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFsts(struct Machine *m) {
|
static void OpFsts(struct Machine *m) {
|
||||||
SetMemoryFloat(m, St0(m));
|
FpuSetMemoryFloat(m, St0(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFstps(struct Machine *m) {
|
static void OpFstps(struct Machine *m) {
|
||||||
|
@ -625,11 +678,11 @@ static void OpFstps(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFstpt(struct Machine *m) {
|
static void OpFstpt(struct Machine *m) {
|
||||||
SetMemoryLdbl(m, FpuPop(m));
|
FpuSetMemoryLdbl(m, FpuPop(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFstl(struct Machine *m) {
|
static void OpFstl(struct Machine *m) {
|
||||||
SetMemoryDouble(m, St0(m));
|
FpuSetMemoryDouble(m, St0(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFstpl(struct Machine *m) {
|
static void OpFstpl(struct Machine *m) {
|
||||||
|
@ -652,15 +705,15 @@ static void OpFxch(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFldcw(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) {
|
static void OpFldt(struct Machine *m) {
|
||||||
FpuPush(m, GetMemoryLongDouble(m));
|
FpuPush(m, FpuGetMemoryLongDouble(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFldl(struct Machine *m) {
|
static void OpFldl(struct Machine *m) {
|
||||||
FpuPush(m, GetMemoryDouble(m));
|
FpuPush(m, FpuGetMemoryDouble(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFldConstant(struct Machine *m) {
|
static void OpFldConstant(struct Machine *m) {
|
||||||
|
@ -694,43 +747,43 @@ static void OpFldConstant(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFstcw(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) {
|
static void OpFilds(struct Machine *m) {
|
||||||
FpuPush(m, GetMemoryShort(m));
|
FpuPush(m, FpuGetMemoryShort(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFildl(struct Machine *m) {
|
static void OpFildl(struct Machine *m) {
|
||||||
FpuPush(m, GetMemoryInt(m));
|
FpuPush(m, FpuGetMemoryInt(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFildll(struct Machine *m) {
|
static void OpFildll(struct Machine *m) {
|
||||||
FpuPush(m, GetMemoryLong(m));
|
FpuPush(m, FpuGetMemoryLong(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFisttpl(struct Machine *m) {
|
static void OpFisttpl(struct Machine *m) {
|
||||||
SetMemoryInt(m, FpuPop(m));
|
FpuSetMemoryInt(m, FpuPop(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFisttpll(struct Machine *m) {
|
static void OpFisttpll(struct Machine *m) {
|
||||||
SetMemoryLong(m, FpuPop(m));
|
FpuSetMemoryLong(m, FpuPop(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFisttps(struct Machine *m) {
|
static void OpFisttps(struct Machine *m) {
|
||||||
SetMemoryShort(m, FpuPop(m));
|
FpuSetMemoryShort(m, FpuPop(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFists(struct Machine *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) {
|
static void OpFistl(struct Machine *m) {
|
||||||
SetMemoryInt(m, FpuRound(m, St0(m)));
|
FpuSetMemoryInt(m, FpuRound(m, St0(m)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFistll(struct Machine *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) {
|
static void OpFistpl(struct Machine *m) {
|
||||||
|
@ -752,7 +805,7 @@ static void OpFcomi(struct Machine *m) {
|
||||||
long double x, y;
|
long double x, y;
|
||||||
x = St0(m);
|
x = St0(m);
|
||||||
y = StRm(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_ZF, x == y);
|
||||||
m->flags = SetFlag(m->flags, FLAGS_CF, x < y);
|
m->flags = SetFlag(m->flags, FLAGS_CF, x < y);
|
||||||
m->flags = SetFlag(m->flags, FLAGS_PF, false);
|
m->flags = SetFlag(m->flags, FLAGS_PF, false);
|
||||||
|
@ -796,7 +849,7 @@ static void OpFfreep(struct Machine *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpFstswMw(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) {
|
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, 2), OpFcmovbe(m));
|
||||||
CASE(DISP(0xDA, FPUREG, 3), OpFcmovu(m));
|
CASE(DISP(0xDA, FPUREG, 3), OpFcmovu(m));
|
||||||
CASE(DISP(0xDA, MEMORY, 0), OpFiaddl(m));
|
CASE(DISP(0xDA, MEMORY, 0), OpFiaddl(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 1), OpFimull(m));
|
CASE(DISP(0xDA, MEMORY, 1), OpFimull(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 2), OpFicoml(m));
|
CASE(DISP(0xDA, MEMORY, 2), OpFicoml(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 3), OpFicompl(m));
|
CASE(DISP(0xDA, MEMORY, 3), OpFicompl(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 4), OpFisubl(m));
|
CASE(DISP(0xDA, MEMORY, 4), OpFisubl(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 5), OpFisubrl(m));
|
CASE(DISP(0xDA, MEMORY, 5), OpFisubrl(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 6), OpFidivl(m));
|
CASE(DISP(0xDA, MEMORY, 6), OpFidivl(m));
|
||||||
CASE(DISP(0xDa, MEMORY, 7), OpFidivrl(m));
|
CASE(DISP(0xDA, MEMORY, 7), OpFidivrl(m));
|
||||||
CASE(DISP(0xDb, FPUREG, 0), OpFcmovnb(m));
|
CASE(DISP(0xDB, FPUREG, 0), OpFcmovnb(m));
|
||||||
CASE(DISP(0xDb, FPUREG, 1), OpFcmovne(m));
|
CASE(DISP(0xDB, FPUREG, 1), OpFcmovne(m));
|
||||||
CASE(DISP(0xDb, FPUREG, 2), OpFcmovnbe(m));
|
CASE(DISP(0xDB, FPUREG, 2), OpFcmovnbe(m));
|
||||||
CASE(DISP(0xDb, FPUREG, 3), OpFcmovnu(m));
|
CASE(DISP(0xDB, FPUREG, 3), OpFcmovnu(m));
|
||||||
CASE(DISP(0xDb, FPUREG, 5), OpFucomi(m));
|
CASE(DISP(0xDB, FPUREG, 5), OpFucomi(m));
|
||||||
CASE(DISP(0xDb, FPUREG, 6), OpFcomi(m));
|
CASE(DISP(0xDB, FPUREG, 6), OpFcomi(m));
|
||||||
CASE(DISP(0xDb, MEMORY, 0), OpFildl(m));
|
CASE(DISP(0xDB, MEMORY, 0), OpFildl(m));
|
||||||
CASE(DISP(0xDb, MEMORY, 1), OpFisttpl(m));
|
CASE(DISP(0xDB, MEMORY, 1), OpFisttpl(m));
|
||||||
CASE(DISP(0xDb, MEMORY, 2), OpFistl(m));
|
CASE(DISP(0xDB, MEMORY, 2), OpFistl(m));
|
||||||
CASE(DISP(0xDb, MEMORY, 3), OpFistpl(m));
|
CASE(DISP(0xDB, MEMORY, 3), OpFistpl(m));
|
||||||
CASE(DISP(0xDb, MEMORY, 5), OpFldt(m));
|
CASE(DISP(0xDB, MEMORY, 5), OpFldt(m));
|
||||||
CASE(DISP(0xDb, MEMORY, 7), OpFstpt(m));
|
CASE(DISP(0xDB, MEMORY, 7), OpFstpt(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 0), OpFaddEstSt(m));
|
CASE(DISP(0xDC, FPUREG, 0), OpFaddEstSt(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 1), OpFmulEstSt(m));
|
CASE(DISP(0xDC, FPUREG, 1), OpFmulEstSt(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 2), OpFcom(m));
|
CASE(DISP(0xDC, FPUREG, 2), OpFcom(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 3), OpFcomp(m));
|
CASE(DISP(0xDC, FPUREG, 3), OpFcomp(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 4), OpFsubEstSt(m));
|
CASE(DISP(0xDC, FPUREG, 4), OpFsubEstSt(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 5), OpFsubrEstSt(m));
|
CASE(DISP(0xDC, FPUREG, 5), OpFsubrEstSt(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 6), OpFdivEstSt(m));
|
CASE(DISP(0xDC, FPUREG, 6), OpFdivEstSt(m));
|
||||||
CASE(DISP(0xDc, FPUREG, 7), OpFdivrEstSt(m));
|
CASE(DISP(0xDC, FPUREG, 7), OpFdivrEstSt(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 0), OpFaddl(m));
|
CASE(DISP(0xDC, MEMORY, 0), OpFaddl(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 1), OpFmull(m));
|
CASE(DISP(0xDC, MEMORY, 1), OpFmull(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 2), OpFcoml(m));
|
CASE(DISP(0xDC, MEMORY, 2), OpFcoml(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 3), OpFcompl(m));
|
CASE(DISP(0xDC, MEMORY, 3), OpFcompl(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 4), OpFsubl(m));
|
CASE(DISP(0xDC, MEMORY, 4), OpFsubl(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 5), OpFsubrl(m));
|
CASE(DISP(0xDC, MEMORY, 5), OpFsubrl(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 6), OpFdivl(m));
|
CASE(DISP(0xDC, MEMORY, 6), OpFdivl(m));
|
||||||
CASE(DISP(0xDc, MEMORY, 7), OpFdivrl(m));
|
CASE(DISP(0xDC, MEMORY, 7), OpFdivrl(m));
|
||||||
CASE(DISP(0xDd, FPUREG, 0), OpFfree(m));
|
CASE(DISP(0xDD, FPUREG, 0), OpFfree(m));
|
||||||
CASE(DISP(0xDd, FPUREG, 1), OpFxch(m));
|
CASE(DISP(0xDD, FPUREG, 1), OpFxch(m));
|
||||||
CASE(DISP(0xDd, FPUREG, 2), OpFst(m));
|
CASE(DISP(0xDD, FPUREG, 2), OpFst(m));
|
||||||
CASE(DISP(0xDd, FPUREG, 3), OpFstp(m));
|
CASE(DISP(0xDD, FPUREG, 3), OpFstp(m));
|
||||||
CASE(DISP(0xDd, FPUREG, 4), OpFucom(m));
|
CASE(DISP(0xDD, FPUREG, 4), OpFucom(m));
|
||||||
CASE(DISP(0xDd, FPUREG, 5), OpFucomp(m));
|
CASE(DISP(0xDD, FPUREG, 5), OpFucomp(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 0), OpFldl(m));
|
CASE(DISP(0xDD, MEMORY, 0), OpFldl(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 1), OpFisttpll(m));
|
CASE(DISP(0xDD, MEMORY, 1), OpFisttpll(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 2), OpFstl(m));
|
CASE(DISP(0xDD, MEMORY, 2), OpFstl(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 3), OpFstpl(m));
|
CASE(DISP(0xDD, MEMORY, 3), OpFstpl(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 4), OpFrstor(m));
|
CASE(DISP(0xDD, MEMORY, 4), OpFrstor(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 6), OpFsave(m));
|
CASE(DISP(0xDD, MEMORY, 6), OpFsave(m));
|
||||||
CASE(DISP(0xDd, MEMORY, 7), OpFstswMw(m));
|
CASE(DISP(0xDD, MEMORY, 7), OpFstswMw(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 0), OpFaddp(m));
|
CASE(DISP(0xDE, FPUREG, 0), OpFaddp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 1), OpFmulp(m));
|
CASE(DISP(0xDE, FPUREG, 1), OpFmulp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 2), OpFcomp(m));
|
CASE(DISP(0xDE, FPUREG, 2), OpFcomp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 3), OpFcompp(m));
|
CASE(DISP(0xDE, FPUREG, 3), OpFcompp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 4), OpFsubp(m));
|
CASE(DISP(0xDE, FPUREG, 4), OpFsubp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 5), OpFsubrp(m));
|
CASE(DISP(0xDE, FPUREG, 5), OpFsubrp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 6), OpFdivp(m));
|
CASE(DISP(0xDE, FPUREG, 6), OpFdivp(m));
|
||||||
CASE(DISP(0xDe, FPUREG, 7), OpFdivrp(m));
|
CASE(DISP(0xDE, FPUREG, 7), OpFdivrp(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 0), OpFiadds(m));
|
CASE(DISP(0xDE, MEMORY, 0), OpFiadds(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 1), OpFimuls(m));
|
CASE(DISP(0xDE, MEMORY, 1), OpFimuls(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 2), OpFicoms(m));
|
CASE(DISP(0xDE, MEMORY, 2), OpFicoms(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 3), OpFicomps(m));
|
CASE(DISP(0xDE, MEMORY, 3), OpFicomps(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 4), OpFisubs(m));
|
CASE(DISP(0xDE, MEMORY, 4), OpFisubs(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 5), OpFisubrs(m));
|
CASE(DISP(0xDE, MEMORY, 5), OpFisubrs(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 6), OpFidivs(m));
|
CASE(DISP(0xDE, MEMORY, 6), OpFidivs(m));
|
||||||
CASE(DISP(0xDe, MEMORY, 7), OpFidivrs(m));
|
CASE(DISP(0xDE, MEMORY, 7), OpFidivrs(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 0), OpFfreep(m));
|
CASE(DISP(0xDF, FPUREG, 0), OpFfreep(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 1), OpFxch(m));
|
CASE(DISP(0xDF, FPUREG, 1), OpFxch(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 2), OpFstp(m));
|
CASE(DISP(0xDF, FPUREG, 2), OpFstp(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 3), OpFstp(m));
|
CASE(DISP(0xDF, FPUREG, 3), OpFstp(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 4), OpFstswAx(m));
|
CASE(DISP(0xDF, FPUREG, 4), OpFstswAx(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 5), OpFucomip(m));
|
CASE(DISP(0xDF, FPUREG, 5), OpFucomip(m));
|
||||||
CASE(DISP(0xDf, FPUREG, 6), OpFcomip(m));
|
CASE(DISP(0xDF, FPUREG, 6), OpFcomip(m));
|
||||||
CASE(DISP(0xDf, MEMORY, 0), OpFilds(m));
|
CASE(DISP(0xDF, MEMORY, 0), OpFilds(m));
|
||||||
CASE(DISP(0xDf, MEMORY, 1), OpFisttps(m));
|
CASE(DISP(0xDF, MEMORY, 1), OpFisttps(m));
|
||||||
CASE(DISP(0xDf, MEMORY, 2), OpFists(m));
|
CASE(DISP(0xDF, MEMORY, 2), OpFists(m));
|
||||||
CASE(DISP(0xDf, MEMORY, 3), OpFistps(m));
|
CASE(DISP(0xDF, MEMORY, 3), OpFistps(m));
|
||||||
CASE(DISP(0xDf, MEMORY, 5), OpFildll(m));
|
CASE(DISP(0xDF, MEMORY, 5), OpFildll(m));
|
||||||
CASE(DISP(0xDf, MEMORY, 7), OpFistpll(m));
|
CASE(DISP(0xDF, MEMORY, 7), OpFistpll(m));
|
||||||
case DISP(0xD9, FPUREG, 4):
|
case DISP(0xD9, FPUREG, 4):
|
||||||
switch (ModrmRm(m->xedd->op.rde)) {
|
switch (ModrmRm(m->xedd->op.rde)) {
|
||||||
CASE(0, OpFchs(m));
|
CASE(0, OpFchs(m));
|
||||||
|
|
|
@ -26,8 +26,15 @@
|
||||||
#include "tool/build/lib/throw.h"
|
#include "tool/build/lib/throw.h"
|
||||||
|
|
||||||
static bool IsOpcodeEqual(uint8_t *a, uint8_t b[16], size_t size) {
|
static bool IsOpcodeEqual(uint8_t *a, uint8_t b[16], size_t size) {
|
||||||
if (likely(size)) {
|
unsigned i;
|
||||||
return memcmp(a, b, size) == 0;
|
if (size) {
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
if (a[i] != b[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} while (++i < size);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,8 @@ static void LoadElfLoadSegment(struct Machine *m, void *code, size_t codesize,
|
||||||
vstart = ROUNDDOWN(phdr->p_vaddr, align);
|
vstart = ROUNDDOWN(phdr->p_vaddr, align);
|
||||||
vbss = ROUNDUP(phdr->p_vaddr + phdr->p_filesz, align);
|
vbss = ROUNDUP(phdr->p_vaddr + phdr->p_filesz, align);
|
||||||
vend = ROUNDUP(phdr->p_vaddr + phdr->p_memsz, align);
|
vend = ROUNDUP(phdr->p_vaddr + phdr->p_memsz, align);
|
||||||
fstart = ROUNDDOWN(felf + phdr->p_offset, align);
|
fstart = felf + ROUNDDOWN(phdr->p_offset, align);
|
||||||
fend = ROUNDUP(felf + phdr->p_offset + phdr->p_filesz, align);
|
fend = felf + ROUNDUP(phdr->p_offset + phdr->p_filesz, align);
|
||||||
bsssize = vend - vbss;
|
bsssize = vend - vbss;
|
||||||
CHECK_GE(vend, vstart);
|
CHECK_GE(vend, vstart);
|
||||||
CHECK_GE(fend, fstart);
|
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,
|
void LoadProgram(struct Machine *m, const char *prog, char **args, char **vars,
|
||||||
struct Elf *elf) {
|
struct Elf *elf) {
|
||||||
int fd;
|
int fd;
|
||||||
|
char *real;
|
||||||
|
ssize_t rc;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
void *code, *stack;
|
void *code, *stack;
|
||||||
size_t codesize, stacksize;
|
size_t i, codesize, mappedsize, extrasize, stacksize;
|
||||||
DCHECK_NOTNULL(prog);
|
DCHECK_NOTNULL(prog);
|
||||||
elf->prog = prog;
|
elf->prog = prog;
|
||||||
if ((fd = open(prog, O_RDONLY)) == -1 ||
|
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);
|
fputs(": not found\n", stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
codesize = st.st_size;
|
|
||||||
stacksize = STACKSIZE;
|
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,
|
CHECK_NE(MAP_FAILED, (stack = mmap(NULL, stacksize, PROT_READ | PROT_WRITE,
|
||||||
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
|
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
|
||||||
CHECK_NE(MAP_FAILED, (code = mmap(NULL, codesize, PROT_READ | PROT_WRITE,
|
code = real = (char *)0x0000400000000000;
|
||||||
MAP_PRIVATE, fd, 0)));
|
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));
|
CHECK_NE(-1, close(fd));
|
||||||
ResetCpu(m);
|
ResetCpu(m);
|
||||||
Write64(m->sp, 0x800000000000);
|
Write64(m->sp, 0x0000800000000000);
|
||||||
RegisterMemory(m, 0x800000000000 - stacksize, stack, stacksize);
|
RegisterMemory(m, 0x0000800000000000 - stacksize, stack, stacksize);
|
||||||
LoadArgv(m, prog, args, vars);
|
LoadArgv(m, prog, args, vars);
|
||||||
if (memcmp(code, "\177ELF", 4) == 0) {
|
if (memcmp(code, "\177ELF", 4) == 0) {
|
||||||
elf->ehdr = code;
|
elf->ehdr = code;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -60,7 +60,7 @@ struct Machine {
|
||||||
struct TlbEntry {
|
struct TlbEntry {
|
||||||
int64_t v;
|
int64_t v;
|
||||||
void *r;
|
void *r;
|
||||||
} tlb[4];
|
} tlb[16];
|
||||||
uint8_t *veg[2 * 8];
|
uint8_t *veg[2 * 8];
|
||||||
uint8_t *beg[2 * 2 * 8];
|
uint8_t *beg[2 * 2 * 8];
|
||||||
struct MachineFpu {
|
struct MachineFpu {
|
||||||
|
|
|
@ -52,6 +52,40 @@ static uint64_t *GetPageTable(pml4t_t p, long i, void *NewPhysicalPage(void)) {
|
||||||
return res;
|
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.
|
* 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();
|
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.
|
* Unmaps pages and frees page tables.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,7 +13,7 @@ typedef uint64_t pml4t_t[512] aligned(4096);
|
||||||
int FreePml4t(pml4t_t, int64_t, uint64_t, void (*)(void *),
|
int FreePml4t(pml4t_t, int64_t, uint64_t, void (*)(void *),
|
||||||
int (*)(void *, size_t));
|
int (*)(void *, size_t));
|
||||||
int RegisterPml4t(pml4t_t, int64_t, int64_t, size_t, void *(*)(void));
|
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;
|
char *FormatPml4t(pml4t_t) nodiscard;
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
|
|
|
@ -68,10 +68,6 @@ static void ResetTlb(struct Machine *m) {
|
||||||
memset(m->tlb, 0, sizeof(m->tlb));
|
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) {
|
void ResetCpu(struct Machine *m) {
|
||||||
m->codevirt = 0;
|
m->codevirt = 0;
|
||||||
m->codereal = NULL;
|
m->codereal = NULL;
|
||||||
|
@ -96,5 +92,4 @@ void ResetCpu(struct Machine *m) {
|
||||||
ResetTlb(m);
|
ResetTlb(m);
|
||||||
ResetSse(m);
|
ResetSse(m);
|
||||||
ResetFpu(m);
|
ResetFpu(m);
|
||||||
ResetMem(m);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 OpString(struct Machine *m, uint32_t rde, int op) {
|
||||||
void *p[2];
|
void *p[2];
|
||||||
|
unsigned n;
|
||||||
|
uint64_t asz;
|
||||||
bool compare;
|
bool compare;
|
||||||
int64_t sgn, v;
|
int64_t sgn, v;
|
||||||
uint8_t s[3][8];
|
uint8_t s[3][8];
|
||||||
unsigned n, lg2;
|
|
||||||
uint64_t asz, seg;
|
|
||||||
sgn = GetFlag(m->flags, FLAGS_DF) ? -1 : 1;
|
sgn = GetFlag(m->flags, FLAGS_DF) ? -1 : 1;
|
||||||
asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff;
|
asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff;
|
||||||
seg = GetSegment(m);
|
n = 1 << RegLog2(rde);
|
||||||
lg2 = RegLog2(rde);
|
|
||||||
n = 1 << lg2;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (Rep(rde) && !Read64(m->cx)) break;
|
if (Rep(rde) && !Read64(m->cx)) break;
|
||||||
v = 0;
|
v = 0;
|
||||||
|
@ -84,16 +82,18 @@ void OpString(struct Machine *m, uint32_t rde, int op) {
|
||||||
compare = false;
|
compare = false;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case STRING_CMPS:
|
case STRING_CMPS:
|
||||||
Alu(lg2, ALU_SUB,
|
Alu(RegLog2(rde), ALU_SUB,
|
||||||
ReadInt(Load(m, (Read64(m->si) + seg) & asz, n, s[2]), lg2),
|
ReadInt(Load(m, (Read64(m->si) + GetSegment(m)) & asz, n, s[2]),
|
||||||
ReadInt(Load(m, Read64(m->di) & asz, n, s[1]), lg2), &m->flags);
|
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->di, (Read64(m->di) + sgn * n) & asz);
|
||||||
Write64(m->si, (Read64(m->si) + sgn * n) & asz);
|
Write64(m->si, (Read64(m->si) + sgn * n) & asz);
|
||||||
compare = true;
|
compare = true;
|
||||||
break;
|
break;
|
||||||
case STRING_MOVS:
|
case STRING_MOVS:
|
||||||
memcpy(BeginStore(m, (v = Read64(m->di) & asz), n, p, s[0]),
|
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->di, (Read64(m->di) + sgn * n) & asz);
|
||||||
Write64(m->si, (Read64(m->si) + sgn * n) & asz);
|
Write64(m->si, (Read64(m->si) + sgn * n) & asz);
|
||||||
break;
|
break;
|
||||||
|
@ -102,23 +102,26 @@ void OpString(struct Machine *m, uint32_t rde, int op) {
|
||||||
Write64(m->di, (Read64(m->di) + sgn * n) & asz);
|
Write64(m->di, (Read64(m->di) + sgn * n) & asz);
|
||||||
break;
|
break;
|
||||||
case STRING_LODS:
|
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);
|
Write64(m->si, (Read64(m->si) + sgn * n) & asz);
|
||||||
break;
|
break;
|
||||||
case STRING_SCAS:
|
case STRING_SCAS:
|
||||||
Alu(lg2, ALU_SUB, ReadInt(Load(m, Read64(m->di) & asz, n, s[1]), lg2),
|
Alu(RegLog2(rde), ALU_SUB,
|
||||||
ReadInt(m->ax, lg2), &m->flags);
|
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);
|
Write64(m->di, (Read64(m->di) + sgn * n) & asz);
|
||||||
compare = true;
|
compare = true;
|
||||||
break;
|
break;
|
||||||
case STRING_OUTS:
|
case STRING_OUTS:
|
||||||
OpOut(m, Read16(m->dx),
|
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);
|
Write64(m->si, (Read64(m->si) + sgn * n) & asz);
|
||||||
break;
|
break;
|
||||||
case STRING_INS:
|
case STRING_INS:
|
||||||
WriteInt(BeginStore(m, (v = Read64(m->di) & asz), n, p, s[0]),
|
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);
|
Write64(m->di, (Read64(m->di) + sgn * n) & asz);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -138,19 +141,18 @@ void OpRepMovsbEnhanced(struct Machine *m, uint32_t rde) {
|
||||||
bool failed;
|
bool failed;
|
||||||
uint8_t *direal, *sireal;
|
uint8_t *direal, *sireal;
|
||||||
unsigned diremain, siremain, i, n;
|
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;
|
if (!(cx = Read64(m->cx))) return;
|
||||||
failed = false;
|
failed = false;
|
||||||
failaddr = 0;
|
failaddr = 0;
|
||||||
seg = GetSegment(m);
|
|
||||||
asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff;
|
asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff;
|
||||||
divirtual = Read64(m->di) & asz;
|
divirtual = Read64(m->di) & asz;
|
||||||
sivirtual = Read64(m->si) & asz;
|
sivirtual = Read64(m->si) & asz;
|
||||||
SetWriteAddr(m, (seg + divirtual) & asz, cx);
|
SetWriteAddr(m, (GetSegment(m) + divirtual) & asz, cx);
|
||||||
SetReadAddr(m, (seg + sivirtual) & asz, cx);
|
SetReadAddr(m, (GetSegment(m) + sivirtual) & asz, cx);
|
||||||
do {
|
do {
|
||||||
diactual = (seg + divirtual) & asz;
|
diactual = (GetSegment(m) + divirtual) & asz;
|
||||||
siactual = (seg + sivirtual) & asz;
|
siactual = (GetSegment(m) + sivirtual) & asz;
|
||||||
if (!(direal = FindReal(m, diactual))) {
|
if (!(direal = FindReal(m, diactual))) {
|
||||||
failaddr = diactual;
|
failaddr = diactual;
|
||||||
failed = true;
|
failed = true;
|
||||||
|
@ -181,17 +183,16 @@ void OpRepStosbEnhanced(struct Machine *m, uint32_t rde) {
|
||||||
bool failed;
|
bool failed;
|
||||||
uint8_t *direal, al;
|
uint8_t *direal, al;
|
||||||
unsigned diremain, i, n;
|
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;
|
if (!(cx = Read64(m->cx))) return;
|
||||||
failaddr = 0;
|
failaddr = 0;
|
||||||
failed = false;
|
failed = false;
|
||||||
al = Read8(m->ax);
|
al = Read8(m->ax);
|
||||||
seg = GetSegment(m);
|
|
||||||
asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff;
|
asz = Asz(rde) ? 0xffffffff : 0xffffffffffffffff;
|
||||||
divirtual = Read64(m->di) & asz;
|
divirtual = Read64(m->di) & asz;
|
||||||
SetWriteAddr(m, (seg + divirtual) & asz, cx);
|
SetWriteAddr(m, (GetSegment(m) + divirtual) & asz, cx);
|
||||||
do {
|
do {
|
||||||
diactual = (seg + divirtual) & asz;
|
diactual = (GetSegment(m) + divirtual) & asz;
|
||||||
if (!(direal = FindReal(m, diactual))) {
|
if (!(direal = FindReal(m, diactual))) {
|
||||||
failaddr = diactual;
|
failaddr = diactual;
|
||||||
failed = true;
|
failed = true;
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
#define P(x) ((x) ? PNN(x) : 0)
|
#define P(x) ((x) ? PNN(x) : 0)
|
||||||
#define ASSIGN(D, S) memcpy(&D, &S, MIN(sizeof(S), sizeof(D)))
|
#define ASSIGN(D, S) memcpy(&D, &S, MIN(sizeof(S), sizeof(D)))
|
||||||
|
|
||||||
static const struct MachineFdCb kMachineFdCbHost = {
|
const struct MachineFdCb kMachineFdCbHost = {
|
||||||
.close = close,
|
.close = close,
|
||||||
.read = read,
|
.read = read,
|
||||||
.write = write,
|
.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 (real == MAP_FAILED) return -1;
|
||||||
if (!(flags & MAP_FIXED)) {
|
if (!(flags & MAP_FIXED)) {
|
||||||
if (0 <= virt && virt < 0x400000) virt = 0x400000;
|
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));
|
CHECK_NE(-1, RegisterMemory(m, virt, real, size));
|
||||||
return virt;
|
return virt;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue