Coder Social home page Coder Social logo

fwsgonzo / libriscv Goto Github PK

View Code? Open in Web Editor NEW
409.0 12.0 43.0 10.36 MB

C++20 RISC-V RV32/64/128 userspace emulator library

License: BSD 3-Clause "New" or "Revised" License

CMake 3.84% C++ 89.43% Shell 1.31% C 4.06% Python 0.42% Zig 0.39% Go 0.23% Nim 0.07% GDB 0.02% Assembly 0.03% Rust 0.12% Dockerfile 0.08%
risc-v riscv-emulator userspace cpp emulator riscv binary-translation interpreter cpp20 low-latency

libriscv's People

Contributors

fire avatar fwsgonzo avatar iyzsong avatar mutzi100 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libriscv's Issues

Bug in native memmove syscall

if (src < dst)
{
for (unsigned i = 0; i != len; i++) {
m.memory.template write<uint8_t> (dst + i,
m.memory.template read<uint8_t> (src + i));
}
} else {
while (len-- != 0) {
m.memory.template write<uint8_t> (dst + len,
m.memory.template read<uint8_t> (src + len));
}
}

The comparison is done the wrong way around. It should be >.

If I have an array a: [1, 2, 3, 4, 5, 6] and want to move it and want to move 3, 4, 5, 6 two places to the front then the call would be memmove(&a[0], &a[2], 4) so src > dst.
Since the if condition would fail, it would move the array from the end like this:
a[3] = a[5] [1, 2, 3, 6, 5, 6]
a[2] = a[4] [1, 2, 5, 6, 5, 6]
a[1] = a[3] [1, 6, 5, 6, 5, 6]
a[0] = a[2] [5, 6, 5, 6, 5, 6]

License is missing

The project looks interesting to me, and I want to use it in some of my commercial projects but I cannot find a license file.

STREAM with compressed instructions misbehaving

The STREAM benchmark compiled with GCC 10 and compressed instructions hits a FUTEX deadlock.

>>> Machine exception 10: FUTEX deadlock (data: 0xB78E5D8)
-> [0] 0x000000000001AF10 + 0x024: __lll_lock_wait_private
-> [1] 0x0000000000015FCE + 0x13c: puts
>>> Program exited, exit code = 0 (0x0)
Instructions executed: 12881
Pages in use: 9 (36 kB memory)

RV128I needs C-extension support

Right now RV128IMFD is supported. We also want to support the C-extension, but it's not easy to test without a real toolchain or even just a 128-bit assembler.

The C-extension is supposedly mostly the same, but C.FLWSP changes to C.LQSP and C.FSWSP changes to C.SQSP.
Reminder to figure out if there is another pair of load/store that changes meaning.
What about C.LQ, C.SQ?

Binary translation bug

There is reproducible binary translation bug that happens when translating the attached binary:

hello_world.tar.gz

The binary is very small and translates only a single code block. Something happens at the end of the block that ends up what looks like duplication of an AUIPC instruction where the second instance is off by 16 bytes. The result is stored in RA, which is used to return back.

There is nothing apparent in the translator codepaths that could do this, so one theory is that the codeblock detector passes an invalid instruction by either off-by-one at end end or something like that.

Implement custom hash table for paging

After removing EASTL, which was a PITA anyway, it's clear there's been a performance regression. To combat that I want to implement a custom hash table that tries to use perfect hashing. Pages are keyed on page numbers which are somewhat sequential, so we will have to see how easy it is to generate perfect hashes for that.

Perhaps a hybrid solution where the initial state of the machine is perfectly hashed, followed by changes being implemented using normal hash table operations.

riscv compliance

Hello

First of all great piece of code, I really enjoy this style of writing, keep it up :)

And the actual question, did this emulator pass the https://github.com/riscv/riscv-compliance tests? And if so, how can I run them myself?

I did not find any information (at least yet) on this topic

Machine serialization needs work

In the trivial case it works well, but there are several things missing: Heap and threads serialization etc.
Not really a bug per se, but it can be confusing if serialization doesn't work in certain cases.

  • Avoid needing to serialize binary
  • Improve unit testing
  • Fix most interactions with arena

Expand compressed instructions for fastsim

It is possible to make compressed instructions faster using fastsim because it stores instructions separately as 32-bit. This will improve C-extension performance, but it will still not be able to match RV32G.

This will also be useful when I make a prototype for bytecode based simulation.

Atomic operations in binary translation

Currently we exit binary translation when we encounter unseen instructions, however instructions that don't jump to a random place are safe to execute within, and so we should just decode it on the spot instead. This would make certain cases much faster with binary translation enabled.

Fast simulator mode with C-extension support

It should be fairly easy now to add C-extension support to fast simulator mode, and perhaps even make it the default - eventually removing the old way of doing instruction caching.

It's not possible to reverse iterate the execute segment with C-extension, so we need a vector to measure the blocks.

A future idea is to detect if a program uses compressed instructions, and do the Right Thing - followed by function pointers to select the best simulation modes.

VMCALL question

So I've noticed that VMCALL uses parameter packs. This normally wouldn't be much of a problem if I call vmcall from C++, but I'd like to make a built-in to a scripting language that my game uses for general object creation (but that I obviously can't give normal players access to). That's where my idea of embedding libriscv came in in the other issue I opened.
Anyway, can I safely make a structure like this:

enum argtype {
    String,
    Number,
    Object,
    Error,
    List,
    FltNum,
    Anonymous,
    Waif,
    Boolean
};

struct Argument {
union val {
// Items
};
Argtype type;
};

struct ArgumentList {
size_t count;
Argument* args;
};

And then pass that structure into the machine like so:

machine.vmcall("function", arglist);

If not, what would I need to do to make something like this work? (Alternatively, could I use C++ types for this?)

SRA, SRAI, C.SRAI optimization

Right now these instructions use a loop to calculate the final value. Instead, we should use something like the conditional negative from bit twiddling hacks:

bool sign = ...;
const uint32_t sign_bits = (0 ^ -sign) + sign;
const uint32_t sign_shifted = sign_bits << (32 - shifts);
reg(dst) = value >> shifts | sign_shifted;

Which avoids the loop.

The over-engineered Golang runtime

Golang seems to have something that resembles a thread (sysmon) that is activated with signals, or something like that. Either way, there is no way around implemented signals, and there is a basic implementation in the emulator now with altstacks.

#0  runtime.rt_sigaction () at /go/src/runtime/sys_linux_riscv64.s:415
#1  0x00000000000428b8 in runtime.sysSigaction (sig=0, new=0xc000033ed8, old=0x0)
#2  0x0000000000058acc in runtime.sigaction (sig=0, new=0xc000033ed8, old=0x0)
    at /go/src/runtime/sigaction.go:15
#3  0x0000000000042738 in runtime.setsig (i=0, fn=0)
#4  0x000000000005bb30 in runtime.sigfwdgo (sig=0, info=0x0, ctx=0x17, ~r0=<optimized out>)
#5  0x000000000005a644 in runtime.sigtrampgo (sig=0, info=0x0, ctx=0x17)
#6  0x00000000000732e8 in runtime.sigtramp ()
#7  0x000000000004293c in runtime.signalM (mp=0x0, sig=0)

Unfortunately it seems to invoke signal 0, which doesn't have a handler (I assume). So, there is something wrong before hitting that call chain.

64-bit C-extension has a known bug

By building and running the newlib64 example with compressed instructions enabled we can see that the result is wrong. It's too complicated to try to debug millions of instructions, but at least we have a failing test case.

The 32-bit extension works well, which may suggest the problem is with the bitshifting instructions (SRA etc.) or there is some missing sign-extension to 64-bit on 32-bit operands.

Speed up binary translation loading times

It is possible to significantly speed up the loading times of the binary translation by hashing the executable portion of the binary only, and then use that to generate a filename. We also don't have to generate the code at all. This also means that we have to store the mappings as a table in the dynamic library.

We can start by hashing only the executable code, as it should be smaller than the generated code anyway, which reduces the hashing time a little bit. Getting rid of the code generation when it is not needed will be the major time saver.

Example how to load a shared library from RISCV

Usecase

I want to from the Windows operating system load a RISVC compiled shared library.

The use case is load a shared library that provides three symbols. There are two levels symbol and an user named entry symbol.

Is there a sample for this?

  1. I can build libriscv for Windows 11
  2. I can compile GDExtensionSummator for RISCV.
  3. ???
  4. Execute code from libgdsummator.linux.release.64.so

p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);

Relevant code

Error NativeExtension::open_library(const String &p_path, const String &p_entry_symbol) {
	Error err = OS::get_singleton()->open_dynamic_library(p_path, library, true);
	if (err != OK) {
		return err;
	}

	void *entry_funcptr = nullptr;

	err = OS::get_singleton()->get_dynamic_library_symbol_handle(library, p_entry_symbol, entry_funcptr, false);

	if (err != OK) {
		OS::get_singleton()->close_dynamic_library(library);
		return err;
	}

	GDNativeInitializationFunction initialization_function = (GDNativeInitializationFunction)entry_funcptr;

	initialization_function(&gdnative_interface, this, &initialization);
	level_initialized = -1;
	return OK;
}
////////////////////////////////////////////////////////////////////////////////
typedef enum {
	GDNATIVE_INITIALIZATION_CORE,
	GDNATIVE_INITIALIZATION_SERVERS,
	GDNATIVE_INITIALIZATION_SCENE,
	GDNATIVE_INITIALIZATION_DRIVER,
	GDNATIVE_INITIALIZATION_EDITOR,
	GDNATIVE_MAX_INITIALIZATION_LEVEL,
} GDNativeInitializationLevel;

typedef struct {
	/* Minimum initialization level required.
	 * If Core or Servers, the extension needs editor or game restart to take effect */
	GDNativeInitializationLevel minimum_initialization_level;
	/* Up to the user to supply when initializing */
	void *userdata;
	/* This function will be called multiple times for each initialization level. */
	void (*initialize)(void *userdata, GDNativeInitializationLevel p_level);
	void (*deinitialize)(void *userdata, GDNativeInitializationLevel p_level);
} GDNativeInitialization;

/* Define a C function prototype that implements the function below and expose it to dlopen() (or similar).
 * It will be called on initialization. The name must be an unique one specified in the .gdextension config file.
 */

typedef GDNativeBool (*GDNativeInitializationFunction)(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization);

References

  1. https://github.com/godotengine/godot/blob/master/drivers/unix/os_unix.cpp#L432-L454
  2. https://github.com/godotengine/godot/blob/master/core/extension/native_extension.cpp#L262-L282
  3. https://github.com/paddy-exe/GDExtensionSummator
  4. https://github.com/pfalcon/foreign-dlopen
  5. https://fabiensanglard.net/quake3/qvm.php

Flat memory mode

In order to beat other emulators (like WASM) we need to allocate memory in one block too. It will significantly improve all memory operations which are on the expensive side right now. It makes things a bit weird because we rely on the permissions and page attributes a lot for all kinds of nifty features.

Implement AMOMIN/AMOMAX pairs

The only missing instructions left now are the parallell min/max atomic helper instructions. Not sure if they are even generated by anything, but at some point they will be.

Debugging with Nim

It's fairly easy to debug with Nim, but there's no easy way to toggle it from the provided example. For now you have change the -d:release to --debugger=native, and then go into the build folder and enable the DEBUGGING CMake option. When you build with this enabled, you can connect remotely with GDB and see your Nim code as you wrote it, line by line.

Provided system calls needs improvement

The provided system calls that comes with the emulator needs to be improved upon to handle basic tasks like reading files and such. Unfortunately, there is a stigma to allowing an emulator full system access, and sanitizing files and paths is not an easy task - especially designing the API and not making so that nobody wants to touch it.

That said, the emulator is not a sandbox. It is a reference implementation that should be able to run basic programs. Any isolation and tight integration into other programs falls out of that scope.

Also, the multi-threading needs to be improved so that it can run basic Go programs.

LTO and ccache

It's clear that LTO detection does not work well when ccache is enabled, unfortunately.

It's not a huge problem as LTO simply gets disabled.

Measure impact of converting decoder cache into indexed pointer array

While I've tried this before, at least twice, it would be nice to do it again more thoroughly. There is a lot of good reasons to try to reduce the size of the instruction cache by converting it to a small indexed array of function pointers, instead of converting executable pages into larger function pointer arrays.

Cannot fully check out repository; possibly unnecessary re-implementation of std::function

One issue and one question (sorry if this isn't the right place for the second).
First, When attempting to clone the repositories submodules, I cannot fully check out the EASTL:

Cloning into 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EABase'...
'plink: -c: line 0: unexpected EOF while looking for matching `''
'plink: -c: line 1: syntax error: unexpected end of file
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:electronicarts/EABase.git' into submodule path 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EABase' failed
Failed to clone 'test/packages/EABase'. Retry scheduled
Cloning into 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EAMain'...
'plink: -c: line 0: unexpected EOF while looking for matching `''
'plink: -c: line 1: syntax error: unexpected end of file
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:electronicarts/EAMain.git' into submodule path 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EAMain' failed
Failed to clone 'test/packages/EAMain'. Retry scheduled
Cloning into 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EASTL'...
'plink: -c: line 0: unexpected EOF while looking for matching `''
'plink: -c: line 1: syntax error: unexpected end of file
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:electronicarts/EASTL.git' into submodule path 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EASTL' failed
Failed to clone 'test/packages/EASTL'. Retry scheduled
Cloning into 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EAStdC'...
'plink: -c: line 0: unexpected EOF while looking for matching `''
'plink: -c: line 1: syntax error: unexpected end of file
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:electronicarts/EAStdC.git' into submodule path 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EAStdC' failed
Failed to clone 'test/packages/EAStdC'. Retry scheduled
Cloning into 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EATest'...
'plink: -c: line 0: unexpected EOF while looking for matching `''
'plink: -c: line 1: syntax error: unexpected end of file
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:electronicarts/EATest.git' into submodule path 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EATest' failed
Failed to clone 'test/packages/EATest'. Retry scheduled
Cloning into 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EAThread'...
'plink: -c: line 0: unexpected EOF while looking for matching `''
'plink: -c: line 1: syntax error: unexpected end of file
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:electronicarts/EAThread.git' into submodule path 'C:/Users/ethin/source/libriscv/lib/EASTL/test/packages/EAAssert/test/packages/EAThread' failed
Failed to clone 'test/packages/EAThread'. Retry scheduled

Naturally, it retries and fails again. Should I just rip out EASTL entirely and replace them with the standard STL types instead?
Second, I notice in your code that you re-implement std::function (or you appear to re-implement it). Is this correct and, if so, can you explain how std::function doesn't suffice for your purposes? I'm asking purely out of curiosity.

clang toolchain compilation for newbies?

i am playing around with the examples, and using the toolchain linked in the readme works.
now i want a toolchain i could redistribute, so i am trying to build a llvm toolchain that can target riscv32 and comes with a non-gpl-ed static libc/cxx. i would like to play around with c++ including stl but (mostly) my own syscalls in the vm.
but i am having a hard time getting the llvm toolchain compiled, especially the llvm-libc. i tried using a riscv-musl instead, but that collides horribly over std::size_t being 32 or 64 bit.
seeing clang/llvm mentioned, are you able to provide the options you used to compile a working llvm toolchain that goes nicely with the vm?

i am currently using this for llvm:
cmake ../llvm-project/llvm -DLLVM_TARGETS_TO_BUILD="RISCV" -DCMAKE_INSTALL_PREFIX=${TOOLCHAIN_DIR} -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;libc;libcxx;libcxxabi" -DLLVM_ENABLE_THREADS=on -DLLVM_STATIC_LINK_CXX_STDLIB=on
but as i said the libc part will fail, complaining about a missing syscall.h. this is with the latest git llvm, same with release 10.

Implement V-extension once standardized

Vector instructions might give a boost in some scenarios, although I don't personally need them for anything I do. The emulator is not a very good number cruncher to begin with, but it will be interesting to see what vector instructions can offer. We could in theory support two sizes: One 128-bit vector and another 512/1024/2048-bit vector just to try to amortize the cost of instructions.

Add more CPU simulation modes

Right now the CPU simulate function is a bunch of ifdefs that tries to maximize speed depending on which options are enabled. Instead, it would be nice if there were one for normal simulation, and another mode for debugging.

This needs more investigation. One potential problem is that debugging adds a lot of extra memory overhead to the emulator.

Trouble executing linux compiled testsuite64 in Windows

Hi,

I was trying to execute the testsuite for an emulator compiled with llvm-mingw.

Nothing happens.

It was odd.

scoop install llvm-mingw
cd emulator 
mkdir -p build
cd build
cmake .. -GNinja
ninja
# Execute emulator with a testsuite64 compiled from wsl ubuntu 20.

New upcoming release

It is about time to make a new release. One of the primary features I wanted in the next release is the unit testing framework combined with Github Actions that ensures that I don't break stuff all the time.

There is multiprocessing support now, and it seems to be working quite well along with proper atomic operations when emulating the RISC-V A instructions. Some minor overhead in starting multiprocessing jobs but it seems to be a solvable problem. Something to work on when I feel like it. It is not a general feature, and it's perhaps best explained in this medium article I wrote.

The emulator can now be built and should work as-is on MinGW 64-bit. Several emulation issues have been fixed, and many new system calls are now supported, including reading and writing to files, reading and writing from standard pipes, and even basic TCP sockets. Many of these things are not very sandboxy and is mostly interesting when we are trying to run a RISC-V program as if it was a normal host program.

There has been some improvements made to the internal debugger, allowing new ways of stepping through the internals of a program. For example simple backtrace and various symbol lookup helpers.

Binary translation has received some love to make it faster to activate, especially when it's already cached. Downside is that if I'm working on it (fixing a problem or adding a feature) it will not realize that something changed internally, and not rebuild the cached program. That is fortunately only a problem for me, and the benefit is heavily outweighing the drawback. I do wish the translator could handle compressed instructions, but that is a task for another time.

  • Github Actions: MinGW w64 cross compiler build
  • Replace all usage of std::runtime_error with a relevant MachineException
  • Handle unaligned loads on non-amd64 architectures
  • Golang hello world program with unit test
  • Figure out why PNG encoding fails on 64-bit RISC-V in many cases
  • Make sure documentation is up to date

ELF loader is insecure

The fuzzer is reliably crashing the ELF loader. This is of course expected as I know about the problematic areas, but they need to be plugged. And the fuzzer needs to agree with me that everything is OK.

Likely 64-bit emulation bug when encoding PNGs

Encoding PNGs are failing on 64-bit and it is easily provoked by changing the compression algorithm. A test case should be added that reveals the problem more easily for me so that I can study it more. Once it is fixed we can proceed to release the new version.

Known issue with printing floating point values

If you print a floating-point value using the newlib example binary you will see that something is very wrong. Some loop doesn't finish, or some calculation is wrong, or something is jumping too far resulting in the output string having 10+ zeroes behind the decimal point, while also multiplying the answer by 10.

So, what's going on here? The answer is I don't know. I have been trying to figure out this problem for a while now, and the _dtoa_r function in newlib is too complex to follow in disassembly. So, my idea of a path to a resolution is to try to find some kind of shorter test-case that has a visibly wrong output. I am thinking about copying all the C++ examples from each cppreference page and seeing if the output is not matching. So far, it has been matching, even the std::regex page.

Setup failed

Hello. I am interested in trying this as a sandbox environment. I'm hoping for something relatively simple.

However, I can't get anything to build. The setup.sh script fails and nothing will compile.

Here is the error:

[ 11%] Creating directories for 'robinhood-populate'
[ 22%] Performing download step (git clone) for 'robinhood-populate'
-- Avoiding repeated git clone, stamp file is up to date:
'/opt/libriscv/emulator/build/_deps/robinhood-subbuild/robinhood-populate-prefix/
src/robinhood-populate-stamp/robinhood-populate-gitinfo.txt'

[ 33%] No patch step for 'robinhood-populate'
[ 44%] Performing update step for 'robinhood-populate'
CMake Error at /opt/libriscv/emulator/build/_deps/robinhood-subbuild/robinhood-populate-prefix/
tmp/robinhood-populate-gitupdate.cmake:10 (message):
  Failed to get the hash for HEAD


make[2]: *** [CMakeFiles/robinhood-populate.dir/build.make:97: robinhood-populate-prefix/
src/robinhood-populate-stamp/robinhood-populate-update] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/robinhood-populate.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

What is robinhood-populate? How do I fix this?

RISC-V Supervisor mode

I have just laid the foundation down to hopefully be able to implement supervisor mode, at some point. By adding a cacheable flag to pages, we can have an uncacheable slow path for memory operations, where we can check if a page has a memory trap callback set. Using that we may be able to implement simple MMIO and such things. If nothing else the memory trap callbacks are great tools for debugging that is now available.

The S-extension will have to be a new CMake option, and all the CSRs and page tables will have to be implemented.

TODO:

  • The CSR emulation in machine.cpp needs a better abstraction
  • The supervisor extension needs to be fleshed out in supervisor.cpp
  • We need to either detect pagetable changes using memory traps, or simply always switch out the pages when the privilege level changes. The latter sounds like a simpler way to get to a working implementation.
  • New constructors are needed in Machine (machine.cpp) in order to construct a Machine for full-system emulation
  • Pass all the sail-riscv supervisor tests

Probably missing case for 64-bit integer division

On x86 you can fault on integer divisions that you don't have room for. I have a case for 32-bit divides, but I don't remember adding one for 64-bit. Should probably look into that - and why isn't the fuzzer catching it?

Windows compatibility

Currently linux-only files:

  • lib/libriscv/socket_calls.cpp
  • lib/libriscv/system_calls.cpp
  • lib/libriscv/rsp_server.hpp

Other:

  • lib/libriscv/machine.hpp
    • Mingw defines stdin as (__acrt_iob_func(0)) so the function name in L151 breaks.
  • MSVC compiler error: invalid numeric argument '/Wextra'

Consider possibility of gathering blocks of code that doesn't exit

For the instruction cache, it would be possible to gather blocks of code that doesn't trap or jump. For example, it could be gathered into a std::vector of instructions that you can safely execute in one go. After, we can increment instruction counter and test against max instructions.

It gets a little bit more complicated when we have to consider instructions that can throw exceptions, like loads and stores.
On top of all of this we need the instruction itself, because it's not fully decoded, just attached to a function pointer.

IDEA:

struct decoded_instruction {
    uint8_t function; // -> array[] of decoders

};

Binary translation should translate whole binary

Right now the translator tries to find interesting blocks that it thinks will work well with binary translation, and only translates those. It would probably be better to just translate the whole thing. I'm still not sure how to do this, because it is important to be able to pause and resume later, and it's not clear to me how to resume from any point. I guess it could be running in a separate thread, and not a pthread, but just a green thread that is resumable at every crossroads (instruction that is a natural exit point).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.