Fix bugs and have emulator emulate itself

main
Justine Tunney 2020-08-31 05:17:31 -07:00
parent 5aabacb361
commit bd29223891
111 changed files with 1283 additions and 2073 deletions

View File

@ -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 "$@"

View File

@ -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

View File

@ -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)

View File

@ -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 &&

View File

@ -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.

View File

@ -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);
}

View File

@ -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) */

View File

@ -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);
}

View File

@ -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) */

View File

@ -1,6 +1,5 @@
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
#define COSMOPOLITAN_LIBC_LOG_LOG_H_
#include "libc/dce.h"
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § liblog
*/

View File

@ -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
*/

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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_
/*───────────────────────────────────────────────────────────────────────────│─╗

View File

@ -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_
/*───────────────────────────────────────────────────────────────────────────│─╗

View File

@ -46,7 +46,7 @@ tinymath_acosl:
fsqrt
fabs # needed in downward rounding mode
#endif
fxch %st(1)
fxch
fpatan
pop %rbp
ret

View File

@ -51,5 +51,4 @@ tinymath_asinl:
.alias tinymath_asinl,asinl
.rodata.cst4
.align 4
.Lone: .float 1.0

View File

@ -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

View File

@ -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

View File

@ -34,7 +34,7 @@ tinymath_exp10l:
fld %st
frndint
fsubr %st,%st(1)
fxch %st(1)
fxch
f2xm1
fld1
faddp

View File

@ -32,7 +32,7 @@ tinymath_exp2l:
fld %st
frndint
fsubr %st,%st(1)
fxch %st(1)
fxch
f2xm1
fadds .Lone(%rip)
fscale

View File

@ -34,7 +34,7 @@ tinymath_expl:
fld %st
frndint
fsubr %st,%st(1)
fxch %st(1)
fxch
f2xm1
fld1
faddp

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -19,7 +19,7 @@
*/
#include "libc/macros.h"
/ Returns log exponent part of float.
/ Returns logx exponent part of float.
/
/ @param 𝑥 is float passed in %xmm0
/ @return result in %eax

View File

@ -19,7 +19,7 @@
*/
#include "libc/macros.h"
/ Returns log exponent part of long double.
/ Returns logx exponent part of long double.
/
/ @param 𝑥 is long double passed on stack
/ @return result in %eax

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -39,7 +39,7 @@ tinymath_powl:
f2xm1
faddp
fscale
fxch %st(1)
fxch
fstp %st
pop %rbp
ret

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -34,7 +34,7 @@ tinymath_sincos:
movsd %xmm0,-8(%rbp)
fldl -8(%rbp)
fsincos
fxch %st(1)
fxch
fstpl (%rdi)
fstpl (%rsi)
leave

View File

@ -34,7 +34,7 @@ tinymath_sincosf:
movss %xmm0,4(%rsp)
flds 4(%rsp)
fsincos
fxch %st(1)
fxch
fstps (%rdi)
fstps (%rsi)
leave

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 := \

View File

@ -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));

View File

@ -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};

View File

@ -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))));
}

View File

@ -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) {

View File

@ -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"

View File

@ -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

View File

@ -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];

View File

@ -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")

View File

@ -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;

View File

@ -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)

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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))

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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"

View File

@ -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"

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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 {

View File

@ -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.
*/

View File

@ -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_

View File

@ -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);
}

View File

@ -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;

View File

@ -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