Add x86_64-linux-gnu emulator

I wanted a tiny scriptable meltdown proof way to run userspace programs
and visualize how program execution impacts memory. It helps to explain
how things like Actually Portable Executable works. It can show you how
the GCC generated code is going about manipulating matrices and more. I
didn't feel fully comfortable with Qemu and Bochs because I'm not smart
enough to understand them. I wanted something like gVisor but with much
stronger levels of assurances. I wanted a single binary that'll run, on
all major operating systems with an embedded GPL barrier ZIP filesystem
that is tiny enough to transpile to JavaScript and run in browsers too.

https://justine.storage.googleapis.com/emulator625.mp4
This commit is contained in:
Justine Tunney 2020-08-25 04:23:25 -07:00
parent 467504308a
commit f4f4caab0e
1052 changed files with 65667 additions and 7825 deletions

View file

@ -38,9 +38,9 @@ c2rangr:push %rbp
ret
1: fldpi
fadd %st
fxch %st(1)
fxch
2: fprem1
fnstsw %ax
fnstsw
test $FPU_C2>>8,%ah
jnz 2b
fstp %st(1)

View file

@ -1,4 +1,4 @@
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
/*-*- 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
@ -27,3 +27,4 @@ tinymath_cbrt:
jmp __cbrt
.endfn tinymath_cbrt,globl
.alias tinymath_cbrt,cbrt
.source __FILE__

View file

@ -1,4 +1,4 @@
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
/*-*- 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
@ -33,3 +33,4 @@ tinymath_cbrtf:
ret
.endfn tinymath_cbrtf,globl
.alias tinymath_cbrtf,cbrtf
.source __FILE__

View file

@ -1,4 +1,4 @@
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
/*-*- 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
@ -37,3 +37,4 @@ tinymath_cbrtl:
ret
.endfn tinymath_cbrtl,globl
.alias tinymath_cbrtl,cbrtl
.source __FILE__

View file

@ -26,7 +26,7 @@ tinymath_copysignl:
.profilable
fldt 32(%rbp)
fxam
fnstsw %ax
fnstsw
fstp %st
fldt 16(%rbp)
testb $2,%ah

View file

@ -20,39 +20,22 @@
#include "libc/macros.h"
.source __FILE__
/ Projects into Rienmann sphere.
/
/ @param z is complex long double passed on stack
/ @note needs sse3
tinymath_cprojl:
.profilable
sub $24,%rsp
fldt 32(%rsp)
fnstcw 14(%rsp)
movzwl 14(%rsp),%eax
orb $12,%ah
movw %ax,12(%rsp)
fldcw 12(%rsp)
fistpq (%rsp)
fldcw 14(%rsp)
movq (%rsp),%rsi
fisttpq 8(%rsp)
fldt 48(%rsp)
movq 8(%rsp),%rsi
mov %rsi,%rax
fldcw 12(%rsp)
fistpq (%rsp)
fldcw 14(%rsp)
movq (%rsp),%rcx
fisttpq 8(%rsp)
mov 8(%rsp),%rcx
add $24,%rsp
mov %rcx,%rdx
ret
.endfn tinymath_cprojl,globl
.alias tinymath_cprojl,cprojl
/ TODO(jart):
/ sub $24,%rsp
/ fldt 32(%rsp)
/ fisttpq 8(%rsp)
/ fldt 48(%rsp)
/ movq 8(%rsp),%rsi
/ mov %rsi,%rax
/ fisttpq 8(%rsp)
/ movq 8(%rsp),%rcx
/ add $24,%rsp
/ mov %rcx,%rdx
/ ret

View file

@ -24,6 +24,8 @@
/
/ @param 𝑥 is a double passed in the lower quadword of %xmm0
/ @return result in lower quadword of %xmm0
exp2: ezlea exp2l,ax
tinymath_exp2:
ezlea tinymath_exp2l,ax
jmp _d2ld2
.endfn exp2,globl
.endfn tinymath_exp2,globl
.alias tinymath_exp2,exp2

View file

@ -20,6 +20,12 @@
#include "libc/macros.h"
.source __FILE__
exp2f: ezlea exp2f,ax
/ Returns 2^𝑥.
/
/ @param 𝑥 is a float passed in the lower quarter of %xmm0
/ @return result in lower quarter of %xmm0
tinymath_exp2f:
ezlea tinymath_exp2l,ax
jmp _f2ld2
.endfn exp2f,globl
.endfn tinymath_exp2f,globl
.alias tinymath_exp2f,exp2f

View file

@ -20,8 +20,12 @@
#include "libc/macros.h"
.source __FILE__
/ Returns 2^x.
exp2l: push %rbp
/ Returns 2^𝑥.
/
/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
/ @return result of exponentiation on FPU stack in %st
tinymath_exp2l:
push %rbp
mov %rsp,%rbp
.profilable
fldt 16(%rbp)
@ -35,7 +39,8 @@ exp2l: push %rbp
fstp %st(1)
pop %rbp
ret
.endfn exp2l,globl
.endfn tinymath_exp2l,globl
.alias tinymath_exp2l,exp2l
.rodata.cst4
.Lone: .float 1.0

View file

@ -20,6 +20,12 @@
#include "libc/macros.h"
.source __FILE__
expm1: ezlea expm1l,ax
/ Returns 𝑒^x-1.
/
/ @param 𝑥 is double scalar in low half of %xmm0
/ @return double scalar in low half of %xmm0
tinymath_expm1:
ezlea tinymath_expm1l,ax
jmp _d2ld2
.endfn expm1,globl
.endfn tinymath_expm1,globl
.alias tinymath_expm1,expm1

View file

@ -20,6 +20,12 @@
#include "libc/macros.h"
.source __FILE__
expm1f: ezlea expm1l,ax
/ Returns 𝑒^x-1.
/
/ @param 𝑥 is float scalar in low quarter of %xmm0
/ @return float scalar in low quarter of %xmm0
tinymath_expm1f:
ezlea tinymath_expm1l,ax
jmp _f2ld2
.endfn expm1f,globl
.endfn tinymath_expm1f,globl
.alias tinymath_expm1f,expm1f

View file

@ -20,8 +20,12 @@
#include "libc/macros.h"
.source __FILE__
/ Returns exp(𝑥) - 1.
expm1l: push %rbp
/ Returns 𝑒^x-1.
/
/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
/ @return result of exponentiation on FPU stack in %st
tinymath_expm1l:
push %rbp
mov %rsp,%rbp
.profilable
fldt 16(%rbp)
@ -41,7 +45,8 @@ expm1l: push %rbp
faddp %st,%st(1)
pop %rbp
ret
.endfn expm1l,globl
.endfn tinymath_expm1l,globl
.alias tinymath_expm1l,expm1l
.rodata.cst4
.Lone: .float 1.0

View file

@ -18,7 +18,6 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
/ Thunks float(*fn)(float,float) -> long double fn.
/
@ -41,3 +40,4 @@ _f2ld2: push %rbp
leave
ret
.endfn _f2ld2,globl,hidden
.source __FILE__

View file

@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "ape/lib/pc.h"
#include "libc/macros.h"
.source __FILE__
@ -27,8 +28,8 @@ tinymath_fmodl:
fldt 32(%rbp)
fldt 16(%rbp)
1: fprem
fnstsw %ax
testb $4,%ah
fnstsw
test $FPU_C2>>8,%ah
jnz 1b
fstp %st(1)
pop %rbp

View file

@ -18,10 +18,25 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
/ Returns log exponent part of double.
/
/ @param 𝑥 is double passed in %xmm0
/ @return result in %eax
/ @note needs sse3
tinymath_ilogb:
ezlea tinymath_ilogbl,ax
jmp _d2ld2
push %rbp
mov %rsp,%rbp
.profilable
push %rax
movsd %xmm0,(%rsp)
fldl (%rsp)
fxtract
fstp %st
fisttpl (%rsp)
mov (%rsp),%eax
leave
ret
.endfn tinymath_ilogb,globl
.alias tinymath_ilogb,ilogb
.source __FILE__

View file

@ -18,10 +18,25 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
/ Returns log exponent part of float.
/
/ @param 𝑥 is float passed in %xmm0
/ @return result in %eax
/ @note needs sse3
tinymath_ilogbf:
ezlea tinymath_ilogbl,ax
jmp _f2ld2
push %rbp
mov %rsp,%rbp
.profilable
push %rax
movss %xmm0,(%rsp)
flds (%rsp)
fxtract
fstp %st
fisttpl (%rsp)
mov (%rsp),%eax
leave
ret
.endfn tinymath_ilogbf,globl
.alias tinymath_ilogbf,ilogbf
.source __FILE__

View file

@ -18,38 +18,24 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
/ Returns log exponent part of long double.
/
/ @param 𝑥 is long double passed on stack
/ @return result in %eax
/ @note needs sse3
tinymath_ilogbl:
push %rbp
mov %rsp,%rbp
.profilable
sub $24,%rsp
fldt 32(%rsp)
fnstcw 14(%rsp)
movzwl 14(%rsp),%eax
orb $12,%ah
movw %ax,12(%rsp)
fldt 16(%rbp)
fxtract
fstp %st
fldcw 12(%rsp)
fistpl 8(%rsp)
fldcw 14(%rsp)
movl 8(%rsp),%eax
add $24,%rsp
push %rax
fisttpl (%rsp)
mov (%rsp),%eax
leave
ret
.endfn tinymath_ilogbl,globl
.alias tinymath_ilogbl,ilogbl
/*
TODO(jart)
.globl ilogbl
.type ilogbl,@function
ilogbl: sub $24,%rsp
fldt 32(%rsp)
fxtract
fstp %st
fisttpl 12(%rsp)
movl 12(%rsp),%eax
add $24,%rsp
ret
.size ilogbl,.-ilogbl
*/
.source __FILE__

View file

@ -20,7 +20,12 @@
#include "libc/macros.h"
.source __FILE__
log1p: push %rbp
/ Returns log(𝟷+𝑥).
/
/ @param 𝑥 is double scalar in low half of %xmm0
/ @return double scalar in low half of %xmm0
tinymath_log1p:
push %rbp
mov %rsp,%rbp
.profilable
push %rax
@ -48,12 +53,11 @@ log1p: push %rbp
fstpl (%rsp)
vmovsd (%rsp),%xmm0
jmp 0b
.endfn log1p,globl
.endfn tinymath_log1p,globl
.alias tinymath_log1p,log1p
.section .rodata.cst16,"aM",@progbits,16
.align 16
.rodata.cst16
.LC16: .long 205731576
.long 2515933592
.long 16381
.long 0
.previous

View file

@ -20,7 +20,12 @@
#include "libc/macros.h"
.source __FILE__
log1pf: push %rbp
/ Returns log(𝟷+𝑥).
/
/ @param 𝑥 is float scalar in low quarter of %xmm0
/ @return float scalar in low quarter of %xmm0
tinymath_log1pf:
push %rbp
mov %rsp,%rbp
.profilable
push %rax
@ -46,12 +51,11 @@ log1pf: push %rbp
fxch %st(1)
fyl2x
jmp 1b
.endfn log1pf,globl
.endfn tinymath_log1pf,globl
.alias tinymath_log1pf,log1pf
.section .rodata.cst16,"aM",@progbits,16
.align 16
.rodata.cst16
.LC16: .long 205731576
.long 2515933592
.long 16381
.long 0
.previous

View file

@ -20,7 +20,12 @@
#include "libc/macros.h"
.source __FILE__
log1pl: push %rbp
/ Returns log(𝟷+𝑥).
/
/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
/ @return result of exponentiation on FPU stack in %st
tinymath_log1pl:
push %rbp
mov %rsp,%rbp
.profilable
fldt 16(%rbp)
@ -42,12 +47,11 @@ log1pl: push %rbp
fxch %st(1)
fyl2x
jmp 0b
.endfn log1pl,globl
.endfn tinymath_log1pl,globl
.alias tinymath_log1pl,log1pl
.section .rodata.cst16,"aM",@progbits,16
.align 16
.rodata.cst16
.LC16: .long 205731576
.long 2515933592
.long 16381
.long 0
.previous

View file

@ -24,6 +24,7 @@
/
/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
/ @return result in %st
/ @see ilogbl()
log2l: push %rbp
mov %rsp,%rbp
.profilable

View file

@ -18,18 +18,14 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
logb: push %rbp
mov %rsp,%rbp
.profilable
push %rax
movsd %xmm0,(%rsp)
fldl (%rsp)
fxtract
fstp %st
fstpl (%rsp)
movsd (%rsp),%xmm0
leave
ret
.endfn logb,globl
/ Returns log exponent part of double.
/
/ @param 𝑥 is double passed in %xmm0
/ @return result in %xmm0
tinymath_logb:
ezlea tinymath_logbl,ax
jmp _d2ld2
.endfn tinymath_logb,globl
.alias tinymath_logb,logb
.source __FILE__

View file

@ -18,18 +18,14 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
logbf: push %rbp
mov %rsp,%rbp
.profilable
push %rax
movss %xmm0,-4(%rbp)
flds -4(%rbp)
fxtract
fstp %st
fstps -4(%rbp)
movss -4(%rbp),%xmm0
leave
ret
.endfn logbf,globl
/ Returns log exponent part of float.
/
/ @param 𝑥 is float passed in %xmm0
/ @return result in %xmm0
tinymath_logbf:
ezlea tinymath_logbl,ax
jmp _f2ld2
.endfn tinymath_logbf,globl
.alias tinymath_logbf,logbf
.source __FILE__

View file

@ -18,9 +18,13 @@
02110-1301 USA
*/
#include "libc/macros.h"
.source __FILE__
logbl: push %rbp
/ Returns log exponent part of long double.
/
/ @param 𝑥 is long double passed on stack
/ @return result in %st0
tinymath_logbl:
push %rbp
mov %rsp,%rbp
.profilable
fldt 16(%rbp)
@ -28,4 +32,6 @@ logbl: push %rbp
fstp %st
pop %rbp
ret
.endfn logbl,globl
.endfn tinymath_logbl,globl
.alias tinymath_logbl,logbl
.source __FILE__

View file

@ -34,7 +34,7 @@ tinymath_lroundl:
or $0b00000100,%dh # -
mov %dx,-4(%rbp)
fxam
fnstsw %ax
fnstsw
fabs
test $FPU_C1>>8,%ah
fadds .Lhalf(%rip)

View file

@ -28,9 +28,9 @@ tinymath_remainderl:
fldt 32(%rbp)
fldt 16(%rbp)
1: fprem1
fnstsw %ax
fnstsw
test $FPU_C2>>8,%ah
jne 1b
jnz 1b
fstp %st(1)
pop %rbp
ret

View file

@ -19,8 +19,11 @@
*/
#include "ape/lib/pc.h"
#include "libc/macros.h"
.source __FILE__
/ Rounds to nearest integer, away from zero.
/
/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
/ @return result of exponentiation on FPU stack in %st
tinymath_roundl:
push %rbp
mov %rsp,%rbp
@ -30,10 +33,10 @@ tinymath_roundl:
fnstcw -8(%rbp)
movzwl -8(%rbp),%edx
and $0b11110011,%dh # RC (Rounding Control)
or $0b00000100,%dh # -
or $0b00000100,%dh # - a.k.a. floor()
mov %dx,-4(%rbp)
fxam
fnstsw %ax
fxam # C1 is set to sign bit
fnstsw
fabs
test $FPU_C1>>8,%ah
fadds .Lhalf(%rip)
@ -46,6 +49,7 @@ tinymath_roundl:
ret
.endfn tinymath_roundl,globl
.alias tinymath_roundl,roundl
.source __FILE__
.rodata.cst4
.Lhalf: .float .5

View file

@ -20,16 +20,21 @@
#include "libc/macros.h"
.source __FILE__
tinymath_scalbnl:
tinymath_scalbnf:
push %rbp
mov %rsp,%rbp
.profilable
sub $24,%rsp
fldt 32(%rsp)
movl %edi,12(%rsp)
fildl 12(%rsp)
push %rax
movss %xmm0,-4(%rbp)
flds -4(%rbp)
movl %edi,-4(%rbp)
fildl -4(%rbp)
fxch %st(1)
add $24,%rsp
fscale
fstp %st(1)
fstps -4(%rbp)
movss -4(%rbp),%xmm0
leave
ret
.endfn tinymath_scalbnl,globl
.alias tinymath_scalbnl,scalbnl
.endfn tinymath_scalbnf,globl
.alias tinymath_scalbnf,scalbnf

View file

@ -20,21 +20,22 @@
#include "libc/macros.h"
.source __FILE__
tinymath_scalbnf:
/ Returns 𝑥 × 𝑟ʸ where 𝑟 is radix of hardware architecture.
/
/ @param 𝑥 is long double passed on stack
/ @param 𝑦 is exponent via %edi
/ @see FLT_RADIX
tinymath_scalbnl:
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)
fldt 16(%rsp)
push %rdi
fildl (%rsp)
fxch
fscale
fstp %st(1)
fstps -4(%rbp)
movss -4(%rbp),%xmm0
leave
ret
.endfn tinymath_scalbnf,globl
.alias tinymath_scalbnf,scalbnf
.endfn tinymath_scalbnl,globl
.alias tinymath_scalbnl,scalbnl

View file

@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "ape/lib/pc.h"
#include "libc/macros.h"
.source __FILE__
@ -31,10 +32,22 @@ tinymath_sincosl:
mov %rsp,%rbp
.profilable
fldt 16(%rbp)
fsincos
0: fsincos
fstsw
test $FPU_C2>>8,%ah
jnz 1f
fstpt (%rsi)
fstpt (%rdi)
pop %rbp
ret
1: fldpi
fadd %st
fxch
2: fprem1
fnstsw
test $FPU_C2>>8,%ah
jnz 2b
fstp %st(1)
jmp 0b
.endfn tinymath_sincosl,globl
.alias tinymath_sincosl,sincosl

View file

@ -26,7 +26,7 @@ tinymath_truncl:
fldt 32(%rsp)
fnstcw 14(%rsp)
movzwl 14(%rsp),%eax
or $12,%ah
or $0b1100,%ah # round to zero
mov %ax,12(%rsp)
fldcw 12(%rsp)
frndint