From 6bd1943d8c2c587537f459bfd7d25db20f28f216 Mon Sep 17 00:00:00 2001 From: nikto_b Date: Fri, 10 Apr 2026 22:24:08 +0300 Subject: [PATCH] add instr, manifest, dev_variant --- Makefile | 5 +- inc/instr.h | 94 +++++++++++++++++++ inc/instr_map.h | 13 +++ inc/mem_seg.h | 28 +++--- manifest_src/gen_manifest_json.py | 16 +++- manifest_src/generate_dev_type.c | 3 +- manifest_src/generate_dev_variant.c | 56 +++++++++++ .../generate_manifest_segments_defines.c | 3 +- src/device.c | 4 - src/instr.c | 91 ++++++++++++++++++ 10 files changed, 291 insertions(+), 22 deletions(-) create mode 100644 inc/instr.h create mode 100644 inc/instr_map.h create mode 100644 manifest_src/generate_dev_variant.c create mode 100644 src/instr.c diff --git a/Makefile b/Makefile index 9832da3..687bb17 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,9 @@ LIBS= STANDART=c23 OPTIMIZE=-Og TARGET=device +ifeq ($(ARCH),) +ARCH := "template" +endif DEFINES=-DOPCODE_WORDSIZE=2 -DMEM_CELL_WORDS=1 -DPC_WORDSIZE=3 -DGP_REG_CELL_WORDS=1 -DIO_REG_CELL_WORDS=1 -DARCH=$(ARCH) @@ -79,7 +82,7 @@ $(MANIFEST_BUILD_DIR)/MANIFEST.json: $(C_HEADERS) $(MANIFEST_TARGETS) $(MANIFEST_BUILD_DIR)/%.elf: $(MANIFEST_SRC_DIR)/%.c Makefile $(C_HEADERS) | $(MANIFEST_BUILD_DIR) @echo -e '\033[1;32mELF\t'$(OBJECTS)'\n\t\t\t->\t'$@'\033[0m' - @$(CC) $(MANIFEST_LFLAGS) $< $(LDLIBS) -I inc -o $@ + @$(CC) $(MANIFEST_LFLAGS) $< $(DEFINES) $(LDLIBS) -I inc -o $@ $(BUILD_DIR): @mkdir -p $(BUILD_DIR) diff --git a/inc/instr.h b/inc/instr.h new file mode 100644 index 0000000..74e4998 --- /dev/null +++ b/inc/instr.h @@ -0,0 +1,94 @@ +#ifndef __INSTR_H__ +#define __INSTR_H__ + +#include +#include +#include +#include "mem.h" + + +#ifndef OPCODE_WORDSIZE + #error OPCODE_WORDSIZE must be provided +// #define OPCODE_WORDSIZE 1 +#endif +#if OPCODE_WORDSIZE == 1 + typedef uint8_t opcode_t; +#elif OPCODE_WORDSIZE == 2 + typedef uint16_t opcode_t; +#elif OPCODE_WORDSIZE == 3 + typedef uint32_t opcode_t; +#elif OPCODE_WORDSIZE == 4 + typedef uint32_t opcode_t; +#else + #error OPCODE_WORDSIZE must be one of 1,2,3,4 +#endif + + +#ifndef PC_WORDSIZE + #error PC_WORDSIZE must be provided +// #define PC_WORDSIZE 1 +#endif +#if PC_WORDSIZE == 1 + typedef uint8_t prog_counter_t; +#elif PC_WORDSIZE == 2 + typedef uint16_t prog_counter_t; +#elif PC_WORDSIZE == 3 + typedef uint32_t prog_counter_t; +#elif PC_WORDSIZE == 4 + typedef uint32_t prog_counter_t; +#else + #error PC_WORDSIZE must be one of 1,2,3,4 +#endif + +typedef uint8_t (*instr_h_func)(prog_counter_t*, device_mem_t*); + +typedef struct +{ + instr_h_func h; + opcode_t base; + opcode_t argsMask; + uint8_t opcodeLen; + +} instruction_metadata_t; + +instr_h_func* genInstrArray(char* errbuf); +void setOpcodeSizes(uint8_t* opcodeSizes); +opcode_t extractOpcode(device_mem_t* devMem, prog_counter_t programCounter); + + + + +#define READ_MEM(__tgt, __mem, __segno, __addr, __cell_t) \ +{\ + uint64_t __globalAddr = __mem->memsegShifts[__segno] + __addr; \ + if (__mem->smartAddrReadHandlers[__globalAddr].func != NULL) \ + { \ + __tgt = *(__cell_t*)__mem->smartAddrReadHandlers[__globalAddr].func(__mem->smartAddrReadHandlers[__globalAddr].ident, __addr, __mem->rawCells + __mem->memsegShifts[__segno]); \ + } \ + else \ + { \ + __tgt = ((__cell_t*)__mem->cells[__segno])[__addr]; \ + } \ + __mem->memreadCellAddrs[__mem->memreadLen] = __globalAddr; \ + __mem->memreadLen += 1; \ +} + +#define WRITE_MEM(__mem, __segno, __addr, __cell_t, __val) \ +{ \ + uint64_t __globalAddr = __mem->memsegShifts[__segno] + __addr; \ + if (__mem->smartAddrWriteHandlers[__globalAddr].func != NULL) \ + { \ + __cell_t __dat = (__cell_t)(__val); \ + __mem->smartAddrWriteHandlers[__globalAddr].func(__mem->smartAddrWriteHandlers[__globalAddr].ident, __addr, __mem->rawCells + __mem->memsegShifts[__segno], (void*)&__dat); \ + } \ + else \ + { \ + ((__cell_t*)__mem->cells[__segno])[__addr] = (__cell_t)(__val); \ + } \ + __mem->memwriteCellAddrs[__mem->memwriteLen] = __globalAddr; \ + __mem->memwriteLen += 1; \ +} + + + +#endif // ifndef __INSTR_H__ \ No newline at end of file diff --git a/inc/instr_map.h b/inc/instr_map.h new file mode 100644 index 0000000..f3297f7 --- /dev/null +++ b/inc/instr_map.h @@ -0,0 +1,13 @@ +#ifndef __INSTR_MAP_H__ +#define __INSTR_MAP_H__ +#include "instr.h" +#include "mem.h" +#include +#include "addrs.h" + +uint8_t _nop (prog_counter_t* pcounter, device_mem_t* devMem); + +#define HANDLER_REGISTERS {\ + {&_nop, 0b0000000000000000, 0b1111111111111111, 2}} + +#endif \ No newline at end of file diff --git a/inc/mem_seg.h b/inc/mem_seg.h index 9e1b760..0a74184 100644 --- a/inc/mem_seg.h +++ b/inc/mem_seg.h @@ -1,23 +1,23 @@ #ifndef __MEM_SEG_H__ #define __MEM_SEG_H__ -<<<<<<< HEAD -#ifndef DEVICE_TYPE -#define DEVICE_TYPE EXTENDED_DEVICE_TYPE_DUMMY -#endif -======= ->>>>>>> 1f4cc4d (Initial commit) +#include "../../../inc/libhmmmm.h" -// #define MEMSEG_PC_SEG_NUM 0 -// #define MEMSEG_PC_ADDR 0 +#ifndef DEVICE_TYPE +#define DEVICE_TYPE EXTENDED_DEVICE_TYPE_INSTR_SIMUL +#endif + + +#define MEMSEG_PS 0 +#define MEMDATA_PS MEMSEG_PS + + +#define MEMSEG_PC_SEG_NUM 1 +#define MEMSEG_PC_ADDR 0 #define MEMSEG_DEFINES {\ - {0, "seg0", 1, 0, 0, 0}, \ - {1, "seg1", 1, 0, 0, 0}, \ - {2, "seg2", 1, 0, 0, 0}, \ - {3, "seg3", 1, 0, 0, 0}, \ - {4, "seg4", 1, 0, 0, 0}, \ - {5, "seg5", 1, 0, 0, 0}, \ + {MEMSEG_PS, "PS", 2, 1024, 0, 1}, \ + {MEMSEG_PC_SEG_NUM, "PC", 2, 1, 1024 + MEMSEG_PC_ADDR + 1, 0} \ } #endif //ifndef __MEM_SEG_H__ \ No newline at end of file diff --git a/manifest_src/gen_manifest_json.py b/manifest_src/gen_manifest_json.py index a1baf99..b127d2f 100644 --- a/manifest_src/gen_manifest_json.py +++ b/manifest_src/gen_manifest_json.py @@ -1,6 +1,9 @@ import sys import csv import json +import os + +SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__)) def main(): if len(sys.argv) != 2: @@ -11,11 +14,22 @@ def main(): with open(manifest_dir + '/dev_type', 'r') as f: dev_type = f.read() + with open(manifest_dir + '/dev_variant', 'r') as f: + dev_variant = f.read() + + try: + with open(SCRIPT_PATH + '/instructions.json', 'r') as f: + instructions = json.load(f) + except Exception as e: + print(f'unable to read instructions file: {e}') + instructions = [] mem_segments = [] out_manifest = { 'mem_segments': mem_segments, - 'dev_type': dev_type + 'dev_type': dev_type, + 'dev_variant': dev_variant, + 'instructions': instructions } with open(manifest_dir + '/seg_data.csv', 'r', newline='') as csvfile: diff --git a/manifest_src/generate_dev_type.c b/manifest_src/generate_dev_type.c index 1eeca5d..deb6dcc 100644 --- a/manifest_src/generate_dev_type.c +++ b/manifest_src/generate_dev_type.c @@ -17,13 +17,14 @@ int main(int argc, char** argv) const char *dirpath = argv[1]; const char *filename = "dev_type"; - char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 1, sizeof(char)); + char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 2, sizeof(char)); if(tgtpath == NULL) { return 1; } sprintf(tgtpath, "%s/%s", dirpath, filename); + tgtpath[strlen(dirpath) + strlen(filename) + 1] = 0; FILE *fptr; diff --git a/manifest_src/generate_dev_variant.c b/manifest_src/generate_dev_variant.c new file mode 100644 index 0000000..6e29bbc --- /dev/null +++ b/manifest_src/generate_dev_variant.c @@ -0,0 +1,56 @@ +#include "mem.h" +#include "mem_seg.h" +#include +#include +#include +#include + +#define STR(name) XSTR(name) +#define XSTR(name) #name + +#ifndef ARCH +#pragma message "ARCH not set, using empty" +#define ARCH asdf +#endif + + +#define __ARCH STR(ARCH) + +int main(int argc, char** argv) +{ + if(argc != 2) + { + printf("provide target directory\n"); + return 1; + } + + const char *dirpath = argv[1]; + const char *filename = "dev_variant"; + + char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 2, sizeof(char)); + if(tgtpath == NULL) + { + return 1; + } + + sprintf(tgtpath, "%s/%s", dirpath, filename); + tgtpath[strlen(dirpath) + strlen(filename) + 1] = 0; + + FILE *fptr; + + fptr = fopen(tgtpath, "w"); + + if(fptr == NULL) + { + printf("errof opening file\n"); + return 1; + } + + char* dev_variant = STR(ARCH); + fprintf(fptr, "%s", dev_variant); + + + fclose(fptr); + free(tgtpath); + return 0; +} \ No newline at end of file diff --git a/manifest_src/generate_manifest_segments_defines.c b/manifest_src/generate_manifest_segments_defines.c index fafd5be..b16d246 100644 --- a/manifest_src/generate_manifest_segments_defines.c +++ b/manifest_src/generate_manifest_segments_defines.c @@ -16,13 +16,14 @@ int main(int argc, char** argv) const char *dirpath = argv[1]; const char *filename = "seg_data.csv"; - char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 1, sizeof(char)); + char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 2, sizeof(char)); if(tgtpath == NULL) { return 1; } sprintf(tgtpath, "%s/%s", dirpath, filename); + tgtpath[strlen(dirpath) + strlen(filename) + 1] = 0; FILE *fptr; diff --git a/src/device.c b/src/device.c index 4343847..ba834ab 100644 --- a/src/device.c +++ b/src/device.c @@ -730,11 +730,7 @@ device_public_context_t* init(device_specs_t* specs, char* errbuf) uint8_t pubDeviceType() { -<<<<<<< HEAD return DEVICE_TYPE; -======= - return EXTENDED_DEVICE_TYPE_DUMMY; ->>>>>>> 1f4cc4d (Initial commit) } diff --git a/src/instr.c b/src/instr.c new file mode 100644 index 0000000..1203152 --- /dev/null +++ b/src/instr.c @@ -0,0 +1,91 @@ +#include "instr.h" +#include "mem.h" + +#include + +#include "addrs.h" + +#include "instr_map.h" +#include "mem_seg.h" + + +uint8_t _invalid_opcode(prog_counter_t* pcounter, device_mem_t* devMem) +{ + opcode_t op = extractOpcode(devMem, *pcounter); + printf("Invalid opcode at 0x%016X: 0x%016X\n", *pcounter, op); + return (uint8_t)(-1); +} + + + +void setCombinations(opcode_t base, opcode_t mask, instr_h_func* tgt, instr_h_func val) +{ + opcode_t start_opcode = base; + do + { + tgt[(start_opcode & mask) | base] = val; + start_opcode += 1; + } while(start_opcode < (base | mask)); + tgt[(start_opcode & mask) | base] = val; +} + + +void setOpcodeSizes(uint8_t* opcodeSizes) +{ + instruction_metadata_t metadataArray[] = HANDLER_REGISTERS; + + for (size_t i = 0; i < ((opcode_t)~0); i++) + { + opcodeSizes[i] = 0; + } + + + for(size_t i = 0; i < sizeof(metadataArray) / sizeof(instruction_metadata_t); i++) + { + opcode_t start_opcode = metadataArray[i].base; + do + { + opcodeSizes[(start_opcode & metadataArray[i].argsMask) | metadataArray[i].base] = metadataArray[i].opcodeLen; + start_opcode += 1; + } while(start_opcode < (metadataArray[i].base | metadataArray[i].argsMask)); + } +} + + +instr_h_func* genInstrArray(char* errbuf) +{ + + instruction_metadata_t metadataArray[] = HANDLER_REGISTERS; + + instr_h_func* instrArray = calloc(((opcode_t)~0), sizeof(instr_h_func*)); + if (instrArray == NULL) + { + sprintf(errbuf, "Unable to allocate instruction table"); + return NULL; + } + + for (size_t i = 0; i < ((opcode_t)~0); i++) + { + instrArray[i] = &_invalid_opcode; + } + + + for(size_t i = 0; i < sizeof(metadataArray) / sizeof(instruction_metadata_t); i++) + { + setCombinations(metadataArray[i].base, metadataArray[i].argsMask, instrArray, metadataArray[i].h); + } + + return instrArray; +} + + +opcode_t extractOpcode(device_mem_t* devMem, prog_counter_t programCounter) +{ + return ((opcode_t*)devMem->cells[MEMSEG_PS])[programCounter]; +} + +size_t pubExtractOpcode(device_mem_t* devMem, size_t _programCounter) +{ + prog_counter_t programCounter = (prog_counter_t)(_programCounter); + return (size_t)(((opcode_t*)devMem->cells[MEMSEG_PS])[programCounter]); +}