Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions backend/remill/lib/Arch/AArch64/Arch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5895,6 +5895,27 @@ bool TryDecodeFCVTZU_ASISDMISC_R(const InstData &data, Instruction &inst) {
return true;
}

// FCVTZS <V><d>, <V><n> (scalar, converts FP to signed integer)
bool TryDecodeFCVTZS_ASISDMISC_R(const InstData &data, Instruction &inst) {
inst.sema_func_arg_type = SemaFuncArgType::State;
RegClass dst_class, src_class;
if (1 == data.sz) {
inst.function += "_64";
dst_class = kReg2D; // Output: integer register
src_class = kReg2DF; // Input: floating-point register
} else {
inst.function += "_32";
dst_class = kReg4S; // Output: integer register
src_class = kReg4SF; // Input: floating-point register
}
if (inst.lift_config.float_exception_enabled) {
AddArrangementSpecifierFPSRStatus(inst);
}
AddRegOperand(inst, kActionWrite, dst_class, kUseAsValue, data.Rd);
AddRegOperand(inst, kActionRead, src_class, kUseAsValue, data.Rn);
return true;
}

// SCVTF <Vd>.<T>, <Vn>.<T> (only 32bit or 64bit)
bool TryDecodeSCVTF_ASIMDMISC_R(const InstData &data, Instruction &inst) {
inst.sema_func_arg_type = SemaFuncArgType::State;
Expand Down
4 changes: 1 addition & 3 deletions backend/remill/lib/Arch/AArch64/Decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25475,9 +25475,7 @@ bool TryDecodeFCVTZS_ASISDMISCFP16_R(const InstData &, Instruction &) {
// 30 1
// 31 0
// FCVTZS <V><d>, <V><n>
bool TryDecodeFCVTZS_ASISDMISC_R(const InstData &, Instruction &) {
return false;
}
// Implemented in Arch.cpp

// FCVTZS FCVTZS_asimdmiscfp16_R:
// 0 x Rd 0
Expand Down
30 changes: 30 additions & 0 deletions backend/remill/lib/Arch/AArch64/Semantics/CONVERT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,29 @@ DEF_SEM_T_STATE(FCVTZU_Float64ToUInt64_FROMV_FPSRStatus, VIf64v2 src) {
return res;
}

// FCVTZS <V><d>, <V><n> (scalar, converts FP to signed integer in vector register)
DEF_SEM_T_STATE(FCVTZS_Float32ToSInt32_FROMV, VIf32v4 src) {
_ecv_u32v4_t res = {};
res[0] = CheckedCast<float32_t, int32_t>(state, FExtractVI32(FReadVI32(src), 0));
return res;
}
DEF_SEM_T_STATE(FCVTZS_Float64ToSInt64_FROMV, VIf64v2 src) {
_ecv_u64v2_t res = {};
res[0] = CheckedCast<float64_t, int64_t>(state, FExtractVI64(FReadVI64(src), 0));
return res;
}
// FPSR
DEF_SEM_T_STATE(FCVTZS_Float32ToSInt32_FROMV_FPSRStatus, VIf32v4 src) {
_ecv_u32v4_t res = {};
res[0] = CheckedCastFPSRStatus<float32_t, int32_t>(state, FExtractVI32(FReadVI32(src), 0));
return res;
}
DEF_SEM_T_STATE(FCVTZS_Float64ToSInt64_FROMV_FPSRStatus, VIf64v2 src) {
_ecv_u64v2_t res = {};
res[0] = CheckedCastFPSRStatus<float64_t, int64_t>(state, FExtractVI64(FReadVI64(src), 0));
return res;
}

// FCVTZS <Wd>, <Sn>
DEF_SEM_U32_STATE(FCVTZS_Float32ToSInt32, RF32 src) {
return CheckedCast<float32_t, int32_t>(state, Read(src));
Expand Down Expand Up @@ -305,6 +328,13 @@ DEF_ISEL(FCVTZS_32D_FLOAT2INT_FPSRSTATUS) =
DEF_ISEL(FCVTZS_64D_FLOAT2INT_FPSRSTATUS) =
FCVTZS_Float64ToSInt64_FPSRStatus; // FCVTZS <Xd>, <Dn>

// FCVTZS (scalar, FP to signed integer in vector register) - ASISDMISC
DEF_ISEL(FCVTZS_ASISDMISC_R_32) = FCVTZS_Float32ToSInt32_FROMV; // FCVTZS <V><d>, <V><n>
DEF_ISEL(FCVTZS_ASISDMISC_R_64) = FCVTZS_Float64ToSInt64_FROMV; // FCVTZS <V><d>, <V><n>
// FPSR
DEF_ISEL(FCVTZS_ASISDMISC_R_32_FPSRSTATUS) = FCVTZS_Float32ToSInt32_FROMV_FPSRStatus; // FCVTZS <V><d>, <V><n>
DEF_ISEL(FCVTZS_ASISDMISC_R_64_FPSRSTATUS) = FCVTZS_Float64ToSInt64_FROMV_FPSRStatus; // FCVTZS <V><d>, <V><n>

DEF_ISEL(FCVTAS_64D_FLOAT2INT) = FCVTAS_Float64ToSInt64; // FCVTAS <Xd>, <Dn>
// FPSR
DEF_ISEL(FCVTAS_64D_FLOAT2INT_FPSRSTATUS) =
Expand Down
41 changes: 41 additions & 0 deletions backend/remill/tests/AArch64/SIMD/FCVTZS_ASISDMISC_R.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
TEST_BEGIN(FCVTZS_ASISDMISC_R_32, fcvtzs_s0_s1_sisd, 1)
TEST_INPUTS(0)
fmov s1, #2.5
fcvtzs s0, s1
TEST_END

TEST_BEGIN(FCVTZS_ASISDMISC_R_32_v2, fcvtzs_s0_s1_sisd_v2, 1)
TEST_INPUTS(0)
fmov s1, #-2.5
fcvtzs s0, s1
TEST_END

TEST_BEGIN(FCVTZS_ASISDMISC_R_64, fcvtzs_d0_d1_sisd, 1)
TEST_INPUTS(0)
fmov d1, #2.5
fcvtzs d0, d1
TEST_END

TEST_BEGIN(FCVTZS_ASISDMISC_R_64_v2, fcvtzs_d0_d1_sisd_v2, 1)
TEST_INPUTS(0)
fmov d1, #-4.0
fcvtzs d0, d1
TEST_END

TEST_BEGIN(FCVTZS_ASISDMISC_R_32_INPUTS, fcvtzs_s_inputs, 1)
TEST_INPUTS(
0x3F8000003F800000,
0x40000000C0000000,
0x41200000BF800000)
fmov d1, ARG1_64
fcvtzs s0, s1
TEST_END

TEST_BEGIN(FCVTZS_ASISDMISC_R_64_INPUTS, fcvtzs_d_inputs, 1)
TEST_INPUTS(
0x3FF0000000000000,
0xC000000000000000,
0x4024000000000000)
fmov d1, ARG1_64
fcvtzs d0, d1
TEST_END
1 change: 1 addition & 0 deletions backend/remill/tests/AArch64/Tests.S
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ SYMBOL(__aarch64_test_table_begin):
// #include "tests/AArch64/SIMD/SCVTF_ASIMDMISC_R.S"
// #include "tests/AArch64/SIMD/UCVTF_ASIMDMISC_R.S"
// #include "tests/AArch64/SIMD/FCVTZU_ASISDMISC_R.S"
#include "tests/AArch64/SIMD/FCVTZS_ASISDMISC_R.S"

#include "tests/AArch64/SYSTEM/Mn_n_SYSTEM_FPSR.S"
#include "tests/AArch64/SYSTEM/Mn_n_SYSTEM_FPCR.S"
Expand Down
168 changes: 129 additions & 39 deletions browser/js-kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,22 @@ var Module = (() => {

// call the target kernel function.
let sysRval = tgtKernelFunction(...sysArgs);
// store the return value of syscall function executing.
m32View[sysRvalPtr] = sysRval;

// notify to process worker
Atomics.store(m32View, waitPtr, 1);
Atomics.notify(m32View, waitPtr, 1);
// support async syscall handlers (e.g. poll with timeout)
if (sysRval instanceof Promise) {
sysRval.then(val => {
m32View[sysRvalPtr] = val;
Atomics.store(m32View, waitPtr, 1);
Atomics.notify(m32View, waitPtr, 1);
});
} else {
// store the return value of syscall function executing.
m32View[sysRvalPtr] = sysRval;

// notify to process worker
Atomics.store(m32View, waitPtr, 1);
Atomics.notify(m32View, waitPtr, 1);
}
}

function exitHandling(workerId) {
Expand Down Expand Up @@ -3000,8 +3010,10 @@ var Module = (() => {
["seq", "busybox"],
["sleep", "busybox"],
["tail", "busybox"],
["top", "busybox"],
["tree", "busybox"],
["uname", "busybox"],
["uptime", "busybox"],
["vi", "busybox"],
["cat", "busybox"],
["touch", "busybox"],
Expand Down Expand Up @@ -3340,9 +3352,16 @@ var Module = (() => {
};
var PROCFS = {
ops_table: null,
_bootTime: null,
init(initPid) {
PROCFS.mount();
PROCFS._bootTime = Date.now();
this.createMyProc(initPid);
// system-wide /proc files
FS.mknod("/proc/stat", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 740);
FS.mknod("/proc/meminfo", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 741);
FS.mknod("/proc/uptime", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 742);
FS.mknod("/proc/loadavg", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 743);
// /proc/self
let selfNode = FS.symlink(`/proc/${initPid}`, `/proc/self`);
// /proc/self/exe for python (FIXME)
Expand Down Expand Up @@ -3531,6 +3550,52 @@ var Module = (() => {
readProcCmdline(task) {
return new TextEncoder().encode(task.comm).buffer;
},
readProcSystemStat() {
// Minimal /proc/stat for busybox top
let now = Date.now();
let uptimeMs = now - PROCFS._bootTime;
let jiffies = Math.floor(uptimeMs / 10); // USER_HZ=100
let user = Math.floor(jiffies * 0.05);
let system = Math.floor(jiffies * 0.02);
let idle = jiffies - user - system;
let lines = [
`cpu ${user} 0 ${system} ${idle} 0 0 0 0 0 0`,
`cpu0 ${user} 0 ${system} ${idle} 0 0 0 0 0 0`,
`intr 0`,
`ctxt 0`,
`btime ${Math.floor(PROCFS._bootTime / 1000)}`,
`processes 1`,
`procs_running 1`,
`procs_blocked 0`,
];
return new TextEncoder().encode(lines.join("\n") + "\n").buffer;
},
readProcMeminfo() {
let totalKB = 512 * 1024;
let freeKB = 256 * 1024;
let availKB = 384 * 1024;
let buffersKB = 16 * 1024;
let cachedKB = 64 * 1024;
let lines = [
`MemTotal: ${totalKB} kB`,
`MemFree: ${freeKB} kB`,
`MemAvailable: ${availKB} kB`,
`Buffers: ${buffersKB} kB`,
`Cached: ${cachedKB} kB`,
`SwapCached: 0 kB`,
`SwapTotal: 0 kB`,
`SwapFree: 0 kB`,
];
return new TextEncoder().encode(lines.join("\n") + "\n").buffer;
},
readProcUptime() {
let uptimeSec = ((Date.now() - PROCFS._bootTime) / 1000).toFixed(2);
let idleSec = (uptimeSec * 0.95).toFixed(2);
return new TextEncoder().encode(`${uptimeSec} ${idleSec}\n`).buffer;
},
readProcLoadavg() {
return new TextEncoder().encode("0.00 0.00 0.00 1/1 1\n").buffer;
},
readProcMaps() {
// Minimal /proc/self/maps template for your 256MiB arena.
//
Expand Down Expand Up @@ -3623,17 +3688,28 @@ var Module = (() => {
let parent = FS.lookupPath(stream.path, {
parent: true
}).node;
// get the target content.
let task = processes.get(+(parent.name)).task;
let content;
if (stream.node.name === `stat`) {
content = PROCFS.readProcStat(task);
} else if (stream.node.name === `cmdline`) {
content = PROCFS.readProcCmdline(task);
} else if (stream.node.name == `maps`) {
content = PROCFS.readProcMaps();
// system-wide /proc files (parent is "proc")
if (parent.name === "proc") {
switch (stream.node.name) {
case "stat": content = PROCFS.readProcSystemStat(); break;
case "meminfo": content = PROCFS.readProcMeminfo(); break;
case "uptime": content = PROCFS.readProcUptime(); break;
case "loadavg": content = PROCFS.readProcLoadavg(); break;
default: throw new FS.ErrnoError(2);
}
} else {
throw new FS.ErrnoError(2);
// per-process /proc/<pid>/ files
let task = processes.get(+(parent.name)).task;
if (stream.node.name === `stat`) {
content = PROCFS.readProcStat(task);
} else if (stream.node.name === `cmdline`) {
content = PROCFS.readProcCmdline(task);
} else if (stream.node.name == `maps`) {
content = PROCFS.readProcMaps();
} else {
throw new FS.ErrnoError(2);
}
}
// copy the buffer
if (position >= content.byteLength) {
Expand Down Expand Up @@ -4400,38 +4476,52 @@ var Module = (() => {
}

function ___syscall_poll_scan(fds, nfds, tmSec, tmNsec) {
try {

growMemViews(gWasmMemory);
growMemViews(gWasmMemory);

let timeout = 0;
if (tmSec == -1) {
timeout = -1;
} else {
timeout = tmSec + tmNsec * 1e-9;
}
let timeoutSec = 0;
if (tmSec == -1) {
timeoutSec = -1;
} else {
timeoutSec = tmSec + tmNsec * 1e-9;
}

let nonzero = 0;
for (var i = 0; i < nfds; i++) {
var pollfd = fds + 8 * i;
var fd = HEAP32[pollfd >> 2];
var events = HEAP16[pollfd + 4 >> 1];
var mask = 32;
var stream = FS.getStream(fd);
if (stream) {
if (stream.stream_ops.poll) {
mask = stream.stream_ops.poll(stream, events, timeout)
// Scan all FDs for readiness, tolerating PTY "wait again" exceptions.
let nonzero = 0;
let needsWait = false;
for (var i = 0; i < nfds; i++) {
var pollfd = fds + 8 * i;
var fd = HEAP32[pollfd >> 2];
var events = HEAP16[pollfd + 4 >> 1];
var mask = 32;
var stream = FS.getStream(fd);
if (stream) {
if (stream.stream_ops.poll) {
try {
mask = stream.stream_ops.poll(stream, events, timeoutSec);
} catch (e) {
// PTY throws ErrnoError(1006) when not readable and timeout is set.
if (e.name === "ErrnoError") {
mask = 0;
needsWait = true;
} else {
throw e;
}
}
}
mask &= events | POLLERR | POLLHUP;
if (mask) nonzero++;
HEAP16[pollfd + 6 >> 1] = mask
}
return nonzero
} catch (e) {
if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
return -e.errno
mask &= events | POLLERR | POLLHUP;
if (mask) nonzero++;
HEAP16[pollfd + 6 >> 1] = mask;
}

// If no FDs are ready and there is a non-zero timeout, sleep before returning.
if (nonzero === 0 && (timeoutSec > 0 || (timeoutSec === -1 && needsWait))) {
var delayMs = timeoutSec > 0 ? Math.min(timeoutSec * 1000, 30000) : 1000;
return new Promise(resolve => setTimeout(() => resolve(0), delayMs));
}

return nonzero;
}

function ___syscall_pselect6_scan(nfds, readfdsP, writefdsP, exceptfdsP, tmSec, tmNsec, sigmaskP) {
Expand Down
Loading
Loading