mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-15 10:36:59 +00:00
jit/decoder: Add generated arm32 tests
Introduces the first unit tests for the ARM32 JIT decoder. A new script automatically generates a test case for every instruction in arm32.inc, providing 100% of the isa. This also includes a critical rework of the decoder's lookup table generation logic. The previous hashing method was flawed, causing build-time overflows and incorrect instruction matching (shadowing) for patterns with wildcards. The new algorithm correctly populates the lookup table. Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
parent
c235e57071
commit
d1e3919a8c
13 changed files with 37513 additions and 502 deletions
|
|
@ -28,7 +28,6 @@ pvm_jit_decoder_arm32_decode (const uint32_t instruction)
|
|||
}
|
||||
}
|
||||
|
||||
LOG_WARNING("Cannot decode instruction 0x%08X", instruction);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Extern C for unit tests. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! @brief Represents static metadata associated with a specific ARM32
|
||||
* instruction. */
|
||||
typedef struct
|
||||
|
|
@ -59,4 +64,7 @@ typedef struct
|
|||
const pvm_jit_decoder_arm32_instruction_info_t *pvm_jit_decoder_arm32_decode(
|
||||
const uint32_t instruction);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // POUND_JIT_DECODER_ARM32_H
|
||||
|
|
|
|||
|
|
@ -11,17 +11,28 @@ INST(BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv") /
|
|||
INST(BX, "BX", "cccc000100101111111111110001mmmm") // v4T
|
||||
INST(BXJ, "BXJ", "cccc000100101111111111110010mmmm") // v5J
|
||||
|
||||
// System / Status Register Access (Specifics)
|
||||
/*
|
||||
* FIX: Moved these to the top.
|
||||
* RFE and SRS start with 1111, which conflicts with LDM/STM (cccc=1111).
|
||||
* Checking these first prevents LDM/STM from shadowing them.
|
||||
*/
|
||||
INST(RFE, "RFE", "1111100--0-1----0000101000000000") // v6
|
||||
INST(SRS, "SRS", "1111100--1-0110100000101000-----") // v6
|
||||
INST(CPS, "CPS", "111100010000---00000000---0-----") // v6
|
||||
INST(SETEND, "SETEND", "1111000100000001000000e000000000") // v6
|
||||
|
||||
// CRC32 instructions
|
||||
INST(CRC32, "CRC32", "cccc00010zz0nnnndddd00000100mmmm") // v8
|
||||
INST(CRC32C, "CRC32C", "cccc00010zz0nnnndddd00100100mmmm") // v8
|
||||
|
||||
// Coprocessor instructions
|
||||
INST(CDP, "CDP", "cccc1110ooooNNNNDDDDppppooo0MMMM") // v2 (CDP2: v5)
|
||||
INST(LDC, "LDC", "cccc110pudw1nnnnDDDDppppvvvvvvvv") // v2 (LDC2: v5)
|
||||
INST(MCR, "MCR", "cccc1110ooo0NNNNttttppppooo1MMMM") // v2 (MCR2: v5)
|
||||
INST(MCRR, "MCRR", "cccc11000100uuuuttttppppooooMMMM") // v5E (MCRR2: v6)
|
||||
INST(MRC, "MRC", "cccc1110ooo1NNNNttttppppooo1MMMM") // v2 (MRC2: v5)
|
||||
INST(MRRC, "MRRC", "cccc11000101uuuuttttppppooooMMMM") // v5E (MRRC2: v6)
|
||||
INST(LDC, "LDC", "cccc110pudw1nnnnDDDDppppvvvvvvvv") // v2 (LDC2: v5)
|
||||
INST(STC, "STC", "cccc110pudw0nnnnDDDDppppvvvvvvvv") // v2 (STC2: v5)
|
||||
|
||||
// Data Processing instructions
|
||||
|
|
@ -101,8 +112,7 @@ INST(SEVL, "SEVL", "----0011001000001111000000000101") /
|
|||
INST(WFE, "WFE", "----0011001000001111000000000010") // v6K
|
||||
INST(WFI, "WFI", "----0011001000001111000000000011") // v6K
|
||||
INST(YIELD, "YIELD", "----0011001000001111000000000001") // v6K
|
||||
INST(NOP, "Reserved Hint", "----0011001000001111------------")
|
||||
INST(NOP, "Reserved Hint", "----001100100000111100000000----")
|
||||
INST(NOP, "NOP", "----0011001000001111000000000000") // v6K
|
||||
|
||||
// Synchronization Primitive instructions
|
||||
INST(CLREX, "CLREX", "11110101011111111111000000011111") // v6K
|
||||
|
|
@ -181,7 +191,7 @@ INST(LDM, "LDM", "cccc100010w1nnnnxxxxxxxxxxxxxxxx") /
|
|||
INST(LDMDA, "LDMDA", "cccc100000w1nnnnxxxxxxxxxxxxxxxx") // v1
|
||||
INST(LDMDB, "LDMDB", "cccc100100w1nnnnxxxxxxxxxxxxxxxx") // v1
|
||||
INST(LDMIB, "LDMIB", "cccc100110w1nnnnxxxxxxxxxxxxxxxx") // v1
|
||||
INST(LDM_usr, "LDM (usr reg)", "----100--101--------------------") // v1
|
||||
INST(LDM_usr, "LDM (usr reg)", "----100--101----0---------------") // v1
|
||||
INST(LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------") // v1
|
||||
INST(STM, "STM", "cccc100010w0nnnnxxxxxxxxxxxxxxxx") // v1
|
||||
INST(STMDA, "STMDA", "cccc100000w0nnnnxxxxxxxxxxxxxxxx") // v1
|
||||
|
|
@ -195,7 +205,6 @@ INST(BFI, "BFI", "cccc0111110vvvvvddddvvvvv001nnnn") /
|
|||
INST(CLZ, "CLZ", "cccc000101101111dddd11110001mmmm") // v5
|
||||
INST(MOVT, "MOVT", "cccc00110100vvvvddddvvvvvvvvvvvv") // v6T2
|
||||
INST(MOVW, "MOVW", "cccc00110000vvvvddddvvvvvvvvvvvv") // v6T2
|
||||
INST(NOP, "NOP", "----0011001000001111000000000000") // v6K
|
||||
INST(SBFX, "SBFX", "cccc0111101wwwwwddddvvvvv101nnnn") // v6T2
|
||||
INST(SEL, "SEL", "cccc01101000nnnndddd11111011mmmm") // v6
|
||||
INST(UBFX, "UBFX", "cccc0111111wwwwwddddvvvvv101nnnn") // v6T2
|
||||
|
|
@ -251,12 +260,12 @@ INST(SMMLA, "SMMLA", "cccc01110101ddddaaaammmm00R1nnnn") /
|
|||
INST(SMMLS, "SMMLS", "cccc01110101ddddaaaammmm11R1nnnn") // v6
|
||||
|
||||
// Multiply (Dual) instructions
|
||||
INST(SMUAD, "SMUAD", "cccc01110000dddd1111mmmm00M1nnnn") // v6
|
||||
INST(SMLAD, "SMLAD", "cccc01110000ddddaaaammmm00M1nnnn") // v6
|
||||
INST(SMLALD, "SMLALD", "cccc01110100ddddaaaammmm00M1nnnn") // v6
|
||||
INST(SMUSD, "SMUSD", "cccc01110000dddd1111mmmm01M1nnnn") // v6
|
||||
INST(SMLSD, "SMLSD", "cccc01110000ddddaaaammmm01M1nnnn") // v6
|
||||
INST(SMLSLD, "SMLSLD", "cccc01110100ddddaaaammmm01M1nnnn") // v6
|
||||
INST(SMUAD, "SMUAD", "cccc01110000dddd1111mmmm00M1nnnn") // v6
|
||||
INST(SMUSD, "SMUSD", "cccc01110000dddd1111mmmm01M1nnnn") // v6
|
||||
|
||||
// Parallel Add/Subtract (Modulo) instructions
|
||||
INST(SADD8, "SADD8", "cccc01100001nnnndddd11111001mmmm") // v6
|
||||
|
|
@ -306,11 +315,8 @@ INST(QSUB, "QSUB", "cccc00010010nnnndddd00000101mmmm") /
|
|||
INST(QDADD, "QDADD", "cccc00010100nnnndddd00000101mmmm") // v5xP
|
||||
INST(QDSUB, "QDSUB", "cccc00010110nnnndddd00000101mmmm") // v5xP
|
||||
|
||||
// Status Register Access instructions
|
||||
INST(CPS, "CPS", "111100010000---00000000---0-----") // v6
|
||||
INST(SETEND, "SETEND", "1111000100000001000000e000000000") // v6
|
||||
// Status Register Access instructions (Generals)
|
||||
// Specifics like CPS/RFE moved to top to prevent shadowing
|
||||
INST(MRS, "MRS", "cccc000100001111dddd000000000000") // v3
|
||||
INST(MSR_imm, "MSR (imm)", "cccc00110010mmmm1111rrrrvvvvvvvv") // v3
|
||||
INST(MSR_reg, "MSR (reg)", "cccc00010010mmmm111100000000nnnn") // v3
|
||||
INST(RFE, "RFE", "1111100--0-1----0000101000000000") // v6
|
||||
INST(SRS, "SRS", "1111100--1-0110100000101000-----") // v6
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,7 @@
|
|||
#include "arm32.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define LOOKUP_TABLE_MAX_BUCKET_SIZE 18U
|
||||
#define LOOKUP_TABLE_MAX_BUCKET_SIZE 64U
|
||||
|
||||
typedef struct {
|
||||
const pvm_jit_decoder_arm32_instruction_info_t *instructions[LOOKUP_TABLE_MAX_BUCKET_SIZE];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue