From a4650360a34ea4fceb30f53d97f24ad980001867 Mon Sep 17 00:00:00 2001 From: carl Date: Tue, 19 Feb 2019 00:33:21 +0800 Subject: [PATCH] * Initial support of CMake + Generation of header files is now made through a C program to make it more portable. --- modules/src/em_data/CMakeLists.txt | 43 ++++ modules/src/em_data/makeem.c | 309 +++++++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 modules/src/em_data/CMakeLists.txt create mode 100644 modules/src/em_data/makeem.c diff --git a/modules/src/em_data/CMakeLists.txt b/modules/src/em_data/CMakeLists.txt new file mode 100644 index 000000000..9e5cffe8f --- /dev/null +++ b/modules/src/em_data/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required (VERSION 2.9) +project(em_data) + +set(SRC + em_spec.h + em_pseu.h + em_pseu.c + em_mnem.h + em_mnem.c + em_flag.c + em_ptyp.c +) + +set(INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/../../h + ${CMAKE_CURRENT_SOURCE_DIR}/../../../h +) + + + +add_library(${PROJECT_NAME} ${SRC}) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${INCLUDE_DIRS}) +target_link_libraries(${PROJECT_NAME} emheaders emh) + +add_executable(makeem makeem.c) +target_link_libraries(makeem data) + +add_custom_command( + OUTPUT em_spec.h em_pseu.h em_pseu.c em_mnem.h em_mnem.c em_flag.c + COMMAND makeem ${CMAKE_CURRENT_SOURCE_DIR}/../../../h/em_table + COMMENT "Generating em_data files" + DEPENDS makeem +) + +install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) + + + + diff --git a/modules/src/em_data/makeem.c b/modules/src/em_data/makeem.c new file mode 100644 index 000000000..574724734 --- /dev/null +++ b/modules/src/em_data/makeem.c @@ -0,0 +1,309 @@ +/** A utility to convert the em definition table to generated code. + * This is more portable than the shell scripts that currently + * exist. + * + * This tool should only be called if the em_table is changeed, it creates + * the following files: + * em_spec.h + * em_pseu.h + * em_pseu.c + * em_mnem.h + * em_mnem.c + * em_flag.c + * + * + */ +#include +#include +#include +#include +#include +#include "array.h" + + + +size_t trimwhitespace(char *out, size_t len, const char *str) +{ + if(len == 0) + return 0; + + const char *end; + size_t out_size; + + // Trim leading space + while(isspace((unsigned char)*str)) str++; + + if(*str == 0) // All spaces? + { + *out = 0; + return 1; + } + + // Trim trailing space + end = str + strlen(str) - 1; + while(end > str && isspace((unsigned char)*end)) end--; + end++; + + // Set output size to minimum of trimmed string length and buffer size minus 1 + out_size = (end - str) < len-1 ? (end - str) : len-1; + + // Copy trimmed string and add null terminator + memcpy(out, str, out_size); + out[out_size] = 0; + + return out_size; +} + + +#define BUFFER_SIZE 4096 + +/** This section contains indexes to the different limits as well as important + * constant values */ +#define SECTION_INDEXES 0 +/** This section contains the "opcodes" for the different mnemonics */ +#define SECTION_MNEMONICS SECTION_INDEXES+1 +/** This section contains the "opcodes" for the em machine */ +#define SECTION_OPCODES SECTION_MNEMONICS+1 + + +static char inbuffer[BUFFER_SIZE]; +static char buffer[BUFFER_SIZE]; + +static struct array section_index; +static struct array section_mnemonics; +static struct array section_opcodes; + + + + +/** Separates the string into its separate tokens, + * and fills up the column data structure accordingly. + * + * maxcolumns indicates the maximum number of columns + * allowed in the text file. + * + */ +struct array *newrow(char* buffer, int maxcolumns) +{ + char* pch = NULL; + int i = 0; + int count = 0; + struct array *columns = NULL; + + columns = calloc(1,sizeof(struct array)); + if (columns == NULL) + { + fprintf(stderr,"Cannot allocate memory.\n"); + exit(EXIT_FAILURE); + } + + + pch = strtok (buffer,"\t "); + if (pch == NULL) + { + fprintf(stderr,"Expecting %d columns for indexes.\n",maxcolumns); + exit(EXIT_FAILURE); + } + array_append(columns,strdup(pch)); + count++; + for (i = count; i < maxcolumns; i++) + { + pch = strtok (NULL, "\t "); + if (pch == NULL) + { + fprintf(stderr,"Expecting %d columns for indexes.\n",maxcolumns); + exit(EXIT_FAILURE); + + } + count++; + array_append(columns,strdup(pch)); + } + return columns; +} + + +void disposerow(struct array *row) +{ + int i = 0; + char* str; + for (i = 0; i < row->count; i++) + { + str = (char*)row->item[i]; + free(str); + row->item[i] = NULL; + } + free(row); +} + + + + +/** Copies a null terminated string, + * but allocates the memory. + * + */ +char* strdup(const char* s) +{ + int length = strlen(s)+1; + char* ptr = malloc(length); + memcpy(ptr, s, length); + return ptr; +} + + +int main(int argc, char *argv[]) +{ + int i = 0; + struct array *columns; + int value; + char *str; + + char c1; + char c2; + FILE* hfile; + FILE* cfile; + char str1[3] = {0,0,0}; + char str2[3] = {0,0,0}; + /** First opcode value, -1 is invalid. */ + int fmnem = -1; + /** First pseudocode value, -1 is invalid. */ + int fpseu = -1; + if (argc != 2) + { + fprintf(stdout,"Requires em_table file and pathname\n"); + return EXIT_FAILURE; + } + + FILE *fd = fopen(argv[1],"r"); + int section = SECTION_INDEXES; + fprintf(stdout,"Opening : %s\n",argv[1]); + if (fd == NULL) + { + fprintf(stderr,"Cannot find file.\n"); + return EXIT_FAILURE; + } + while (fgets(inbuffer,BUFFER_SIZE,fd)!=NULL) + { + /* First section, opcode limits. */ + trimwhitespace(buffer,BUFFER_SIZE,inbuffer); + /** Next section */ + if (strlen(buffer)==0) + { + section++; + continue; + } + + + if (section == SECTION_INDEXES) + { + /* Split the row text into columns. */ + columns = newrow(buffer, 2); + array_append(§ion_index, columns); + } + else + if (section == SECTION_MNEMONICS) + { + columns = newrow(buffer, 3); + array_append(§ion_mnemonics, columns); + } else + if (section == SECTION_OPCODES) + { + columns = newrow(buffer, 3); + array_append(§ion_opcodes, columns); + } + } + fclose(fd); + + /* process the indexes */ + hfile = fopen("em_spec.h","w"); + for (i = 0; i < section_index.count; i++) + { + columns = (struct array*)section_index.item[i]; + str = columns->item[0]; + if (strcmp("fpseu",columns->item[0])==0) + { + fpseu = atoi(columns->item[1]); + + } + if (strcmp("fmnem",columns->item[0])==0) + { + fmnem = atoi(columns->item[1]); + + } + fprintf(hfile,"#define sp_%s\t %s\n",columns->item[0],columns->item[1]); + } + fprintf(hfile,"#define sp_lpseu\t% d\n",fpseu+section_mnemonics.count - 1); + fprintf(hfile,"#define sp_lmnem\t %d\n",fmnem+section_opcodes.count - 1); + fclose(hfile); + + + /** Check validity of first indexes. */ + if ((fpseu == -1) || (fmnem == -1)) + { + fprintf(stderr,"Error fpseu or fmnem first index values are not defined.\n"); + exit(EXIT_FAILURE); + } + + /* process the pseudocodes */ + hfile = fopen("em_pseu.h","w"); + cfile = fopen("em_pseu.c","w"); + fprintf(cfile,"char em_pseu[][4] = {\n"); + for (i = 0; i < section_mnemonics.count; i++) + { + columns = (struct array*)section_mnemonics.item[i]; + str = columns->item[1]; + value = atoi(str); + fprintf(hfile,"#define ps_%s\t%d\n",columns->item[0],value+fpseu); + fprintf(cfile," \"%s\",\n",columns->item[0]); + } + fprintf(cfile,"};\n"); + fclose(hfile); + fclose(cfile); + + /* process the opcodes */ + hfile = fopen("em_mnem.h","w"); + cfile = fopen("em_mnem.c","w"); + fprintf(cfile,"char em_mnem[][4] = {\n"); + for (i = 0; i < section_opcodes.count; i++) + { + columns = (struct array*)section_opcodes.item[i]; + fprintf(hfile,"#define op_%s\t%d\n",columns->item[0],i+fmnem); + fprintf(cfile," \"%s\",\n",columns->item[0]); + } + fprintf(cfile,"};\n"); + fclose(hfile); + fclose(cfile); + + /* Create the flag files from opcodes */ + cfile = fopen("em_flag.c","w"); + fprintf(cfile,"#include \"em_flag.h\"\n"); + fprintf(cfile,"char em_flag[] = {\n"); + for (i = 0; i < section_opcodes.count; i++) + { + columns = (struct array*)section_opcodes.item[i]; + /* 2nd column indicate the parameter format, always on 2 columns. */ + if (strlen(columns->item[1])!=2) + { + fprintf(stderr,"Error opcode type characterstic should be on 2 characters.\n"); + exit(EXIT_FAILURE); + } + str = (char*)columns->item[1]; + c1 = toupper(str[0]); + c2 = toupper(str[1]); + str1[0] = c1; + str1[1] = '\0'; + str2[0] = c2; + str2[1] = '\0'; + if (c1 == '-') + strcpy(str1,"NO"); + if (c2 == '-') + strcpy(str2,"NO"); + fprintf(cfile, "PAR_%s | FLO_%s,\n",str1,str2); + } + fprintf(cfile,"};\n"); + fclose(cfile); + + + return EXIT_SUCCESS; + +} -- 2.34.1