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