Add 'lib/runtime/' from commit 'db5cddbec10c4b7c086eda716d48d4711632901f'
git-subtree-dir: lib/runtime git-subtree-mainline: 566a2341f5b726d86f5d42a72beb9c70b83f31b6 git-subtree-split: db5cddbec10c4b7c086eda716d48d4711632901f
This commit is contained in:
commit
7a0d528cda
2
lib/runtime/.gitignore
vendored
Normal file
2
lib/runtime/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Cargo.lock
|
32
lib/runtime/Cargo.toml
Normal file
32
lib/runtime/Cargo.toml
Normal file
@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "yggdrasil-rt"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
|
||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
||||
compiler_builtins = { version = "0.1", optional = true }
|
||||
|
||||
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
|
||||
[build-dependencies]
|
||||
abi-generator = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
yggdrasil-abi-def = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi-def.git" }
|
||||
prettyplease = "0.2.15"
|
||||
cc = "*"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
alloc = ["dep:alloc", "yggdrasil-abi/alloc"]
|
||||
rustc-dep-of-std = [
|
||||
"core",
|
||||
"alloc",
|
||||
"compiler_builtins/rustc-dep-of-std",
|
||||
"yggdrasil-abi/rustc-dep-of-std",
|
||||
"abi-lib/rustc-dep-of-std"
|
||||
]
|
65
lib/runtime/build.rs
Normal file
65
lib/runtime/build.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use abi_generator::{
|
||||
abi::{ty::TypeWidth, AbiBuilder},
|
||||
syntax::UnwrapFancy,
|
||||
TargetEnv,
|
||||
};
|
||||
|
||||
fn add_file<'a>(build: &'a mut cc::Build, name: &'a str) -> &'a mut cc::Build {
|
||||
println!("cargo:rerun-if-changed={}", name);
|
||||
build.file(name)
|
||||
}
|
||||
|
||||
fn build_libm() {
|
||||
println!("cargo:rerun-if-changed=libm/private.h");
|
||||
|
||||
let mut build = cc::Build::new();
|
||||
|
||||
build
|
||||
.compiler("clang")
|
||||
.flag("-ffreestanding")
|
||||
.flag("-nostdlib");
|
||||
|
||||
add_file(&mut build, "libm/s_truncf.c");
|
||||
add_file(&mut build, "libm/s_ceilf.c");
|
||||
add_file(&mut build, "libm/s_floorf.c");
|
||||
add_file(&mut build, "libm/s_fabsf.c");
|
||||
add_file(&mut build, "libm/s_scalbnf.c");
|
||||
add_file(&mut build, "libm/s_copysignf.c");
|
||||
add_file(&mut build, "libm/e_powf.c");
|
||||
add_file(&mut build, "libm/e_sqrtf.c");
|
||||
add_file(&mut build, "libm/e_hypotf.c");
|
||||
add_file(&mut build, "libm/e_fmodf.c");
|
||||
add_file(&mut build, "libm/w_powf.c");
|
||||
add_file(&mut build, "libm/w_hypotf.c");
|
||||
add_file(&mut build, "libm/w_fmodf.c");
|
||||
|
||||
build.compile("m");
|
||||
}
|
||||
|
||||
fn generate_abi() {
|
||||
let output_dir = std::env::var("OUT_DIR").expect("$OUT_DIR not set");
|
||||
let generated_calls = Path::new(&output_dir).join("generated_calls.rs");
|
||||
|
||||
let abi = AbiBuilder::from_string(
|
||||
yggdrasil_abi_def::ABI_FILE,
|
||||
TargetEnv {
|
||||
thin_pointer_width: TypeWidth::U64,
|
||||
fat_pointer_width: TypeWidth::U64,
|
||||
},
|
||||
)
|
||||
.unwrap_fancy("Could not parse/read ABI file");
|
||||
|
||||
let calls = prettyplease::unparse(
|
||||
&abi.emit_file(false, true)
|
||||
.unwrap_fancy("Could not emit system calls"),
|
||||
);
|
||||
|
||||
fs::write(generated_calls, calls).unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
build_libm();
|
||||
generate_abi();
|
||||
}
|
81
lib/runtime/libm/e_fmodf.c
Normal file
81
lib/runtime/libm/e_fmodf.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float one = 1.0, Zero[] = {0.0, -0.0,};
|
||||
|
||||
float
|
||||
__ieee754_fmodf(float x, float y)
|
||||
{
|
||||
int32_t n,hx,hy,hz,ix,iy,sx,i;
|
||||
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
GET_FLOAT_WORD(hy,y);
|
||||
sx = hx&0x80000000; /* sign of x */
|
||||
hx ^=sx; /* |x| */
|
||||
hy &= 0x7fffffff; /* |y| */
|
||||
|
||||
/* purge off exception values */
|
||||
if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */
|
||||
(hy>0x7f800000)) /* or y is NaN */
|
||||
return (x*y)/(x*y);
|
||||
if(hx<hy) return x; /* |x|<|y| return x */
|
||||
if(hx==hy)
|
||||
return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/
|
||||
|
||||
/* determine ix = ilogb(x) */
|
||||
if(hx<0x00800000) { /* subnormal x */
|
||||
for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
|
||||
} else ix = (hx>>23)-127;
|
||||
|
||||
/* determine iy = ilogb(y) */
|
||||
if(hy<0x00800000) { /* subnormal y */
|
||||
for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
|
||||
} else iy = (hy>>23)-127;
|
||||
|
||||
/* set up {hx,lx}, {hy,ly} and align y to x */
|
||||
if(ix >= -126)
|
||||
hx = 0x00800000|(0x007fffff&hx);
|
||||
else { /* subnormal x, shift x to normal */
|
||||
n = -126-ix;
|
||||
hx = hx<<n;
|
||||
}
|
||||
if(iy >= -126)
|
||||
hy = 0x00800000|(0x007fffff&hy);
|
||||
else { /* subnormal y, shift y to normal */
|
||||
n = -126-iy;
|
||||
hy = hy<<n;
|
||||
}
|
||||
|
||||
/* fix point fmod */
|
||||
n = ix - iy;
|
||||
while(n--) {
|
||||
hz=hx-hy;
|
||||
if(hz<0){hx = hx+hx;}
|
||||
else {
|
||||
if(hz==0) /* return sign(x)*0 */
|
||||
return Zero[(uint32_t)sx>>31];
|
||||
hx = hz+hz;
|
||||
}
|
||||
}
|
||||
hz=hx-hy;
|
||||
if(hz>=0) {hx=hz;}
|
||||
|
||||
/* convert back to floating value and restore the sign */
|
||||
if(hx==0) /* return sign(x)*0 */
|
||||
return Zero[(uint32_t)sx>>31];
|
||||
while(hx<0x00800000) { /* normalize x */
|
||||
hx = hx+hx;
|
||||
iy -= 1;
|
||||
}
|
||||
if(iy>= -126) { /* normalize output */
|
||||
hx = ((hx-0x00800000)|((iy+127)<<23));
|
||||
SET_FLOAT_WORD(x,hx|sx);
|
||||
} else { /* subnormal output */
|
||||
n = -126 - iy;
|
||||
hx >>= n;
|
||||
SET_FLOAT_WORD(x,hx|sx);
|
||||
x *= one; /* create necessary signal */
|
||||
}
|
||||
return x; /* exact output */
|
||||
}
|
65
lib/runtime/libm/e_hypotf.c
Normal file
65
lib/runtime/libm/e_hypotf.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
float
|
||||
__ieee754_hypotf(float x, float y)
|
||||
{
|
||||
float a=x,b=y,t1,t2,yy1,y2,w;
|
||||
int32_t j,k,ha,hb;
|
||||
|
||||
GET_FLOAT_WORD(ha,x);
|
||||
ha &= 0x7fffffff;
|
||||
GET_FLOAT_WORD(hb,y);
|
||||
hb &= 0x7fffffff;
|
||||
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
|
||||
SET_FLOAT_WORD(a,ha); /* a <- |a| */
|
||||
SET_FLOAT_WORD(b,hb); /* b <- |b| */
|
||||
if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
|
||||
k=0;
|
||||
if(ha > 0x58800000) { /* a>2**50 */
|
||||
if(ha >= 0x7f800000) { /* Inf or NaN */
|
||||
w = a+b; /* for sNaN */
|
||||
if(ha == 0x7f800000) w = a;
|
||||
if(hb == 0x7f800000) w = b;
|
||||
return w;
|
||||
}
|
||||
/* scale a and b by 2**-60 */
|
||||
ha -= 0x5d800000; hb -= 0x5d800000; k += 60;
|
||||
SET_FLOAT_WORD(a,ha);
|
||||
SET_FLOAT_WORD(b,hb);
|
||||
}
|
||||
if(hb < 0x26800000) { /* b < 2**-50 */
|
||||
if(hb <= 0x007fffff) { /* subnormal b or 0 */
|
||||
if(hb==0) return a;
|
||||
SET_FLOAT_WORD(t1,0x3f000000); /* t1=2^126 */
|
||||
b *= t1;
|
||||
a *= t1;
|
||||
k -= 126;
|
||||
} else { /* scale a and b by 2^60 */
|
||||
ha += 0x5d800000; /* a *= 2^60 */
|
||||
hb += 0x5d800000; /* b *= 2^60 */
|
||||
k -= 60;
|
||||
SET_FLOAT_WORD(a,ha);
|
||||
SET_FLOAT_WORD(b,hb);
|
||||
}
|
||||
}
|
||||
/* medium size a and b */
|
||||
w = a-b;
|
||||
if (w>b) {
|
||||
SET_FLOAT_WORD(t1,ha&0xfffff000);
|
||||
t2 = a-t1;
|
||||
w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
|
||||
} else {
|
||||
a = a+a;
|
||||
SET_FLOAT_WORD(yy1,hb&0xfffff000);
|
||||
y2 = b - yy1;
|
||||
SET_FLOAT_WORD(t1,ha+0x00800000);
|
||||
t2 = a - t1;
|
||||
w = __ieee754_sqrtf(t1*yy1-(w*(-w)-(t1*y2+t2*b)));
|
||||
}
|
||||
if(k!=0) {
|
||||
SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
|
||||
return t1*w;
|
||||
} else return w;
|
||||
}
|
227
lib/runtime/libm/e_powf.c
Normal file
227
lib/runtime/libm/e_powf.c
Normal file
@ -0,0 +1,227 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float huge = 1.0e+30, tiny = 1.0e-30;
|
||||
|
||||
static const float
|
||||
bp[] = {1.0, 1.5,},
|
||||
dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
|
||||
dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
|
||||
zero = 0.0,
|
||||
one = 1.0,
|
||||
two = 2.0,
|
||||
two24 = 16777216.0, /* 0x4b800000 */
|
||||
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
|
||||
L1 = 6.0000002384e-01, /* 0x3f19999a */
|
||||
L2 = 4.2857143283e-01, /* 0x3edb6db7 */
|
||||
L3 = 3.3333334327e-01, /* 0x3eaaaaab */
|
||||
L4 = 2.7272811532e-01, /* 0x3e8ba305 */
|
||||
L5 = 2.3066075146e-01, /* 0x3e6c3255 */
|
||||
L6 = 2.0697501302e-01, /* 0x3e53f142 */
|
||||
P1 = 1.6666667163e-01, /* 0x3e2aaaab */
|
||||
P2 = -2.7777778450e-03, /* 0xbb360b61 */
|
||||
P3 = 6.6137559770e-05, /* 0x388ab355 */
|
||||
P4 = -1.6533901999e-06, /* 0xb5ddea0e */
|
||||
P5 = 4.1381369442e-08, /* 0x3331bb4c */
|
||||
lg2 = 6.9314718246e-01, /* 0x3f317218 */
|
||||
lg2_h = 6.93145752e-01, /* 0x3f317200 */
|
||||
lg2_l = 1.42860654e-06, /* 0x35bfbe8c */
|
||||
ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
|
||||
cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
|
||||
cp_h = 9.6179199219e-01, /* 0x3f763800 =head of cp */
|
||||
cp_l = 4.7017383622e-06, /* 0x369dc3a0 =tail of cp_h */
|
||||
ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
|
||||
ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
|
||||
ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
|
||||
|
||||
float
|
||||
__ieee754_powf(float x, float y)
|
||||
{
|
||||
float z,ax,z_h,z_l,p_h,p_l;
|
||||
float yy1,t1,t2,r,s,t,u,v,w;
|
||||
int32_t i,j,k,yisint,n;
|
||||
int32_t hx,hy,ix,iy,is;
|
||||
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
GET_FLOAT_WORD(hy,y);
|
||||
ix = hx&0x7fffffff; iy = hy&0x7fffffff;
|
||||
|
||||
/* y==zero: x**0 = 1 */
|
||||
if(iy==0) return one;
|
||||
|
||||
/* +-NaN return x+y */
|
||||
if(ix > 0x7f800000 ||
|
||||
iy > 0x7f800000)
|
||||
return x+y;
|
||||
|
||||
/* determine if y is an odd int when x < 0
|
||||
* yisint = 0 ... y is not an integer
|
||||
* yisint = 1 ... y is an odd int
|
||||
* yisint = 2 ... y is an even int
|
||||
*/
|
||||
yisint = 0;
|
||||
if(hx<0) {
|
||||
if(iy>=0x4b800000) yisint = 2; /* even integer y */
|
||||
else if(iy>=0x3f800000) {
|
||||
k = (iy>>23)-0x7f; /* exponent */
|
||||
j = iy>>(23-k);
|
||||
if((j<<(23-k))==iy) yisint = 2-(j&1);
|
||||
}
|
||||
}
|
||||
|
||||
/* special value of y */
|
||||
if (iy==0x7f800000) { /* y is +-inf */
|
||||
if (ix==0x3f800000)
|
||||
return y - y; /* inf**+-1 is NaN */
|
||||
else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
|
||||
return (hy>=0)? y: zero;
|
||||
else /* (|x|<1)**-,+inf = inf,0 */
|
||||
return (hy<0)?-y: zero;
|
||||
}
|
||||
if(iy==0x3f800000) { /* y is +-1 */
|
||||
if(hy<0) return one/x; else return x;
|
||||
}
|
||||
if(hy==0x40000000) return x*x; /* y is 2 */
|
||||
if(hy==0x3f000000) { /* y is 0.5 */
|
||||
if(hx>=0) /* x >= +0 */
|
||||
return __ieee754_sqrtf(x);
|
||||
}
|
||||
|
||||
ax = fabsf(x);
|
||||
/* special value of x */
|
||||
if(ix==0x7f800000||ix==0||ix==0x3f800000){
|
||||
z = ax; /*x is +-0,+-inf,+-1*/
|
||||
if(hy<0) z = one/z; /* z = (1/|x|) */
|
||||
if(hx<0) {
|
||||
if(((ix-0x3f800000)|yisint)==0) {
|
||||
z = (z-z)/(z-z); /* (-1)**non-int is NaN */
|
||||
} else if(yisint==1)
|
||||
z = -z; /* (x<0)**odd = -(|x|**odd) */
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
/* (x<0)**(non-int) is NaN */
|
||||
if(((((uint32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
|
||||
|
||||
/* |y| is huge */
|
||||
if(iy>0x4d000000) { /* if |y| > 2**27 */
|
||||
/* over/underflow if x is not close to one */
|
||||
if(ix<0x3f7ffff8) return (hy<0)? huge*huge:tiny*tiny;
|
||||
if(ix>0x3f800007) return (hy>0)? huge*huge:tiny*tiny;
|
||||
/* now |1-x| is tiny <= 2**-20, suffice to compute
|
||||
log(x) by x-x^2/2+x^3/3-x^4/4 */
|
||||
t = ax-one; /* t has 20 trailing zeros */
|
||||
w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25));
|
||||
u = ivln2_h*t; /* ivln2_h has 16 sig. bits */
|
||||
v = t*ivln2_l-w*ivln2;
|
||||
t1 = u+v;
|
||||
GET_FLOAT_WORD(is,t1);
|
||||
SET_FLOAT_WORD(t1,is&0xfffff000);
|
||||
t2 = v-(t1-u);
|
||||
} else {
|
||||
float s2,s_h,s_l,t_h,t_l;
|
||||
n = 0;
|
||||
/* take care subnormal number */
|
||||
if(ix<0x00800000)
|
||||
{ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
|
||||
n += ((ix)>>23)-0x7f;
|
||||
j = ix&0x007fffff;
|
||||
/* determine interval */
|
||||
ix = j|0x3f800000; /* normalize ix */
|
||||
if(j<=0x1cc471) k=0; /* |x|<sqrt(3/2) */
|
||||
else if(j<0x5db3d7) k=1; /* |x|<sqrt(3) */
|
||||
else {k=0;n+=1;ix -= 0x00800000;}
|
||||
SET_FLOAT_WORD(ax,ix);
|
||||
|
||||
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
|
||||
u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
|
||||
v = one/(ax+bp[k]);
|
||||
s = u*v;
|
||||
s_h = s;
|
||||
GET_FLOAT_WORD(is,s_h);
|
||||
SET_FLOAT_WORD(s_h,is&0xfffff000);
|
||||
/* t_h=ax+bp[k] High */
|
||||
SET_FLOAT_WORD(t_h,((ix>>1)|0x20000000)+0x0040000+(k<<21));
|
||||
t_l = ax - (t_h-bp[k]);
|
||||
s_l = v*((u-s_h*t_h)-s_h*t_l);
|
||||
/* compute log(ax) */
|
||||
s2 = s*s;
|
||||
r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
|
||||
r += s_l*(s_h+s);
|
||||
s2 = s_h*s_h;
|
||||
t_h = (float)3.0+s2+r;
|
||||
GET_FLOAT_WORD(is,t_h);
|
||||
SET_FLOAT_WORD(t_h,is&0xfffff000);
|
||||
t_l = r-((t_h-(float)3.0)-s2);
|
||||
/* u+v = s*(1+...) */
|
||||
u = s_h*t_h;
|
||||
v = s_l*t_h+t_l*s;
|
||||
/* 2/(3log2)*(s+...) */
|
||||
p_h = u+v;
|
||||
GET_FLOAT_WORD(is,p_h);
|
||||
SET_FLOAT_WORD(p_h,is&0xfffff000);
|
||||
p_l = v-(p_h-u);
|
||||
z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
|
||||
z_l = cp_l*p_h+p_l*cp+dp_l[k];
|
||||
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
|
||||
t = (float)n;
|
||||
t1 = (((z_h+z_l)+dp_h[k])+t);
|
||||
GET_FLOAT_WORD(is,t1);
|
||||
SET_FLOAT_WORD(t1,is&0xfffff000);
|
||||
t2 = z_l-(((t1-t)-dp_h[k])-z_h);
|
||||
}
|
||||
|
||||
s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
|
||||
if(((((uint32_t)hx>>31)-1)|(yisint-1))==0)
|
||||
s = -one; /* (-ve)**(odd int) */
|
||||
|
||||
/* split up y into yy1+y2 and compute (yy1+y2)*(t1+t2) */
|
||||
GET_FLOAT_WORD(is,y);
|
||||
SET_FLOAT_WORD(yy1,is&0xfffff000);
|
||||
p_l = (y-yy1)*t1+y*t2;
|
||||
p_h = yy1*t1;
|
||||
z = p_l+p_h;
|
||||
GET_FLOAT_WORD(j,z);
|
||||
if (j>0x43000000) /* if z > 128 */
|
||||
return s*huge*huge; /* overflow */
|
||||
else if (j==0x43000000) { /* if z == 128 */
|
||||
if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
|
||||
}
|
||||
else if ((uint32_t)j==0xc3160000){ /* z == -150 */
|
||||
if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
|
||||
}
|
||||
else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */
|
||||
return s*tiny*tiny; /* underflow */
|
||||
/*
|
||||
* compute 2**(p_h+p_l)
|
||||
*/
|
||||
i = j&0x7fffffff;
|
||||
k = (i>>23)-0x7f;
|
||||
n = 0;
|
||||
if(i>0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
|
||||
n = j+(0x00800000>>(k+1));
|
||||
k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */
|
||||
SET_FLOAT_WORD(t,n&~(0x007fffff>>k));
|
||||
n = ((n&0x007fffff)|0x00800000)>>(23-k);
|
||||
if(j<0) n = -n;
|
||||
p_h -= t;
|
||||
}
|
||||
t = p_l+p_h;
|
||||
GET_FLOAT_WORD(is,t);
|
||||
SET_FLOAT_WORD(t,is&0xfffff000);
|
||||
u = t*lg2_h;
|
||||
v = (p_l-(t-p_h))*lg2+t*lg2_l;
|
||||
z = u+v;
|
||||
w = v-(z-u);
|
||||
t = z*z;
|
||||
t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
|
||||
r = (z*t1)/(t1-two)-(w+z*w);
|
||||
z = one-(r-z);
|
||||
GET_FLOAT_WORD(j,z);
|
||||
j = (int32_t)((uint32_t)j + ((uint32_t)n<<23));
|
||||
if((j>>23)<=0) z = scalbnf(z,n); /* subnormal output */
|
||||
else SET_FLOAT_WORD(z,j);
|
||||
return s*z;
|
||||
}
|
71
lib/runtime/libm/e_sqrtf.c
Normal file
71
lib/runtime/libm/e_sqrtf.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float one = 1.0, tiny=1.0e-30;
|
||||
|
||||
float
|
||||
__ieee754_sqrtf(float x)
|
||||
{
|
||||
float z;
|
||||
int32_t sign = (int)0x80000000;
|
||||
int32_t ix,s,q,m,t,i;
|
||||
uint32_t r;
|
||||
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
|
||||
/* take care of Inf and NaN */
|
||||
if((ix&0x7f800000)==0x7f800000) {
|
||||
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
|
||||
sqrt(-inf)=sNaN */
|
||||
}
|
||||
/* take care of zero */
|
||||
if(ix<=0) {
|
||||
if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
|
||||
else if(ix<0)
|
||||
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
|
||||
}
|
||||
/* normalize x */
|
||||
m = (ix>>23);
|
||||
if(m==0) { /* subnormal x */
|
||||
for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
|
||||
m -= i-1;
|
||||
}
|
||||
m -= 127; /* unbias exponent */
|
||||
ix = (ix&0x007fffff)|0x00800000;
|
||||
if(m&1) /* odd m, double x to make it even */
|
||||
ix += ix;
|
||||
m >>= 1; /* m = [m/2] */
|
||||
|
||||
/* generate sqrt(x) bit by bit */
|
||||
ix += ix;
|
||||
q = s = 0; /* q = sqrt(x) */
|
||||
r = 0x01000000; /* r = moving bit from right to left */
|
||||
|
||||
while(r!=0) {
|
||||
t = s+r;
|
||||
if(t<=ix) {
|
||||
s = t+r;
|
||||
ix -= t;
|
||||
q += r;
|
||||
}
|
||||
ix += ix;
|
||||
r>>=1;
|
||||
}
|
||||
|
||||
/* use floating add to find out rounding direction */
|
||||
if(ix!=0) {
|
||||
z = one-tiny; /* trigger inexact flag */
|
||||
if (z>=one) {
|
||||
z = one+tiny;
|
||||
if (z>one)
|
||||
q += 2;
|
||||
else
|
||||
q += (q&1);
|
||||
}
|
||||
}
|
||||
ix = (q>>1)+0x3f000000;
|
||||
ix += (m <<23);
|
||||
SET_FLOAT_WORD(z,ix);
|
||||
return z;
|
||||
}
|
34
lib/runtime/libm/private.h
Normal file
34
lib/runtime/libm/private.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
typedef union
|
||||
{
|
||||
float value;
|
||||
uint32_t word;
|
||||
} ieee_float_shape_type;
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
|
||||
#define GET_FLOAT_WORD(i,d) \
|
||||
do { \
|
||||
ieee_float_shape_type gf_u; \
|
||||
gf_u.value = (d); \
|
||||
(i) = gf_u.word; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
|
||||
#define SET_FLOAT_WORD(d,i) \
|
||||
do { \
|
||||
ieee_float_shape_type sf_u; \
|
||||
sf_u.word = (i); \
|
||||
(d) = sf_u.value; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
float __ieee754_sqrtf(float x);
|
||||
float __ieee754_powf(float x, float y);
|
||||
float __ieee754_hypotf(float x, float y);
|
||||
float __ieee754_fmodf(float x, float y);
|
||||
|
||||
float scalbnf(float x, int n);
|
||||
float copysignf(float x, float y);
|
||||
float fabsf(float x);
|
35
lib/runtime/libm/s_ceilf.c
Normal file
35
lib/runtime/libm/s_ceilf.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float huge = 1.0e30;
|
||||
|
||||
float
|
||||
ceilf(float x)
|
||||
{
|
||||
int32_t i0,jj0;
|
||||
uint32_t i;
|
||||
|
||||
GET_FLOAT_WORD(i0,x);
|
||||
jj0 = ((i0>>23)&0xff)-0x7f;
|
||||
if(jj0<23) {
|
||||
if(jj0<0) { /* raise inexact if x != 0 */
|
||||
if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
|
||||
if(i0<0) {i0=0x80000000;}
|
||||
else if(i0!=0) { i0=0x3f800000;}
|
||||
}
|
||||
} else {
|
||||
i = (0x007fffff)>>jj0;
|
||||
if((i0&i)==0) return x; /* x is integral */
|
||||
if(huge+x>(float)0.0) { /* raise inexact flag */
|
||||
if(i0>0) i0 += (0x00800000)>>jj0;
|
||||
i0 &= (~i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(jj0==0x80) return x+x; /* inf or NaN */
|
||||
else return x; /* x is integral */
|
||||
}
|
||||
SET_FLOAT_WORD(x,i0);
|
||||
return x;
|
||||
}
|
13
lib/runtime/libm/s_copysignf.c
Normal file
13
lib/runtime/libm/s_copysignf.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
float
|
||||
copysignf(float x, float y)
|
||||
{
|
||||
uint32_t ix,iy;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
GET_FLOAT_WORD(iy,y);
|
||||
SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
|
||||
return x;
|
||||
}
|
12
lib/runtime/libm/s_fabsf.c
Normal file
12
lib/runtime/libm/s_fabsf.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
float
|
||||
fabsf(float x)
|
||||
{
|
||||
uint32_t ix;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
SET_FLOAT_WORD(x,ix&0x7fffffff);
|
||||
return x;
|
||||
}
|
35
lib/runtime/libm/s_floorf.c
Normal file
35
lib/runtime/libm/s_floorf.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float huge = 1.0e30;
|
||||
|
||||
float
|
||||
floorf(float x)
|
||||
{
|
||||
int32_t i0,jj0;
|
||||
uint32_t i;
|
||||
GET_FLOAT_WORD(i0,x);
|
||||
jj0 = ((i0>>23)&0xff)-0x7f;
|
||||
if(jj0<23) {
|
||||
if(jj0<0) { /* raise inexact if x != 0 */
|
||||
if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
|
||||
if(i0>=0) {i0=0;}
|
||||
else if((i0&0x7fffffff)!=0)
|
||||
{ i0=0xbf800000;}
|
||||
}
|
||||
} else {
|
||||
i = (0x007fffff)>>jj0;
|
||||
if((i0&i)==0) return x; /* x is integral */
|
||||
if(huge+x>(float)0.0) { /* raise inexact flag */
|
||||
if(i0<0) i0 += (0x00800000)>>jj0;
|
||||
i0 &= (~i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(jj0==0x80) return x+x; /* inf or NaN */
|
||||
else return x; /* x is integral */
|
||||
}
|
||||
SET_FLOAT_WORD(x,i0);
|
||||
return x;
|
||||
}
|
37
lib/runtime/libm/s_scalbnf.c
Normal file
37
lib/runtime/libm/s_scalbnf.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float
|
||||
two25 = 3.355443200e+07, /* 0x4c000000 */
|
||||
twom25 = 2.9802322388e-08, /* 0x33000000 */
|
||||
huge = 1.0e+30,
|
||||
tiny = 1.0e-30;
|
||||
|
||||
float
|
||||
scalbnf(float x, int n)
|
||||
{
|
||||
int32_t k,ix;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
k = (ix&0x7f800000)>>23; /* extract exponent */
|
||||
if (k==0) { /* 0 or subnormal x */
|
||||
if ((ix&0x7fffffff)==0) return x; /* +-0 */
|
||||
x *= two25;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
k = ((ix&0x7f800000)>>23) - 25;
|
||||
if (n< -50000) return tiny*x; /*underflow*/
|
||||
}
|
||||
if (k==0xff) return x+x; /* NaN or Inf */
|
||||
k = k+n;
|
||||
if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */
|
||||
if (k > 0) /* normal result */
|
||||
{SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
|
||||
if (k <= -25) {
|
||||
if (n > 50000) /* in case integer overflow in n+k */
|
||||
return huge*copysignf(huge,x); /*overflow*/
|
||||
else return tiny*copysignf(tiny,x); /*underflow*/
|
||||
}
|
||||
k += 25; /* subnormal result */
|
||||
SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
|
||||
return x*twom25;
|
||||
}
|
29
lib/runtime/libm/s_truncf.c
Normal file
29
lib/runtime/libm/s_truncf.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static const float huge = 1.0e30F;
|
||||
|
||||
float truncf(float x) {
|
||||
int32_t i0,jj0;
|
||||
uint32_t i;
|
||||
GET_FLOAT_WORD(i0,x);
|
||||
jj0 = ((i0>>23)&0xff)-0x7f;
|
||||
if(jj0<23) {
|
||||
if(jj0<0) { /* raise inexact if x != 0 */
|
||||
if(huge+x>0.0F) /* |x|<1, so return 0*sign(x) */
|
||||
i0 &= 0x80000000;
|
||||
} else {
|
||||
i = (0x007fffff)>>jj0;
|
||||
if((i0&i)==0) return x; /* x is integral */
|
||||
if(huge+x>0.0F) /* raise inexact flag */
|
||||
i0 &= (~i);
|
||||
}
|
||||
} else {
|
||||
if(jj0==0x80) return x+x; /* inf or NaN */
|
||||
else return x; /* x is integral */
|
||||
}
|
||||
SET_FLOAT_WORD(x,i0);
|
||||
return x;
|
||||
|
||||
}
|
20
lib/runtime/libm/w_fmodf.c
Normal file
20
lib/runtime/libm/w_fmodf.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
float
|
||||
fmodf(float x, float y) /* wrapper fmodf */
|
||||
{
|
||||
// #ifdef _IEEE_LIBM
|
||||
return __ieee754_fmodf(x,y);
|
||||
// #else
|
||||
// float z;
|
||||
// z = __ieee754_fmodf(x,y);
|
||||
// if(_LIB_VERSION == _IEEE_ ||isnanf(y)||isnanf(x)) return z;
|
||||
// if(y==(float)0.0) {
|
||||
// /* fmodf(x,0) */
|
||||
// return (float)__kernel_standard((double)x,(double)y,127);
|
||||
// } else
|
||||
// return z;
|
||||
// #endif
|
||||
}
|
21
lib/runtime/libm/w_hypotf.c
Normal file
21
lib/runtime/libm/w_hypotf.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
float
|
||||
hypotf(float x, float y) /* wrapper hypotf */
|
||||
{
|
||||
// #ifdef _IEEE_LIBM
|
||||
return __ieee754_hypotf(x,y);
|
||||
// #else
|
||||
// float z;
|
||||
// z = __ieee754_hypotf(x,y);
|
||||
// if(_LIB_VERSION == _IEEE_) return z;
|
||||
// if((!finitef(z))&&finitef(x)&&finitef(y))
|
||||
// /* hypot overflow */
|
||||
// return (float)__kernel_standard((double)x,(double)y,104);
|
||||
// else
|
||||
// return z;
|
||||
// #endif
|
||||
}
|
||||
|
45
lib/runtime/libm/w_powf.c
Normal file
45
lib/runtime/libm/w_powf.c
Normal file
@ -0,0 +1,45 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
float
|
||||
powf(float x, float y) /* wrapper powf */
|
||||
{
|
||||
// #ifdef _IEEE_LIBM
|
||||
return __ieee754_powf(x,y);
|
||||
// #else
|
||||
// float z;
|
||||
// z=__ieee754_powf(x,y);
|
||||
// if(_LIB_VERSION == _IEEE_|| isnanf(y)) return z;
|
||||
// if(isnanf(x)) {
|
||||
// if(y==(float)0.0)
|
||||
// /* powf(NaN,0.0) */
|
||||
// return (float)__kernel_standard((double)x,(double)y,142);
|
||||
// else
|
||||
// return z;
|
||||
// }
|
||||
// if(x==(float)0.0){
|
||||
// if(y==(float)0.0)
|
||||
// /* powf(0.0,0.0) */
|
||||
// return (float)__kernel_standard((double)x,(double)y,120);
|
||||
// if(finitef(y)&&y<(float)0.0)
|
||||
// /* powf(0.0,negative) */
|
||||
// return (float)__kernel_standard((double)x,(double)y,123);
|
||||
// return z;
|
||||
// }
|
||||
// if(!finitef(z)) {
|
||||
// if(finitef(x)&&finitef(y)) {
|
||||
// if(isnanf(z))
|
||||
// /* powf neg**non-int */
|
||||
// return (float)__kernel_standard((double)x,(double)y,124);
|
||||
// else
|
||||
// /* powf overflow */
|
||||
// return (float)__kernel_standard((double)x,(double)y,121);
|
||||
// }
|
||||
// }
|
||||
// if(z==(float)0.0&&finitef(x)&&finitef(y))
|
||||
// /* powf underflow */
|
||||
// return (float)__kernel_standard((double)x,(double)y,122);
|
||||
// return z;
|
||||
// #endif
|
||||
}
|
51
lib/runtime/src/debug.rs
Normal file
51
lib/runtime/src/debug.rs
Normal file
@ -0,0 +1,51 @@
|
||||
//! Debug tracing module
|
||||
|
||||
use core::fmt;
|
||||
|
||||
///
|
||||
#[macro_export]
|
||||
macro_rules! debug_trace {
|
||||
($($args:tt)+) => {
|
||||
$crate::debug::_debug_trace(format_args!($($args)+))
|
||||
};
|
||||
}
|
||||
|
||||
struct TracePrinter {
|
||||
buf: [u8; 512],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl fmt::Write for TracePrinter {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for &c in s.as_bytes() {
|
||||
self.buf[self.len] = c;
|
||||
self.len += 1;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Trace raw message into the kernel's log. If the message is not a valid unicode string, it will
|
||||
/// get discarded.
|
||||
pub fn trace_raw(data: &[u8]) {
|
||||
if let Ok(str) = core::str::from_utf8(data) {
|
||||
unsafe {
|
||||
crate::sys::debug_trace(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _debug_trace(a: core::fmt::Arguments<'_>) {
|
||||
use fmt::Write;
|
||||
|
||||
let mut printer = TracePrinter { buf: [0; 512], len: 0 };
|
||||
printer.write_fmt(a).ok();
|
||||
|
||||
if printer.len != 0 {
|
||||
unsafe {
|
||||
let s = core::str::from_utf8_unchecked(&printer.buf[..printer.len]);
|
||||
crate::sys::debug_trace(s);
|
||||
}
|
||||
}
|
||||
}
|
27
lib/runtime/src/io.rs
Normal file
27
lib/runtime/src/io.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
pub mod device {
|
||||
pub use abi::io::{DeviceRequest, MountOptions, UnmountOptions};
|
||||
}
|
||||
|
||||
pub mod terminal {
|
||||
pub use abi::io::{
|
||||
TerminalInputOptions, TerminalLineOptions, TerminalOptions, TerminalOutputOptions,
|
||||
TerminalSize,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod message_channel {
|
||||
pub use abi::io::{
|
||||
ChannelPublisherId, MessageDestination, ReceivedMessageMetadata, SentMessage,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod poll {
|
||||
pub use abi::io::PollControl;
|
||||
}
|
||||
|
||||
pub use abi::io::{
|
||||
DirectoryEntry, FileAttr, FileMetadataUpdate, FileMetadataUpdateMode, FileMode, FileType,
|
||||
OpenOptions, RawFd, SeekFrom,
|
||||
};
|
102
lib/runtime/src/lib.rs
Normal file
102
lib/runtime/src/lib.rs
Normal file
@ -0,0 +1,102 @@
|
||||
//! Yggdrasil OS application runtime
|
||||
#![feature(rustc_private, exposed_provenance)]
|
||||
#![no_std]
|
||||
#![deny(missing_docs)]
|
||||
#![allow(nonstandard_style)]
|
||||
|
||||
#[cfg(not(feature = "rustc-dep-of-std"))]
|
||||
extern crate compiler_builtins;
|
||||
extern crate yggdrasil_abi as abi;
|
||||
|
||||
pub use abi::error::Error;
|
||||
pub use abi::path;
|
||||
pub mod debug;
|
||||
pub mod io;
|
||||
pub mod net;
|
||||
pub mod process;
|
||||
pub mod sys;
|
||||
pub mod time;
|
||||
|
||||
pub mod mem {
|
||||
//! Memory-related data structures
|
||||
|
||||
pub use abi::mem::MappingSource;
|
||||
}
|
||||
|
||||
pub mod system {
|
||||
//! System-related data structures
|
||||
|
||||
pub use abi::system::*;
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
use core::ffi::{c_char, c_void};
|
||||
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn bcmp(p0: *const c_void, p1: *const c_void, len: usize) -> i32 {
|
||||
memcmp(p0, p1, len)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn memcmp(p0: *const c_void, p1: *const c_void, len: usize) -> i32 {
|
||||
let mut offset = 0;
|
||||
|
||||
if len == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while offset < len {
|
||||
let c0 = (p0 as *const u8).add(offset).read_volatile();
|
||||
let c1 = (p1 as *const u8).add(offset).read_volatile();
|
||||
|
||||
if c0 > c1 {
|
||||
return (c0 - c1) as i32;
|
||||
} else if c0 < c1 {
|
||||
return -((c1 - c0) as i32);
|
||||
}
|
||||
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
/// XXX
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memcpy(p0: *mut c_void, p1: *const c_void, len: usize) -> *mut c_void {
|
||||
compiler_builtins::mem::memcpy(p0 as _, p1 as _, len) as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn memmove(dst: *mut c_void, src: *const c_void, n: usize) -> *mut c_void {
|
||||
compiler_builtins::mem::memmove(dst as _, src as _, n) as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn memset(dst: *mut c_void, val: i32, len: usize) -> *mut c_void {
|
||||
let mut offset = 0;
|
||||
while offset < len {
|
||||
(dst as *mut u8).add(offset).write_volatile(val as u8);
|
||||
offset += 1;
|
||||
}
|
||||
dst
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-dep-of-std")]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn strlen(mut s: *mut c_char) -> usize {
|
||||
if s.is_null() {
|
||||
return 0;
|
||||
}
|
||||
let mut len = 0;
|
||||
while s.read() != 0 {
|
||||
len += 1;
|
||||
s = s.add(1);
|
||||
}
|
||||
len
|
||||
}
|
54
lib/runtime/src/net.rs
Normal file
54
lib/runtime/src/net.rs
Normal file
@ -0,0 +1,54 @@
|
||||
//! Network-related functions and types
|
||||
|
||||
pub use abi::net::{MacAddress, SocketInterfaceQuery, SocketOption, SocketType};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod dns {
|
||||
//! DNS resolver module for `std`
|
||||
use abi::net::dns::DnsSerialize;
|
||||
|
||||
pub use abi::net::dns::{
|
||||
DnsClass, DnsMessage, DnsMethod, DnsRecordData, DnsReplyCode, DnsType,
|
||||
};
|
||||
|
||||
/// Interface for performing UDP communication
|
||||
pub trait UdpRequester {
|
||||
/// Error returned by the requester
|
||||
type Error;
|
||||
|
||||
/// Sends a message through the communication channel
|
||||
fn send_message(&mut self, message: &[u8]) -> Result<(), Self::Error>;
|
||||
|
||||
/// Wait for a message, parses it and runs a function on it to determine whether to return
|
||||
fn receive_message<F: Fn(&[u8]) -> Option<DnsMessage>>(
|
||||
&mut self,
|
||||
map: F,
|
||||
) -> Result<DnsMessage, Self::Error>;
|
||||
}
|
||||
|
||||
/// Performs a raw DNS query without analyzing the reply
|
||||
pub fn perform_query<R: UdpRequester>(
|
||||
requester: &mut R,
|
||||
name: &str,
|
||||
ty: DnsType,
|
||||
xid: u16,
|
||||
cookie: u64,
|
||||
) -> Result<DnsMessage, R::Error> {
|
||||
let mut packet = alloc::vec![];
|
||||
let query = DnsMessage::query(name, ty, xid, cookie);
|
||||
query.serialize(&mut packet);
|
||||
requester.send_message(&packet)?;
|
||||
|
||||
let message = requester.receive_message(|data| {
|
||||
let message = DnsMessage::parse(data)?;
|
||||
|
||||
if message.xid != xid || message.method != DnsMethod::REPLY {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(message)
|
||||
})?;
|
||||
|
||||
Ok(message)
|
||||
}
|
||||
}
|
6
lib/runtime/src/process.rs
Normal file
6
lib/runtime/src/process.rs
Normal file
@ -0,0 +1,6 @@
|
||||
//! Process management data types
|
||||
|
||||
pub use abi::process::{
|
||||
ExecveOptions, ExitCode, MutexOperation, ProcessId, ProcessInfoElement, ProgramArgumentInner,
|
||||
Signal, SignalEntryData, SpawnOption, SpawnOptions, ThreadId, ThreadSpawnOptions,
|
||||
};
|
44
lib/runtime/src/sys/aarch64.rs
Normal file
44
lib/runtime/src/sys/aarch64.rs
Normal file
@ -0,0 +1,44 @@
|
||||
/// AArch64 implementation of a syscall macro
|
||||
#[macro_export]
|
||||
macro_rules! syscall {
|
||||
($num:expr $(,)?) => {{
|
||||
let mut res: usize;
|
||||
core::arch::asm!("svc #0", lateout("x0") res, in("x8") usize::from($num));
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr $(,)?) => {{
|
||||
let mut res: usize = $a0;
|
||||
core::arch::asm!("svc #0",
|
||||
inlateout("x0") res,
|
||||
in("x8") usize::from($num));
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr $(,)?) => {{
|
||||
let mut res: usize = $a0;
|
||||
core::arch::asm!("svc #0",
|
||||
inlateout("x0") res, in("x1") $a1,
|
||||
in("x8") usize::from($num));
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr, $a2:expr $(,)?) => {{
|
||||
let mut res: usize = $a0;
|
||||
core::arch::asm!("svc #0",
|
||||
inlateout("x0") res, in("x1") $a1, in("x2") $a2,
|
||||
in("x8") usize::from($num));
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr $(,)?) => {{
|
||||
let mut res: usize = $a0;
|
||||
core::arch::asm!("svc #0",
|
||||
inlateout("x0") res, in("x1") $a1, in("x2") $a2,
|
||||
in("x3") $a3, in("x8") usize::from($num));
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr $(,)?) => {{
|
||||
let mut res: usize = $a0;
|
||||
core::arch::asm!("svc #0",
|
||||
inlateout("x0") res, in("x1") $a1, in("x2") $a2,
|
||||
in("x3") $a3, in("x4") $a4, in("x8") usize::from($num));
|
||||
res
|
||||
}};
|
||||
}
|
25
lib/runtime/src/sys/mod.rs
Normal file
25
lib/runtime/src/sys/mod.rs
Normal file
@ -0,0 +1,25 @@
|
||||
//! System call implementations
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[macro_use]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[macro_use]
|
||||
mod x86_64;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
mod generated {
|
||||
// Import all the necessary types from generated ABI
|
||||
use abi::{
|
||||
error::Error,
|
||||
io::{ChannelPublisherId, FileMode, OpenOptions, PollControl, RawFd},
|
||||
mem::MappingSource,
|
||||
net::SocketType,
|
||||
process::{ProcessId, Signal},
|
||||
SyscallFunction,
|
||||
};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/generated_calls.rs"));
|
||||
}
|
||||
|
||||
pub use generated::*;
|
106
lib/runtime/src/sys/x86_64.rs
Normal file
106
lib/runtime/src/sys/x86_64.rs
Normal file
@ -0,0 +1,106 @@
|
||||
/// x86-64 implementation of a system call macro
|
||||
#[macro_export]
|
||||
macro_rules! syscall {
|
||||
($num:expr $(,)?) => {{
|
||||
let mut res = usize::from($num);
|
||||
core::arch::asm!(
|
||||
"syscall",
|
||||
inlateout("rax") res,
|
||||
out("rdi") _,
|
||||
out("rsi") _,
|
||||
out("rdx") _,
|
||||
out("r10") _,
|
||||
out("r8") _,
|
||||
out("r9") _,
|
||||
// Clobbered by syscall
|
||||
out("rcx") _,
|
||||
out("r11") _,
|
||||
);
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr $(,)?) => {{
|
||||
let mut res = usize::from($num);
|
||||
core::arch::asm!(
|
||||
"syscall",
|
||||
inlateout("rax") res,
|
||||
in("rdi") $a0,
|
||||
out("rsi") _,
|
||||
out("rdx") _,
|
||||
out("r10") _,
|
||||
out("r8") _,
|
||||
out("r9") _,
|
||||
// Clobbered by syscall
|
||||
out("rcx") _,
|
||||
out("r11") _,
|
||||
);
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr $(,)?) => {{
|
||||
let mut res = usize::from($num);
|
||||
core::arch::asm!(
|
||||
"syscall",
|
||||
inlateout("rax") res,
|
||||
in("rdi") $a0,
|
||||
in("rsi") $a1,
|
||||
out("rdx") _,
|
||||
out("r10") _,
|
||||
out("r8") _,
|
||||
out("r9") _,
|
||||
// Clobbered by syscall
|
||||
out("rcx") _,
|
||||
out("r11") _,
|
||||
);
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr, $a2:expr $(,)?) => {{
|
||||
let mut res = usize::from($num);
|
||||
core::arch::asm!(
|
||||
"syscall",
|
||||
inlateout("rax") res,
|
||||
in("rdi") $a0,
|
||||
in("rsi") $a1,
|
||||
in("rdx") $a2,
|
||||
out("r10") _,
|
||||
out("r8") _,
|
||||
out("r9") _,
|
||||
// Clobbered by syscall
|
||||
out("rcx") _,
|
||||
out("r11") _,
|
||||
);
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr $(,)?) => {{
|
||||
let mut res = usize::from($num);
|
||||
core::arch::asm!(
|
||||
"syscall",
|
||||
inlateout("rax") res,
|
||||
in("rdi") $a0,
|
||||
in("rsi") $a1,
|
||||
in("rdx") $a2,
|
||||
in("r10") $a3,
|
||||
out("r8") _,
|
||||
out("r9") _,
|
||||
// Clobbered by syscall
|
||||
out("rcx") _,
|
||||
out("r11") _,
|
||||
);
|
||||
res
|
||||
}};
|
||||
($num:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr $(,)?) => {{
|
||||
let mut res = usize::from($num);
|
||||
core::arch::asm!(
|
||||
"syscall",
|
||||
inlateout("rax") res,
|
||||
in("rdi") $a0,
|
||||
in("rsi") $a1,
|
||||
in("rdx") $a2,
|
||||
in("r10") $a3,
|
||||
in("r8") $a4,
|
||||
out("r9") _,
|
||||
// Clobbered by syscall
|
||||
out("rcx") _,
|
||||
out("r11") _,
|
||||
);
|
||||
res
|
||||
}};
|
||||
}
|
18
lib/runtime/src/time.rs
Normal file
18
lib/runtime/src/time.rs
Normal file
@ -0,0 +1,18 @@
|
||||
//! System time management
|
||||
|
||||
/// System time representation
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Timespec {
|
||||
/// Seconds component
|
||||
pub seconds: u64,
|
||||
/// Nanoseconds component
|
||||
pub nanoseconds: u64,
|
||||
}
|
||||
|
||||
impl Timespec {
|
||||
/// Constructs a [Timespec] with all components set to zero
|
||||
pub const fn zero() -> Self {
|
||||
Self { seconds: 0, nanoseconds: 0 }
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user