asm: Instruction encoding and decoding
This commit is contained in:
@ -4,8 +4,64 @@
|
||||
#include <assert.h>
|
||||
#include <common.h>
|
||||
|
||||
enum instruction_format {
|
||||
AMAL,
|
||||
IML,
|
||||
IPL,
|
||||
AMLS,
|
||||
ASSS,
|
||||
ASLI,
|
||||
ASLR,
|
||||
ASRD,
|
||||
};
|
||||
|
||||
// #ifdef AIN49__IMPL
|
||||
enum amal_ac : u8 {
|
||||
ADD = 000,
|
||||
STR = 001,
|
||||
MPL = 002,
|
||||
DVD = 004,
|
||||
RSD = 005,
|
||||
DEM = 006,
|
||||
ET = 010,
|
||||
VEL = 011,
|
||||
AUT = 012,
|
||||
NAM = 014,
|
||||
NEC = 015,
|
||||
};
|
||||
|
||||
enum asss_ac : u8 {
|
||||
RV = 00,
|
||||
IRRV = 04,
|
||||
NCIVC = 03,
|
||||
NCRV = 02,
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
struct instruction {
|
||||
enum instruction_format format;
|
||||
union {
|
||||
struct {
|
||||
bool s, i1, i2; enum amal_ac ac; u4 rf;
|
||||
union {
|
||||
u8 imm; i8 simm;
|
||||
struct {
|
||||
union { u4 r2; u4 imm2; i4 simm2; };
|
||||
union { u4 r1; u4 imm1; u4 simm1; };
|
||||
};
|
||||
} data;
|
||||
} AMAL;
|
||||
struct { u4 r; u48 imm; } IML;
|
||||
struct { bool s; u4 r; union { u12 imm; i12 simm; }; } IPL;
|
||||
struct { bool s; u4 rd; u4 rl; i12 imm; } AMLS;
|
||||
enum asss_ac ASSS_ac;
|
||||
struct { bool I, E, N, U, R; u48 imm; } ASLI;
|
||||
struct { bool I, E, N, U, R; u4 rl; } ASLR;
|
||||
struct { bool I, E, N, U, R; u4 rl; i12 imm; } ASRD;
|
||||
};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
u12 *ain48_read_instr(u12 *code, struct instruction *i);
|
||||
u12 *ain48_write_instr(u12 *code, struct instruction *i);
|
||||
|
||||
// #endif // def AIN48__IMPL
|
||||
#endif // AIN48__H
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
// # NUMBER TYPES
|
||||
typedef unsigned _BitInt(4) u4;
|
||||
typedef uint8_t u8;
|
||||
typedef unsigned _BitInt(12) u12;
|
||||
typedef uint16_t u16;
|
||||
|
||||
191
src/ain48.c
Normal file
191
src/ain48.c
Normal file
@ -0,0 +1,191 @@
|
||||
#include <ain48.h>
|
||||
#include <string.h>
|
||||
|
||||
u12 *ain48_write_instruction(u12 *code, struct instruction *i) {
|
||||
u4 u4tmp;
|
||||
u8 u8tmp;
|
||||
switch (i->format) {
|
||||
case AMAL:
|
||||
*code++ = i->AMAL.ac | (i->AMAL.s ? 1 << 4 : 0) |
|
||||
(i->AMAL.i1 ? 1 << 5 : 0) | (i->AMAL.i2 ? 1 << 6 : 0);
|
||||
*code = ((u12)i->AMAL.rf) << 8;
|
||||
if (!i->AMAL.i1)
|
||||
*code |= ((u12)i->AMAL.data.r1) << 4;
|
||||
if (!i->AMAL.i2)
|
||||
*code |= ((u12)i->AMAL.data.r2);
|
||||
if (i->AMAL.i1 && i->AMAL.i2) {
|
||||
if (i->AMAL.s)
|
||||
memcpy(&u8tmp, &i->AMAL.data.simm, sizeof(u8));
|
||||
else
|
||||
u8tmp = i->AMAL.data.imm;
|
||||
*code |= u8tmp;
|
||||
} else if (i->AMAL.i1) {
|
||||
if (i->AMAL.s)
|
||||
memcpy(&u4tmp, &i->AMAL.data.simm1, sizeof(u4));
|
||||
else
|
||||
u4tmp = i->AMAL.data.imm1;
|
||||
*code |= u4tmp;
|
||||
} else if (i->AMAL.i2) {
|
||||
if (i->AMAL.s)
|
||||
memcpy(&u4tmp, &i->AMAL.data.simm2, sizeof(u4));
|
||||
else
|
||||
u4tmp = i->AMAL.data.imm2;
|
||||
*code |= ((u12)u4tmp) << 4;
|
||||
}
|
||||
return ++code;
|
||||
case IML:
|
||||
*code++ = 00400 | i->IML.r;
|
||||
*code++ = i->IML.imm & 07777;
|
||||
*code++ = (i->IML.imm >> 12) & 07777;
|
||||
*code++ = (i->IML.imm >> 24) & 07777;
|
||||
*code++ = (i->IML.imm >> 36) & 07777;
|
||||
return code;
|
||||
case IPL:
|
||||
*code++ = 00500 | (i->IPL.s ? (1 << 4) : 0) | i->IPL.r;
|
||||
if (i->IPL.s) {
|
||||
memcpy(code++, &i->IPL.simm, sizeof(u12));
|
||||
} else {
|
||||
*code++ = i->IPL.imm;
|
||||
}
|
||||
return code;
|
||||
case AMLS:
|
||||
*code++ = 01000 | (i->AMLS.s ? 1 << 8 : 0) | (((u12)i->AMLS.rd) << 4) |
|
||||
i->AMLS.rl;
|
||||
memcpy(code++, &i->AMLS.imm, sizeof(u12));
|
||||
return code;
|
||||
case ASSS:
|
||||
*code++ = 07770 | i->ASSS_ac;
|
||||
return code;
|
||||
case ASLI:
|
||||
*code++ = 04000 | (i->ASLI.R ? 1 << 0 : 0) | (i->ASLI.U ? 1 << 1 : 0) |
|
||||
(i->ASLI.N ? 1 << 2 : 0) | (i->ASLI.E ? 1 << 3 : 0) |
|
||||
(i->ASLI.I ? 1 << 4 : 0);
|
||||
*code++ = i->ASLI.imm & 07777;
|
||||
*code++ = (i->ASLI.imm >> 12) & 07777;
|
||||
*code++ = (i->ASLI.imm >> 24) & 07777;
|
||||
*code++ = (i->ASLI.imm >> 36) & 07777;
|
||||
return code;
|
||||
case ASLR:
|
||||
*code++ = 05000 | (i->ASLR.R ? 1 << 0 : 0) | (i->ASLR.U ? 1 << 1 : 0) |
|
||||
(i->ASLR.N ? 1 << 2 : 0) | (i->ASLR.E ? 1 << 3 : 0) |
|
||||
(i->ASLR.I ? 1 << 4 : 0) | (((u12)i->ASLR.rl) << 5);
|
||||
return code;
|
||||
case ASRD:
|
||||
*code++ = 05000 | (i->ASRD.R ? 1 << 0 : 0) | (i->ASRD.U ? 1 << 1 : 0) |
|
||||
(i->ASRD.N ? 1 << 2 : 0) | (i->ASRD.E ? 1 << 3 : 0) |
|
||||
(i->ASLR.I ? 1 << 4 : 0) | (((u12)i->ASRD.rl) << 5);
|
||||
memcpy(code++, &i->ASRD.imm, sizeof(u12));
|
||||
return code;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
u12 *ain48_read_instr(u12 *code, struct instruction *i) {
|
||||
u12 byte = *code++;
|
||||
if ((byte & 07600) == 0) { // AMAL
|
||||
i->format = AMAL;
|
||||
i->AMAL.i1 = (byte & 00040) > 0;
|
||||
i->AMAL.i2 = (byte & 00100) > 0;
|
||||
i->AMAL.s = (byte & 00020) > 0;
|
||||
i->AMAL.ac = (enum amal_ac) (byte & 00017);
|
||||
byte = *code++;
|
||||
i->AMAL.rf = (byte >> 8) & 017;
|
||||
if (!i->AMAL.i1)
|
||||
i->AMAL.data.r1 = (byte >> 4) & 017;
|
||||
if (!i->AMAL.i2)
|
||||
i->AMAL.data.r2 = byte & 017;
|
||||
if (i->AMAL.i1 && i->AMAL.i2) {
|
||||
if (i->AMAL.s) {
|
||||
u8 tmp = byte & 0377;
|
||||
memcpy(&i->AMAL.data.simm, &tmp, sizeof(i8));
|
||||
} else
|
||||
i->AMAL.data.imm = byte & 0337;
|
||||
} else if (i->AMAL.i1) {
|
||||
if (i->AMAL.s) {
|
||||
u4 tmp = byte & 017;
|
||||
memcpy(&i->AMAL.data.simm1, &tmp, sizeof(i4));
|
||||
}
|
||||
else
|
||||
i->AMAL.data.imm1 = byte & 017;
|
||||
} else if (i->AMAL.i2) {
|
||||
if (i->AMAL.s) {
|
||||
u4 tmp = (byte >> 4) & 017;
|
||||
memcpy(&i->AMAL.data.simm2, &tmp, sizeof(i4));
|
||||
}
|
||||
else
|
||||
i->AMAL.data.imm2 = (byte >> 4) & 017;
|
||||
}
|
||||
return code;
|
||||
} else if ((byte & 07600) == 00400) { // IML
|
||||
i->format = IML;
|
||||
i->IML.r = byte & 017;
|
||||
byte = *code++;
|
||||
i->IML.imm = (u48)byte;
|
||||
byte = *code++;
|
||||
i->IML.imm |= ((u48)byte << 12);
|
||||
byte = *code++;
|
||||
i->IML.imm |= ((u48)byte << 24);
|
||||
byte = *code++;
|
||||
i->IML.imm |= ((u48)byte << 36);
|
||||
return code;
|
||||
} else if ((byte & 07600) == 00600) { // IPL
|
||||
i->format = IPL;
|
||||
i->IPL.r = byte & 017;
|
||||
i->IPL.s = (byte & 00020) > 0;
|
||||
byte = *code++;
|
||||
if (i->IPL.s) {
|
||||
memcpy(&i->IPL.simm, &byte, sizeof(i12));
|
||||
} else {
|
||||
i->IPL.imm = byte;
|
||||
}
|
||||
return code;
|
||||
} else if ((byte & 07000) == 01000) { // AMLS
|
||||
i->format = AMLS;
|
||||
i->AMLS.s = (byte & 00400) > 0;
|
||||
i->AMLS.rd = (byte >> 4) & 017;
|
||||
i->AMLS.rl = byte & 017;
|
||||
memcpy(&i->AMLS.imm, code++, sizeof(i12));
|
||||
return code;
|
||||
} else if ((byte & 07770) == 07770) { // ASSS
|
||||
i->format = ASSS;
|
||||
i->ASSS_ac = byte & 00007;
|
||||
return code;
|
||||
} else if ((byte & 07000) == 04000) { // ASLI
|
||||
i->format = ASLI;
|
||||
i->ASLI.R = (byte & 0b1) > 0;
|
||||
i->ASLI.U = (byte & 0b10) > 0;
|
||||
i->ASLI.N = (byte & 0b100) > 0;
|
||||
i->ASLI.E = (byte & 0b1000) > 0;
|
||||
i->ASLI.I = (byte & 0b10000) > 0;
|
||||
byte = *code++;
|
||||
i->ASLI.imm = (u48)byte;
|
||||
byte = *code++;
|
||||
i->ASLI.imm |= ((u48)byte << 12);
|
||||
byte = *code++;
|
||||
i->ASLI.imm |= ((u48)byte << 24);
|
||||
byte = *code++;
|
||||
i->ASLI.imm |= ((u48)byte << 36);
|
||||
return code;
|
||||
} else if ((byte & 07000) == 05000) { // ASLR
|
||||
i->format = ASLR;
|
||||
i->ASLR.R = (byte & 0b1) > 0;
|
||||
i->ASLR.U = (byte & 0b10) > 0;
|
||||
i->ASLR.N = (byte & 0b100) > 0;
|
||||
i->ASLR.E = (byte & 0b1000) > 0;
|
||||
i->ASLR.I = (byte & 0b10000) > 0;
|
||||
i->ASLR.rl = (byte >> 5) & 017;
|
||||
return code;
|
||||
} else if ((byte & 07000) == 06000) { // ASRD
|
||||
i->format = ASRD;
|
||||
i->ASRD.R = (byte & 0b1) > 0;
|
||||
i->ASRD.U = (byte & 0b10) > 0;
|
||||
i->ASRD.N = (byte & 0b100) > 0;
|
||||
i->ASRD.E = (byte & 0b1000) > 0;
|
||||
i->ASRD.I = (byte & 0b10000) > 0;
|
||||
i->ASRD.rl = (byte >> 5) & 017;
|
||||
memcpy(&i->ASRD.imm, code++, sizeof(i12));
|
||||
return code;
|
||||
} else return nullptr; // ILLEGAL INSTRUCTION
|
||||
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <ain48.h>
|
||||
|
||||
i32 asm_main(i32 argc, char *argv[]) {
|
||||
if (argc != 3) {
|
||||
|
||||
@ -9,19 +9,18 @@ enum subprorgram {
|
||||
|
||||
|
||||
const char *available = (R"m(
|
||||
asm
|
||||
)m");
|
||||
asm)m");
|
||||
|
||||
i32 asm_main(i32 argc, char *argv[]);
|
||||
i32 main(i32 argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "No subprogram called\nAvalible subprograms:%s\n", available);
|
||||
log_err("No subprogram called\nAvalible subprograms:%s", available);
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[1], "asm")) {
|
||||
return asm_main(argc - 1, argv + 1);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown subprogram `%s`\nAvailable subpograms:%s", argv[1], available);
|
||||
log_err("Unknown subprogram `%s`\nAvailable subpograms:%s", argv[1], available);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user