Skip to content

Commit 9a6379d

Browse files
authored
Merge pull request #8 from imbev/main
Misc improvements
2 parents 8fd53c0 + d87f46c commit 9a6379d

File tree

9 files changed

+122
-85
lines changed

9 files changed

+122
-85
lines changed

docs/concepts/_category_.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"position": 3,
55
"link": {
66
"type": "generated-index",
7-
"description": "Learn more about the libriscv APIs."
7+
"description": "Learn more about libriscv concepts and important parts of the C++ API."
88
}
99
}

docs/concepts/vmcalls.md

+3-74
Original file line numberDiff line numberDiff line change
@@ -272,79 +272,8 @@ inline std::optional<Script::sgaddr_t> Script::call(gaddr_t address, Args&&... a
272272
```
273273
From `script.call(...)` as implemented in the [gamedev example](https://github.com/libriscv/libriscv/blob/master/examples/gamedev/script.hpp). `ScriptDepthMeter` measures the current call depth in order to avoid too many recursive calls back into the script, while also using the faster `vmcall()` on the first call.
274274

275-
## VM Calls with the C API
276275

277-
In the C API each argument register has to be populated manually, and the return value(s) have to be read as well.
276+
## Examples
278277

279-
A general rule for passing data to a function is that:
280-
1. Each integer goes into the next free integer register
281-
2. Each pointer goes into the next free integer register
282-
283-
```c
284-
LIBRISCV_ARG_REGISTER(regs, 0) = 1;
285-
LIBRISCV_ARG_REGISTER(regs, 1) = true;
286-
LIBRISCV_ARG_REGISTER(regs, 2) = libriscv_stack_push(machine, regs, mystruct, sizeof(mystruct));
287-
LIBRISCV_ARG_REGISTER(regs, 3) = libriscv_address_of(machine, "my_function");
288-
```
289-
A function address is also a pointer, which goes into the integer register file.
290-
291-
292-
3. Each float goes into the next free float register of that type
293-
294-
```c
295-
LIBRISCV_FP32_ARG_REG(regs, 0) = 1.0f;
296-
LIBRISCV_FP32_ARG_REG(regs, 1) = 2.0f;
297-
LIBRISCV_FP64_ARG_REG(regs, 2) = 3.0;
298-
LIBRISCV_FP64_ARG_REG(regs, 3) = 4.0;
299-
```
300-
32- and 64-bit floating point values use the same register file.
301-
302-
303-
### Example
304-
305-
Function:
306-
```c
307-
long my_function(const char* arg1, const bool arg2, const struct my_struct* arg3, size_t arg4, float arg5);
308-
```
309-
310-
Input values:
311-
```c
312-
const char* mystring = "";
313-
const bool mybool = true;
314-
const struct mystruct s;
315-
const size_t mysize = 4;
316-
const float myfloat = 5.0f;
317-
```
318-
319-
C++ API:
320-
```cpp
321-
long result = machine.vmcall(guest_function_address,
322-
mystring, mybool, mystruct, mysize, myfloat);
323-
```
324-
325-
C API:
326-
```c
327-
/* We start by setting up the call, providing the address of the function */
328-
libriscv_setup_vmcall(machine, guest_function_address);
329-
330-
/**
331-
* We push structs on the stack, and get a guest pointer in return.
332-
* Guest pointers go into integer registers along with other integers
333-
**/
334-
LIBRISCV_ARG_REGISTER(regs, 0) = libriscv_stack_push(machine, regs, ...);
335-
LIBRISCV_ARG_REGISTER(regs, 1) = true;
336-
LIBRISCV_ARG_REGISTER(regs, 2) = libriscv_stack_push(machine, regs, ...);
337-
LIBRISCV_ARG_REGISTER(regs, 3) = 4;
338-
/* Floating point values go into their own registers */
339-
LIBRISCV_FP32_ARG_REG(regs, 0) = 5.0f;
340-
341-
/* Running the VM will now execute the function with the above arguments as input */
342-
if (libriscv_run(machine, ~0)) {
343-
fprintf(stderr, "Ooops! Function call failed!\n");
344-
exit(1);
345-
}
346-
347-
/* Integer return values are in A0. */
348-
long result = LIBRISCV_ARG_REGISTER(regs, 0);
349-
printf("The function returned: %ld\n", result);
350-
```
278+
- [C](/docs/host_langs/c_lang#vm-call-example)
279+
- [C++](/docs/host_langs/cpp_lang#vm-call-example)

docs/getting_started/_category_.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"position": 2,
55
"link": {
66
"type": "generated-index",
7-
"description": "Learn more about libriscv performance."
7+
"description": "Get started with libriscv here! This tutorial will guide you through a simple C++ host and C guest program."
88
}
99
}

docs/getting_started/guest.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ zig cc -target riscv64-linux guest.c -o guest.bin
4141

4242
### Note
4343

44-
Guest binaries may also be written in other [languages](/docs/category/guest-languages).
44+
Guest programs may also be written in other [languages](/docs/category/guest-languages).

docs/getting_started/host.md

+5
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,8 @@ Hello from host!
111111
Hello world!
112112
Hello from riscv64 guest!
113113
```
114+
115+
### Note
116+
117+
Host programs may also be written in other [languages](/docs/category/host-languages).
118+

docs/getting_started/intro.md

-5
This file was deleted.

docs/host_langs/c_lang.md

+80-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 2
2+
sidebar_position: 3
33
---
44

55
# C
@@ -24,6 +24,84 @@ Visual Studio is a proprietary C & C++ compiler for Windows. Learn more at https
2424

2525
The C header for the libriscv C API can be found at https://github.com/libriscv/libriscv/blob/master/c/libriscv.h
2626

27+
### VM Calls
28+
29+
In the C API each argument register has to be populated manually, and the return value(s) have to be read as well.
30+
31+
A general rule for passing data to a function is that:
32+
1. Each integer goes into the next free integer register
33+
2. Each pointer goes into the next free integer register
34+
35+
```c
36+
LIBRISCV_ARG_REGISTER(regs, 0) = 1;
37+
LIBRISCV_ARG_REGISTER(regs, 1) = true;
38+
LIBRISCV_ARG_REGISTER(regs, 2) = libriscv_stack_push(machine, regs, mystruct, sizeof(mystruct));
39+
LIBRISCV_ARG_REGISTER(regs, 3) = libriscv_address_of(machine, "my_function");
40+
```
41+
A function address is also a pointer, which goes into the integer register file.
42+
43+
44+
3. Each float goes into the next free float register of that type
45+
46+
```c
47+
LIBRISCV_FP32_ARG_REG(regs, 0) = 1.0f;
48+
LIBRISCV_FP32_ARG_REG(regs, 1) = 2.0f;
49+
LIBRISCV_FP64_ARG_REG(regs, 2) = 3.0;
50+
LIBRISCV_FP64_ARG_REG(regs, 3) = 4.0;
51+
```
52+
32- and 64-bit floating point values use the same register file.
53+
2754
## Examples
2855

29-
An advanced example can be found at https://github.com/libriscv/libriscv/blob/master/examples/advanced/src/example.c
56+
### VM call example
57+
58+
Guest Function:
59+
```c
60+
long my_function(
61+
const char* arg1,
62+
const bool arg2,
63+
const struct my_struct* arg3,
64+
size_t arg4,
65+
float arg5
66+
);
67+
```
68+
69+
Input values:
70+
```c
71+
const char* mystring = "";
72+
const bool mybool = true;
73+
const struct mystruct s;
74+
const size_t mysize = 4;
75+
const float myfloat = 5.0f;
76+
```
77+
78+
C Host:
79+
```c
80+
/* We start by setting up the call, providing the address of the function */
81+
libriscv_setup_vmcall(machine, guest_function_address);
82+
83+
/**
84+
* We push structs on the stack, and get a guest pointer in return.
85+
* Guest pointers go into integer registers along with other integers
86+
**/
87+
LIBRISCV_ARG_REGISTER(regs, 0) = libriscv_stack_push(machine, regs, ...);
88+
LIBRISCV_ARG_REGISTER(regs, 1) = true;
89+
LIBRISCV_ARG_REGISTER(regs, 2) = libriscv_stack_push(machine, regs, ...);
90+
LIBRISCV_ARG_REGISTER(regs, 3) = 4;
91+
/* Floating point values go into their own registers */
92+
LIBRISCV_FP32_ARG_REG(regs, 0) = 5.0f;
93+
94+
/* Running the VM will now execute the function with the above arguments as input */
95+
if (libriscv_run(machine, ~0)) {
96+
fprintf(stderr, "Ooops! Function call failed!\n");
97+
exit(1);
98+
}
99+
100+
/* Integer return values are in A0. */
101+
long result = LIBRISCV_ARG_REGISTER(regs, 0);
102+
printf("The function returned: %ld\n", result);
103+
```
104+
105+
### Advanced example
106+
107+
https://github.com/libriscv/libriscv/blob/master/examples/advanced/src/example.c

docs/host_langs/cpp_lang.md

+30
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,34 @@ C++ headers for libriscv can be found at https://github.com/libriscv/libriscv/tr
2626

2727
## Examples
2828

29+
### VM call example
30+
31+
Guest Function:
32+
```c
33+
long my_function(
34+
const char* arg1,
35+
const bool arg2,
36+
const struct my_struct* arg3,
37+
size_t arg4,
38+
float arg5
39+
);
40+
```
41+
42+
Input values:
43+
```c
44+
const char* mystring = "";
45+
const bool mybool = true;
46+
const struct mystruct s;
47+
const size_t mysize = 4;
48+
const float myfloat = 5.0f;
49+
```
50+
51+
C++ Host:
52+
```cpp
53+
long result = machine.vmcall(guest_function_address,
54+
mystring, mybool, mystruct, mysize, myfloat);
55+
```
56+
57+
### Misc examples
58+
2959
Most examples located here are written for a C++ host: https://github.com/libriscv/libriscv/tree/master/examples

docs/host_langs/godot_integration/_category_.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"label": "GDScript",
33
"collapsed": true,
4-
"position": 2,
4+
"position": 3,
55
"link": {
66
"type": "generated-index",
77
"description": "GDScript is a scripting language to be used with the Godot Game engine."

0 commit comments

Comments
 (0)