Compare commits
35 Commits
e24e8dfe2d
...
easter-egg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdf14cf545 | ||
|
|
c3c94583f4 | ||
|
|
1fe555aaba | ||
| 7155ad8d5a | |||
| 0449074ef6 | |||
| 484c2a6afe | |||
| 6f8a9d80f2 | |||
| 36889e160b | |||
| 4e1a601175 | |||
|
|
f82aa627c4 | ||
|
|
7d3781681d | ||
| 6ac82b47e7 | |||
| 48785b6a94 | |||
| c8bfdf44b6 | |||
| eba69f767e | |||
| 67ed4a7fc4 | |||
| 0015387d60 | |||
| 15bf03097f | |||
| 43f5d26b3d | |||
| f0148dbe45 | |||
| b397371a53 | |||
| aabcfc6f0c | |||
| 41dd2b87b4 | |||
| 3d80b690c4 | |||
| a077c084a2 | |||
| 38006fe19a | |||
| 6895309679 | |||
| 08e994ad44 | |||
| 2f38eb38b8 | |||
| 5f342991b0 | |||
| a5ffb69565 | |||
| 8697b44f53 | |||
| c6c63d6391 | |||
| c6fdb59791 | |||
|
|
291aa0a949 |
@@ -16,107 +16,107 @@ constexpr u8 ADDR_MODE_MASKS[][2] = {
|
||||
{ 0x1E, 0x00 }, // FIR
|
||||
{ 0x1E, 0x00 }, // FZR
|
||||
{ 0x1E, 0x1F }, // LSR
|
||||
{ 0x00, 0x00 }, // FVR
|
||||
{ 0x00, 0x00 }, // MOV
|
||||
{ 0x00, 0x00 }, // MOR
|
||||
{ 0x04, 0x00 }, // FVR
|
||||
{ 0x1E, 0xFF }, // MOV
|
||||
{ 0x04, 0x04 }, // MOR
|
||||
{ 0x00, 0x00 }, // AMOV
|
||||
{ 0x04, 0x04 }, // SWP
|
||||
{ 0x04, 0x00 }, // AHM
|
||||
{ 0x00, 0x00 }, // COM
|
||||
{ 0x00, 0x00 }, // NEG
|
||||
{ 0x00, 0x00 }, // EXS
|
||||
{ 0x00, 0x00 }, // INC
|
||||
{ 0x00, 0x00 }, // DEC
|
||||
{ 0x00, 0x00 }, // ADD
|
||||
{ 0x00, 0x00 }, // SUB
|
||||
{ 0x00, 0x00 }, // MUL
|
||||
{ 0x00, 0x00 }, // UMUL
|
||||
{ 0x00, 0x00 }, // DIV
|
||||
{ 0x00, 0x00 }, // UDIV
|
||||
{ 0x00, 0x00 }, // MOD
|
||||
{ 0x00, 0x00 }, // UMOD
|
||||
{ 0x00, 0x00 }, // DMOD
|
||||
{ 0x00, 0x00 }, // UDMD
|
||||
{ 0x00, 0x00 }, // FBT
|
||||
{ 0x00, 0x00 }, // STB
|
||||
{ 0x00, 0x00 }, // CRB
|
||||
{ 0x00, 0x00 }, // TSB
|
||||
{ 0x00, 0x00 }, // BOOL
|
||||
{ 0x00, 0x00 }, // NOT
|
||||
{ 0x00, 0x00 }, // AND
|
||||
{ 0x00, 0x00 }, // OR
|
||||
{ 0x00, 0x00 }, // XOR
|
||||
{ 0x00, 0x00 }, // SHL
|
||||
{ 0x00, 0x00 }, // SHR
|
||||
{ 0x00, 0x00 }, // SSR
|
||||
{ 0x00, 0x00 }, // ROL
|
||||
{ 0x00, 0x00 }, // ROR
|
||||
{ 0x00, 0x00 }, // CNT
|
||||
{ 0x00, 0x00 }, // EQ
|
||||
{ 0x00, 0x00 }, // NE
|
||||
{ 0x00, 0x00 }, // GT
|
||||
{ 0x00, 0x00 }, // GE
|
||||
{ 0x00, 0x00 }, // LT
|
||||
{ 0x00, 0x00 }, // LE
|
||||
{ 0x00, 0x00 }, // JMP
|
||||
{ 0x00, 0x00 }, // JEQ
|
||||
{ 0x00, 0x00 }, // JNE
|
||||
{ 0x00, 0x00 }, // JIF
|
||||
{ 0x00, 0x00 }, // JMR
|
||||
{ 0x00, 0x00 }, // JER
|
||||
{ 0x00, 0x00 }, // JNR
|
||||
{ 0x00, 0x00 }, // JIR
|
||||
{ 0x00, 0x00 }, // SFB
|
||||
{ 0x00, 0x00 }, // LFB
|
||||
{ 0x00, 0x00 }, // JUF
|
||||
{ 0x00, 0x00 }, // JUR
|
||||
{ 0x00, 0x00 }, // PUSH
|
||||
{ 0x00, 0x00 }, // POP
|
||||
{ 0x00, 0x00 }, // ALLOC
|
||||
{ 0x00, 0x00 }, // HFREE
|
||||
{ 0x00, 0x00 }, // CALL
|
||||
{ 0xFF, 0x00 }, // COM
|
||||
{ 0xFF, 0x00 }, // NEG
|
||||
{ 0xFF, 0x00 }, // EXS
|
||||
{ 0xFF, 0x00 }, // INC
|
||||
{ 0xFF, 0x00 }, // DEC
|
||||
{ 0x1E, 0xFF }, // ADD
|
||||
{ 0x1E, 0xFF }, // SUB
|
||||
{ 0x1E, 0xFF }, // MUL
|
||||
{ 0x1E, 0xFF }, // UMUL
|
||||
{ 0x1E, 0xFF }, // DIV
|
||||
{ 0x1E, 0xFF }, // UDIV
|
||||
{ 0x1E, 0xFF }, // MOD
|
||||
{ 0x1E, 0xFF }, // UMOD
|
||||
{ 0x1E, 0xFF }, // DMOD
|
||||
{ 0x1E, 0xFF }, // UDMD
|
||||
{ 0xFF, 0x00 }, // FBT
|
||||
{ 0x1E, 0xFF }, // STB
|
||||
{ 0x1E, 0xFF }, // CRB
|
||||
{ 0x1E, 0xFF }, // TSB
|
||||
{ 0xFF, 0x00 }, // BOOL
|
||||
{ 0xFF, 0x00 }, // NOT
|
||||
{ 0x1E, 0xFF }, // AND
|
||||
{ 0x1E, 0xFF }, // OR
|
||||
{ 0x1E, 0xFF }, // XOR
|
||||
{ 0x1E, 0xFF }, // SHL
|
||||
{ 0x1E, 0xFF }, // SHR
|
||||
{ 0x1E, 0xFF }, // SSR
|
||||
{ 0x1E, 0xFF }, // ROL
|
||||
{ 0x1E, 0xFF }, // ROR
|
||||
{ 0xFF, 0x00 }, // CNT
|
||||
{ 0x1E, 0xFF }, // EQ
|
||||
{ 0x1E, 0xFF }, // NE
|
||||
{ 0x1E, 0xFF }, // GT
|
||||
{ 0x1E, 0xFF }, // GE
|
||||
{ 0x1E, 0xFF }, // LT
|
||||
{ 0x1E, 0xFF }, // LE
|
||||
{ 0xFF, 0x00 }, // JMP
|
||||
{ 0xFF, 0x00 }, // JEQ
|
||||
{ 0xFF, 0x00 }, // JNE
|
||||
{ 0x1E, 0xFF }, // JIF
|
||||
{ 0xFF, 0x00 }, // JMR
|
||||
{ 0xFF, 0x00 }, // JER
|
||||
{ 0xFF, 0x00 }, // JNR
|
||||
{ 0x1E, 0xFF }, // JIR
|
||||
{ 0x1E, 0xFF }, // SFB
|
||||
{ 0x1E, 0xFF }, // LFB
|
||||
{ 0x1E, 0xFF }, // JUF
|
||||
{ 0x1E, 0xFF }, // JUR
|
||||
{ 0xFF, 0x00 }, // PUSH
|
||||
{ 0xFF, 0x00 }, // POP
|
||||
{ 0xFF, 0x00 }, // ALLOC
|
||||
{ 0xFF, 0x00 }, // HFREE
|
||||
{ 0xFF, 0x00 }, // CALL
|
||||
{ 0x00, 0x00 }, // RET
|
||||
{ 0x00, 0x00 }, // EDI
|
||||
{ 0x00, 0x00 }, // SHSS
|
||||
{ 0x00, 0x00 }, // FLI
|
||||
{ 0x00, 0x00 }, // FNEG
|
||||
{ 0x00, 0x00 }, // FADD
|
||||
{ 0x00, 0x00 }, // FSUB
|
||||
{ 0x00, 0x00 }, // FMUL
|
||||
{ 0x00, 0x00 }, // FDIV
|
||||
{ 0x00, 0x00 }, // FMOD
|
||||
{ 0x00, 0x00 }, // FDMOD
|
||||
{ 0x00, 0x00 }, // FEPS
|
||||
{ 0x00, 0x00 }, // FEEP
|
||||
{ 0x00, 0x00 }, // FEQ
|
||||
{ 0x00, 0x00 }, // FNE
|
||||
{ 0x00, 0x00 }, // FGT
|
||||
{ 0x00, 0x00 }, // FGE
|
||||
{ 0x00, 0x00 }, // FLT
|
||||
{ 0x00, 0x00 }, // FLE
|
||||
{ 0x00, 0x00 }, // F2D
|
||||
{ 0x00, 0x00 }, // D2F
|
||||
{ 0x00, 0x00 }, // I2F
|
||||
{ 0x00, 0x00 }, // I2D
|
||||
{ 0x00, 0x00 }, // L2F
|
||||
{ 0x00, 0x00 }, // L2D
|
||||
{ 0x00, 0x00 }, // F2I
|
||||
{ 0x00, 0x00 }, // F2L
|
||||
{ 0x00, 0x00 }, // D2I
|
||||
{ 0x00, 0x00 }, // D2L
|
||||
{ 0x00, 0x00 }, // SIN
|
||||
{ 0x00, 0x00 }, // COS
|
||||
{ 0x00, 0x00 }, // TAN
|
||||
{ 0x00, 0x00 }, // ASIN
|
||||
{ 0x00, 0x00 }, // ACOS
|
||||
{ 0x00, 0x00 }, // ATAN
|
||||
{ 0x00, 0x00 }, // ATAN2
|
||||
{ 0x00, 0x00 }, // EXP
|
||||
{ 0x00, 0x00 }, // LOG
|
||||
{ 0x00, 0x00 }, // LOGAB
|
||||
{ 0x00, 0x00 }, // POW
|
||||
{ 0x00, 0x00 }, // SQRT
|
||||
{ 0x00, 0x00 }, // ROOT
|
||||
{ 0xFF, 0x00 }, // EDI
|
||||
{ 0xFF, 0x00 }, // SHSS
|
||||
{ 0xFF, 0x00 }, // FLI
|
||||
{ 0xFF, 0x00 }, // FNEG
|
||||
{ 0x1E, 0xFF }, // FADD
|
||||
{ 0x1E, 0xFF }, // FSUB
|
||||
{ 0x1E, 0xFF }, // FMUL
|
||||
{ 0x1E, 0xFF }, // FDIV
|
||||
{ 0x1E, 0xFF }, // FMOD
|
||||
{ 0x1E, 0xFF }, // FDMOD
|
||||
{ 0xFF, 0x00 }, // FEPS
|
||||
{ 0xFF, 0x00 }, // FEEP
|
||||
{ 0x1E, 0xFF }, // FEQ
|
||||
{ 0x1E, 0xFF }, // FNE
|
||||
{ 0x1E, 0xFF }, // FGT
|
||||
{ 0x1E, 0xFF }, // FGE
|
||||
{ 0x1E, 0xFF }, // FLT
|
||||
{ 0x1E, 0xFF }, // FLE
|
||||
{ 0xFF, 0x00 }, // F2D
|
||||
{ 0xFF, 0x00 }, // D2F
|
||||
{ 0xFF, 0x00 }, // I2F
|
||||
{ 0xFF, 0x00 }, // I2D
|
||||
{ 0xFF, 0x00 }, // L2F
|
||||
{ 0xFF, 0x00 }, // L2D
|
||||
{ 0xFF, 0x00 }, // F2I
|
||||
{ 0xFF, 0x00 }, // F2L
|
||||
{ 0xFF, 0x00 }, // D2I
|
||||
{ 0xFF, 0x00 }, // D2L
|
||||
{ 0xFF, 0x00 }, // SIN
|
||||
{ 0xFF, 0x00 }, // COS
|
||||
{ 0xFF, 0x00 }, // TAN
|
||||
{ 0xFF, 0x00 }, // ASIN
|
||||
{ 0xFF, 0x00 }, // ACOS
|
||||
{ 0xFF, 0x00 }, // ATAN
|
||||
{ 0x1E, 0xFF }, // ATAN2
|
||||
{ 0xFF, 0x00 }, // EXP
|
||||
{ 0xFF, 0x00 }, // LOG
|
||||
{ 0x1E, 0xFF }, // LOGAB
|
||||
{ 0x1E, 0xFF }, // POW
|
||||
{ 0xFF, 0x00 }, // SQRT
|
||||
{ 0x1E, 0xFF }, // ROOT
|
||||
{ 0x00, 0x00 }, // ADC
|
||||
{ 0x00, 0x00 }, // SWC
|
||||
{ 0x00, 0x00 }, // MWO
|
||||
@@ -127,6 +127,8 @@ constexpr u8 ADDR_MODE_MASKS[][2] = {
|
||||
{ 0x00, 0x00 }, // MINV
|
||||
{ 0x00, 0x00 }, // MTRA
|
||||
{ 0x00, 0x00 }, // MDET
|
||||
{ 0x00, 0x00 }, // QMKA
|
||||
{ 0x00, 0x00 }, // QMUL
|
||||
{ 0x00, 0x00 }, // XADD
|
||||
{ 0x00, 0x00 }, // XSUB
|
||||
{ 0x00, 0x00 }, // XAMA
|
||||
@@ -140,18 +142,18 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
|
||||
0x00, // NOP
|
||||
0x00, // SPDR
|
||||
0x01, // MMODE
|
||||
0x0F, // INT
|
||||
0x0C, // LRV
|
||||
0x0F, // FSR
|
||||
0x0F, // FIR
|
||||
0x0F, // FZR
|
||||
0x0F, // LSR
|
||||
0x0F, // FVR
|
||||
0x00, // MOV
|
||||
0x00, // MOR
|
||||
0x00, // AMOV
|
||||
0x00, // SWP
|
||||
0x0F, // AHM
|
||||
0x08, // INT
|
||||
0x08, // LRV
|
||||
0x08, // FSR
|
||||
0x08, // FIR
|
||||
0x08, // FZR
|
||||
0x08, // LSR
|
||||
0x08, // FVR
|
||||
0x0F, // MOV
|
||||
0x08, // MOR
|
||||
0x08, // AMOV
|
||||
0x08, // SWP
|
||||
0x08, // AHM
|
||||
0x0F, // COM
|
||||
0x0F, // NEG
|
||||
0x0F, // EXS
|
||||
@@ -208,22 +210,22 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
|
||||
0x0F, // RET
|
||||
0x0F, // EDI
|
||||
0x0F, // SHSS
|
||||
0x00, // FLI
|
||||
0x00, // FNEG
|
||||
0x00, // FADD
|
||||
0x00, // FSUB
|
||||
0x00, // FMUL
|
||||
0x00, // FDIV
|
||||
0x00, // FMOD
|
||||
0x00, // FDMOD
|
||||
0x00, // FEPS
|
||||
0x00, // FEEP
|
||||
0x00, // FEQ
|
||||
0x00, // FNE
|
||||
0x00, // FGT
|
||||
0x00, // FGE
|
||||
0x00, // FLT
|
||||
0x00, // FLE
|
||||
0x0C, // FLI
|
||||
0x0C, // FNEG
|
||||
0x0C, // FADD
|
||||
0x0C, // FSUB
|
||||
0x0C, // FMUL
|
||||
0x0C, // FDIV
|
||||
0x0C, // FMOD
|
||||
0x0C, // FDMOD
|
||||
0x0C, // FEPS
|
||||
0x0C, // FEEP
|
||||
0x0C, // FEQ
|
||||
0x0C, // FNE
|
||||
0x0C, // FGT
|
||||
0x0C, // FGE
|
||||
0x0C, // FLT
|
||||
0x0C, // FLE
|
||||
0x00, // F2D
|
||||
0x00, // D2F
|
||||
0x00, // I2F
|
||||
@@ -234,19 +236,19 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
|
||||
0x00, // F2L
|
||||
0x00, // D2I
|
||||
0x00, // D2L
|
||||
0x00, // SIN
|
||||
0x00, // COS
|
||||
0x00, // TAN
|
||||
0x00, // ASIN
|
||||
0x00, // ACOS
|
||||
0x00, // ATAN
|
||||
0x00, // ATAN2
|
||||
0x00, // EXP
|
||||
0x00, // LOG
|
||||
0x00, // LOGAB
|
||||
0x00, // POW
|
||||
0x00, // SQRT
|
||||
0x00, // ROOT
|
||||
0x0C, // SIN
|
||||
0x0C, // COS
|
||||
0x0C, // TAN
|
||||
0x0C, // ASIN
|
||||
0x0C, // ACOS
|
||||
0x0C, // ATAN
|
||||
0x0C, // ATAN2
|
||||
0x0C, // EXP
|
||||
0x0C, // LOG
|
||||
0x0C, // LOGAB
|
||||
0x0C, // POW
|
||||
0x0C, // SQRT
|
||||
0x0C, // ROOT
|
||||
0x00, // ADC
|
||||
0x00, // SWC
|
||||
0x00, // MWO
|
||||
@@ -257,6 +259,8 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
|
||||
0x00, // MINV
|
||||
0x00, // MTRA
|
||||
0x00, // MDET
|
||||
0x00, // QMKA
|
||||
0x00, // QMUL
|
||||
0x00, // XADD
|
||||
0x00, // XSUB
|
||||
0x00, // XAMA
|
||||
|
||||
Binary file not shown.
2
makefile
2
makefile
@@ -15,7 +15,7 @@ OBJEXT := o
|
||||
#Flags, Libraries and Includes
|
||||
ROOT := ./
|
||||
CFLAGS := -std=c++20 -O2 \
|
||||
-Wall -Wextra \
|
||||
-Wall -Werror -Wextra \
|
||||
-Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align \
|
||||
-Wunused -Woverloaded-virtual -Wconversion \
|
||||
-Wsign-conversion -Wnull-dereference -Wdouble-promotion \
|
||||
|
||||
244
pygen.ipynb
244
pygen.ipynb
@@ -15,7 +15,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 1,
|
||||
"id": "b0fcd533",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -68,7 +68,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 2,
|
||||
"id": "b33de8ac",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -144,7 +144,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 4,
|
||||
"id": "58645013",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -152,7 +152,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Real instructions : 126\n",
|
||||
"Real instructions : 128\n",
|
||||
"Reserved slots : 14\n",
|
||||
"Duplicate check : PASSED\n",
|
||||
"\n",
|
||||
@@ -163,13 +163,14 @@
|
||||
"Bit Wise 14\n",
|
||||
"Boolean 12\n",
|
||||
"Branch 12\n",
|
||||
"Casts 10\n",
|
||||
"Floating Point 10\n",
|
||||
"Casts 10\n",
|
||||
"Memory 9\n",
|
||||
"Trigonometric 7\n",
|
||||
"Exponential 6\n",
|
||||
"Matrix 6\n",
|
||||
"SIMD 5\n",
|
||||
"Quaternion 2\n",
|
||||
"Easter Eggs 1\n",
|
||||
"\n",
|
||||
"First 5 instructions:\n",
|
||||
@@ -177,8 +178,8 @@
|
||||
"0 000 NOP System 0 00 00\n",
|
||||
"1 001 SPDR System 0 00 00\n",
|
||||
"2 002 MMODE System 1 05 01\n",
|
||||
"3 003 INT System 1 1F 0F\n",
|
||||
"4 004 LRV System 1 1F 0C\n"
|
||||
"3 003 INT System 1 1F 08\n",
|
||||
"4 004 LRV System 1 1F 08\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -214,6 +215,7 @@
|
||||
" 'dis', # addressing mode: Displaced\n",
|
||||
" 'addr_mask_1', # accepted addressing mode mask for param 1\n",
|
||||
" 'addr_mask_2', # accepted addressing mode mask for param 2\n",
|
||||
" 'ignores_addrm',# whether the instruction ignores addressing modes\n",
|
||||
" 'B', # type size: Byte (1 byte) supported?\n",
|
||||
" 'S', # type size: Short (2 bytes) supported?\n",
|
||||
" 'I', # type size: Int (4 bytes) supported?\n",
|
||||
@@ -221,6 +223,7 @@
|
||||
" 'F', # type size: Float supported?\n",
|
||||
" 'D', # type size: Double supported?\n",
|
||||
" 'type_mask', # combined type size mask as hex string\n",
|
||||
" 'expensive', # marks computationally expensive instructions\n",
|
||||
" 'operation', # human-readable description of what the instruction does\n",
|
||||
" 'skip_2', # trailing empty column\n",
|
||||
"]\n",
|
||||
@@ -280,7 +283,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 5,
|
||||
"id": "452bc76c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -289,7 +292,7 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Masks written to: .//autogen/InstructionMasks.hpp\n",
|
||||
"Lines generated : 268\n"
|
||||
"Lines generated : 272\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -354,7 +357,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 6,
|
||||
"id": "5aaebef0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -362,7 +365,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Instructions formatted: 126\n",
|
||||
"Instructions formatted: 128\n",
|
||||
"\n",
|
||||
"--- Preview (first 2 instructions) ---\n",
|
||||
" // [System] 0x000 — NOP: No Operation\n",
|
||||
@@ -377,7 +380,7 @@
|
||||
"\n",
|
||||
"\n",
|
||||
"CPU.hpp updated successfully at: .//src//spider/runtime/cpu/CPU.hpp\n",
|
||||
"Total lines in updated file: 674\n"
|
||||
"Total lines in updated file: 883\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -445,6 +448,221 @@
|
||||
"print(f'\\nCPU.hpp updated successfully at: {CPU_HPP_PATH}')\n",
|
||||
"print(f'Total lines in updated file: {len(updated.splitlines())}')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "instrmap_gen",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"InstrMap.cpp written to: .//src//spider/runtime/instr/InstrMap.cpp\n",
|
||||
" Size : 34,157 bytes\n",
|
||||
" Array entries : 512 (128 populated, 384 nullptr)\n",
|
||||
" Switch cases : 128\n",
|
||||
" Line endings : LF-only verified\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# ── Generate InstrMap.cpp ────────────────────────────────────────────────────\n",
|
||||
"# Produces two dispatch implementations in one file:\n",
|
||||
"# 1. CPUInstr InstrMap[512] — array of member-function pointers\n",
|
||||
"# 2. void CPU::execute(u16) — switch/case version\n",
|
||||
"#\n",
|
||||
"# Both use UPPERCASE method names matching the mnemonic column.\n",
|
||||
"\n",
|
||||
"TABLE_SIZE = 512 # 9-bit opcode space\n",
|
||||
"\n",
|
||||
"# Build opcode -> mnemonic lookup from the cleaned instruction DataFrame.\n",
|
||||
"opcode_to_mnem: dict[int, str] = {}\n",
|
||||
"opcode_to_name: dict[int, str] = {}\n",
|
||||
"opcode_to_group: dict[int, str] = {}\n",
|
||||
"\n",
|
||||
"for _, row in instrs_df.iterrows():\n",
|
||||
" bc = str(row['byte_code']).strip()\n",
|
||||
" opc = int(bc, 16)\n",
|
||||
" opcode_to_mnem[opc] = str(row['mnemonic']).strip()\n",
|
||||
" opcode_to_name[opc] = str(row['name']).strip()\n",
|
||||
" opcode_to_group[opc] = str(row['group']).strip()\n",
|
||||
"\n",
|
||||
"# Also track reserved slots for annotation.\n",
|
||||
"reserved_opcodes: set[int] = set()\n",
|
||||
"for _, row in reserved_df.iterrows():\n",
|
||||
" bc = str(row['byte_code']).strip()\n",
|
||||
" if bc and bc != 'nan':\n",
|
||||
" reserved_opcodes.add(int(bc, 16))\n",
|
||||
"\n",
|
||||
"# ── Assemble the file ───────────────────────────────────────────────────────\n",
|
||||
"L = []\n",
|
||||
"L.append('/**')\n",
|
||||
"L.append(' * @file InstrMap.cpp')\n",
|
||||
"L.append(' * @brief Spider VM instruction dispatch — array and switch implementations.')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * AUTO-GENERATED by pygen.ipynb — DO NOT EDIT BY HAND.')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * This file provides two equivalent dispatch mechanisms:')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * 1. InstrMap[] — A lookup table of member-function pointers indexed by')\n",
|
||||
"L.append(' * opcode. O(1) dispatch; suitable for platforms where')\n",
|
||||
"L.append(' * indirect calls through function pointers are efficient.')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * 2. CPU::execute(u16) — A switch/case over every opcode. Lets the')\n",
|
||||
"L.append(' * compiler emit a jump table or branch tree; may be')\n",
|
||||
"L.append(' * preferable on microcontrollers or when link-time')\n",
|
||||
"L.append(' * optimisation can inline the handlers.')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' */')\n",
|
||||
"L.append('') # [CHANGE] Use absolute path to make paths more explicit\n",
|
||||
"L.append('#include <spider/runtime/cpu/CPU.hpp>')\n",
|
||||
"L.append('')\n",
|
||||
"L.append('namespace spider {')\n",
|
||||
"L.append('')\n",
|
||||
"\n",
|
||||
"# ── Version 1: Array: ────────────────────────────────────────────────────────\n",
|
||||
"L.append('// =============================================================')\n",
|
||||
"L.append('// Version 1 — Lookup table of member-function pointers')\n",
|
||||
"L.append('// =============================================================')\n",
|
||||
"L.append('')\n",
|
||||
"# [CHANGE] Use CPU::Fn Instead\n",
|
||||
"#L.append('/** Pointer-to-member type for a zero-argument CPU instruction. */')\n",
|
||||
"#L.append('using CPUInstr = void (CPU::*)();')\n",
|
||||
"L.append('')\n",
|
||||
"L.append('/**')\n",
|
||||
"L.append(f' * Instruction dispatch table ({TABLE_SIZE} entries, 9-bit opcode space).')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * Usage:')\n",
|
||||
"L.append(' * u16 opcode = fetch();')\n",
|
||||
"L.append(' * CPU::Fn fn = InstrMap[opcode];')\n",
|
||||
"L.append(' * if (fn) (cpu.*fn)();')\n",
|
||||
"L.append(' */') # [CHANGE] Made it part of the CPU & avoided explicit size.\n",
|
||||
"L.append(f'CPU::Fn CPU::instrMap[] = {{')\n",
|
||||
"\n",
|
||||
"for opc in range(TABLE_SIZE):\n",
|
||||
" mnem = opcode_to_mnem.get(opc)\n",
|
||||
" if mnem:\n",
|
||||
" name = opcode_to_name[opc]\n",
|
||||
" L.append(f' &CPU::{mnem + \",\":<28s}// 0x{opc:03X} — {name}')\n",
|
||||
" else:\n",
|
||||
" tag = ''\n",
|
||||
" if opc in reserved_opcodes:\n",
|
||||
" tag = ' (reserved)'\n",
|
||||
" L.append(f' {\"nullptr,\":<28s}// 0x{opc:03X}{tag}')\n",
|
||||
"\n",
|
||||
"L.append('};')\n",
|
||||
"L.append('')\n",
|
||||
"L.append('')\n",
|
||||
"\n",
|
||||
"# ── Version 2: Switch ──────────────────────────────────────────────────────\n",
|
||||
"L.append('// =============================================================')\n",
|
||||
"L.append('// Version 2 — Switch dispatch')\n",
|
||||
"L.append('// =============================================================')\n",
|
||||
"L.append('')\n",
|
||||
"L.append('/**')\n",
|
||||
"L.append(' * Execute the instruction identified by @p opcode.')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * This is functionally equivalent to the InstrMap[] table above')\n",
|
||||
"L.append(' * but expressed as a switch so the compiler can choose the best')\n",
|
||||
"L.append(' * lowering strategy (jump table, binary search, etc.).')\n",
|
||||
"L.append(' *')\n",
|
||||
"L.append(' * @param opcode 9-bit instruction opcode (0x000 - 0x1FF).')\n",
|
||||
"L.append(' */')\n",
|
||||
"L.append('void CPU::executeSwLk() {')\n",
|
||||
"L.append(' switch (_opcode) {')\n",
|
||||
"\n",
|
||||
"last_group = None\n",
|
||||
"for opc in sorted(opcode_to_mnem.keys()):\n",
|
||||
" mnem = opcode_to_mnem[opc]\n",
|
||||
" group = opcode_to_group[opc]\n",
|
||||
" if group != last_group:\n",
|
||||
" L.append('')\n",
|
||||
" L.append(f' // ── {group} ' + '─' * max(1, 44 - len(group)))\n",
|
||||
" last_group = group\n",
|
||||
" L.append(f' case 0x{opc:03X}: {mnem}(); break;')\n",
|
||||
"\n",
|
||||
"L.append('')\n",
|
||||
"L.append(' default:')\n",
|
||||
"L.append(' break;')\n",
|
||||
"L.append(' }')\n",
|
||||
"L.append('}')\n",
|
||||
"L.append('')\n",
|
||||
"L.append('} // namespace spider')\n",
|
||||
"L.append('')\n",
|
||||
"\n",
|
||||
"INSTRMAP_SRC = '\\n'.join(L)\n",
|
||||
"\n",
|
||||
"# ── Write to file ───────────────────────────────────────────────────────────\n",
|
||||
"# [CHANGE] Write this in the instructions folder to avoid CPU file bloat\n",
|
||||
"INSTRMAP_PATH = f'{SRC_ROOT}/spider/runtime/instr/InstrMap.cpp'\n",
|
||||
"\n",
|
||||
"with open(INSTRMAP_PATH, 'wb') as f:\n",
|
||||
" f.write(INSTRMAP_SRC.encode('utf-8'))\n",
|
||||
"\n",
|
||||
"# Verify LF-only\n",
|
||||
"with open(INSTRMAP_PATH, 'rb') as f:\n",
|
||||
" raw_bytes = f.read()\n",
|
||||
"assert b'\\r' not in raw_bytes, 'CRLF detected in InstrMap.cpp!'\n",
|
||||
"\n",
|
||||
"array_count = INSTRMAP_SRC.count('&CPU::')\n",
|
||||
"switch_count = INSTRMAP_SRC.count('case 0x')\n",
|
||||
"\n",
|
||||
"print(f'InstrMap.cpp written to: {INSTRMAP_PATH}')\n",
|
||||
"print(f' Size : {len(raw_bytes):,} bytes')\n",
|
||||
"print(f' Array entries : {TABLE_SIZE} ({array_count} populated, {TABLE_SIZE - array_count} nullptr)')\n",
|
||||
"print(f' Switch cases : {switch_count}')\n",
|
||||
"print(f' Line endings : LF-only verified')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "9f190f4c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# ---------- GENERATE INSTR_XX FILES ----------\n",
|
||||
"INSTR_DIR = f'{SRC_ROOT}/spider/runtime/instr'\n",
|
||||
"\n",
|
||||
"# Generate the files\n",
|
||||
"# Each file goes from 00 to 1F (0-31), 32 instr / file\n",
|
||||
"for x0 in range(0, TABLE_SIZE, 32):\n",
|
||||
" x1 = x0 + 31\n",
|
||||
" fname = f'{INSTR_DIR}/Instr_{x0:03X}-{x1:03X}.cpp'\n",
|
||||
"\n",
|
||||
" # TODO: Check if there are missing instructions\n",
|
||||
" if file_exists(fname):\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" # CREATE FILE FROM SCRATCH\n",
|
||||
" L = []\n",
|
||||
" L.append('/**')\n",
|
||||
" L.append(' * @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!')\n",
|
||||
" L.append(' *')\n",
|
||||
" L.append(' */')\n",
|
||||
" L.append('') # [CHANGE] Use absolute path to make paths more explicit\n",
|
||||
" L.append('#include <spider/runtime/cpu/CPU.hpp>')\n",
|
||||
" L.append('')\n",
|
||||
" L.append('namespace spider {')\n",
|
||||
" L.append('')\n",
|
||||
"\n",
|
||||
" for opc in range(x0, x1 + 1):\n",
|
||||
" mnem = opcode_to_mnem.get(opc)\n",
|
||||
" if mnem is None: continue\n",
|
||||
"\n",
|
||||
" L.append(f' void CPU::{mnem}() {{')\n",
|
||||
" L.append(f' // TODO: Implement {mnem}')\n",
|
||||
" L.append(f' }}')\n",
|
||||
" L.append('')\n",
|
||||
"\n",
|
||||
" L.append('}')\n",
|
||||
" L.append('')\n",
|
||||
"\n",
|
||||
" with open(fname, 'wb') as f:\n",
|
||||
" f.write('\\n'.join(L).encode('utf-8'))\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
@@ -463,7 +681,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.7"
|
||||
"version": "3.14.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace spider {
|
||||
|
||||
void Runtime::run() {}
|
||||
|
||||
void Runtime::run(u64 n) {}
|
||||
//void Runtime::run(u64 n) {}
|
||||
|
||||
// Misc //
|
||||
|
||||
@@ -45,9 +45,10 @@ namespace spider {
|
||||
/**
|
||||
* Non-owning reel setup.
|
||||
*/
|
||||
void Runtime::hookReel(InstrReel* reel, bool own) {
|
||||
cpu.hookInstrReel(reel);
|
||||
if(own) this->reel = reel;
|
||||
void Runtime::hookReel(InstrReel* newReel, bool own) {
|
||||
delete this->reel;
|
||||
cpu.hookInstrReel(newReel);
|
||||
if(own) this->reel = newReel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace spider {
|
||||
/**
|
||||
* Non-owning reel setup.
|
||||
*/
|
||||
void hookReel(InstrReel* reel, bool own = false);
|
||||
void hookReel(InstrReel* newReel, bool own = false);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace spider {
|
||||
RE{}, RN{}, RV{}, RM{},
|
||||
ALU0{}, ALU1{},
|
||||
_dst(nullptr), _src(nullptr),
|
||||
_instr(0), _addrm(0), _size(0),
|
||||
_opcode(0), _addrm(0), _size(0),
|
||||
_store(0), _post(&CPU::imp),
|
||||
_ram(nullptr), _reel(nullptr) {
|
||||
}
|
||||
@@ -67,9 +67,10 @@ namespace spider {
|
||||
|
||||
void CPU::fetchInstr() {
|
||||
u16 i = _reel->readU16(RI);
|
||||
_instr = (i >> 7) & 0x1FF;
|
||||
_addrm = (i >> 2) & 0x1F;
|
||||
_size = i & 0x3;
|
||||
const u16 oc = (i >> 7);
|
||||
_opcode = oc & 0x1FF; // GCC WHY!
|
||||
_addrm = static_cast<u8>((i >> 2) & 0x1F);
|
||||
_size = static_cast<u8>(i & 0x3);
|
||||
RI += 2;
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ namespace spider {
|
||||
_opers[1] = _opers[0];
|
||||
|
||||
// call specific addressing mode
|
||||
(this->*(CPU::addrModes[_addrm & 0x7]))();
|
||||
(this->*(CPU::addrModes[_addrm & 0b111]))(); // mask added here too
|
||||
}
|
||||
|
||||
void CPU::fetchOperSrc() {
|
||||
@@ -87,13 +88,19 @@ namespace spider {
|
||||
_alu = &ALU1;
|
||||
|
||||
// call specific addressing mode
|
||||
(this->*(CPU::addrModes[_addrm & 0x7]))();
|
||||
(this->*(CPU::addrModes[_addrm & 0b111]))(); // mask keeps index within 0-7
|
||||
|
||||
// modify the _addrm register
|
||||
_addrm >>= 3;
|
||||
_addrm = static_cast<u8>((_addrm >> 3) & 0x1F);
|
||||
_addrm++;
|
||||
}
|
||||
|
||||
|
||||
void CPU::execute() {
|
||||
(this->*(CPU::instrMap[_opcode]))(); // no null check needed
|
||||
}
|
||||
|
||||
|
||||
// Addressing Modes //
|
||||
|
||||
/**
|
||||
@@ -107,21 +114,7 @@ namespace spider {
|
||||
* Immediate Addressing Mode
|
||||
*/
|
||||
void CPU::imm() {
|
||||
switch(_size) {
|
||||
case 0b00:
|
||||
_alu->_u8 = _reel->readU8(RI);
|
||||
break;
|
||||
case 0b01:
|
||||
_alu->_u16 = _reel->readU16(RI);
|
||||
break;
|
||||
case 0b10:
|
||||
_alu->_u32 = _reel->readU32(RI);
|
||||
break;
|
||||
case 0b11:
|
||||
_alu->_u64 = _reel->readU64(RI);
|
||||
break;
|
||||
}
|
||||
|
||||
_reel->loadRegister(RI, _size, _alu);
|
||||
_opers[0] = _alu;
|
||||
_post = &CPU::imp;
|
||||
RI += 1 << _size;
|
||||
@@ -130,51 +123,35 @@ namespace spider {
|
||||
/**
|
||||
* Absolute Addressing Mode
|
||||
*/
|
||||
void CPU::abs() { // TODO cache ptr size
|
||||
u8 dat_size = 1 << _size;
|
||||
u8 ptr_size = 1 << getFlag(CPU::FLAG_MEMORY_MODE);
|
||||
u64 ptr = 0;
|
||||
void CPU::abs() {
|
||||
// Load the actual ptr into the ALU
|
||||
u8 mm = u8(getFlag(CPU::FLAG_MEMORY_MODE));
|
||||
_reel->loadRegister(RI, mm, _alu);
|
||||
RI += 1 << mm;
|
||||
|
||||
if(ptr_size + dat_size > _ram->size()) return; // TODO: avoid overflow
|
||||
|
||||
switch(ptr_size) {
|
||||
case 1:
|
||||
ptr = _reel->readU8(RI);
|
||||
break;
|
||||
case 2:
|
||||
ptr = _reel->readU16(RI);
|
||||
break;
|
||||
case 4:
|
||||
ptr = _reel->readU32(RI);
|
||||
break;
|
||||
case 8:
|
||||
ptr = _reel->readU64(RI);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_size) {
|
||||
case 0b00:
|
||||
spider::loadLE(&_alu->_u8, &(*_ram)[ptr]);
|
||||
break;
|
||||
case 0b01:
|
||||
spider::loadLE(&_alu->_u16, &(*_ram)[ptr]);
|
||||
break;
|
||||
case 0b10:
|
||||
spider::loadLE(&_alu->_u32, &(*_ram)[ptr]);
|
||||
break;
|
||||
case 0b11:
|
||||
spider::loadLE(&_alu->_u64, &(*_ram)[ptr]);
|
||||
break;
|
||||
}
|
||||
|
||||
RI += dat_size;
|
||||
// read the memory from RAM
|
||||
_store = _alu->_u64;
|
||||
_ram->loadRegister(_store, _size, _alu);
|
||||
_post = &CPU::psw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Addressing Mode
|
||||
*/
|
||||
void CPU::reg() {
|
||||
|
||||
void CPU::reg() { // NOT FINISHED
|
||||
// Two consecutive registers can be declared
|
||||
// Shift if the top part will become .reg too
|
||||
u8 sh = ((_addrm & 0b11000) == 0b11000) * 4;
|
||||
u8 use = 1 - (sh >> 2); // (sh / 4)
|
||||
|
||||
// get byte
|
||||
u8 reg = (_reel->readU8(RI) >> sh) & 0xF;
|
||||
_alu = &GPR[reg];
|
||||
_opers[0] = _alu; // explicitly sets _opers[0] = _dst
|
||||
RI += use;
|
||||
|
||||
// store no-op
|
||||
_post = &CPU::imp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,9 +16,10 @@ namespace spider {
|
||||
static constexpr const u64 FLAG_EXCEPTION = 0b0000000000000000000000000000000000000000000000000000000000001000;
|
||||
static constexpr const u64 FLAG_MEMORY_MODE = 0b0000000000000000000000000000000000000000000000000000000000110000;
|
||||
|
||||
public: // Map of addressing modes
|
||||
public: // Map of addressing modes & Instructions
|
||||
|
||||
static CPU::Fn addrModes[];
|
||||
static CPU::Fn instrMap[];
|
||||
|
||||
public: // General Purpose Registers
|
||||
union {
|
||||
@@ -61,7 +62,7 @@ namespace spider {
|
||||
};
|
||||
|
||||
// Holds the current instruction opcode
|
||||
u16 _instr : 9;
|
||||
u16 _opcode : 9;
|
||||
|
||||
// Holds the current addressing modes,
|
||||
// before they were used
|
||||
@@ -82,11 +83,11 @@ namespace spider {
|
||||
/**
|
||||
* Pointer to the current RAM hooked into
|
||||
* the CPU.
|
||||
*
|
||||
*
|
||||
* It is unproved whether having the RAM directly
|
||||
* into the CPU is better than not, or whether a
|
||||
* virtual BUS is better.
|
||||
*
|
||||
*
|
||||
* Alas, this way we can have a CPU state switch
|
||||
* between memory and instruction banks.
|
||||
*/
|
||||
@@ -95,7 +96,7 @@ namespace spider {
|
||||
/**
|
||||
* Pointer to the current Instruction Reel
|
||||
* hooked into the CPU.
|
||||
*
|
||||
*
|
||||
* Ditto as RAM.
|
||||
*/
|
||||
InstrReel* _reel;
|
||||
@@ -111,7 +112,7 @@ namespace spider {
|
||||
~CPU();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
CPU& operator=(const CPU& other) = default;
|
||||
|
||||
CPU& operator=(CPU&& other) noexcept = default;
|
||||
@@ -123,7 +124,7 @@ namespace spider {
|
||||
void hookInstrReel(InstrReel* reel);
|
||||
|
||||
constexpr u64 getFlag(u64 mask);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -136,11 +137,11 @@ namespace spider {
|
||||
* Fetches the destination operand,
|
||||
* by calling the appropriate addressing
|
||||
* mode.
|
||||
*
|
||||
*
|
||||
* Will read the bottom 3 bits.
|
||||
* For instructions with two operands,
|
||||
* call Src first.
|
||||
*
|
||||
*
|
||||
* The internal variable _addrm
|
||||
* will not be modified. It will
|
||||
* be important when writing
|
||||
@@ -150,19 +151,36 @@ namespace spider {
|
||||
|
||||
/**
|
||||
* Fetches the source operand.
|
||||
*
|
||||
*
|
||||
* For use in two operand instructions.
|
||||
*
|
||||
*
|
||||
* Will read the bottom 3 bits. It will
|
||||
* then shift the _addrm 3 spaces
|
||||
* to ensure it aligns with the DST
|
||||
* next.
|
||||
*
|
||||
*
|
||||
* Additionally, it will add 1 to _addrm
|
||||
* to account with
|
||||
*/
|
||||
void fetchOperSrc();
|
||||
|
||||
/**
|
||||
* Executes an opcode, by means of directly
|
||||
* accessing the instruction map and
|
||||
* calling that function pointer.
|
||||
*/
|
||||
void execute();
|
||||
|
||||
/**
|
||||
* Executes an opcode, by means of using
|
||||
* a large switch statement. Only suitable
|
||||
* for environments where the instruction
|
||||
* map is not possible.
|
||||
*
|
||||
* This has yet to be proved!!!
|
||||
*/
|
||||
void executeSwLk();
|
||||
|
||||
public: // Addressing Modes
|
||||
|
||||
/**
|
||||
@@ -179,32 +197,32 @@ namespace spider {
|
||||
* Absolute Addressing Mode
|
||||
*/
|
||||
void abs();
|
||||
|
||||
|
||||
/**
|
||||
* Register Addressing Mode
|
||||
*/
|
||||
void reg();
|
||||
|
||||
|
||||
/**
|
||||
* Indrect Addressing Mode
|
||||
*/
|
||||
void ind();
|
||||
|
||||
|
||||
/**
|
||||
* Pointer Addressing Mode
|
||||
*/
|
||||
void ptr();
|
||||
|
||||
|
||||
/**
|
||||
* Indexed Addressing Mode
|
||||
*/
|
||||
void idx();
|
||||
|
||||
|
||||
/**
|
||||
* Scaled Addressing Mode
|
||||
*/
|
||||
void sca();
|
||||
|
||||
|
||||
/**
|
||||
* Displaced Addressing Mode
|
||||
*/
|
||||
@@ -234,327 +252,327 @@ namespace spider {
|
||||
void MMODE();
|
||||
|
||||
// [System] 0x003 — INT: Interrupt
|
||||
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Performs system interrupt no. (Dst) (See table)
|
||||
void INT();
|
||||
|
||||
// [System] 0x004 — LRV: Load Interrupt Vector Register
|
||||
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 0C
|
||||
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Dst -> RV
|
||||
void LRV();
|
||||
|
||||
// [System] 0x005 — FSR: Fetch System Register
|
||||
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: System Register at Dst -> Dst
|
||||
void FSR();
|
||||
|
||||
// [System] 0x006 — FIR: Fetch Instruction Register
|
||||
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Instruction Register -> Dst
|
||||
void FIR();
|
||||
|
||||
// [System] 0x007 — FZR: Fetch Stack Base Register
|
||||
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Stack Base Register -> Dst
|
||||
void FZR();
|
||||
|
||||
// [System] 0x008 — LSR: Load System Register
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: 1F | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: 1F | TypeMask: 08
|
||||
// Operation: Src -> System Register at Dst
|
||||
void LSR();
|
||||
|
||||
// [System] 0x009 — FVR: Fetch Interrupt Vector Register
|
||||
// Params: 1 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Interrupt Vector Register -> Dst
|
||||
void FVR();
|
||||
|
||||
// [Memory] 0x00A — MOV: Moves values
|
||||
// Params: 2 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Src -> Dst
|
||||
void MOV();
|
||||
|
||||
// [Memory] 0x00B — MOR: Moves registers
|
||||
// Params: 2 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 04 AddrMask2: 04 | TypeMask: 08
|
||||
// Operation: R Scr -> R Dst
|
||||
void MOR();
|
||||
|
||||
// [Memory] 0x00C — AMOV: Array Move, uses X and Y as ptrs, A as amount
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Array from X to Y, by A amount
|
||||
void AMOV();
|
||||
|
||||
// [Memory] 0x00D — SWP: Swap registers
|
||||
// Params: 2 | AddrMask1: 04 AddrMask2: 04 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 04 AddrMask2: 04 | TypeMask: 08
|
||||
// Operation: Src <-> Dst
|
||||
void SWP();
|
||||
|
||||
// [Memory] 0x00E — AHM: Ask Host for Memory
|
||||
// Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 08
|
||||
// Operation: Asks the host for a specific size of memory. Responds with 0 or 1
|
||||
void AHM();
|
||||
|
||||
// [Integer] 0x010 — COM: One's complement
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: ~ Dst -> Dst
|
||||
void COM();
|
||||
|
||||
// [Integer] 0x011 — NEG: Two's complement
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: - Dst -> Dst
|
||||
void NEG();
|
||||
|
||||
// [Integer] 0x012 — EXS: Extend Sign
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Last bit is copied and expanded for the next int size
|
||||
void EXS();
|
||||
|
||||
// [Integer] 0x013 — INC: Increment
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst + 1 -> Dst
|
||||
void INC();
|
||||
|
||||
// [Integer] 0x014 — DEC: Decrement
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst - 1 -> Dst
|
||||
void DEC();
|
||||
|
||||
// [Integer] 0x015 — ADD: Addition
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst + Src -> Dst
|
||||
void ADD();
|
||||
|
||||
// [Integer] 0x016 — SUB: Subtraction
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst - Src-> Dst
|
||||
void SUB();
|
||||
|
||||
// [Integer] 0x017 — MUL: Multiplication
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Signed Dst * Src -> Dst
|
||||
void MUL();
|
||||
|
||||
// [Integer] 0x018 — UMUL: Unsigned Multiplication
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Unsigned Dst * Src -> Dst
|
||||
void UMUL();
|
||||
|
||||
// [Integer] 0x019 — DIV: Division
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Signed Dst / Src -> Dst
|
||||
void DIV();
|
||||
|
||||
// [Integer] 0x01A — UDIV: Unsigned Division
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Unsigned Dst / Src -> Dst
|
||||
void UDIV();
|
||||
|
||||
// [Integer] 0x01B — MOD: Modulus
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Signed Dst % Src -> Dst
|
||||
void MOD();
|
||||
|
||||
// [Integer] 0x01C — UMOD: Unsigned Modulus
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Unsigned Dst % Src -> Dst
|
||||
void UMOD();
|
||||
|
||||
// [Integer] 0x01D — DMOD: Division and Modulus
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Signed Dst / Src -> X, Dst % Src -> Y
|
||||
void DMOD();
|
||||
|
||||
// [Integer] 0x01E — UDMD: Unsigned Division and Modulus
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Unsigned Dst / Src -> X, Dst % Src -> Y
|
||||
void UDMD();
|
||||
|
||||
// [System] 0x01F — FBT: Test and update Flag Register (Integer) Bits
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Flags of Dst -
|
||||
void FBT();
|
||||
|
||||
// [Bit Wise] 0x020 — STB: Set Bit
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Src# bit is set on Dst
|
||||
void STB();
|
||||
|
||||
// [Bit Wise] 0x021 — CRB: Clear Bit
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Src# bit is cleared on Dst
|
||||
void CRB();
|
||||
|
||||
// [Bit Wise] 0x022 — TSB: Test Bit
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Src# bit is tested against Dst, updates Equal Flag
|
||||
void TSB();
|
||||
|
||||
// [Bit Wise] 0x023 — BOOL: Sets the booleaness of a value
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Tests Dst != 0, updates Equal Flag
|
||||
void BOOL();
|
||||
|
||||
// [Bit Wise] 0x024 — NOT: Sets the inverse booleaness of a value (! BOOL)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Tests Dst == 0, updates Equal Flag
|
||||
void NOT();
|
||||
|
||||
// [Bit Wise] 0x025 — AND: Boolean AND operation
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst AND Src into Dst
|
||||
void AND();
|
||||
|
||||
// [Bit Wise] 0x026 — OR: Boolean OR operation
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst OR Src into Dst
|
||||
void OR();
|
||||
|
||||
// [Bit Wise] 0x027 — XOR: Boolean XOR operation
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst XOR Src into Dst
|
||||
void XOR();
|
||||
|
||||
// [Bit Wise] 0x028 — SHL: Arithmetic Shift Left
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst << Src into Dst
|
||||
void SHL();
|
||||
|
||||
// [Bit Wise] 0x029 — SHR: Arithmetic Shift Right
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst >> Src into Dst
|
||||
void SHR();
|
||||
|
||||
// [Bit Wise] 0x02A — SSR: Signed Shift Right
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst >>> Src into Dst
|
||||
void SSR();
|
||||
|
||||
// [Bit Wise] 0x02B — ROL: Rotate Left
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst ROL Src into Dst
|
||||
void ROL();
|
||||
|
||||
// [Bit Wise] 0x02C — ROR: Rotate Right
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst ROR Src into Dst
|
||||
void ROR();
|
||||
|
||||
// [Bit Wise] 0x02D — CNT: Counts bits
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: # of 1's into Dst
|
||||
void CNT();
|
||||
|
||||
// [Boolean] 0x030 — EQ: Equal
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst == Src into Dst
|
||||
void EQ();
|
||||
|
||||
// [Boolean] 0x031 — NE: Not Equal
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst != Src into Dst
|
||||
void NE();
|
||||
|
||||
// [Boolean] 0x032 — GT: Greater Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst > Src into Dst
|
||||
void GT();
|
||||
|
||||
// [Boolean] 0x033 — GE: Greater or Equal Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst >= Src into Dst
|
||||
void GE();
|
||||
|
||||
// [Boolean] 0x034 — LT: Lower Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst < Src into Dst
|
||||
void LT();
|
||||
|
||||
// [Boolean] 0x035 — LE: Lower or Equal Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst <= Src into Dst
|
||||
void LE();
|
||||
|
||||
// [Branch] 0x038 — JMP: Jump to absolute position
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst -> Instruction Register
|
||||
void JMP();
|
||||
|
||||
// [Branch] 0x039 — JEQ: Jumps to position if EQ flag is set
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst -> Instruction Register IF Flags.EQ
|
||||
void JEQ();
|
||||
|
||||
// [Branch] 0x03A — JNE: Jumps to position if EQ flag is cleared
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst -> Instruction Register IF NOT Flags.EQ
|
||||
void JNE();
|
||||
|
||||
// [Branch] 0x03B — JIF: Jumps if value provided is booleanly true
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst -> Instruction Register IF Src
|
||||
void JIF();
|
||||
|
||||
// [Branch] 0x03C — JMR: Jump Relative
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst + Instruction Register -> Instruction Register
|
||||
void JMR();
|
||||
|
||||
// [Branch] 0x03D — JER: Jumps to relative position if EQ flag is set
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst + Instruction Register -> Instruction Register IF Flags.EQ
|
||||
void JER();
|
||||
|
||||
// [Branch] 0x03E — JNR: Jumps to relative position if EQ flag is cleared
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst + Instruction Register -> Instruction Register IF NOT Flags.EQ
|
||||
void JNR();
|
||||
|
||||
// [Branch] 0x03F — JIR: Jumps to relative position if value provided is booleanly true
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation: Dst + Instruction Register -> Instruction Register IF Src
|
||||
void JIR();
|
||||
|
||||
// [System] 0x040 — SFB: Store (User) Flag Bit
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation:
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation:
|
||||
void SFB();
|
||||
|
||||
// [System] 0x041 — LFB: Load (User) Flag Bit
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation:
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation:
|
||||
void LFB();
|
||||
|
||||
// [Branch] 0x042 — JUF: Jump to absolute position, if user flag is true
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation:
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation:
|
||||
void JUF();
|
||||
|
||||
// [Branch] 0x043 — JUR: Jump to relative position, if user flag is true
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation:
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
|
||||
// Operation:
|
||||
void JUR();
|
||||
|
||||
// [Memory] 0x044 — PUSH: Push to stack
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst -> pushed into stack
|
||||
void PUSH();
|
||||
|
||||
// [Memory] 0x045 — POP: Pop from stack
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: popped from stack -> Dst
|
||||
void POP();
|
||||
|
||||
// [Memory] 0x046 — ALLOC: Allocate to heap
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Dst -> heap ptr of size Dst
|
||||
void ALLOC();
|
||||
|
||||
// [Memory] 0x047 — HFREE: Delete from heap
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Frees heap ptr in Dst
|
||||
void HFREE();
|
||||
|
||||
// [Branch] 0x04A — CALL: Call function at instruction index
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: Performs a function call, step XX
|
||||
void CALL();
|
||||
|
||||
@@ -564,207 +582,207 @@ namespace spider {
|
||||
void RET();
|
||||
|
||||
// [System] 0x04C — EDI: Enable/Disable External Interrupts
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: bool( Dst ) -> Enable External Interrupts Bit
|
||||
void EDI();
|
||||
|
||||
// [System] 0x04D — SHSS: Set Hotswap Signal Bit
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
|
||||
// Operation: bool( Dst ) -> Hot Swap Signal Bit
|
||||
void SHSS();
|
||||
|
||||
// [Floating Point] 0x050 — FLI: Float Load Immediate
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation:
|
||||
void FLI();
|
||||
|
||||
// [Floating Point] 0x051 — FNEG: Float negate
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: - Dst -> Dst
|
||||
void FNEG();
|
||||
|
||||
// [Floating Point] 0x052 — FADD: Float add
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst + Src -> Dst
|
||||
void FADD();
|
||||
|
||||
// [Floating Point] 0x053 — FSUB: Float subtract
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst - Src-> Dst
|
||||
void FSUB();
|
||||
|
||||
// [Floating Point] 0x054 — FMUL: Float multiplication
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst * Src -> Dst
|
||||
void FMUL();
|
||||
|
||||
// [Floating Point] 0x055 — FDIV: Float division
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst / Src -> Dst
|
||||
void FDIV();
|
||||
|
||||
// [Floating Point] 0x056 — FMOD: Float modulus
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst % Src -> Dst
|
||||
void FMOD();
|
||||
|
||||
// [Floating Point] 0x057 — FDMOD: Float division and modulus
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst / Src -> X, Dst % Src -> Y
|
||||
void FDMOD();
|
||||
|
||||
// [Floating Point] 0x058 — FEPS: Sets the float epsilon value, for comparison
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: Dst -> Epsilon Register
|
||||
void FEPS();
|
||||
|
||||
// [Floating Point] 0x059 — FEEP: Float Enable/Disable Epsilon
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: bool( Dst ) -> Epsilon Enable Bit
|
||||
void FEEP();
|
||||
|
||||
// [Boolean] 0x05A — FEQ: Float Equal
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst == Src into Dst
|
||||
void FEQ();
|
||||
|
||||
// [Boolean] 0x05B — FNE: Float Not Equal
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst != Src into Dst
|
||||
void FNE();
|
||||
|
||||
// [Boolean] 0x05C — FGT: Float Greater Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst > Src into Dst
|
||||
void FGT();
|
||||
|
||||
// [Boolean] 0x05D — FGE: Float Greater or Equal Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst >= Src into Dst
|
||||
void FGE();
|
||||
|
||||
// [Boolean] 0x05E — FLT: Float Lower Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst < Src into Dst
|
||||
void FLT();
|
||||
|
||||
// [Boolean] 0x05F — FLE: Float Lower or Equal Than
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: Dst <= Src into Dst
|
||||
void FLE();
|
||||
|
||||
// [Casts] 0x060 — F2D: F32 (Float) to F64 (Double)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void F2D();
|
||||
|
||||
// [Casts] 0x061 — D2F: F64 (Double) to F32 (Float)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void D2F();
|
||||
|
||||
// [Casts] 0x062 — I2F: I32 (Integer) to F32 (Float)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void I2F();
|
||||
|
||||
// [Casts] 0x063 — I2D: I32 (Integer) to F64 (Double)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void I2D();
|
||||
|
||||
// [Casts] 0x064 — L2F: I64 (Long) to F32 (Float)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void L2F();
|
||||
|
||||
// [Casts] 0x065 — L2D: I64 (Long) to F64 (Double)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void L2D();
|
||||
|
||||
// [Casts] 0x066 — F2I: F32 (Float) to I32 (Integer)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void F2I();
|
||||
|
||||
// [Casts] 0x067 — F2L: F32 (Float) to I64 (Long)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void F2L();
|
||||
|
||||
// [Casts] 0x068 — D2I: F64 (Double) to I32 (Integer)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void D2I();
|
||||
|
||||
// [Casts] 0x069 — D2L: F64 (Double) to I64 (Long)
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
|
||||
// Operation: (cast) Dst -> Dst
|
||||
void D2L();
|
||||
|
||||
// [Trigonometric] 0x06C — SIN: Sine Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: sin( Dst ) -> Dst
|
||||
void SIN();
|
||||
|
||||
// [Trigonometric] 0x06D — COS: Cosine Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: cos( Dst ) -> Dst
|
||||
void COS();
|
||||
|
||||
// [Trigonometric] 0x06E — TAN: Tangent Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: tan( Dst ) -> Dst
|
||||
void TAN();
|
||||
|
||||
// [Trigonometric] 0x06F — ASIN: Arc Sine Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: asin( Dst ) -> Dst
|
||||
void ASIN();
|
||||
|
||||
// [Trigonometric] 0x070 — ACOS: Arc Cosine Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: acos( Dst ) -> Dst
|
||||
void ACOS();
|
||||
|
||||
// [Trigonometric] 0x071 — ATAN: Arc Tangent Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: atan( Dst ) -> Dst
|
||||
void ATAN();
|
||||
|
||||
// [Trigonometric] 0x072 — ATAN2: Arc Tangent Function with 2 Arguments
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: atan( Dst, Src ) -> Dst
|
||||
void ATAN2();
|
||||
|
||||
// [Exponential] 0x074 — EXP: Exponential Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: exp( Dst ) -> Dst
|
||||
void EXP();
|
||||
|
||||
// [Exponential] 0x075 — LOG: Natural Logarithm
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: ln( Dst ) -> Dst
|
||||
void LOG();
|
||||
|
||||
// [Exponential] 0x076 — LOGAB: Logarithm A of B
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: log( Dst, Src ) -> Dst
|
||||
void LOGAB();
|
||||
|
||||
// [Exponential] 0x077 — POW: Power Function
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: pow( Dst, Src ) -> Dst
|
||||
void POW();
|
||||
|
||||
// [Exponential] 0x078 — SQRT: Square Root
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
|
||||
// Operation: sqrt( Dst ) -> Dst
|
||||
void SQRT();
|
||||
|
||||
// [Exponential] 0x079 — ROOT: General Root
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
|
||||
// Operation: pow( Dst, 1 / Src ) -> Dst
|
||||
void ROOT();
|
||||
|
||||
@@ -790,66 +808,80 @@ namespace spider {
|
||||
|
||||
// [Matrix] 0x080 — MADD: Matrix Addition
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void MADD();
|
||||
|
||||
// [Matrix] 0x081 — MSUB: Matrix Subtraction
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void MSUB();
|
||||
|
||||
// [Matrix] 0x082 — MMUL: Matrix Multiply
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void MMUL();
|
||||
|
||||
// [Matrix] 0x083 — MINV: Matrix Inverse
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void MINV();
|
||||
|
||||
// [Matrix] 0x084 — MTRA: Matrix Transpose
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void MTRA();
|
||||
|
||||
// [Matrix] 0x085 — MDET: Matrix Determinant
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void MDET();
|
||||
|
||||
// [Quaternion] 0x086 — QMKA: Quaternion Make from Angles
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
void QMKA();
|
||||
|
||||
// [Quaternion] 0x087 — QMUL: Quaternion Multiply
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
void QMUL();
|
||||
|
||||
// [SIMD] 0x08A — XADD: SIMD Addition
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void XADD();
|
||||
|
||||
// [SIMD] 0x08B — XSUB: SIMD Subtract
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void XSUB();
|
||||
|
||||
// [SIMD] 0x08C — XAMA: SIMD Alternate Multiply-Add
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void XAMA();
|
||||
|
||||
// [SIMD] 0x08D — XMUL: SIMD Multiply
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void XMUL();
|
||||
|
||||
// [SIMD] 0x08E — XDIV: SIMD Divide
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void XDIV();
|
||||
|
||||
// [Easter Eggs] 0x0F0 — UPY: Will place "YUPI" in memory
|
||||
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
|
||||
// Operation:
|
||||
// Operation:
|
||||
void UPY();
|
||||
|
||||
//[Easter Egg] 0x0F1 - LLGS: Injects the custom 8x4 ASCII spider logo
|
||||
// into RAM [0x80-0x9F] and signs Register RA with the "LLGS" hex literal.
|
||||
void LLGS();
|
||||
|
||||
// </pygen-target> //
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,53 @@ namespace spider {
|
||||
* type-punning which is the "standard" right now.
|
||||
*/
|
||||
union register_t {
|
||||
|
||||
// -- Un/Signed 64 -- //
|
||||
|
||||
u64 _u64;
|
||||
i64 _i64;
|
||||
f64 _f64;
|
||||
u8 _bytes[8];
|
||||
|
||||
// -- Un/Signed 32 -- //
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
u32 _u32; u32 : 32;
|
||||
#else
|
||||
u32 : 32; u32 _u32;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
i32 _i32; i32 : 32;
|
||||
#else
|
||||
i32 : 32; i32 _i32;
|
||||
#endif
|
||||
};
|
||||
|
||||
// -- Un/Signed 16 -- //
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
u16 _u16;
|
||||
u16 : 16; u16 : 16; u16 : 16;
|
||||
#else
|
||||
u16 : 16; u16 : 16; u16 : 16;
|
||||
u16 _u16;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
i16 _i16;
|
||||
i16 : 16; i16 : 16; i16 : 16;
|
||||
#else
|
||||
i16 : 16; i16 : 16; i16 : 16;
|
||||
i16 _i16;
|
||||
#endif
|
||||
};
|
||||
|
||||
// -- Un/Signed 8 -- //
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
@@ -35,22 +78,17 @@ namespace spider {
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
u16 _u16;
|
||||
u16 : 16; u16 : 16; u16 : 16;
|
||||
i8 _i8; // ditto
|
||||
i8 : 8; i8 : 8; i8 : 8; i8 : 8; i8 : 8; i8 : 8; i8 : 8;
|
||||
#else
|
||||
u16 : 16; u16 : 16; u16 : 16;
|
||||
u16 _u16;
|
||||
i8 : 8; i8 : 8; i8 : 8; i8 : 8; i8 : 8; i8 : 8; i8 : 8;
|
||||
i8 _i8;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
u32 _u32; u32 : 32;
|
||||
#else
|
||||
u32 : 32; u32 _u32;
|
||||
#endif
|
||||
};
|
||||
// -- Floating Point -- //
|
||||
|
||||
f64 _f64;
|
||||
struct {
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
f32 _f32; u32 : 32;
|
||||
@@ -59,6 +97,10 @@ namespace spider {
|
||||
#endif
|
||||
};
|
||||
|
||||
// -- Access -- //
|
||||
|
||||
u8 _bytes[8];
|
||||
|
||||
u8& operator[](size_t i) { // 0 is always LSB
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
return _bytes[i];
|
||||
@@ -75,6 +117,7 @@ namespace spider {
|
||||
return _bytes[7 - i];
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
static_assert(sizeof(register_t) == 8, "The register type must be exactly 8 bytes.");
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace spider {
|
||||
;
|
||||
}
|
||||
|
||||
void drawCPUTempl(Terminal& t, CPU& cpu) {
|
||||
void drawCPUTempl(Terminal& t) {
|
||||
i32 r = 8, c = 1;
|
||||
i32 w = 35, h = 31;
|
||||
t.drawBox(r, c, w, h, "CPU");
|
||||
@@ -171,10 +171,10 @@ namespace spider {
|
||||
t.flush();
|
||||
}
|
||||
|
||||
i32 addressWidth(isize ramSize) {
|
||||
u32 addressWidth(isize ramSize) {
|
||||
if (ramSize == 0) return 1;
|
||||
isize maxAddr = ramSize - 1;
|
||||
i32 digits = 0;
|
||||
u32 digits = 0;
|
||||
// Shift by increments of 4 (one hex nibble)
|
||||
// We use a do-while to ensure at least 1 digit is returned for small RAMs
|
||||
do {
|
||||
@@ -193,13 +193,13 @@ namespace spider {
|
||||
* @param progress The current progress
|
||||
* @param total The total
|
||||
*/
|
||||
void drawScrollThumb(Terminal& term, i32 x, i32 y, i32 trackHeight, isize progress, isize total) {
|
||||
void drawScrollThumb(Terminal& term, u32 x, u32 y, u32 trackHeight, isize progress, isize total) {
|
||||
if (total == 0 || trackHeight <= 0) return;
|
||||
|
||||
// 1. Draw the background track (Light Shade: ░)
|
||||
term.style(Terminal::FG_B_BLACK); // Dim the track
|
||||
for (int i = 0; i < trackHeight; ++i) {
|
||||
term.move(y + i, x).print("░");
|
||||
for (u32 i = 0; i < trackHeight; ++i) {
|
||||
term.move(i32(y + i), i32(x)).print("░");
|
||||
}
|
||||
|
||||
// 2. Calculate Thumb Position
|
||||
@@ -210,10 +210,10 @@ namespace spider {
|
||||
f64 ratio = f64(progress) / f64(total);
|
||||
|
||||
// Map to track coordinates
|
||||
i32 thumbOffset = i32(ratio * (trackHeight - 1));
|
||||
u32 thumbOffset = u32(ratio * (trackHeight - 1));
|
||||
|
||||
// 3. Draw the Thumb (Full Block: █)
|
||||
term.move(y + thumbOffset, x);
|
||||
term.move(i32(y + thumbOffset), i32(x));
|
||||
term.style(Terminal::FG_WHITE).print("█");
|
||||
term.style(Terminal::RESET);
|
||||
}
|
||||
@@ -230,30 +230,30 @@ namespace spider {
|
||||
*/
|
||||
void drawRAM(Terminal& term, RAM& ram, u64 scrollPos) {
|
||||
// 1. Draw the container box
|
||||
i32 y = 3;
|
||||
i32 height = 36;
|
||||
u32 y = 3;
|
||||
u32 height = 36;
|
||||
|
||||
// 2. Configuration for the hex layout
|
||||
int addrWidth = addressWidth(ram.size());
|
||||
int bytesPerRow = 8;
|
||||
int displayRows = height - 2; // Subtract top/bottom borders
|
||||
i32 width = (2 + 2 + 16 + 7 + 3 + 8 + 4) + addrWidth;
|
||||
i32 x = 37;
|
||||
u32 addrWidth = addressWidth(ram.size());
|
||||
u32 bytesPerRow = 8;
|
||||
u32 displayRows = height - 2; // Subtract top/bottom borders
|
||||
u32 width = (2 + 2 + 16 + 7 + 3 + 8 + 4) + addrWidth;
|
||||
u32 x = 37;
|
||||
|
||||
// create box
|
||||
term.drawBox(y, x, width, height, "RAM");
|
||||
term.drawBox(i32(y), i32(x), i32(width), i32(height), "RAM");
|
||||
drawScrollThumb(term, x + width - 2, y + 1, height - 2, scrollPos, ram.size());
|
||||
|
||||
// Ensure scrollPos is within bounds and aligned
|
||||
if (scrollPos < 0) scrollPos = 0;
|
||||
//if (scrollPos < 0) scrollPos = 0;
|
||||
if (scrollPos > ram.size()) scrollPos = ram.size();
|
||||
|
||||
for (int i = 0; i < displayRows; ++i) {
|
||||
for (u32 i = 0; i < displayRows; ++i) {
|
||||
isize currentRowAddr = scrollPos + (i * bytesPerRow);
|
||||
|
||||
// address lock
|
||||
if (currentRowAddr >= ram.size()) {
|
||||
term.move(y + 1 + i, x + 1);
|
||||
term.move(i32(y + 1 + i), i32(x + 1));
|
||||
term.print(std::string(width - 3, ' '));
|
||||
continue;
|
||||
}
|
||||
@@ -266,11 +266,11 @@ namespace spider {
|
||||
ss << std::setfill('0') << std::uppercase << std::hex;
|
||||
|
||||
// address
|
||||
ssaddr << std::setw(addrWidth) << currentRowAddr << " ";
|
||||
ssaddr << std::setw(i32(addrWidth)) << currentRowAddr << " ";
|
||||
|
||||
// Hex Bytes
|
||||
std::string asciiPart = "";
|
||||
for (int j = 0; j < bytesPerRow; ++j) {
|
||||
for (u32 j = 0; j < bytesPerRow; ++j) {
|
||||
isize targetAddr = currentRowAddr + j;
|
||||
if (targetAddr >= ram.size()) {
|
||||
ss << ""; // Padding for end of memory
|
||||
@@ -279,12 +279,12 @@ namespace spider {
|
||||
}
|
||||
|
||||
u8 byte = ram[targetAddr];
|
||||
ss << std::setfill('0') << std::setw(2) << std::hex << (u32)byte << " ";
|
||||
asciiPart += (std::isprint(byte) ? (char)byte : '.');
|
||||
ss << std::setfill('0') << std::setw(2) << std::hex << u32(byte) << " ";
|
||||
asciiPart += (std::isprint(byte) ? char(byte) : '.');
|
||||
}
|
||||
|
||||
// --- Combine and Print ---
|
||||
term.move(y + 1 + i, x + 2); // Move inside the box
|
||||
term.move(i32(y + 1 + i), i32(x + 2)); // Move inside the box
|
||||
term.style(Terminal::FG_B_CYAN).print(ssaddr.str()); // Hex part in Cyan
|
||||
term.style(Terminal::FG_WHITE).print(ss.str());
|
||||
term.style(Terminal::FG_B_YELLOW).print(" | ");
|
||||
@@ -330,18 +330,16 @@ namespace spider {
|
||||
int liveDebugMain() {
|
||||
Terminal t;
|
||||
Runtime runtime(1024);
|
||||
|
||||
|
||||
InstrReelFixed fix(100);
|
||||
runtime.ram[0] = 0xFF;
|
||||
runtime.ram[1] = 0xEE;
|
||||
runtime.ram[2] = 0xDD;
|
||||
runtime.ram[3] = 0xCC;
|
||||
runtime.ram[4] = 0xBB;
|
||||
runtime.ram[5] = 0xAA;
|
||||
runtime.ram[6] = 0x99;
|
||||
runtime.ram[7] = 0x88;
|
||||
fix.writeU16(0, 0b0000111);
|
||||
|
||||
|
||||
|
||||
runtime.hookReel(&fix, false);
|
||||
|
||||
|
||||
|
||||
bool running = true, update = true;
|
||||
u64 ramScroll = 0;
|
||||
u8 key = Terminal::UNKNOWN;
|
||||
@@ -351,7 +349,7 @@ namespace spider {
|
||||
|
||||
drawTime(t);
|
||||
drawHead(t);
|
||||
drawCPUTempl(t, runtime.cpu);
|
||||
drawCPUTempl(t);
|
||||
|
||||
// delay for time
|
||||
auto last_exec = std::chrono::steady_clock::now();
|
||||
@@ -388,7 +386,7 @@ namespace spider {
|
||||
case Terminal::ENTER:
|
||||
update = true;
|
||||
runtime.cpu.fetchInstr();
|
||||
runtime.cpu.fetchOperDst();
|
||||
runtime.cpu.execute(); // looks up instrMap[_opcode] & calls the correct instruction method (e.g. FMUL)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
748
src/spider/runtime/instr/InstrMap.cpp
Normal file
748
src/spider/runtime/instr/InstrMap.cpp
Normal file
@@ -0,0 +1,748 @@
|
||||
/**
|
||||
* @file InstrMap.cpp
|
||||
* @brief Spider VM instruction dispatch — array and switch implementations.
|
||||
*
|
||||
* AUTO-GENERATED by pygen.ipynb — DO NOT EDIT BY HAND.
|
||||
*
|
||||
* This file provides two equivalent dispatch mechanisms:
|
||||
*
|
||||
* 1. InstrMap[] — A lookup table of member-function pointers indexed by
|
||||
* opcode. O(1) dispatch; suitable for platforms where
|
||||
* indirect calls through function pointers are efficient.
|
||||
*
|
||||
* 2. CPU::execute(u16) — A switch/case over every opcode. Lets the
|
||||
* compiler emit a jump table or branch tree; may be
|
||||
* preferable on microcontrollers or when link-time
|
||||
* optimisation can inline the handlers.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
// =============================================================
|
||||
// Version 1 — Lookup table of member-function pointers
|
||||
// =============================================================
|
||||
|
||||
|
||||
/**
|
||||
* Instruction dispatch table (512 entries, 9-bit opcode space).
|
||||
*
|
||||
* Usage:
|
||||
* u16 opcode = fetch();
|
||||
* CPU::Fn fn = InstrMap[opcode];
|
||||
* if (fn) (cpu.*fn)();
|
||||
*/
|
||||
CPU::Fn CPU::instrMap[] = {
|
||||
&CPU::NOP, // 0x000 — No Operation
|
||||
&CPU::SPDR, // 0x001 — Will place the Spider version of the interpreter in RA
|
||||
&CPU::MMODE, // 0x002 — Set Memory Mode
|
||||
&CPU::INT, // 0x003 — Interrupt
|
||||
&CPU::LRV, // 0x004 — Load Interrupt Vector Register
|
||||
&CPU::FSR, // 0x005 — Fetch System Register
|
||||
&CPU::FIR, // 0x006 — Fetch Instruction Register
|
||||
&CPU::FZR, // 0x007 — Fetch Stack Base Register
|
||||
&CPU::LSR, // 0x008 — Load System Register
|
||||
&CPU::FVR, // 0x009 — Fetch Interrupt Vector Register
|
||||
&CPU::MOV, // 0x00A — Moves values
|
||||
&CPU::MOR, // 0x00B — Moves registers
|
||||
&CPU::AMOV, // 0x00C — Array Move, uses X and Y as ptrs, A as amount
|
||||
&CPU::SWP, // 0x00D — Swap registers
|
||||
&CPU::AHM, // 0x00E — Ask Host for Memory
|
||||
nullptr, // 0x00F (reserved)
|
||||
&CPU::COM, // 0x010 — One's complement
|
||||
&CPU::NEG, // 0x011 — Two's complement
|
||||
&CPU::EXS, // 0x012 — Extend Sign
|
||||
&CPU::INC, // 0x013 — Increment
|
||||
&CPU::DEC, // 0x014 — Decrement
|
||||
&CPU::ADD, // 0x015 — Addition
|
||||
&CPU::SUB, // 0x016 — Subtraction
|
||||
&CPU::MUL, // 0x017 — Multiplication
|
||||
&CPU::UMUL, // 0x018 — Unsigned Multiplication
|
||||
&CPU::DIV, // 0x019 — Division
|
||||
&CPU::UDIV, // 0x01A — Unsigned Division
|
||||
&CPU::MOD, // 0x01B — Modulus
|
||||
&CPU::UMOD, // 0x01C — Unsigned Modulus
|
||||
&CPU::DMOD, // 0x01D — Division and Modulus
|
||||
&CPU::UDMD, // 0x01E — Unsigned Division and Modulus
|
||||
&CPU::FBT, // 0x01F — Test and update Flag Register (Integer) Bits
|
||||
&CPU::STB, // 0x020 — Set Bit
|
||||
&CPU::CRB, // 0x021 — Clear Bit
|
||||
&CPU::TSB, // 0x022 — Test Bit
|
||||
&CPU::BOOL, // 0x023 — Sets the booleaness of a value
|
||||
&CPU::NOT, // 0x024 — Sets the inverse booleaness of a value (! BOOL)
|
||||
&CPU::AND, // 0x025 — Boolean AND operation
|
||||
&CPU::OR, // 0x026 — Boolean OR operation
|
||||
&CPU::XOR, // 0x027 — Boolean XOR operation
|
||||
&CPU::SHL, // 0x028 — Arithmetic Shift Left
|
||||
&CPU::SHR, // 0x029 — Arithmetic Shift Right
|
||||
&CPU::SSR, // 0x02A — Signed Shift Right
|
||||
&CPU::ROL, // 0x02B — Rotate Left
|
||||
&CPU::ROR, // 0x02C — Rotate Right
|
||||
&CPU::CNT, // 0x02D — Counts bits
|
||||
nullptr, // 0x02E (reserved)
|
||||
nullptr, // 0x02F (reserved)
|
||||
&CPU::EQ, // 0x030 — Equal
|
||||
&CPU::NE, // 0x031 — Not Equal
|
||||
&CPU::GT, // 0x032 — Greater Than
|
||||
&CPU::GE, // 0x033 — Greater or Equal Than
|
||||
&CPU::LT, // 0x034 — Lower Than
|
||||
&CPU::LE, // 0x035 — Lower or Equal Than
|
||||
nullptr, // 0x036 (reserved)
|
||||
nullptr, // 0x037 (reserved)
|
||||
&CPU::JMP, // 0x038 — Jump to absolute position
|
||||
&CPU::JEQ, // 0x039 — Jumps to position if EQ flag is set
|
||||
&CPU::JNE, // 0x03A — Jumps to position if EQ flag is cleared
|
||||
&CPU::JIF, // 0x03B — Jumps if value provided is booleanly true
|
||||
&CPU::JMR, // 0x03C — Jump Relative
|
||||
&CPU::JER, // 0x03D — Jumps to relative position if EQ flag is set
|
||||
&CPU::JNR, // 0x03E — Jumps to relative position if EQ flag is cleared
|
||||
&CPU::JIR, // 0x03F — Jumps to relative position if value provided is booleanly true
|
||||
&CPU::SFB, // 0x040 — Store (User) Flag Bit
|
||||
&CPU::LFB, // 0x041 — Load (User) Flag Bit
|
||||
&CPU::JUF, // 0x042 — Jump to absolute position, if user flag is true
|
||||
&CPU::JUR, // 0x043 — Jump to relative position, if user flag is true
|
||||
&CPU::PUSH, // 0x044 — Push to stack
|
||||
&CPU::POP, // 0x045 — Pop from stack
|
||||
&CPU::ALLOC, // 0x046 — Allocate to heap
|
||||
&CPU::HFREE, // 0x047 — Delete from heap
|
||||
nullptr, // 0x048 (reserved)
|
||||
nullptr, // 0x049 (reserved)
|
||||
&CPU::CALL, // 0x04A — Call function at instruction index
|
||||
&CPU::RET, // 0x04B — Return from a function
|
||||
&CPU::EDI, // 0x04C — Enable/Disable External Interrupts
|
||||
&CPU::SHSS, // 0x04D — Set Hotswap Signal Bit
|
||||
nullptr, // 0x04E (reserved)
|
||||
nullptr, // 0x04F (reserved)
|
||||
&CPU::FLI, // 0x050 — Float Load Immediate
|
||||
&CPU::FNEG, // 0x051 — Float negate
|
||||
&CPU::FADD, // 0x052 — Float add
|
||||
&CPU::FSUB, // 0x053 — Float subtract
|
||||
&CPU::FMUL, // 0x054 — Float multiplication
|
||||
&CPU::FDIV, // 0x055 — Float division
|
||||
&CPU::FMOD, // 0x056 — Float modulus
|
||||
&CPU::FDMOD, // 0x057 — Float division and modulus
|
||||
&CPU::FEPS, // 0x058 — Sets the float epsilon value, for comparison
|
||||
&CPU::FEEP, // 0x059 — Float Enable/Disable Epsilon
|
||||
&CPU::FEQ, // 0x05A — Float Equal
|
||||
&CPU::FNE, // 0x05B — Float Not Equal
|
||||
&CPU::FGT, // 0x05C — Float Greater Than
|
||||
&CPU::FGE, // 0x05D — Float Greater or Equal Than
|
||||
&CPU::FLT, // 0x05E — Float Lower Than
|
||||
&CPU::FLE, // 0x05F — Float Lower or Equal Than
|
||||
&CPU::F2D, // 0x060 — F32 (Float) to F64 (Double)
|
||||
&CPU::D2F, // 0x061 — F64 (Double) to F32 (Float)
|
||||
&CPU::I2F, // 0x062 — I32 (Integer) to F32 (Float)
|
||||
&CPU::I2D, // 0x063 — I32 (Integer) to F64 (Double)
|
||||
&CPU::L2F, // 0x064 — I64 (Long) to F32 (Float)
|
||||
&CPU::L2D, // 0x065 — I64 (Long) to F64 (Double)
|
||||
&CPU::F2I, // 0x066 — F32 (Float) to I32 (Integer)
|
||||
&CPU::F2L, // 0x067 — F32 (Float) to I64 (Long)
|
||||
&CPU::D2I, // 0x068 — F64 (Double) to I32 (Integer)
|
||||
&CPU::D2L, // 0x069 — F64 (Double) to I64 (Long)
|
||||
nullptr, // 0x06A (reserved)
|
||||
nullptr, // 0x06B (reserved)
|
||||
&CPU::SIN, // 0x06C — Sine Function
|
||||
&CPU::COS, // 0x06D — Cosine Function
|
||||
&CPU::TAN, // 0x06E — Tangent Function
|
||||
&CPU::ASIN, // 0x06F — Arc Sine Function
|
||||
&CPU::ACOS, // 0x070 — Arc Cosine Function
|
||||
&CPU::ATAN, // 0x071 — Arc Tangent Function
|
||||
&CPU::ATAN2, // 0x072 — Arc Tangent Function with 2 Arguments
|
||||
nullptr, // 0x073 (reserved)
|
||||
&CPU::EXP, // 0x074 — Exponential Function
|
||||
&CPU::LOG, // 0x075 — Natural Logarithm
|
||||
&CPU::LOGAB, // 0x076 — Logarithm A of B
|
||||
&CPU::POW, // 0x077 — Power Function
|
||||
&CPU::SQRT, // 0x078 — Square Root
|
||||
&CPU::ROOT, // 0x079 — General Root
|
||||
nullptr, // 0x07A (reserved)
|
||||
nullptr, // 0x07B (reserved)
|
||||
&CPU::ADC, // 0x07C — Add with Carry
|
||||
&CPU::SWC, // 0x07D — Subtract with Carry (Borrow)
|
||||
&CPU::MWO, // 0x07E — Multiply with Overflow
|
||||
&CPU::UMO, // 0x07F — Unsigned Multiply with Overflow
|
||||
&CPU::MADD, // 0x080 — Matrix Addition
|
||||
&CPU::MSUB, // 0x081 — Matrix Subtraction
|
||||
&CPU::MMUL, // 0x082 — Matrix Multiply
|
||||
&CPU::MINV, // 0x083 — Matrix Inverse
|
||||
&CPU::MTRA, // 0x084 — Matrix Transpose
|
||||
&CPU::MDET, // 0x085 — Matrix Determinant
|
||||
&CPU::QMKA, // 0x086 — Quaternion Make from Angles
|
||||
&CPU::QMUL, // 0x087 — Quaternion Multiply
|
||||
nullptr, // 0x088
|
||||
nullptr, // 0x089
|
||||
&CPU::XADD, // 0x08A — SIMD Addition
|
||||
&CPU::XSUB, // 0x08B — SIMD Subtract
|
||||
&CPU::XAMA, // 0x08C — SIMD Alternate Multiply-Add
|
||||
&CPU::XMUL, // 0x08D — SIMD Multiply
|
||||
&CPU::XDIV, // 0x08E — SIMD Divide
|
||||
nullptr, // 0x08F
|
||||
nullptr, // 0x090
|
||||
nullptr, // 0x091
|
||||
nullptr, // 0x092
|
||||
nullptr, // 0x093
|
||||
nullptr, // 0x094
|
||||
nullptr, // 0x095
|
||||
nullptr, // 0x096
|
||||
nullptr, // 0x097
|
||||
nullptr, // 0x098
|
||||
nullptr, // 0x099
|
||||
nullptr, // 0x09A
|
||||
nullptr, // 0x09B
|
||||
nullptr, // 0x09C
|
||||
nullptr, // 0x09D
|
||||
nullptr, // 0x09E
|
||||
nullptr, // 0x09F
|
||||
nullptr, // 0x0A0
|
||||
nullptr, // 0x0A1
|
||||
nullptr, // 0x0A2
|
||||
nullptr, // 0x0A3
|
||||
nullptr, // 0x0A4
|
||||
nullptr, // 0x0A5
|
||||
nullptr, // 0x0A6
|
||||
nullptr, // 0x0A7
|
||||
nullptr, // 0x0A8
|
||||
nullptr, // 0x0A9
|
||||
nullptr, // 0x0AA
|
||||
nullptr, // 0x0AB
|
||||
nullptr, // 0x0AC
|
||||
nullptr, // 0x0AD
|
||||
nullptr, // 0x0AE
|
||||
nullptr, // 0x0AF
|
||||
nullptr, // 0x0B0
|
||||
nullptr, // 0x0B1
|
||||
nullptr, // 0x0B2
|
||||
nullptr, // 0x0B3
|
||||
nullptr, // 0x0B4
|
||||
nullptr, // 0x0B5
|
||||
nullptr, // 0x0B6
|
||||
nullptr, // 0x0B7
|
||||
nullptr, // 0x0B8
|
||||
nullptr, // 0x0B9
|
||||
nullptr, // 0x0BA
|
||||
nullptr, // 0x0BB
|
||||
nullptr, // 0x0BC
|
||||
nullptr, // 0x0BD
|
||||
nullptr, // 0x0BE
|
||||
nullptr, // 0x0BF
|
||||
nullptr, // 0x0C0
|
||||
nullptr, // 0x0C1
|
||||
nullptr, // 0x0C2
|
||||
nullptr, // 0x0C3
|
||||
nullptr, // 0x0C4
|
||||
nullptr, // 0x0C5
|
||||
nullptr, // 0x0C6
|
||||
nullptr, // 0x0C7
|
||||
nullptr, // 0x0C8
|
||||
nullptr, // 0x0C9
|
||||
nullptr, // 0x0CA
|
||||
nullptr, // 0x0CB
|
||||
nullptr, // 0x0CC
|
||||
nullptr, // 0x0CD
|
||||
nullptr, // 0x0CE
|
||||
nullptr, // 0x0CF
|
||||
nullptr, // 0x0D0
|
||||
nullptr, // 0x0D1
|
||||
nullptr, // 0x0D2
|
||||
nullptr, // 0x0D3
|
||||
nullptr, // 0x0D4
|
||||
nullptr, // 0x0D5
|
||||
nullptr, // 0x0D6
|
||||
nullptr, // 0x0D7
|
||||
nullptr, // 0x0D8
|
||||
nullptr, // 0x0D9
|
||||
nullptr, // 0x0DA
|
||||
nullptr, // 0x0DB
|
||||
nullptr, // 0x0DC
|
||||
nullptr, // 0x0DD
|
||||
nullptr, // 0x0DE
|
||||
nullptr, // 0x0DF
|
||||
nullptr, // 0x0E0
|
||||
nullptr, // 0x0E1
|
||||
nullptr, // 0x0E2
|
||||
nullptr, // 0x0E3
|
||||
nullptr, // 0x0E4
|
||||
nullptr, // 0x0E5
|
||||
nullptr, // 0x0E6
|
||||
nullptr, // 0x0E7
|
||||
nullptr, // 0x0E8
|
||||
nullptr, // 0x0E9
|
||||
nullptr, // 0x0EA
|
||||
nullptr, // 0x0EB
|
||||
nullptr, // 0x0EC
|
||||
nullptr, // 0x0ED
|
||||
nullptr, // 0x0EE
|
||||
nullptr, // 0x0EF
|
||||
&CPU::UPY, // 0x0F0 — Will place "YUPI" in memory
|
||||
&CPU::LLGS, // 0x0F1 — Spider ASCII art (LLGS easter egg)
|
||||
nullptr, // 0x0F2
|
||||
nullptr, // 0x0F3
|
||||
nullptr, // 0x0F4
|
||||
nullptr, // 0x0F5
|
||||
nullptr, // 0x0F6
|
||||
nullptr, // 0x0F7
|
||||
nullptr, // 0x0F8
|
||||
nullptr, // 0x0F9
|
||||
nullptr, // 0x0FA
|
||||
nullptr, // 0x0FB
|
||||
nullptr, // 0x0FC
|
||||
nullptr, // 0x0FD
|
||||
nullptr, // 0x0FE
|
||||
nullptr, // 0x0FF
|
||||
nullptr, // 0x100
|
||||
nullptr, // 0x101
|
||||
nullptr, // 0x102
|
||||
nullptr, // 0x103
|
||||
nullptr, // 0x104
|
||||
nullptr, // 0x105
|
||||
nullptr, // 0x106
|
||||
nullptr, // 0x107
|
||||
nullptr, // 0x108
|
||||
nullptr, // 0x109
|
||||
nullptr, // 0x10A
|
||||
nullptr, // 0x10B
|
||||
nullptr, // 0x10C
|
||||
nullptr, // 0x10D
|
||||
nullptr, // 0x10E
|
||||
nullptr, // 0x10F
|
||||
nullptr, // 0x110
|
||||
nullptr, // 0x111
|
||||
nullptr, // 0x112
|
||||
nullptr, // 0x113
|
||||
nullptr, // 0x114
|
||||
nullptr, // 0x115
|
||||
nullptr, // 0x116
|
||||
nullptr, // 0x117
|
||||
nullptr, // 0x118
|
||||
nullptr, // 0x119
|
||||
nullptr, // 0x11A
|
||||
nullptr, // 0x11B
|
||||
nullptr, // 0x11C
|
||||
nullptr, // 0x11D
|
||||
nullptr, // 0x11E
|
||||
nullptr, // 0x11F
|
||||
nullptr, // 0x120
|
||||
nullptr, // 0x121
|
||||
nullptr, // 0x122
|
||||
nullptr, // 0x123
|
||||
nullptr, // 0x124
|
||||
nullptr, // 0x125
|
||||
nullptr, // 0x126
|
||||
nullptr, // 0x127
|
||||
nullptr, // 0x128
|
||||
nullptr, // 0x129
|
||||
nullptr, // 0x12A
|
||||
nullptr, // 0x12B
|
||||
nullptr, // 0x12C
|
||||
nullptr, // 0x12D
|
||||
nullptr, // 0x12E
|
||||
nullptr, // 0x12F
|
||||
nullptr, // 0x130
|
||||
nullptr, // 0x131
|
||||
nullptr, // 0x132
|
||||
nullptr, // 0x133
|
||||
nullptr, // 0x134
|
||||
nullptr, // 0x135
|
||||
nullptr, // 0x136
|
||||
nullptr, // 0x137
|
||||
nullptr, // 0x138
|
||||
nullptr, // 0x139
|
||||
nullptr, // 0x13A
|
||||
nullptr, // 0x13B
|
||||
nullptr, // 0x13C
|
||||
nullptr, // 0x13D
|
||||
nullptr, // 0x13E
|
||||
nullptr, // 0x13F
|
||||
nullptr, // 0x140
|
||||
nullptr, // 0x141
|
||||
nullptr, // 0x142
|
||||
nullptr, // 0x143
|
||||
nullptr, // 0x144
|
||||
nullptr, // 0x145
|
||||
nullptr, // 0x146
|
||||
nullptr, // 0x147
|
||||
nullptr, // 0x148
|
||||
nullptr, // 0x149
|
||||
nullptr, // 0x14A
|
||||
nullptr, // 0x14B
|
||||
nullptr, // 0x14C
|
||||
nullptr, // 0x14D
|
||||
nullptr, // 0x14E
|
||||
nullptr, // 0x14F
|
||||
nullptr, // 0x150
|
||||
nullptr, // 0x151
|
||||
nullptr, // 0x152
|
||||
nullptr, // 0x153
|
||||
nullptr, // 0x154
|
||||
nullptr, // 0x155
|
||||
nullptr, // 0x156
|
||||
nullptr, // 0x157
|
||||
nullptr, // 0x158
|
||||
nullptr, // 0x159
|
||||
nullptr, // 0x15A
|
||||
nullptr, // 0x15B
|
||||
nullptr, // 0x15C
|
||||
nullptr, // 0x15D
|
||||
nullptr, // 0x15E
|
||||
nullptr, // 0x15F
|
||||
nullptr, // 0x160
|
||||
nullptr, // 0x161
|
||||
nullptr, // 0x162
|
||||
nullptr, // 0x163
|
||||
nullptr, // 0x164
|
||||
nullptr, // 0x165
|
||||
nullptr, // 0x166
|
||||
nullptr, // 0x167
|
||||
nullptr, // 0x168
|
||||
nullptr, // 0x169
|
||||
nullptr, // 0x16A
|
||||
nullptr, // 0x16B
|
||||
nullptr, // 0x16C
|
||||
nullptr, // 0x16D
|
||||
nullptr, // 0x16E
|
||||
nullptr, // 0x16F
|
||||
nullptr, // 0x170
|
||||
nullptr, // 0x171
|
||||
nullptr, // 0x172
|
||||
nullptr, // 0x173
|
||||
nullptr, // 0x174
|
||||
nullptr, // 0x175
|
||||
nullptr, // 0x176
|
||||
nullptr, // 0x177
|
||||
nullptr, // 0x178
|
||||
nullptr, // 0x179
|
||||
nullptr, // 0x17A
|
||||
nullptr, // 0x17B
|
||||
nullptr, // 0x17C
|
||||
nullptr, // 0x17D
|
||||
nullptr, // 0x17E
|
||||
nullptr, // 0x17F
|
||||
nullptr, // 0x180
|
||||
nullptr, // 0x181
|
||||
nullptr, // 0x182
|
||||
nullptr, // 0x183
|
||||
nullptr, // 0x184
|
||||
nullptr, // 0x185
|
||||
nullptr, // 0x186
|
||||
nullptr, // 0x187
|
||||
nullptr, // 0x188
|
||||
nullptr, // 0x189
|
||||
nullptr, // 0x18A
|
||||
nullptr, // 0x18B
|
||||
nullptr, // 0x18C
|
||||
nullptr, // 0x18D
|
||||
nullptr, // 0x18E
|
||||
nullptr, // 0x18F
|
||||
nullptr, // 0x190
|
||||
nullptr, // 0x191
|
||||
nullptr, // 0x192
|
||||
nullptr, // 0x193
|
||||
nullptr, // 0x194
|
||||
nullptr, // 0x195
|
||||
nullptr, // 0x196
|
||||
nullptr, // 0x197
|
||||
nullptr, // 0x198
|
||||
nullptr, // 0x199
|
||||
nullptr, // 0x19A
|
||||
nullptr, // 0x19B
|
||||
nullptr, // 0x19C
|
||||
nullptr, // 0x19D
|
||||
nullptr, // 0x19E
|
||||
nullptr, // 0x19F
|
||||
nullptr, // 0x1A0
|
||||
nullptr, // 0x1A1
|
||||
nullptr, // 0x1A2
|
||||
nullptr, // 0x1A3
|
||||
nullptr, // 0x1A4
|
||||
nullptr, // 0x1A5
|
||||
nullptr, // 0x1A6
|
||||
nullptr, // 0x1A7
|
||||
nullptr, // 0x1A8
|
||||
nullptr, // 0x1A9
|
||||
nullptr, // 0x1AA
|
||||
nullptr, // 0x1AB
|
||||
nullptr, // 0x1AC
|
||||
nullptr, // 0x1AD
|
||||
nullptr, // 0x1AE
|
||||
nullptr, // 0x1AF
|
||||
nullptr, // 0x1B0
|
||||
nullptr, // 0x1B1
|
||||
nullptr, // 0x1B2
|
||||
nullptr, // 0x1B3
|
||||
nullptr, // 0x1B4
|
||||
nullptr, // 0x1B5
|
||||
nullptr, // 0x1B6
|
||||
nullptr, // 0x1B7
|
||||
nullptr, // 0x1B8
|
||||
nullptr, // 0x1B9
|
||||
nullptr, // 0x1BA
|
||||
nullptr, // 0x1BB
|
||||
nullptr, // 0x1BC
|
||||
nullptr, // 0x1BD
|
||||
nullptr, // 0x1BE
|
||||
nullptr, // 0x1BF
|
||||
nullptr, // 0x1C0
|
||||
nullptr, // 0x1C1
|
||||
nullptr, // 0x1C2
|
||||
nullptr, // 0x1C3
|
||||
nullptr, // 0x1C4
|
||||
nullptr, // 0x1C5
|
||||
nullptr, // 0x1C6
|
||||
nullptr, // 0x1C7
|
||||
nullptr, // 0x1C8
|
||||
nullptr, // 0x1C9
|
||||
nullptr, // 0x1CA
|
||||
nullptr, // 0x1CB
|
||||
nullptr, // 0x1CC
|
||||
nullptr, // 0x1CD
|
||||
nullptr, // 0x1CE
|
||||
nullptr, // 0x1CF
|
||||
nullptr, // 0x1D0
|
||||
nullptr, // 0x1D1
|
||||
nullptr, // 0x1D2
|
||||
nullptr, // 0x1D3
|
||||
nullptr, // 0x1D4
|
||||
nullptr, // 0x1D5
|
||||
nullptr, // 0x1D6
|
||||
nullptr, // 0x1D7
|
||||
nullptr, // 0x1D8
|
||||
nullptr, // 0x1D9
|
||||
nullptr, // 0x1DA
|
||||
nullptr, // 0x1DB
|
||||
nullptr, // 0x1DC
|
||||
nullptr, // 0x1DD
|
||||
nullptr, // 0x1DE
|
||||
nullptr, // 0x1DF
|
||||
nullptr, // 0x1E0
|
||||
nullptr, // 0x1E1
|
||||
nullptr, // 0x1E2
|
||||
nullptr, // 0x1E3
|
||||
nullptr, // 0x1E4
|
||||
nullptr, // 0x1E5
|
||||
nullptr, // 0x1E6
|
||||
nullptr, // 0x1E7
|
||||
nullptr, // 0x1E8
|
||||
nullptr, // 0x1E9
|
||||
nullptr, // 0x1EA
|
||||
nullptr, // 0x1EB
|
||||
nullptr, // 0x1EC
|
||||
nullptr, // 0x1ED
|
||||
nullptr, // 0x1EE
|
||||
nullptr, // 0x1EF
|
||||
nullptr, // 0x1F0
|
||||
nullptr, // 0x1F1
|
||||
nullptr, // 0x1F2
|
||||
nullptr, // 0x1F3
|
||||
nullptr, // 0x1F4
|
||||
nullptr, // 0x1F5
|
||||
nullptr, // 0x1F6
|
||||
nullptr, // 0x1F7
|
||||
nullptr, // 0x1F8
|
||||
nullptr, // 0x1F9
|
||||
nullptr, // 0x1FA
|
||||
nullptr, // 0x1FB
|
||||
nullptr, // 0x1FC
|
||||
nullptr, // 0x1FD
|
||||
nullptr, // 0x1FE
|
||||
nullptr, // 0x1FF
|
||||
};
|
||||
|
||||
|
||||
// =============================================================
|
||||
// Version 2 — Switch dispatch
|
||||
// =============================================================
|
||||
|
||||
/**
|
||||
* Execute the instruction identified by @p opcode.
|
||||
*
|
||||
* This is functionally equivalent to the InstrMap[] table above
|
||||
* but expressed as a switch so the compiler can choose the best
|
||||
* lowering strategy (jump table, binary search, etc.).
|
||||
*
|
||||
* @param opcode 9-bit instruction opcode (0x000 - 0x1FF).
|
||||
*/
|
||||
void CPU::executeSwLk() {
|
||||
switch (_opcode) {
|
||||
|
||||
// ── System ──────────────────────────────────────
|
||||
case 0x000: NOP(); break;
|
||||
case 0x001: SPDR(); break;
|
||||
case 0x002: MMODE(); break;
|
||||
case 0x003: INT(); break;
|
||||
case 0x004: LRV(); break;
|
||||
case 0x005: FSR(); break;
|
||||
case 0x006: FIR(); break;
|
||||
case 0x007: FZR(); break;
|
||||
case 0x008: LSR(); break;
|
||||
case 0x009: FVR(); break;
|
||||
|
||||
// ── Memory ──────────────────────────────────────
|
||||
case 0x00A: MOV(); break;
|
||||
case 0x00B: MOR(); break;
|
||||
case 0x00C: AMOV(); break;
|
||||
case 0x00D: SWP(); break;
|
||||
case 0x00E: AHM(); break;
|
||||
|
||||
// ── Integer ─────────────────────────────────────
|
||||
case 0x010: COM(); break;
|
||||
case 0x011: NEG(); break;
|
||||
case 0x012: EXS(); break;
|
||||
case 0x013: INC(); break;
|
||||
case 0x014: DEC(); break;
|
||||
case 0x015: ADD(); break;
|
||||
case 0x016: SUB(); break;
|
||||
case 0x017: MUL(); break;
|
||||
case 0x018: UMUL(); break;
|
||||
case 0x019: DIV(); break;
|
||||
case 0x01A: UDIV(); break;
|
||||
case 0x01B: MOD(); break;
|
||||
case 0x01C: UMOD(); break;
|
||||
case 0x01D: DMOD(); break;
|
||||
case 0x01E: UDMD(); break;
|
||||
|
||||
// ── System ──────────────────────────────────────
|
||||
case 0x01F: FBT(); break;
|
||||
|
||||
// ── Bit Wise ────────────────────────────────────
|
||||
case 0x020: STB(); break;
|
||||
case 0x021: CRB(); break;
|
||||
case 0x022: TSB(); break;
|
||||
case 0x023: BOOL(); break;
|
||||
case 0x024: NOT(); break;
|
||||
case 0x025: AND(); break;
|
||||
case 0x026: OR(); break;
|
||||
case 0x027: XOR(); break;
|
||||
case 0x028: SHL(); break;
|
||||
case 0x029: SHR(); break;
|
||||
case 0x02A: SSR(); break;
|
||||
case 0x02B: ROL(); break;
|
||||
case 0x02C: ROR(); break;
|
||||
case 0x02D: CNT(); break;
|
||||
|
||||
// ── Boolean ─────────────────────────────────────
|
||||
case 0x030: EQ(); break;
|
||||
case 0x031: NE(); break;
|
||||
case 0x032: GT(); break;
|
||||
case 0x033: GE(); break;
|
||||
case 0x034: LT(); break;
|
||||
case 0x035: LE(); break;
|
||||
|
||||
// ── Branch ──────────────────────────────────────
|
||||
case 0x038: JMP(); break;
|
||||
case 0x039: JEQ(); break;
|
||||
case 0x03A: JNE(); break;
|
||||
case 0x03B: JIF(); break;
|
||||
case 0x03C: JMR(); break;
|
||||
case 0x03D: JER(); break;
|
||||
case 0x03E: JNR(); break;
|
||||
case 0x03F: JIR(); break;
|
||||
|
||||
// ── System ──────────────────────────────────────
|
||||
case 0x040: SFB(); break;
|
||||
case 0x041: LFB(); break;
|
||||
|
||||
// ── Branch ──────────────────────────────────────
|
||||
case 0x042: JUF(); break;
|
||||
case 0x043: JUR(); break;
|
||||
|
||||
// ── Memory ──────────────────────────────────────
|
||||
case 0x044: PUSH(); break;
|
||||
case 0x045: POP(); break;
|
||||
case 0x046: ALLOC(); break;
|
||||
case 0x047: HFREE(); break;
|
||||
|
||||
// ── Branch ──────────────────────────────────────
|
||||
case 0x04A: CALL(); break;
|
||||
case 0x04B: RET(); break;
|
||||
|
||||
// ── System ──────────────────────────────────────
|
||||
case 0x04C: EDI(); break;
|
||||
case 0x04D: SHSS(); break;
|
||||
|
||||
// ── Floating Point ──────────────────────────────
|
||||
case 0x050: FLI(); break;
|
||||
case 0x051: FNEG(); break;
|
||||
case 0x052: FADD(); break;
|
||||
case 0x053: FSUB(); break;
|
||||
case 0x054: FMUL(); break;
|
||||
case 0x055: FDIV(); break;
|
||||
case 0x056: FMOD(); break;
|
||||
case 0x057: FDMOD(); break;
|
||||
case 0x058: FEPS(); break;
|
||||
case 0x059: FEEP(); break;
|
||||
|
||||
// ── Boolean ─────────────────────────────────────
|
||||
case 0x05A: FEQ(); break;
|
||||
case 0x05B: FNE(); break;
|
||||
case 0x05C: FGT(); break;
|
||||
case 0x05D: FGE(); break;
|
||||
case 0x05E: FLT(); break;
|
||||
case 0x05F: FLE(); break;
|
||||
|
||||
// ── Casts ───────────────────────────────────────
|
||||
case 0x060: F2D(); break;
|
||||
case 0x061: D2F(); break;
|
||||
case 0x062: I2F(); break;
|
||||
case 0x063: I2D(); break;
|
||||
case 0x064: L2F(); break;
|
||||
case 0x065: L2D(); break;
|
||||
case 0x066: F2I(); break;
|
||||
case 0x067: F2L(); break;
|
||||
case 0x068: D2I(); break;
|
||||
case 0x069: D2L(); break;
|
||||
|
||||
// ── Trigonometric ───────────────────────────────
|
||||
case 0x06C: SIN(); break;
|
||||
case 0x06D: COS(); break;
|
||||
case 0x06E: TAN(); break;
|
||||
case 0x06F: ASIN(); break;
|
||||
case 0x070: ACOS(); break;
|
||||
case 0x071: ATAN(); break;
|
||||
case 0x072: ATAN2(); break;
|
||||
|
||||
// ── Exponential ─────────────────────────────────
|
||||
case 0x074: EXP(); break;
|
||||
case 0x075: LOG(); break;
|
||||
case 0x076: LOGAB(); break;
|
||||
case 0x077: POW(); break;
|
||||
case 0x078: SQRT(); break;
|
||||
case 0x079: ROOT(); break;
|
||||
|
||||
// ── Integer ─────────────────────────────────────
|
||||
case 0x07C: ADC(); break;
|
||||
case 0x07D: SWC(); break;
|
||||
case 0x07E: MWO(); break;
|
||||
case 0x07F: UMO(); break;
|
||||
|
||||
// ── Matrix ──────────────────────────────────────
|
||||
case 0x080: MADD(); break;
|
||||
case 0x081: MSUB(); break;
|
||||
case 0x082: MMUL(); break;
|
||||
case 0x083: MINV(); break;
|
||||
case 0x084: MTRA(); break;
|
||||
case 0x085: MDET(); break;
|
||||
|
||||
// ── Quaternion ──────────────────────────────────
|
||||
case 0x086: QMKA(); break;
|
||||
case 0x087: QMUL(); break;
|
||||
|
||||
// ── SIMD ────────────────────────────────────────
|
||||
case 0x08A: XADD(); break;
|
||||
case 0x08B: XSUB(); break;
|
||||
case 0x08C: XAMA(); break;
|
||||
case 0x08D: XMUL(); break;
|
||||
case 0x08E: XDIV(); break;
|
||||
|
||||
// ── Easter Eggs ─────────────────────────────────
|
||||
case 0x0F0: UPY(); break;
|
||||
case 0x0F1: LLGS(); break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace spider
|
||||
@@ -1,9 +0,0 @@
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::NOP() {
|
||||
// No Operation //
|
||||
}
|
||||
|
||||
}
|
||||
356
src/spider/runtime/instr/Instr_000-01F.cpp
Normal file
356
src/spider/runtime/instr/Instr_000-01F.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::NOP() {
|
||||
// TODO: Implement NOP
|
||||
}
|
||||
|
||||
void CPU::SPDR() {
|
||||
// TODO: Implement SPDR
|
||||
}
|
||||
|
||||
void CPU::MMODE() {
|
||||
// TODO: Implement MMODE
|
||||
}
|
||||
|
||||
void CPU::INT() {
|
||||
// TODO: Implement INT
|
||||
}
|
||||
|
||||
void CPU::LRV() {
|
||||
// TODO: Implement LRV
|
||||
}
|
||||
|
||||
void CPU::FSR() {
|
||||
// TODO: Implement FSR
|
||||
}
|
||||
|
||||
void CPU::FIR() {
|
||||
// TODO: Implement FIR
|
||||
}
|
||||
|
||||
void CPU::FZR() {
|
||||
// TODO: Implement FZR
|
||||
}
|
||||
|
||||
void CPU::LSR() {
|
||||
// TODO: Implement LSR
|
||||
}
|
||||
|
||||
void CPU::FVR() {
|
||||
// TODO: Implement FVR
|
||||
}
|
||||
|
||||
void CPU::MOV() {
|
||||
// TODO: Implement MOV
|
||||
}
|
||||
|
||||
void CPU::MOR() {
|
||||
// TODO: Implement MOR
|
||||
}
|
||||
|
||||
void CPU::AMOV() {
|
||||
// TODO: Implement AMOV
|
||||
}
|
||||
|
||||
void CPU::SWP() {
|
||||
// TODO: Implement SWP
|
||||
}
|
||||
|
||||
void CPU::AHM() {
|
||||
// TODO: Implement AHM
|
||||
}
|
||||
|
||||
void CPU::COM() {
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = ~_dst->_u8;
|
||||
break;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = ~_dst->_u16;
|
||||
break;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = ~_dst->_u32;
|
||||
break;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = ~_dst->_u64;
|
||||
break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::NEG() {
|
||||
// TODO: Implement NEG
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = 1 + ~_dst->_u8;
|
||||
break;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = 1+ ~_dst->_u16;
|
||||
break;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = 1 + ~_dst->_u32;
|
||||
break;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = 1 + ~_dst->_u64;
|
||||
break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::EXS() { // THIS IS INCORRECT!!!
|
||||
// TODO: Implement EXS
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_i16 = static_cast<i16>(_dst->_i8);
|
||||
break;
|
||||
case 0b01: //short
|
||||
_dst->_i32 = static_cast<i32>(_dst->_i16);
|
||||
break;
|
||||
case 0b10: //int
|
||||
_dst->_i64 = static_cast<i64>(_dst->_i32);
|
||||
break;
|
||||
case 0b11: //long
|
||||
_dst->_i64 = _dst->_i64;
|
||||
break;
|
||||
}
|
||||
_dst->_u32 = _dst->_u8;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::INC() {
|
||||
// TODO: Implement INC
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 += 1;
|
||||
case 0b01: //short
|
||||
_dst->_u16 += 1;
|
||||
case 0b10: //int
|
||||
_dst->_u32 += 1;
|
||||
case 0b11: //long
|
||||
_dst->_u64 += 1;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::DEC() {
|
||||
// TODO: Implement DEC
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 -= 1;
|
||||
case 0b01: //short
|
||||
_dst->_u16 -= 1;
|
||||
case 0b10: //int
|
||||
_dst->_u32 -= 1;
|
||||
case 0b11: //long
|
||||
_dst->_u64 -= 1;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::ADD() {
|
||||
// TODO: Implement ADD
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 += _src->_u8;
|
||||
case 0b01: //short
|
||||
_dst->_u16 += _src->_u16;
|
||||
case 0b10: //int
|
||||
_dst->_u32 += _src->_u32;
|
||||
case 0b11: //long
|
||||
_dst->_u64 += _src->_u64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::SUB() {
|
||||
// TODO: Implement SUB
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 -= _src->_u8;
|
||||
case 0b01: //short
|
||||
_dst->_u16 -= _src->_u16;
|
||||
case 0b10: //int
|
||||
_dst->_u32 -= _src->_u32;
|
||||
case 0b11: //long
|
||||
_dst->_u64 -= _src->_u64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::MUL() {
|
||||
// TODO: Implement MUL
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_i8 = _src->_i8 * _dst->_i8;
|
||||
case 0b01: //short
|
||||
_dst->_i16 = _src->_i16 * _dst->_i16;
|
||||
case 0b10: //int
|
||||
_dst->_i32 = _src->_i32 * _dst->_i32;
|
||||
case 0b11: //long
|
||||
_dst->_i64 = _src->_i64 * _dst->_i64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::UMUL() {
|
||||
// TODO: Implement UMUL
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = _src->_u8 * _dst->_u8;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = _src->_u16 * _dst->_u16;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = _src->_u32 * _dst->_u32;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = _src->_u64 * _dst->_u64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::DIV() {
|
||||
// TODO: Implement DIV
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_i8 = _dst->_i8 / _src->_i8;
|
||||
case 0b01: //short
|
||||
_dst->_i16 = _dst->_i16 / _src->_i16;
|
||||
case 0b10: //int
|
||||
_dst->_i32 = _dst->_i32 / _src->_i32;
|
||||
case 0b11: //long
|
||||
_dst->_i64 = _dst->_i64 / _src->_i64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::UDIV() {
|
||||
// TODO: Implement UDIV
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = _dst->_u8 / _src->_u8;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = _dst->_u16 / _src->_u16;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = _dst->_u32 / _src->_u32;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = _dst->_u64 / _src->_u64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::MOD() {
|
||||
// TODO: Implement MOD
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_i8 = _dst->_i8 % _src->_i8;
|
||||
case 0b01: //short
|
||||
_dst->_i16 = _dst->_i16 % _src->_i16;
|
||||
case 0b10: //int
|
||||
_dst->_i32 = _dst->_i32 % _src->_i32;
|
||||
case 0b11: //long
|
||||
_dst->_i64 = _dst->_i64 % _src->_i64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::UMOD() {
|
||||
// TODO: Implement UMOD
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = _dst->_u8 % _src->_u8;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = _dst->_u16 % _src->_u16;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = _dst->_u32 % _src->_u32;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = _dst->_u64 % _src->_u64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::DMOD() {
|
||||
// TODO: Implement DMOD
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
RX._i8 = _dst->_i8 / _src->_i8;
|
||||
RY._i8 = _dst->_i8 % _src->_i8;
|
||||
case 0b01: //short
|
||||
RX._i16 = _dst->_i16 / _src->_i16;
|
||||
RY._i16 = _dst->_i16 % _src->_i16;
|
||||
case 0b10: //int
|
||||
RX._i32 = _dst->_i32 / _src->_i32;
|
||||
RY._i32 = _dst->_i32 % _src->_i32;
|
||||
case 0b11: //long
|
||||
RX._i64 = _dst->_i64 / _src->_i64;
|
||||
RY._i64 = _dst->_i64 % _src->_i64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::UDMD() {
|
||||
// TODO: Implement UDMD
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
RX._u8 = _dst->_u8 / _src->_u8;
|
||||
RY._u8 = _dst->_u8 % _src->_u8;
|
||||
case 0b01: //short
|
||||
RX._u16 = _dst->_u16 / _src->_u16;
|
||||
RY._u16 = _dst->_u16 % _src->_u16;
|
||||
case 0b10: //int
|
||||
RX._u32 = _dst->_u32 / _src->_u32;
|
||||
RY._u32 = _dst->_u32 % _src->_u32;
|
||||
case 0b11: //long
|
||||
RX._u64 = _dst->_u64 / _src->_u64;
|
||||
RY._u64 = _dst->_u64 % _src->_u64;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::FBT() {
|
||||
// TODO: Implement FBT
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
RF = (RF & ~(0x3 << 9)) | ((_dst->_u8 >> 9) & 0x3) << 9;
|
||||
case 0b01: //short
|
||||
RF = (RF & ~(0x3 << 9)) | ((_dst->_u16 >> 9) & 0x3) << 9;
|
||||
case 0b10: //int
|
||||
RF = (RF & ~(0x3 << 9)) | ((_dst->_u32 >> 9) & 0x3) << 9;
|
||||
case 0b11: //long
|
||||
RF = (RF & ~(0x3 << 9)) | ((_dst->_u64 >> 9) & 0x3) << 9;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
}
|
||||
197
src/spider/runtime/instr/Instr_020-03F.cpp
Normal file
197
src/spider/runtime/instr/Instr_020-03F.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::STB() {
|
||||
// TODO: Implement STB
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 |= (1 << _src->_u8);
|
||||
case 0b01: //short
|
||||
_dst->_u16 |= (1 << _src->_u16);
|
||||
case 0b10: //int
|
||||
_dst->_u32 |= (1 << _src->_u32);
|
||||
case 0b11: //long
|
||||
_dst->_u64 |= (1 << _src->_u64);
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::CRB() {
|
||||
// TODO: Implement CRB
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 &= ~(1 << _src->_u8);
|
||||
case 0b01: //short
|
||||
_dst->_u16 &= ~(1 << _src->_u16);
|
||||
case 0b10: //int
|
||||
_dst->_u32 &= ~(1 << _src->_u32);
|
||||
case 0b11: //long
|
||||
_dst->_u64 &= ~(1 << _src->_u64);
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::TSB() {
|
||||
// TODO: Implement TSB
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
switch (((RF >> _src->_u8) & 1) != ((_dst->_u8 >> _src->_u8) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u8);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u8);
|
||||
}
|
||||
case 0b01: //short
|
||||
switch (((RF >> _src->_u16) & 1) != ((_dst->_u16 >> _src->_u16) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u16);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u16);
|
||||
}
|
||||
case 0b10: //int
|
||||
switch (((RF >> _src->_u32) & 1) != ((_dst->_u32 >> _src->_u32) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u32);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u32);
|
||||
}
|
||||
case 0b11: //long
|
||||
switch (((RF >> _src->_u64) & 1) != ((_dst->_u64 >> _src->_u64) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u64);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u64);
|
||||
}
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::BOOL() {
|
||||
// TODO: Implement BOOL
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = _dst != 0;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = _dst != 0;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = _dst != 0;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = _dst != 0;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::NOT() {
|
||||
// TODO: Implement NOT
|
||||
}
|
||||
|
||||
void CPU::AND() {
|
||||
// TODO: Implement AND
|
||||
}
|
||||
|
||||
void CPU::OR() {
|
||||
// TODO: Implement OR
|
||||
}
|
||||
|
||||
void CPU::XOR() {
|
||||
// TODO: Implement XOR
|
||||
}
|
||||
|
||||
void CPU::SHL() {
|
||||
// TODO: Implement SHL
|
||||
}
|
||||
|
||||
void CPU::SHR() {
|
||||
// TODO: Implement SHR
|
||||
}
|
||||
|
||||
void CPU::SSR() {
|
||||
// TODO: Implement SSR
|
||||
}
|
||||
|
||||
void CPU::ROL() {
|
||||
// TODO: Implement ROL
|
||||
}
|
||||
|
||||
void CPU::ROR() {
|
||||
// TODO: Implement ROR
|
||||
}
|
||||
|
||||
void CPU::CNT() {
|
||||
// TODO: Implement CNT
|
||||
}
|
||||
|
||||
void CPU::EQ() {
|
||||
// TODO: Implement EQ
|
||||
}
|
||||
|
||||
void CPU::NE() {
|
||||
// TODO: Implement NE
|
||||
}
|
||||
|
||||
void CPU::GT() {
|
||||
// TODO: Implement GT
|
||||
}
|
||||
|
||||
void CPU::GE() {
|
||||
// TODO: Implement GE
|
||||
}
|
||||
|
||||
void CPU::LT() {
|
||||
// TODO: Implement LT
|
||||
}
|
||||
|
||||
void CPU::LE() {
|
||||
// TODO: Implement LE
|
||||
}
|
||||
|
||||
void CPU::JMP() {
|
||||
// TODO: Implement JMP
|
||||
}
|
||||
|
||||
void CPU::JEQ() {
|
||||
// TODO: Implement JEQ
|
||||
}
|
||||
|
||||
void CPU::JNE() {
|
||||
// TODO: Implement JNE
|
||||
}
|
||||
|
||||
void CPU::JIF() {
|
||||
// TODO: Implement JIF
|
||||
}
|
||||
|
||||
void CPU::JMR() {
|
||||
// TODO: Implement JMR
|
||||
}
|
||||
|
||||
void CPU::JER() {
|
||||
// TODO: Implement JER
|
||||
}
|
||||
|
||||
void CPU::JNR() {
|
||||
// TODO: Implement JNR
|
||||
}
|
||||
|
||||
void CPU::JIR() {
|
||||
// TODO: Implement JIR
|
||||
}
|
||||
|
||||
}
|
||||
279
src/spider/runtime/instr/Instr_040-05F.cpp
Normal file
279
src/spider/runtime/instr/Instr_040-05F.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
#include <cmath> // provides std::fmod, std::fma and cast support
|
||||
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::SFB() {
|
||||
// TODO: Implement SFB
|
||||
}
|
||||
|
||||
void CPU::LFB() {
|
||||
// TODO: Implement LFB
|
||||
}
|
||||
|
||||
void CPU::JUF() {
|
||||
// TODO: Implement JUF
|
||||
}
|
||||
|
||||
void CPU::JUR() {
|
||||
// TODO: Implement JUR
|
||||
}
|
||||
|
||||
void CPU::PUSH() {
|
||||
// TODO: Implement PUSH
|
||||
}
|
||||
|
||||
void CPU::POP() {
|
||||
// TODO: Implement POP
|
||||
}
|
||||
|
||||
void CPU::ALLOC() {
|
||||
// TODO: Implement ALLOC
|
||||
}
|
||||
|
||||
void CPU::HFREE() {
|
||||
// TODO: Implement HFREE
|
||||
}
|
||||
|
||||
void CPU::CALL() {
|
||||
// TODO: Implement CALL
|
||||
}
|
||||
|
||||
void CPU::RET() {
|
||||
// TODO: Implement RET
|
||||
}
|
||||
|
||||
void CPU::EDI() {
|
||||
// TODO: Implement EDI
|
||||
}
|
||||
|
||||
void CPU::SHSS() {
|
||||
// TODO: Implement SHSS
|
||||
}
|
||||
|
||||
void CPU::FLI() {
|
||||
// TODO: Implement FLI
|
||||
}
|
||||
|
||||
void CPU::FNEG() {
|
||||
// TODO: Implement FNEG
|
||||
}
|
||||
|
||||
void CPU::FADD() {
|
||||
// TODO: Implement FADD
|
||||
}
|
||||
|
||||
void CPU::FSUB() {
|
||||
// TODO: Implement FSUB
|
||||
}
|
||||
|
||||
// ── 0x054 — FMUL: Float Multiplication ───────────────────────────────────
|
||||
void CPU::FMUL() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch (_size) {
|
||||
case 0b10: _dst->_f32 *= _src->_f32; break; // f32
|
||||
case 0b11: _dst->_f64 *= _src->_f64; break; // f64
|
||||
default: break; // invalid size
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x055 — FDIV: Float Division ─────────────────────────────────────────
|
||||
void CPU::FDIV() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch (_size) {
|
||||
case 0b10: _dst->_f32 /= _src->_f32; break;
|
||||
case 0b11: _dst->_f64 /= _src->_f64; break;
|
||||
default: break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x056 — FMOD: Float Modulus ──────────────────────────────────────────
|
||||
// C++ has no % for floats — std::fmod performs the equivalent operation
|
||||
void CPU::FMOD() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch (_size) {
|
||||
case 0b10: _dst->_f32 = std::fmod(_dst->_f32, _src->_f32); break;
|
||||
case 0b11: _dst->_f64 = std::fmod(_dst->_f64, _src->_f64); break;
|
||||
default: break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x057 — FDMOD: Float Division and Modulus ────────────────────────────
|
||||
// dst / src = RX (quotient) * src + RY (remainder)
|
||||
void CPU::FDMOD() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
switch (_size) {
|
||||
case 0b10: {
|
||||
f32 q = static_cast<f32>(static_cast<i32>(_dst->_f32 / _src->_f32));
|
||||
f32 r = _dst->_f32 - (q * _src->_f32);
|
||||
RX._f32 = q;
|
||||
RY._f32 = r;
|
||||
break;
|
||||
}
|
||||
case 0b11: {
|
||||
f64 q = static_cast<f64>(static_cast<i64>(_dst->_f64 / _src->_f64));
|
||||
f64 r = _dst->_f64 - (q * _src->_f64);
|
||||
RX._f64 = q;
|
||||
RY._f64 = r;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x058 — FEPS: Set Float Epsilon Value ────────────────────────────────
|
||||
// Loads the epsilon value into RN (the epsilon register)
|
||||
void CPU::FEPS() {
|
||||
fetchOperDst();
|
||||
switch (_size) {
|
||||
case 0b10: RN = _dst->_u32; break; // store f32 bits in RN
|
||||
case 0b11: RN = _dst->_u64; break; // store f64 bits in RN
|
||||
default: break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x059 — FEEP: Float Enable/Disable Epsilon ───────────────────────────
|
||||
// Bit 12 of RF is the Epsilon Enable flag
|
||||
void CPU::FEEP() {
|
||||
fetchOperDst();
|
||||
constexpr u64 EPSILON_ENABLE_BIT = (1ULL << 12);
|
||||
if (_dst->_u64) RF |= EPSILON_ENABLE_BIT; // non-zero → enable
|
||||
else RF &= ~EPSILON_ENABLE_BIT; // zero → disable
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x05A — FEQ: Float Equal ──────────────────────────────────────────────
|
||||
// Sets bit 10 (Zero/Equal flag) in RF if dst == src
|
||||
void CPU::FEQ() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
constexpr u64 ZERO_FLAG = (1ULL << 10);
|
||||
bool equal = false;
|
||||
switch (_size) {
|
||||
case 0b10: equal = (_dst->_f32 == _src->_f32); break;
|
||||
case 0b11: equal = (_dst->_f64 == _src->_f64); break;
|
||||
default: break;
|
||||
}
|
||||
if (equal) RF |= ZERO_FLAG;
|
||||
else RF &= ~ZERO_FLAG;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x05B — FNE: Float Not Equal ─────────────────────────────────────────
|
||||
void CPU::FNE() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
constexpr u64 ZERO_FLAG = (1ULL << 10);
|
||||
bool notEqual = false;
|
||||
switch (_size) {
|
||||
case 0b10: notEqual = (_dst->_f32 != _src->_f32); break;
|
||||
case 0b11: notEqual = (_dst->_f64 != _src->_f64); break;
|
||||
default: break;
|
||||
}
|
||||
if (notEqual) RF |= ZERO_FLAG;
|
||||
else RF &= ~ZERO_FLAG;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x05C — FGT: Float Greater Than ──────────────────────────────────────
|
||||
// Sets/clears bit 9 (Negative flag) in RF
|
||||
void CPU::FGT() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
constexpr u64 NEGATIVE_FLAG = (1ULL << 9);
|
||||
bool gt = false;
|
||||
switch (_size) {
|
||||
case 0b10: gt = (_dst->_f32 > _src->_f32); break;
|
||||
case 0b11: gt = (_dst->_f64 > _src->_f64); break;
|
||||
default: break;
|
||||
}
|
||||
if (gt) RF &= ~NEGATIVE_FLAG;
|
||||
else RF |= NEGATIVE_FLAG;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x05D — FGE: Float Greater or Equal ──────────────────────────────────
|
||||
void CPU::FGE() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
constexpr u64 NEGATIVE_FLAG = (1ULL << 9);
|
||||
constexpr u64 ZERO_FLAG = (1ULL << 10);
|
||||
bool ge = false;
|
||||
bool eq = false;
|
||||
switch (_size) {
|
||||
case 0b10:
|
||||
ge = (_dst->_f32 >= _src->_f32);
|
||||
eq = (_dst->_f32 == _src->_f32);
|
||||
break;
|
||||
case 0b11:
|
||||
ge = (_dst->_f64 >= _src->_f64);
|
||||
eq = (_dst->_f64 == _src->_f64);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (ge) RF &= ~NEGATIVE_FLAG;
|
||||
else RF |= NEGATIVE_FLAG;
|
||||
if (eq) RF |= ZERO_FLAG;
|
||||
else RF &= ~ZERO_FLAG;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x05E — FLT: Float Lower Than ────────────────────────────────────────
|
||||
void CPU::FLT() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
constexpr u64 NEGATIVE_FLAG = (1ULL << 9);
|
||||
bool lt = false;
|
||||
switch (_size) {
|
||||
case 0b10: lt = (_dst->_f32 < _src->_f32); break;
|
||||
case 0b11: lt = (_dst->_f64 < _src->_f64); break;
|
||||
default: break;
|
||||
}
|
||||
if (lt) RF |= NEGATIVE_FLAG;
|
||||
else RF &= ~NEGATIVE_FLAG;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x05F — FLE: Float Lower or Equal ────────────────────────────────────
|
||||
void CPU::FLE() {
|
||||
fetchOperSrc();
|
||||
fetchOperDst();
|
||||
constexpr u64 NEGATIVE_FLAG = (1ULL << 9);
|
||||
constexpr u64 ZERO_FLAG = (1ULL << 10);
|
||||
bool le = false;
|
||||
bool eq = false;
|
||||
switch (_size) {
|
||||
case 0b10:
|
||||
le = (_dst->_f32 <= _src->_f32);
|
||||
eq = (_dst->_f32 == _src->_f32);
|
||||
break;
|
||||
case 0b11:
|
||||
le = (_dst->_f64 <= _src->_f64);
|
||||
eq = (_dst->_f64 == _src->_f64);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (le) RF &= ~NEGATIVE_FLAG;
|
||||
else RF |= NEGATIVE_FLAG;
|
||||
if (eq) RF |= ZERO_FLAG;
|
||||
else RF &= ~ZERO_FLAG;
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
148
src/spider/runtime/instr/Instr_060-07F.cpp
Normal file
148
src/spider/runtime/instr/Instr_060-07F.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
#include <cmath> // provides std::fmod, std::fma and cast support
|
||||
|
||||
|
||||
namespace spider {
|
||||
|
||||
// ── 0x060 — F2D: Float (f32) to Double (f64) ─────────────────────────────
|
||||
// Widening conversion — no precision is lost
|
||||
void CPU::F2D() {
|
||||
fetchOperDst();
|
||||
_dst->_f64 = static_cast<f64>(_dst->_f32);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x061 — D2F: Double (f64) to Float (f32) ─────────────────────────────
|
||||
// Narrowing conversion — precision may be lost
|
||||
void CPU::D2F() {
|
||||
fetchOperDst();
|
||||
_dst->_f32 = static_cast<f32>(_dst->_f64);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x062 — I2F: Integer (i32) to Float (f32) ────────────────────────────
|
||||
void CPU::I2F() {
|
||||
fetchOperDst();
|
||||
_dst->_f32 = static_cast<f32>(_dst->_u32);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x063 — I2D: Integer (i32) to Double (f64) ───────────────────────────
|
||||
void CPU::I2D() {
|
||||
fetchOperDst();
|
||||
_dst->_f64 = static_cast<f64>(_dst->_u32);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x064 — L2F: Long (i64) to Float (f32) ───────────────────────────────
|
||||
void CPU::L2F() {
|
||||
fetchOperDst();
|
||||
_dst->_f32 = static_cast<f32>(_dst->_u64);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x065 — L2D: Long (i64) to Double (f64) ──────────────────────────────
|
||||
void CPU::L2D() {
|
||||
fetchOperDst();
|
||||
_dst->_f64 = static_cast<f64>(_dst->_u64);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x066 — F2I: Float (f32) to Integer (i32) ────────────────────────────
|
||||
// Truncates toward zero
|
||||
void CPU::F2I() {
|
||||
fetchOperDst();
|
||||
_dst->_u32 = static_cast<u32>(_dst->_f32);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
// ── 0x067 — F2L: Float (f32) to Long (i64) ───────────────────────────────
|
||||
// Truncates toward zero
|
||||
void CPU::F2L() {
|
||||
fetchOperDst();
|
||||
_dst->_u64 = static_cast<u64>(_dst->_f32);
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
void CPU::D2I() {
|
||||
// TODO: Implement D2I
|
||||
}
|
||||
|
||||
void CPU::D2L() {
|
||||
// TODO: Implement D2L
|
||||
}
|
||||
|
||||
void CPU::SIN() {
|
||||
// TODO: Implement SIN
|
||||
}
|
||||
|
||||
void CPU::COS() {
|
||||
// TODO: Implement COS
|
||||
}
|
||||
|
||||
void CPU::TAN() {
|
||||
// TODO: Implement TAN
|
||||
}
|
||||
|
||||
void CPU::ASIN() {
|
||||
// TODO: Implement ASIN
|
||||
}
|
||||
|
||||
void CPU::ACOS() {
|
||||
// TODO: Implement ACOS
|
||||
}
|
||||
|
||||
void CPU::ATAN() {
|
||||
// TODO: Implement ATAN
|
||||
}
|
||||
|
||||
void CPU::ATAN2() {
|
||||
// TODO: Implement ATAN2
|
||||
}
|
||||
|
||||
void CPU::EXP() {
|
||||
// TODO: Implement EXP
|
||||
}
|
||||
|
||||
void CPU::LOG() {
|
||||
// TODO: Implement LOG
|
||||
}
|
||||
|
||||
void CPU::LOGAB() {
|
||||
// TODO: Implement LOGAB
|
||||
}
|
||||
|
||||
void CPU::POW() {
|
||||
// TODO: Implement POW
|
||||
}
|
||||
|
||||
void CPU::SQRT() {
|
||||
// TODO: Implement SQRT
|
||||
}
|
||||
|
||||
void CPU::ROOT() {
|
||||
// TODO: Implement ROOT
|
||||
}
|
||||
|
||||
void CPU::ADC() {
|
||||
// TODO: Implement ADC
|
||||
}
|
||||
|
||||
void CPU::SWC() {
|
||||
// TODO: Implement SWC
|
||||
}
|
||||
|
||||
void CPU::MWO() {
|
||||
// TODO: Implement MWO
|
||||
}
|
||||
|
||||
void CPU::UMO() {
|
||||
// TODO: Implement UMO
|
||||
}
|
||||
|
||||
}
|
||||
62
src/spider/runtime/instr/Instr_080-09F.cpp
Normal file
62
src/spider/runtime/instr/Instr_080-09F.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::MADD() {
|
||||
// TODO: Implement MADD
|
||||
}
|
||||
|
||||
void CPU::MSUB() {
|
||||
// TODO: Implement MSUB
|
||||
}
|
||||
|
||||
void CPU::MMUL() {
|
||||
// TODO: Implement MMUL
|
||||
}
|
||||
|
||||
void CPU::MINV() {
|
||||
// TODO: Implement MINV
|
||||
}
|
||||
|
||||
void CPU::MTRA() {
|
||||
// TODO: Implement MTRA
|
||||
}
|
||||
|
||||
void CPU::MDET() {
|
||||
// TODO: Implement MDET
|
||||
}
|
||||
|
||||
void CPU::QMKA() {
|
||||
// TODO: Implement QMKA
|
||||
}
|
||||
|
||||
void CPU::QMUL() {
|
||||
// TODO: Implement QMUL
|
||||
}
|
||||
|
||||
void CPU::XADD() {
|
||||
// TODO: Implement XADD
|
||||
}
|
||||
|
||||
void CPU::XSUB() {
|
||||
// TODO: Implement XSUB
|
||||
}
|
||||
|
||||
void CPU::XAMA() {
|
||||
// TODO: Implement XAMA
|
||||
}
|
||||
|
||||
void CPU::XMUL() {
|
||||
// TODO: Implement XMUL
|
||||
}
|
||||
|
||||
void CPU::XDIV() {
|
||||
// TODO: Implement XDIV
|
||||
}
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_0A0-0BF.cpp
Normal file
10
src/spider/runtime/instr/Instr_0A0-0BF.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_0C0-0DF.cpp
Normal file
10
src/spider/runtime/instr/Instr_0C0-0DF.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
14
src/spider/runtime/instr/Instr_0E0-0FF.cpp
Normal file
14
src/spider/runtime/instr/Instr_0E0-0FF.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::UPY() {
|
||||
// TODO: Implement UPY
|
||||
}
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_100-11F.cpp
Normal file
10
src/spider/runtime/instr/Instr_100-11F.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_120-13F.cpp
Normal file
10
src/spider/runtime/instr/Instr_120-13F.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_140-15F.cpp
Normal file
10
src/spider/runtime/instr/Instr_140-15F.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_160-17F.cpp
Normal file
10
src/spider/runtime/instr/Instr_160-17F.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_180-19F.cpp
Normal file
10
src/spider/runtime/instr/Instr_180-19F.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_1A0-1BF.cpp
Normal file
10
src/spider/runtime/instr/Instr_1A0-1BF.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_1C0-1DF.cpp
Normal file
10
src/spider/runtime/instr/Instr_1C0-1DF.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
10
src/spider/runtime/instr/Instr_1E0-1FF.cpp
Normal file
10
src/spider/runtime/instr/Instr_1E0-1FF.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
}
|
||||
61
src/spider/runtime/instr/Instr_LLGS.cpp
Normal file
61
src/spider/runtime/instr/Instr_LLGS.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @brief LLGS — Easter egg by Arturo Balam (Data - 7A)
|
||||
*
|
||||
* Opcode: 0x0F1
|
||||
*
|
||||
* Writes a Spider ASCII art into RAM starting at address 0x00,
|
||||
* and loads the author signature into RA as a packed ASCII string.
|
||||
* This version matches the custom mechanical spider design
|
||||
* and is formatted to fit an 8-byte RAM viewer width.
|
||||
*
|
||||
* RAM layout after LLGS executes (8 characters per row, 4 rows total):
|
||||
* 0x00: "// _ \\" (Row 1)
|
||||
* 0x08: "\\( )// " (Row 2)
|
||||
* 0x10: " //()\\ " (Row 3)
|
||||
* 0x18: " \\ // " (Row 4)
|
||||
*
|
||||
* RA after execution: 0x4C4C475300000000ULL ("LLGS" in ASCII, zero-padded)
|
||||
* (L=0x4C, L=0x4C, G=0x47, S=0x53)
|
||||
*/
|
||||
|
||||
#include <spider/runtime/cpu/CPU.hpp>
|
||||
#include <spider/runtime/memory/RAM.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
void CPU::LLGS() {
|
||||
|
||||
// -- Write Spider ASCII art into RAM ---------------------------------
|
||||
// Padded with exact spaces to ensure it never wraps in an 8-byte viewer
|
||||
|
||||
// Row 0: "// _ \\ "
|
||||
_ram->at(0x00) = '/'; _ram->at(0x01) = '/';
|
||||
_ram->at(0x02) = ' '; _ram->at(0x03) = '_';
|
||||
_ram->at(0x04) = ' '; _ram->at(0x05) = '\\';
|
||||
_ram->at(0x06) = '\\'; _ram->at(0x07) = ' ';
|
||||
|
||||
// Row 1: "\\( )// "
|
||||
_ram->at(0x08) = '\\'; _ram->at(0x09) = '\\';
|
||||
_ram->at(0x0A) = '('; _ram->at(0x0B) = ' ';
|
||||
_ram->at(0x0C) = ')'; _ram->at(0x0D) = '/';
|
||||
_ram->at(0x0E) = '/'; _ram->at(0x0F) = ' ';
|
||||
|
||||
// Row 2: " //()\\ "
|
||||
_ram->at(0x10) = ' '; _ram->at(0x11) = '/';
|
||||
_ram->at(0x12) = '/'; _ram->at(0x13) = '(';
|
||||
_ram->at(0x14) = ')'; _ram->at(0x15) = '\\';
|
||||
_ram->at(0x16) = '\\'; _ram->at(0x17) = ' ';
|
||||
|
||||
// Row 3: " \\ // "
|
||||
_ram->at(0x18) = ' '; _ram->at(0x19) = '\\';
|
||||
_ram->at(0x1A) = '\\'; _ram->at(0x1B) = ' ';
|
||||
_ram->at(0x1C) = ' '; _ram->at(0x1D) = '/';
|
||||
_ram->at(0x1E) = '/'; _ram->at(0x1F) = ' ';
|
||||
|
||||
// -- Load mnemonic into RA ------------------------
|
||||
// "LLGS" packed as ASCII bytes into RA
|
||||
RA._u64 = 0x4C4C475300000000ULL;
|
||||
|
||||
}
|
||||
|
||||
} // namespace spider
|
||||
105
src/spider/runtime/math/Matrix.cpp
Normal file
105
src/spider/runtime/math/Matrix.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "Matrix.hpp"
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
/*
|
||||
namespace spider {
|
||||
|
||||
template<typename T>
|
||||
void matrix_fill(T diag, Matrix<T> mat) {
|
||||
for (isize i = 0; i < mat.rows; i++) {
|
||||
for (isize j = 0; j < mat.cols; j++) {
|
||||
m.data[i + j * mat.rows] = i == j ? diag : T(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void matrix_mult(Matrix<T> m1, Matrix<T> m2, Matrix<T> mr) {
|
||||
// natural constrains of matrix multiplication
|
||||
if (m1.rows != mr.rows) return;
|
||||
if (m2.cols != mr.cols) return;
|
||||
if (m1.cols != m2.rows) return;
|
||||
|
||||
// fill result with zeroes
|
||||
std::fill(mr.data, mr.data + mr.rows * mr.cols, T(0));
|
||||
|
||||
// Begin Loop
|
||||
for (isize j = 0; j < mr.cols; j++) { // P
|
||||
for (isize n = 0; n < m1.cols; n++) { // N
|
||||
const T val_m2 = m2.data[n + j * m2.rows] * diag;
|
||||
isize i = 0;
|
||||
|
||||
#if defined(__AVX__)
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
const __m256 v_m2 = _mm256_set1_ps(val_m2);
|
||||
for (; i <= mr.rows - 8; i += 8) {
|
||||
__m256 v_m1 = _mm256_loadu_ps(&m1.data[i + n * m1.rows]);
|
||||
__m256 v_mr = _mm256_loadu_ps(&mr.data[i + j * mr.rows]);
|
||||
v_mr = _mm256_fmadd_ps(v_m1, v_m2, v_mr);
|
||||
_mm256_storeu_ps(&mr.data[i + j * mr.rows], v_mr);
|
||||
}
|
||||
if (i < mr.rows) {
|
||||
float buf_m1[8] = { 0 }, buf_mr[8] = { 0 };
|
||||
isize rem = mr.rows - i;
|
||||
std::memcpy(buf_m1, &m1.data[i + n * m1.rows], rem * sizeof(T));
|
||||
std::memcpy(buf_mr, &mr.data[i + j * mr.rows], rem * sizeof(T));
|
||||
_mm256_storeu_ps(buf_mr, _mm256_fmadd_ps(_mm256_loadu_ps(buf_m1), v_m2, _mm256_loadu_ps(buf_mr)));
|
||||
std::memcpy(&mr.data[i + j * mr.rows], buf_mr, rem * sizeof(T));
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>) {
|
||||
const __m256d v_m2 = _mm256_set1_pd(val_m2);
|
||||
for (; i <= mr.rows - 4; i += 4) {
|
||||
__m256d v_m1 = _mm256_loadu_pd(&m1.data[i + n * m1.rows]);
|
||||
__m256d v_mr = _mm256_loadu_pd(&mr.data[i + j * mr.rows]);
|
||||
v_mr = _mm256_fmadd_pd(v_m1, v_m2, v_mr);
|
||||
_mm256_storeu_pd(&mr.data[i + j * mr.rows], v_mr);
|
||||
}
|
||||
if (i < mr.rows) {
|
||||
double buf_m1[4] = { 0 }, buf_mr[4] = { 0 };
|
||||
isize rem = mr.rows - i;
|
||||
std::memcpy(buf_m1, &m1.data[i + n * m1.rows], rem * sizeof(T));
|
||||
std::memcpy(buf_mr, &mr.data[i + j * mr.rows], rem * sizeof(T));
|
||||
_mm256_storeu_pd(buf_mr, _mm256_fmadd_pd(_mm256_loadu_pd(buf_m1), v_m2, _mm256_loadu_pd(buf_mr)));
|
||||
std::memcpy(&mr.data[i + j * mr.rows], buf_mr, rem * sizeof(T));
|
||||
}
|
||||
}
|
||||
else
|
||||
#elif defined(__SSE2__)
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
const __m128 v_m2 = _mm_set1_ps(val_m2);
|
||||
for (; i <= mr.rows - 4; i += 4) {
|
||||
__m128 v_m1 = _mm_loadu_ps(&m1.data[i + n * m1.rows]);
|
||||
__m128 v_mr = _mm_loadu_ps(&mr.data[i + j * mr.rows]);
|
||||
v_mr = _mm_add_ps(v_mr, _mm_mul_ps(v_m1, v_m2));
|
||||
_mm_storeu_ps(&mr.data[i + j * mr.rows], v_mr);
|
||||
}
|
||||
// Tail buffer logic omitted for brevity, same as float AVX but with size 4
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>) {
|
||||
const __m128d v_m2 = _mm_set1_pd(val_m2);
|
||||
for (; i <= mr.rows - 2; i += 2) {
|
||||
__m128d v_m1 = _mm_loadu_pd(&m1.data[i + n * m1.rows]);
|
||||
__m128d v_mr = _mm_loadu_pd(&mr.data[i + j * mr.rows]);
|
||||
v_mr = _mm_add_pd(v_mr, _mm_mul_pd(v_m1, v_m2));
|
||||
_mm_storeu_pd(&mr.data[i + j * mr.rows], v_mr);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Fallback for non-SIMD or unsupported types
|
||||
for (; i < mr.rows; i++) {
|
||||
mr.data[i + j * mr.rows] += m1.data[i + n * m1.rows] * val_m2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
31
src/spider/runtime/math/Matrix.hpp
Normal file
31
src/spider/runtime/math/Matrix.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <spider/runtime/common.hpp>
|
||||
|
||||
/*
|
||||
namespace spider {
|
||||
|
||||
template<typename T>
|
||||
struct Matrix {
|
||||
T* data;
|
||||
isize rows, cols;
|
||||
};
|
||||
|
||||
void matrix_fill(f32 diag, Matrix<f32> mat);
|
||||
|
||||
void matrix_fill(f64 diag, Matrix<f64> mat);
|
||||
|
||||
Matrix<f32> matrix_mul(Matrix<f32> m1, Matrix<f32> m2);
|
||||
|
||||
Matrix<f64> matrix_mul(Matrix<f64> m1, Matrix<f64> m2);
|
||||
|
||||
Matrix<f32> matrix_inv(Matrix<f32> mat);
|
||||
|
||||
Matrix<f64> matrix_inv(Matrix<f64> mat);
|
||||
|
||||
f32 matrix_det(Matrix<f32> mat);
|
||||
|
||||
f64 matrix_det(Matrix<f64> mat);
|
||||
|
||||
}
|
||||
*/
|
||||
109
src/spider/runtime/math/Matrix_Multiply.cpp
Normal file
109
src/spider/runtime/math/Matrix_Multiply.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
template<typename T, int Rows, int Cols>
|
||||
struct Matrix {
|
||||
T data[Rows][Cols];
|
||||
|
||||
void setZero() {
|
||||
for (int i = 0; i < Rows; i++) {
|
||||
for (int j = 0; j < Cols; j++) {
|
||||
data[i][j] = T();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int M, int N, int P>
|
||||
Matrix<T, M, P> mat_multiply(Matrix<T, M, N> A, Matrix<T, N, P> B) {
|
||||
//Determination of resulting matrix size
|
||||
// COMPILE-TIME calculation (using constexpr)
|
||||
constexpr int RSize = (M > P) ? M : P;
|
||||
|
||||
// COMPILE-TIME square size calculation
|
||||
constexpr int CSize = (RSize <= 4) ? 4 :
|
||||
(RSize % 4 == 0) ? RSize :
|
||||
4 * (RSize / 4 + 1);
|
||||
|
||||
// SIMD width selection
|
||||
int simd_width;
|
||||
if (RSize > 8) {
|
||||
simd_width = 8;
|
||||
}
|
||||
else if (RSize > 4 && RSize < 8){
|
||||
simd_width = 4;
|
||||
}
|
||||
else {
|
||||
simd_width = RSize;
|
||||
}
|
||||
|
||||
|
||||
// Create result square matrix with size CSize(optimization)
|
||||
Matrix<T, CSize, CSize> tempResult;
|
||||
tempResult.setZero();
|
||||
|
||||
// Matrix multiplication with SIMD-style unrolling
|
||||
for (int i = 0; i < M; i++) { // For each row in A
|
||||
for (int k = 0; k < N; k++) { // For each inner dimension
|
||||
T a_val = A.data[i][k];
|
||||
|
||||
// Process columns in chunks of simd_width
|
||||
int j = 0;
|
||||
while (j < P) {
|
||||
int remaining = P - j;
|
||||
|
||||
if (remaining >= simd_width) {
|
||||
// Full SIMD operation - unrolled loops
|
||||
if (simd_width == 8) {
|
||||
tempResult.data[i][j] += a_val * B.data[k][j];
|
||||
tempResult.data[i][j+1] += a_val * B.data[k][j+1];
|
||||
tempResult.data[i][j+2] += a_val * B.data[k][j+2];
|
||||
tempResult.data[i][j+3] += a_val * B.data[k][j+3];
|
||||
tempResult.data[i][j+4] += a_val * B.data[k][j+4];
|
||||
tempResult.data[i][j+5] += a_val * B.data[k][j+5];
|
||||
tempResult.data[i][j+6] += a_val * B.data[k][j+6];
|
||||
tempResult.data[i][j+7] += a_val * B.data[k][j+7];
|
||||
}
|
||||
else if (simd_width == 4) {
|
||||
tempResult.data[i][j] += a_val * B.data[k][j];
|
||||
tempResult.data[i][j+1] += a_val * B.data[k][j+1];
|
||||
tempResult.data[i][j+2] += a_val * B.data[k][j+2];
|
||||
tempResult.data[i][j+3] += a_val * B.data[k][j+3];
|
||||
}
|
||||
else if (simd_width == 3) {
|
||||
tempResult.data[i][j] += a_val * B.data[k][j];
|
||||
tempResult.data[i][j+1] += a_val * B.data[k][j+1];
|
||||
tempResult.data[i][j+2] += a_val * B.data[k][j+2];
|
||||
}
|
||||
else if (simd_width == 2) {
|
||||
tempResult.data[i][j] += a_val * B.data[k][j];
|
||||
tempResult.data[i][j+1] += a_val * B.data[k][j+1];
|
||||
}
|
||||
else { // simd_width == 1
|
||||
tempResult.data[i][j] += a_val * B.data[k][j];
|
||||
}
|
||||
|
||||
j += simd_width;
|
||||
}
|
||||
else {
|
||||
// Handle remaining columns that don't fit in SIMD width
|
||||
for (int s = 0; s < remaining; s++) {
|
||||
tempResult.data[i][j + s] += a_val * B.data[k][j + s];
|
||||
}
|
||||
j += remaining;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the actual result (M x P) from the temporary square matrix
|
||||
Matrix<T, M, P> result;
|
||||
for (int i = 0; i < M; i++) {
|
||||
for (int j = 0; j < P; j++) {
|
||||
result.data[i][j] = tempResult.data[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
@@ -3,20 +3,57 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace spider {
|
||||
|
||||
/**
|
||||
* Multiplies two quaternions together.
|
||||
* General case, use it when no optimizations exist.
|
||||
*/
|
||||
template<typename T>
|
||||
inline Quat<T> quat_mul_gnrl(Quat<T> A, Quat<T> B) {
|
||||
return {
|
||||
B.w * A.w - B.x * A.x - B.y * A.y - B.z * A.z,
|
||||
B.w * A.x + B.x * A.w - B.y * A.z + B.z * A.y,
|
||||
B.w * A.y + B.x * A.z + B.y * A.w - B.z * A.x,
|
||||
B.w * A.z - B.x * A.y + B.y * A.x + B.z * A.w
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies two quaternions together.
|
||||
* Attempts to use SIMD instructions when available.
|
||||
*/
|
||||
template<typename T>
|
||||
inline Quat<T> quat_mul_smart(Quat<T> A, Quat<T> B) {
|
||||
}
|
||||
|
||||
Quat<f32> quat_mul(Quat<f32> q1, Quat<f32> q2) {
|
||||
return quat_mul_gnrl<f32>(q1, q2);
|
||||
}
|
||||
|
||||
//void quat_mat(Quat<f32> quat, f32* mat) {
|
||||
// // TODO
|
||||
//}
|
||||
|
||||
Quat<f64> quat_mul(Quat<f64> q1, Quat<f64> q2) {
|
||||
return quat_mul_gnrl<f64>(q1, q2);
|
||||
}
|
||||
|
||||
//void quat_mat(Quat<f64> q1, f64* mat) {
|
||||
// // TODO
|
||||
//}
|
||||
|
||||
/*
|
||||
int quatMain() {
|
||||
Quat<double> q1 = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
Quat<double> q2 = { 0.5f, 0.5f, 0.5f, 0.5f };
|
||||
|
||||
Quat<double> result = quat_multiply(q1, q2); // Returns the result!
|
||||
|
||||
std::cout << "Result: ("
|
||||
<< result.w << ", "
|
||||
<< result.x << ", "
|
||||
<< result.y << ", "
|
||||
<< result.z << ")" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -10,15 +10,47 @@ namespace spider {
|
||||
};
|
||||
|
||||
/**
|
||||
* Multiplies two quaternions together.
|
||||
* Creates a quaternion from Euler Angles.
|
||||
*/
|
||||
template<typename T> inline Quat<T> quat_multiply(Quat<T> A, Quat<T> B) {
|
||||
return {
|
||||
B.w * A.w - B.x * A.x - B.y * A.y - B.z * A.z,
|
||||
B.w * A.x + B.x * A.w - B.y * A.z + B.z * A.y,
|
||||
B.w * A.y + B.x * A.z + B.y * A.w - B.z * A.x,
|
||||
B.w * A.z - B.x * A.y + B.y * A.x + B.z * A.w
|
||||
};
|
||||
}
|
||||
Quat<f32> quat_make_euler(f32 x, f32 y, f32 z);
|
||||
|
||||
/**
|
||||
* Creates a quaternion from an axis and an angle.
|
||||
*/
|
||||
Quat<f32> quat_make_axis_angle(f32 angle, f32 x, f32 y, f32 z);
|
||||
|
||||
/**
|
||||
* Creates a quaternion from Euler Angles.
|
||||
*/
|
||||
Quat<f64> quat_make_euler(f64 x, f64 y, f64 z);
|
||||
|
||||
/**
|
||||
* Creates a quaternion from an axis and an angle.
|
||||
*/
|
||||
Quat<f64> quat_make_axis_angle(f64 angle, f64 x, f64 y, f64 z);
|
||||
|
||||
/**
|
||||
* Multiples a quaternion with another quaternion.
|
||||
* The result is output to the qr variable.
|
||||
* This pointer can be the same as q1.
|
||||
*/
|
||||
Quat<f32> quat_mul(Quat<f32> q1, Quat<f32> q2);
|
||||
|
||||
/**
|
||||
* Converts a quaternion to a matrix.
|
||||
*/
|
||||
void quat_mat(Quat<f32> quat, f32* mat);
|
||||
|
||||
/**
|
||||
* Multiples a quaternion with another quaternion.
|
||||
* The result is output to the qr variable.
|
||||
* This pointer can be the same as q1.
|
||||
*/
|
||||
Quat<f64> quat_mul(Quat<f64> q1, Quat<f64> q2);
|
||||
|
||||
/**
|
||||
* Converts a quaternion to a matrix.
|
||||
*/
|
||||
void quat_mat(Quat<f64> q1, f64* mat);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "RAM.hpp"
|
||||
|
||||
#include <spider/runtime/cpu/Register.hpp>
|
||||
|
||||
#include <spider/runtime/memory/Types.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace spider {
|
||||
@@ -72,6 +76,11 @@ namespace spider {
|
||||
return (i < _size) ? _mem[i] : _oob;
|
||||
}
|
||||
|
||||
void RAM::loadRegister(u64 i, u8 size_code, register_t* r) {
|
||||
i = std::min(i, _size);
|
||||
spider::loadRegister[size_code](r, _mem + i, _size - i);
|
||||
}
|
||||
|
||||
// Misc //
|
||||
|
||||
void RAM::resize(u64 new_size) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <spider/runtime/common.hpp>
|
||||
|
||||
#include <spider/runtime/cpu/Register.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,8 @@ namespace spider {
|
||||
|
||||
u8 at(u64 i) const;
|
||||
|
||||
void loadRegister(u64 i, u8 size_code, register_t* r);
|
||||
|
||||
public:
|
||||
|
||||
void resize(u64 new_size);
|
||||
|
||||
@@ -118,8 +118,8 @@ namespace spider {
|
||||
std::memcpy(bytes, &n, sizeof(T));
|
||||
#endif
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
T tmp = byteswap(n);
|
||||
std::memcpy(bytes, &tmp, sizeof(T));
|
||||
n = byteswap(n);
|
||||
std::memcpy(bytes, &n, sizeof(T));
|
||||
#endif
|
||||
#if !SPIDER_BIG_ENDIAN && !SPIDER_LITTLE_ENDIAN
|
||||
for (size_t i = 0; i < sizeof(T); ++i) {
|
||||
@@ -151,9 +151,8 @@ namespace spider {
|
||||
std::memcpy(n, bytes, sizeof(T));
|
||||
#endif
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
T tmp;
|
||||
std::memcpy(&tmp, bytes, sizeof(T));
|
||||
*n = byteswap(tmp);
|
||||
std::memcpy(&n, bytes, sizeof(T));
|
||||
*n = byteswap(*n);
|
||||
#endif
|
||||
#if !SPIDER_BIG_ENDIAN && !SPIDER_LITTLE_ENDIAN
|
||||
using U = std::make_unsigned_t<T>;
|
||||
@@ -185,8 +184,8 @@ namespace spider {
|
||||
inline void storeLE(T n, u8* bytes) {
|
||||
static_assert(std::is_trivially_copyable<T>::value);
|
||||
#if SPIDER_BIG_ENDIAN
|
||||
T tmp = byteswap(n);
|
||||
std::memcpy(bytes, &tmp, sizeof(T));
|
||||
n = byteswap(n);
|
||||
std::memcpy(bytes, &n, sizeof(T));
|
||||
#endif
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
std::memcpy(bytes, &n, sizeof(T));
|
||||
@@ -218,9 +217,8 @@ namespace spider {
|
||||
inline void loadLE(T* n, const u8* bytes) {
|
||||
static_assert(std::is_trivially_copyable<T>::value);
|
||||
#if SPIDER_BIG_ENDIAN
|
||||
T tmp;
|
||||
std::memcpy(&tmp, bytes, sizeof(T));
|
||||
*n = byteswap(tmp);
|
||||
std::memcpy(&n, bytes, sizeof(T));
|
||||
*n = byteswap(n);
|
||||
#endif
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
std::memcpy(n, bytes, sizeof(T));
|
||||
@@ -249,5 +247,80 @@ namespace spider {
|
||||
*n = bit_cast<f64>(tmp);
|
||||
}
|
||||
|
||||
// ADVANCED Load Little Endian //
|
||||
|
||||
/**
|
||||
* Loads LE bytes into a type.
|
||||
* Also considers that the array may end, actually.
|
||||
*/
|
||||
template<typename T>
|
||||
inline void loadPartialLE(T* n, const u8* bytes, isize length) {
|
||||
*n = 0;
|
||||
length = std::min(sizeof(T), length);
|
||||
#if SPIDER_BIG_ENDIAN
|
||||
std::memcpy(n, bytes, length);
|
||||
*n = byteswap(n);
|
||||
#endif
|
||||
#if SPIDER_LITTLE_ENDIAN
|
||||
std::memcpy(n, bytes, length);
|
||||
#endif
|
||||
#if !SPIDER_BIG_ENDIAN && !SPIDER_LITTLE_ENDIAN
|
||||
using U = std::make_unsigned_t<T>;
|
||||
U result = 0;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
result |= static_cast<U>(bytes[i]) << (i * 8);
|
||||
}
|
||||
*n = static_cast<T>(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void loadPartialLE<f32>(f32* n, const u8* bytes, isize length) {
|
||||
u32 tmp;
|
||||
loadPartialLE(&tmp, bytes, length);
|
||||
*n = bit_cast<f32>(tmp);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void loadPartialLE<f64>(f64* n, const u8* bytes, isize length) {
|
||||
u64 tmp;
|
||||
loadPartialLE(&tmp, bytes, length);
|
||||
*n = bit_cast<f64>(tmp);
|
||||
}
|
||||
|
||||
inline void loadRegisterU8(register_t* r, const u8* bytes, isize length) {
|
||||
loadPartialLE(&r->_u8, bytes, length);
|
||||
}
|
||||
|
||||
inline void loadRegisterU16(register_t* r, const u8* bytes, isize length) {
|
||||
loadPartialLE(&r->_u16, bytes, length);
|
||||
}
|
||||
|
||||
inline void loadRegisterU32(register_t* r, const u8* bytes, isize length) {
|
||||
loadPartialLE(&r->_u32, bytes, length);
|
||||
}
|
||||
|
||||
inline void loadRegisterU64(register_t* r, const u8* bytes, isize length) {
|
||||
loadPartialLE(&r->_u64, bytes, length);
|
||||
}
|
||||
|
||||
using _regload = void (*)(register_t* r, const u8* bytes, isize length);
|
||||
|
||||
inline _regload loadRegister[] = {
|
||||
&loadRegisterU8, &loadRegisterU16,
|
||||
&loadRegisterU32, &loadRegisterU64
|
||||
};
|
||||
|
||||
// MISCs
|
||||
|
||||
inline void loadPartialBytes(const u8* from, isize fromOffset, isize fromLength, u8* to, isize toLength) {
|
||||
size_t safeOffset = std::min(fromOffset, fromLength);
|
||||
from += safeOffset;
|
||||
fromLength -= safeOffset;
|
||||
size_t writable = std::min(fromLength, toLength);
|
||||
std::copy(from, from + writable, to);
|
||||
std::fill(to + writable, to + toLength, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <spider/SpiderRuntime.hpp>
|
||||
|
||||
#include <spider/runtime/memory/ByteArray.hpp>
|
||||
|
||||
#include <spider/runtime/cpu/Register.hpp>
|
||||
|
||||
namespace spider {
|
||||
|
||||
/**
|
||||
@@ -55,6 +58,8 @@ namespace spider {
|
||||
*/
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) = 0;
|
||||
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) = 0;
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace spider {
|
||||
growTo((length >> 8) + ((length & 255) != 0));
|
||||
}
|
||||
|
||||
InstrReelDyn::InstrReelDyn(const u8* data, u64 length) {}
|
||||
//InstrReelDyn::InstrReelDyn(const u8* data, u64 length) {}
|
||||
|
||||
InstrReelDyn::InstrReelDyn(const InstrReelDyn& copy)
|
||||
: _blocks(copy._blocks), _size(copy._size) {
|
||||
@@ -89,7 +89,7 @@ namespace spider {
|
||||
dat = 0;
|
||||
for (isize i = 0; i < sizeof(dat); i++) {
|
||||
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||
dat |= u16(b.data[s_index++ & 0xFF]) << (i * 8);
|
||||
dat |= u16(b.data[s_index++ & 0xFF] << (i * 8));
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
@@ -179,6 +179,12 @@ namespace spider {
|
||||
}
|
||||
}
|
||||
|
||||
void InstrReelDyn::loadRegister(u64 ip, u8 size_code, register_t* r) {
|
||||
u8 bytes[8];
|
||||
readRange(ip, bytes, 1 << size_code);
|
||||
spider::loadRegister[size_code](r, bytes, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
@@ -190,17 +196,14 @@ namespace spider {
|
||||
|
||||
// TODO!
|
||||
|
||||
void InstrReelDyn::writeU8(u64 ip, u8 dat) {}
|
||||
|
||||
void InstrReelDyn::writeU16(u64 ip, u16 dat) {}
|
||||
|
||||
void InstrReelDyn::writeU32(u64 ip, u32 dat) {}
|
||||
|
||||
void InstrReelDyn::writeU64(u64 ip, u64 dat) {}
|
||||
//void InstrReelDyn::writeU8(u64 ip, u8 dat) {}
|
||||
//void InstrReelDyn::writeU16(u64 ip, u16 dat) {}
|
||||
//void InstrReelDyn::writeU32(u64 ip, u32 dat) {}
|
||||
//void InstrReelDyn::writeU64(u64 ip, u64 dat) {}
|
||||
|
||||
/**
|
||||
* Appends instruction at the end.
|
||||
*/
|
||||
void InstrReelDyn::append(u16 bc) {}
|
||||
//void InstrReelDyn::append(u16 bc) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@ namespace spider {
|
||||
*/
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) override;
|
||||
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) override;
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
|
||||
@@ -47,49 +47,36 @@ namespace spider {
|
||||
// Instruction abstraction //
|
||||
|
||||
u8 InstrReelFixed::readU8(u64 ip) {
|
||||
// guard against access
|
||||
if(ip + 1 > _size) return 0;
|
||||
|
||||
// send byte
|
||||
return _mem[ip];
|
||||
u8 dat;
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
u16 InstrReelFixed::readU16(u64 ip) {
|
||||
// guard against access
|
||||
if(ip + 2 > _size) return 0;
|
||||
|
||||
// build a 16-bit big endian number
|
||||
u16 dat;
|
||||
spider::loadLE(&dat, _mem + ip);
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
u32 InstrReelFixed::readU32(u64 ip) {
|
||||
// guard against access
|
||||
if(ip + 4 > _size) return 0;
|
||||
|
||||
// build a 32-bit big endian number
|
||||
u32 dat;
|
||||
spider::loadLE(&dat, _mem + ip);
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
u64 InstrReelFixed::readU64(u64 ip) {
|
||||
// guard against access
|
||||
if(ip + 8 > _size) return 0;
|
||||
|
||||
// build a 64-bit big endian number
|
||||
u64 dat;
|
||||
spider::loadLE(&dat, _mem + ip);
|
||||
spider::loadPartialLE(&dat, _mem + ip, _size);
|
||||
return dat;
|
||||
}
|
||||
|
||||
void InstrReelFixed::readRange(u64 ip, u8* out, u64 length) {
|
||||
if(ip + length > _size) {
|
||||
std::memset(out, 0, length);
|
||||
return;
|
||||
}
|
||||
std::memcpy(out, _mem + ip, length);
|
||||
spider::loadPartialBytes(_mem, isize(ip), _size, out, length);
|
||||
}
|
||||
|
||||
void InstrReelFixed::loadRegister(u64 ip, u8 size_code, register_t* r) {
|
||||
ip = std::min(ip, _size);
|
||||
spider::loadRegister[size_code](r, _mem + ip, _size - ip);
|
||||
}
|
||||
|
||||
u64 InstrReelFixed::size() {
|
||||
|
||||
@@ -70,6 +70,8 @@ namespace spider {
|
||||
*/
|
||||
virtual void readRange(u64 ip, u8* out, u64 length) override;
|
||||
|
||||
virtual void loadRegister(u64 ip, u8 size_code, register_t* r) override;
|
||||
|
||||
/**
|
||||
* Current size of the instructions.
|
||||
*/
|
||||
|
||||
@@ -11,8 +11,15 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h> //This was missing,
|
||||
//The ioctl, TIOCGWINSZ and winsize used in getSize() live in that header, but it was never included.
|
||||
#endif
|
||||
|
||||
|
||||
//the Linux includes at the top are inside #if SPIDER_OS_LINUX which IS defined,
|
||||
//but getSize() is inside #if SPIDER_DISTRO_DESKTOP which is NOT defined,
|
||||
//so the compiler sees the ioctl call without the include that would have covered it.
|
||||
|
||||
#if defined(SPIDER_DISTRO_DESKTOP)
|
||||
|
||||
namespace spider {
|
||||
@@ -148,7 +155,7 @@ namespace spider {
|
||||
|
||||
// 4. Overlay the title if provided
|
||||
if (!title.empty()) {
|
||||
move(startRow, startCol + (width - title.size() - 2) / 2);
|
||||
move(startRow, startCol + (width - i32(title.size()) - 2) / 2);
|
||||
std::cout << " " << title << " ";
|
||||
}
|
||||
|
||||
@@ -218,7 +225,8 @@ namespace spider {
|
||||
struct termios oldt, newt;
|
||||
tcgetattr(STDIN_FILENO, &oldt);
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~(ICANON | ECHO);
|
||||
//newt.c_lflag &= ~(ICANON | ECHO);
|
||||
newt.c_lflag &= static_cast<tcflag_t>(~(ICANON | ECHO)); //added this line
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
|
||||
u8 result = Terminal::UNKNOWN;
|
||||
@@ -247,7 +255,8 @@ namespace spider {
|
||||
}
|
||||
} else if (ch == 10) result = Terminal::ENTER;
|
||||
else if (ch == 127) result = Terminal::BACKSPACE;
|
||||
else result = (u8)ch;
|
||||
else result = static_cast<u8>(ch); //added this line
|
||||
//else result = (u8)ch;
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
return result;
|
||||
|
||||
@@ -156,8 +156,8 @@ namespace spider {
|
||||
if (s.length() >= isize(width)) {
|
||||
std::cout << s;
|
||||
} else {
|
||||
i32 total_padding = width - s.length();
|
||||
i32 left_padding = total_padding / 2;
|
||||
isize total_padding = isize(width) - s.length();
|
||||
isize left_padding = total_padding / 2;
|
||||
std::cout << std::string(left_padding, ' ');
|
||||
std::cout << s;
|
||||
std::cout << std::string(total_padding - left_padding, ' ');
|
||||
|
||||
Reference in New Issue
Block a user