duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

README.md (3999B)


      1 # Biscuit: RISC-V Runtime Code Generation Library
      2 
      3 *RISC it for the biscuit*
      4 
      5 ## About
      6 
      7 An experimental runtime code generator for RISC-V.
      8 
      9 This allows for runtime code generation of RISC-V instructions. Similar
     10 to how [Xbyak](https://github.com/herumi/xbyak) allows for runtime code generation of x86 instructions.
     11 
     12 
     13 ## Implemented ISA Features
     14 
     15 Includes both 32-bit and 64-bit instructions in the following:
     16 
     17 | Feature   | Version |
     18 |:----------|:-------:|
     19 | A         | 2.1     |
     20 | B         | 1.0     |
     21 | C         | 2.0     |
     22 | D         | 2.2     |
     23 | F         | 2.2     |
     24 | H         | 1.0 RC  |
     25 | K         | 1.0.1   |
     26 | M         | 2.0     |
     27 | N         | 1.1     |
     28 | Q         | 2.2     |
     29 | RV32I     | 2.1     |
     30 | RV64I     | 2.1     |
     31 | S         | 1.12    |
     32 | V         | 1.0     |
     33 | Sstc      | 0.5.4   |
     34 | Zfh       | 1.0     |
     35 | Zfhmin    | 1.0     |
     36 | Zicbom    | 1.0     |
     37 | Zicbop    | 1.0     |
     38 | Zicboz    | 1.0     |
     39 | Zicsr     | 2.0     |
     40 | Zifencei  | 2.0     |
     41 | Zihintntl | 0.2     |
     42 
     43 Note that usually only extensions considered ratified will be implemented
     44 as non-ratified documents are considerably more likely to have
     45 large changes made to them, which makes maintaining instruction
     46 APIs a little annoying.
     47 
     48 
     49 ## Dependencies
     50 
     51 Biscuit requires no external dependencies for its library other than the C++ standard library. 
     52 The tests, however, use the Catch2 testing library. This is included in tree so there's no need
     53 to worry about installing it yourself if you wish to run said tests.
     54 
     55 
     56 ## Building Biscuit
     57 
     58 1. Generate the build files for the project with CMake
     59 2. Hit the build button in your IDE of choice, or run the relevant console command to build for the CMake generator you've chosen.
     60 3. Done.
     61 
     62 
     63 ## Running Tests
     64 
     65 1. Generate the build files for the project with CMake
     66 2. Build the tests
     67 3. Run the test executable directly, or enter `ctest` into your terminal.
     68 
     69 
     70 ## License
     71 
     72 The library is licensed under the MIT license.
     73 
     74 While it's not a requirement whatsoever, it'd be pretty neat if you told me that you found the library useful :-)
     75 
     76 
     77 ## Example
     78 
     79 The following is an adapted equivalent of the `strlen` implementation within the RISC-V bit manipulation extension specification.
     80 For brevity, it has been condensed to only handle little-endian platforms.
     81 
     82 ```cpp
     83 // We prepare some contiguous buffer and give the pointer to the beginning
     84 // of the data and the total size of the buffer in bytes to the assembler.
     85 
     86 void strlen_example(uint8_t* buffer, size_t buffer_size) {
     87     using namespace biscuit;
     88 
     89     constexpr int ptrlog = 3;
     90     constexpr int szreg  = 8;
     91 
     92     Assembler as(buffer, buffer_size);
     93     Label done;
     94     Label loop;
     95 
     96     as.ANDI(a3, a0, szreg - 1); // Offset
     97     as.ANDI(a1, a0, 0xFF8);     // Align pointer
     98 
     99     as.LI(a4, szreg);
    100     as.SUB(a4, a4, a3);         // XLEN - offset
    101     as.SLLI(a3, a3, ptrlog);    // offset * 8
    102     as.LD(a2, 0, a1);           // Chunk
    103 
    104     //
    105     // Shift the partial/unaligned chunk we loaded to remove the bytes
    106     // from before the start of the string, adding NUL bytes at the end.
    107     //
    108     as.SRL(a2, a2, a3);         // chunk >> (offset * 8)
    109     as.ORCB(a2, a2);
    110     as.NOT(a2, a2);
    111 
    112     // Non-NUL bytes in the string have been expanded to 0x00, while
    113     // NUL bytes have become 0xff. Search for the first set bit
    114     // (corresponding to a NUL byte in the original chunk).
    115     as.CTZ(a2, a2);
    116 
    117     // The first chunk is special: compare against the number of valid
    118     // bytes in this chunk.
    119     as.SRLI(a0, a2, 3);
    120     as.BGTU(a4, a0, &done);
    121     as.ADDI(a3, a1, szreg);
    122     as.LI(a4, -1);
    123 
    124     // Our critical loop is 4 instructions and processes data in 4 byte
    125     // or 8 byte chunks.
    126     as.Bind(&loop);
    127 
    128     as.LD(a2, szreg, a1);
    129     as.ADDI(a1, a1, szreg);
    130     as.ORCB(a2, a2);
    131     as.BEQ(a2, a4, &loop);
    132 
    133     as.NOT(a2, a2);
    134     as.CTZ(a2, a2);
    135     as.SUB(a1, a1, a3);
    136     as.ADD(a0, a0, a1);
    137     as.SRLI(a2, a2, 3);
    138     as.ADD(a0, a0, a2);
    139 
    140     as.Bind(&done);
    141 
    142     as.RET();
    143 }
    144 ```