From b57f21556a7e8a19e3900948284e04e0dbb99aa8 Mon Sep 17 00:00:00 2001 From: ZZY <2450266535@qq.com> Date: Tue, 1 Apr 2025 23:27:25 +0800 Subject: [PATCH] =?UTF-8?q?stable=20=E9=87=8D=E6=9E=84=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 抽象出Machine Code --- .gitignore | 2 + assembler/riscv32/riscv32.h | 30 ---- linker/Makefile | 21 --- linker/header.h | 6 - src/Makefile | 30 ++++ src/assembler/assembler.c | 144 ++++++++++++++++++ src/assembler/assembler.h | 18 +++ {assembler => src/assembler}/riscv32/Makefile | 2 +- .../assembler/riscv32/parse.c | 0 src/assembler/riscv32/riscv32_asm.c | 15 ++ src/assembler/riscv32/riscv32_asm.h | 18 +++ .../assembler}/riscv32/symtab_asm.c | 8 + .../assembler}/riscv32/symtab_asm.h | 0 src/assembler/riscv32/test.asm.s | 62 ++++++++ .../ir/ir.c => src/assembler/syscall.h | 0 {ccompiler => src/ccompiler}/Makefile | 12 +- {ccompiler => src/ccompiler}/backend/Makefile | 0 .../ccompiler}/backend/backend.c | 0 .../ccompiler}/backend/backend.h | 2 +- .../ccompiler}/backend/riscv32/README.md | 0 .../ccompiler}/backend/riscv32/riscv32.c | 25 +-- .../ccompiler}/backend/riscv32/riscv32.h | 3 +- {ccompiler => src/ccompiler}/ccompiler.c | 0 {ccompiler => src/ccompiler}/ccompiler.h | 0 .../ccompiler}/frontend/Makefile | 0 .../ccompiler}/frontend/frontend.c | 0 .../ccompiler}/frontend/frontend.h | 0 .../ccompiler}/frontend/lexer/README.md | 0 .../ccompiler}/frontend/lexer/lexer.c | 0 .../ccompiler}/frontend/lexer/lexer.h | 0 .../ccompiler}/frontend/lexer/lexer_log.h | 0 .../ccompiler}/frontend/lexer/token.c | 0 .../ccompiler}/frontend/lexer/token.h | 0 .../ccompiler/frontend/parser/ast-gdb.py | 0 .../ccompiler}/frontend/parser/ast.c | 0 .../ccompiler}/frontend/parser/ast.h | 3 +- .../ccompiler}/frontend/parser/ast/README.md | 0 .../ccompiler}/frontend/parser/ast/block.c | 0 .../ccompiler}/frontend/parser/ast/decl.c | 0 .../ccompiler}/frontend/parser/ast/expr.c | 0 .../ccompiler}/frontend/parser/ast/func.c | 0 .../ccompiler}/frontend/parser/ast/program.c | 0 .../ccompiler}/frontend/parser/ast/stmt.c | 0 .../ccompiler}/frontend/parser/ast/term.c | 0 .../ccompiler}/frontend/parser/ast/type.c | 0 .../ccompiler}/frontend/parser/parser.c | 0 .../ccompiler}/frontend/parser/parser.h | 2 +- src/ccompiler/frontend/parser/symtab/symtab.c | 62 ++++++++ src/ccompiler/frontend/parser/symtab/symtab.h | 39 +++++ .../ccompiler}/frontend/parser/type.h | 0 .../ccompiler}/middleend/Makefile | 0 src/ccompiler/middleend/ir/ir.c | 0 .../ccompiler}/middleend/ir/ir.h | 0 .../ccompiler}/middleend/ir/ir_ast.c | 0 .../ccompiler}/middleend/ir/ir_ast.h | 0 .../ccompiler}/middleend/ir/ir_dump.c | 0 .../ccompiler}/middleend/ir/ir_lib.c | 0 .../ccompiler}/middleend/ir/ir_lib.h | 0 .../ccompiler}/middleend/ir/ir_type.c | 0 .../ccompiler}/middleend/ir/ir_type.h | 0 .../ccompiler}/middleend/middleend.c | 0 .../ccompiler}/middleend/middleend.h | 0 src/ccompiler/middleend/reg_alloc.c | 0 .../ccompiler}/middleend/reg_alloc.h | 0 src/linker/Makefile | 17 +++ src/linker/header.h | 10 ++ {linker => src/linker}/riscv32_crt.c | 10 +- {linker => src/linker}/riscv32_linker.c | 30 ++-- src/mcode/Makefile | 17 +++ .../mcode}/riscv32/riscv32_def.h | 0 .../mcode}/riscv32/riscv32_instr.h | 117 +++++++------- .../mcode/riscv32/riscv32_mcode.c | 123 +++++---------- src/mcode/riscv32/riscv32_mcode.h | 23 +++ src/pprocesser/main.c | 0 linker/test_main.c => src/smcc.c | 14 +- src/test.c | 52 +++++++ 76 files changed, 657 insertions(+), 260 deletions(-) delete mode 100644 assembler/riscv32/riscv32.h delete mode 100644 linker/Makefile delete mode 100644 linker/header.h create mode 100644 src/Makefile create mode 100644 src/assembler/assembler.c create mode 100644 src/assembler/assembler.h rename {assembler => src/assembler}/riscv32/Makefile (89%) rename ccompiler/frontend/parser/ast-gdb.py => src/assembler/riscv32/parse.c (100%) create mode 100644 src/assembler/riscv32/riscv32_asm.c create mode 100644 src/assembler/riscv32/riscv32_asm.h rename {assembler => src/assembler}/riscv32/symtab_asm.c (85%) rename {assembler => src/assembler}/riscv32/symtab_asm.h (100%) create mode 100644 src/assembler/riscv32/test.asm.s rename ccompiler/middleend/ir/ir.c => src/assembler/syscall.h (100%) rename {ccompiler => src/ccompiler}/Makefile (78%) rename {ccompiler => src/ccompiler}/backend/Makefile (100%) rename {ccompiler => src/ccompiler}/backend/backend.c (100%) rename {ccompiler => src/ccompiler}/backend/backend.h (94%) rename {ccompiler => src/ccompiler}/backend/riscv32/README.md (100%) rename {ccompiler => src/ccompiler}/backend/riscv32/riscv32.c (91%) rename {ccompiler => src/ccompiler}/backend/riscv32/riscv32.h (69%) rename {ccompiler => src/ccompiler}/ccompiler.c (100%) rename {ccompiler => src/ccompiler}/ccompiler.h (100%) rename {ccompiler => src/ccompiler}/frontend/Makefile (100%) rename {ccompiler => src/ccompiler}/frontend/frontend.c (100%) rename {ccompiler => src/ccompiler}/frontend/frontend.h (100%) rename {ccompiler => src/ccompiler}/frontend/lexer/README.md (100%) rename {ccompiler => src/ccompiler}/frontend/lexer/lexer.c (100%) rename {ccompiler => src/ccompiler}/frontend/lexer/lexer.h (100%) rename {ccompiler => src/ccompiler}/frontend/lexer/lexer_log.h (100%) rename {ccompiler => src/ccompiler}/frontend/lexer/token.c (100%) rename {ccompiler => src/ccompiler}/frontend/lexer/token.h (100%) rename ccompiler/middleend/reg_alloc.c => src/ccompiler/frontend/parser/ast-gdb.py (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast.h (99%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/README.md (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/block.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/decl.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/expr.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/func.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/program.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/stmt.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/term.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/ast/type.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/parser.c (100%) rename {ccompiler => src/ccompiler}/frontend/parser/parser.h (92%) create mode 100644 src/ccompiler/frontend/parser/symtab/symtab.c create mode 100644 src/ccompiler/frontend/parser/symtab/symtab.h rename {ccompiler => src/ccompiler}/frontend/parser/type.h (100%) rename {ccompiler => src/ccompiler}/middleend/Makefile (100%) create mode 100644 src/ccompiler/middleend/ir/ir.c rename {ccompiler => src/ccompiler}/middleend/ir/ir.h (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_ast.c (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_ast.h (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_dump.c (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_lib.c (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_lib.h (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_type.c (100%) rename {ccompiler => src/ccompiler}/middleend/ir/ir_type.h (100%) rename {ccompiler => src/ccompiler}/middleend/middleend.c (100%) rename {ccompiler => src/ccompiler}/middleend/middleend.h (100%) create mode 100644 src/ccompiler/middleend/reg_alloc.c rename {ccompiler => src/ccompiler}/middleend/reg_alloc.h (100%) create mode 100644 src/linker/Makefile create mode 100644 src/linker/header.h rename {linker => src/linker}/riscv32_crt.c (59%) rename {linker => src/linker}/riscv32_linker.c (61%) create mode 100644 src/mcode/Makefile rename {assembler => src/mcode}/riscv32/riscv32_def.h (100%) rename {assembler => src/mcode}/riscv32/riscv32_instr.h (80%) rename assembler/riscv32/riscv32.c => src/mcode/riscv32/riscv32_mcode.c (66%) create mode 100644 src/mcode/riscv32/riscv32_mcode.h create mode 100644 src/pprocesser/main.c rename linker/test_main.c => src/smcc.c (75%) create mode 100644 src/test.c diff --git a/.gitignore b/.gitignore index 9ce61d9..fd8fa09 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ # smcc compiler generated files *.bin +.s +.asm # linux binary files *.o diff --git a/assembler/riscv32/riscv32.h b/assembler/riscv32/riscv32.h deleted file mode 100644 index 5920550..0000000 --- a/assembler/riscv32/riscv32.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __SMCC_ASM_RISCV32_H__ -#define __SMCC_ASM_RISCV32_H__ - -#include -#include -#include -#include "riscv32_def.h" -#include "symtab_asm.h" - -typedef struct rotated_instr { - u32_t address; - symasm_entry_t target; - rv32_instr_t instr; -} rotated_instr_t; - -typedef struct rv32_prog { - strpool_t* strpool; - symtab_asm_t symtab; - u32_t text_base_address; - vector_header(text, u32_t); - u32_t data_base_address; - vector_header(data, iptr_t); - vector_header(rinstrs, rotated_instr_t); -} rv32_prog_t; - -void init_rv32_prog(rv32_prog_t* prog, strpool_t* strpool); -int emit_rv32_instr(rv32_prog_t* prog, rv32_instr_t *instr, u32_t idx, symasm_entry_t *target); -// int gen_rv32_instr(rv32_prog_t* prog); - -#endif diff --git a/linker/Makefile b/linker/Makefile deleted file mode 100644 index 49f6dee..0000000 --- a/linker/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -CC = gcc -CFLAGS = -g -Wall -I.. -# CLFAGS += -fsanitize=address - -all: smcc -smcc: cc asm lib - $(CC) $(CFLAGS) riscv32_crt.c riscv32_linker.c test_main.c -L../assembler/riscv32 -lasm -L../ccompiler -lcc -L../lib -lcore -o smcc - -lib: - make -C ../lib - -asm: - make -C ../assembler/riscv32 - -cc: - make -C ../ccompiler - -clean: - make -C ../lib clean - make -C ../assembler/riscv32 clean - make -C ../ccompiler clean \ No newline at end of file diff --git a/linker/header.h b/linker/header.h deleted file mode 100644 index b98e477..0000000 --- a/linker/header.h +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include -#include - -rv32_prog_t* gen_rv32_crt(); -rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]); \ No newline at end of file diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..9aa4ba1 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,30 @@ +CC = gcc +CFLAGS = -g -Wall -I.. +LIBS = -Lccompiler -lcc -Lassembler/riscv32 -lasm -Llinker -llk -Lmcode -lmc -L../lib -lcore +# CLFAGS += -fsanitize=address + +all: smcc +smcc: cc asm lib mc lk + $(CC) $(CFLAGS) smcc.c $(LIBS) -o smcc + +lib: + make -C ../lib + +asm: + make -C assembler/riscv32 + +mc: + make -C mcode + +cc: + make -C ccompiler + +lk: + make -C linker + +clean: + make -C ../lib clean + make -C assembler/riscv32 clean + make -C ccompiler clean + make -C mcode clean + make -C linker clean \ No newline at end of file diff --git a/src/assembler/assembler.c b/src/assembler/assembler.c new file mode 100644 index 0000000..6712458 --- /dev/null +++ b/src/assembler/assembler.c @@ -0,0 +1,144 @@ + +#include +#include +#include + +enum asm_symbol_type{ + DATA_BYTE, + DATA_WORD, + DATA_HALFWORD, + DATA_DOUBLEWORD, + DATA_STRING, + DATA_SYMBLE, + TEXT_LABEL, + UNKNOWN, +}; + +struct asm_symbol_table { + const char* name; + enum asm_symbol_type type; + union { + long long data_doubleword; + long data_word; + short data_halfword; + char data_byte; + char* data_string; + } data; +}; + +static const char comments[] = { + '#', +}; + +static inline int is_blank(char ch) { + return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\v' || ch == '\f' || ch == '\r'; +} + +void parse_line_without_blank(const char* in, const char** out_start, const char** out_end) { + while (*in == '\0' || is_blank(*in)) { + in ++; + } + *out_start = in; + while (*in != '\0') { + if (*in == '\r' || *in == '\n') { + break; + } + for (int i = 0; i < sizeof(comments); i ++) { + if (*in == comments[i]) { + break; + } + } + in ++; + } + + if (*out_end == *out_start) { + goto END; + } + + while (is_blank(*in)) { + in --; + } + +END: + *out_end = in; + return; +} + +void parse_data_symbol(const char* start, const char* end, struct asm_symbol_table* table) { + table->name = start; + while(start < end) { + if (*start == ':') { + + } + } + table->type = UNKNOWN; +} + +#define TMP_BUFF_SIZE 1024 + +enum parse_state { + IN_DATA, + IN_TEXT, + IN_UNKNOWN, +}; +void get_symbol_table(FILE* in) { + enum parse_state state = IN_UNKNOWN; + fseek(in, 0, SEEK_SET); + char buf[TMP_BUFF_SIZE]; + + int current_line = 0; + while (1) { + current_line ++; + char *start = fgets(buf, sizeof(buf), in); + if (start == NULL) { + return; + } + char *end; + parse_line_without_blank(buf, &start, &end); + + if (start == end) { + continue; + } + + if (start[0] == '.') { + // .data .text and so on + if (strcmp(start, ".data") == 0) { + state = IN_DATA; + } else if (strcmp(start, ".text") == 0) { + state = IN_TEXT; + } else { + printf("unknown directive at line %d\n", current_line); + state = IN_UNKNOWN; + } + continue; + } + + switch (state) { + case IN_DATA: + parse_data_symbol(start, end); + break; + case IN_TEXT: + break; + case IN_UNKNOWN: + break; + } + } + +} + +void assembler(FILE* in, FILE* out, char *start_symble) { + char buf[TMP_BUFF_SIZE]; + + char *res = fgets(buf, sizeof(buf), in); + if (res == NULL) { + return; + } + + if (res[0] == '.') { + // maybe .data .text and so on + } else if (res[0] == ' ') { + + } + + +} diff --git a/src/assembler/assembler.h b/src/assembler/assembler.h new file mode 100644 index 0000000..a309207 --- /dev/null +++ b/src/assembler/assembler.h @@ -0,0 +1,18 @@ +#ifndef __SMCC_ASM_H__ +#define __SMCC_ASM_H__ +// typedef unsigned long long rt_size_t; +// extern void* _syscall_fopen (const char* path); +// extern int _syscall_fread (void* handle, char* buf, rt_size_t size); +// extern int _syscall_fwrite (void* handle, const char* buf, rt_size_t size); +// extern void _syscall_fseek (void* handle, long offset); + + +#include + +#include "riscv32/riscv32_asm.h" +#include "riscv32/riscv32_asm.h" +typedef union asm_prog { + rv32_prog_t rv32; +} asm_prog_t; + +#endif diff --git a/assembler/riscv32/Makefile b/src/assembler/riscv32/Makefile similarity index 89% rename from assembler/riscv32/Makefile rename to src/assembler/riscv32/Makefile index d83f471..052074f 100644 --- a/assembler/riscv32/Makefile +++ b/src/assembler/riscv32/Makefile @@ -1,6 +1,6 @@ CC = gcc AR = ar -CFLAGS = -g -Wall -I../.. +CFLAGS = -g -Wall -I../../.. # 自动收集所有子模块源文件 EXCLUDE = test*.c diff --git a/ccompiler/frontend/parser/ast-gdb.py b/src/assembler/riscv32/parse.c similarity index 100% rename from ccompiler/frontend/parser/ast-gdb.py rename to src/assembler/riscv32/parse.c diff --git a/src/assembler/riscv32/riscv32_asm.c b/src/assembler/riscv32/riscv32_asm.c new file mode 100644 index 0000000..658e165 --- /dev/null +++ b/src/assembler/riscv32/riscv32_asm.c @@ -0,0 +1,15 @@ +#include "riscv32_asm.h" + +void init_rv32_prog(rv32_prog_t* prog, strpool_t* strpool) { + if (strpool == NULL) { + prog->strpool = salloc_alloc(sizeof(strpool_t)); + init_strpool(prog->strpool); + } else { + prog->strpool = strpool; + } + prog->data_base_address = 0; + vector_init(prog->data); + prog->text_base_address = 0; + init_symtab_asm(&prog->symtab); + init_rv32_mcode(&prog->mcode, sizeof(symasm_entry_t)); +} diff --git a/src/assembler/riscv32/riscv32_asm.h b/src/assembler/riscv32/riscv32_asm.h new file mode 100644 index 0000000..d1507f2 --- /dev/null +++ b/src/assembler/riscv32/riscv32_asm.h @@ -0,0 +1,18 @@ +#ifndef __SMCC_RISCV32_ASM_H__ +#define __SMCC_RISCV32_ASM_H__ + +#include +#include +#include "symtab_asm.h" +typedef struct rv32_prog { + strpool_t* strpool; + symtab_asm_t symtab; + u32_t text_base_address; + u32_t data_base_address; + vector_header(data, iptr_t); + mcode_rv32_t mcode; +} rv32_prog_t; + +void init_rv32_prog(rv32_prog_t* prog, strpool_t* strpool); + +#endif diff --git a/assembler/riscv32/symtab_asm.c b/src/assembler/riscv32/symtab_asm.c similarity index 85% rename from assembler/riscv32/symtab_asm.c rename to src/assembler/riscv32/symtab_asm.c index ea117a4..0d7ecb1 100644 --- a/assembler/riscv32/symtab_asm.c +++ b/src/assembler/riscv32/symtab_asm.c @@ -1,5 +1,13 @@ #include "symtab_asm.h" +// /* append label */ +// static inline int +// rv32_append_label(mcode_rv32_t* prog, void* label, u32_t offset) { +// // prog->symtab +// symtab_asm_put(&prog->symtab, label, offset); +// return 0; +// } + static u32_t hash_func(const symasm_entry_t* key) { return rt_strhash(key->name); } diff --git a/assembler/riscv32/symtab_asm.h b/src/assembler/riscv32/symtab_asm.h similarity index 100% rename from assembler/riscv32/symtab_asm.h rename to src/assembler/riscv32/symtab_asm.h diff --git a/src/assembler/riscv32/test.asm.s b/src/assembler/riscv32/test.asm.s new file mode 100644 index 0000000..cb46a3d --- /dev/null +++ b/src/assembler/riscv32/test.asm.s @@ -0,0 +1,62 @@ +# This example shows an implementation of the mathematical +# factorial function (! function) to find the factorial value of !7 = 5040. + +.data +argument: .word 7 +str1: .string "Factorial value of " +str2: .string " is " + +.text +main: + lw a0, argument # Load argument from static data + jal ra, fact # Jump-and-link to the 'fact' label + + # Print the result to console + mv a1, a0 + lw a0, argument + jal ra, printResult + + # Exit program + li a7, 10 + ecall + +fact: + addi sp, sp, -16 + sw ra, 8(sp) + sw a0, 0(sp) + addi t0, a0, -1 + bge t0, zero, nfact + + addi a0, zero, 1 + addi sp, sp, 16 + jr x1 + +nfact: + addi a0, a0, -1 + jal ra, fact + addi t1, a0, 0 + lw a0, 0(sp) + lw ra, 8(sp) + addi sp, sp, 16 + mul a0, a0, t1 + ret + +# --- printResult --- +# a0: Value which factorial number was computed from +# a1: Factorial result +printResult: + mv t0, a0 + mv t1, a1 + la a0, str1 + li a7, 4 + ecall + mv a0, t0 + li a7, 1 + ecall + la a0, str2 + li a7, 4 + ecall + mv a0, t1 + li a7, 1 + ecall + ret diff --git a/ccompiler/middleend/ir/ir.c b/src/assembler/syscall.h similarity index 100% rename from ccompiler/middleend/ir/ir.c rename to src/assembler/syscall.h diff --git a/ccompiler/Makefile b/src/ccompiler/Makefile similarity index 78% rename from ccompiler/Makefile rename to src/ccompiler/Makefile index 6fdab56..f25747c 100644 --- a/ccompiler/Makefile +++ b/src/ccompiler/Makefile @@ -28,17 +28,17 @@ # 顶层Makefile修改 CC = gcc AR = ar -CFLAGS = -g -Wall -I.. +CFLAGS = -g -Wall -I.. -I../.. MODULES = frontend middleend backend -FRONTEND_SUBDIRS = lexer parser parser/ast +FRONTEND_SUBDIRS = lexer parser parser/ast parser/symtab MODULES += $(addprefix frontend/, $(FRONTEND_SUBDIRS)) -MIDDLEEND_MODULES = ir -MODULES += middleend/$(MIDDLEEND_MODULES) +MIDDLEEND_SUBDIRS = ir +MODULES += $(addprefix middleend/, $(MIDDLEEND_SUBDIRS)) -BACKEND_MODULES = riscv32 -MODULES += backend/$(BACKEND_MODULES) +BACKEND_SUBDIRS = riscv32 +MODULES += $(addprefix backend/, $(BACKEND_SUBDIRS)) # 自动收集所有子模块源文件 EXCLUDE = test*.c diff --git a/ccompiler/backend/Makefile b/src/ccompiler/backend/Makefile similarity index 100% rename from ccompiler/backend/Makefile rename to src/ccompiler/backend/Makefile diff --git a/ccompiler/backend/backend.c b/src/ccompiler/backend/backend.c similarity index 100% rename from ccompiler/backend/backend.c rename to src/ccompiler/backend/backend.c diff --git a/ccompiler/backend/backend.h b/src/ccompiler/backend/backend.h similarity index 94% rename from ccompiler/backend/backend.h rename to src/ccompiler/backend/backend.h index 83990fc..66c1441 100644 --- a/ccompiler/backend/backend.h +++ b/src/ccompiler/backend/backend.h @@ -11,7 +11,7 @@ // #endif // TODO 统一 汇编器 接口 -#include +#include #include "../middleend/ir/ir.h" typedef enum cc_arch { CC_ARCH_RISCV32, diff --git a/ccompiler/backend/riscv32/README.md b/src/ccompiler/backend/riscv32/README.md similarity index 100% rename from ccompiler/backend/riscv32/README.md rename to src/ccompiler/backend/riscv32/README.md diff --git a/ccompiler/backend/riscv32/riscv32.c b/src/ccompiler/backend/riscv32/riscv32.c similarity index 91% rename from ccompiler/backend/riscv32/riscv32.c rename to src/ccompiler/backend/riscv32/riscv32.c index 32355d7..56d3c5b 100644 --- a/ccompiler/backend/riscv32/riscv32.c +++ b/src/ccompiler/backend/riscv32/riscv32.c @@ -1,5 +1,5 @@ #include "riscv32.h" -#include +#include typedef struct { ir_func_t* func; @@ -45,7 +45,7 @@ static int system_func(const char* name) { return -1; } -static int get_node_val(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_node_t* ptr, int reg) { +static int get_node_val(mcode_rv32_t* out_asm, gen_ctx_t* ctx, ir_node_t* ptr, int reg) { int len = 0; switch (ptr->tag) { case IR_NODE_CONST_INT: { @@ -63,7 +63,8 @@ static int get_node_val(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_node_t* ptr, in return len; } -static int gen_instr(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_node_t* instr) { +static int gen_instr(rv32_prog_t* _out_asm, gen_ctx_t* ctx, ir_node_t* instr) { + mcode_rv32_t* out_asm = &_out_asm->mcode; int idx = 0; int offset; char buf[1024]; @@ -164,12 +165,12 @@ static int gen_instr(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_node_t* instr) { get_node_val(out_asm, ctx, instr->data.branch.cond, REG_T0); rt.snprintf(buf, sizeof(buf), "L%s%p", instr->data.branch.true_bblock->label, instr->data.branch.true_bblock); - label.name = strpool_intern(out_asm->strpool, buf); + label.name = strpool_intern(_out_asm->strpool, buf); label.attr = LOCAL; rv32_bne_l(out_asm, REG_T0, REG_X0, &label); rt.snprintf(buf, sizeof(buf), "L%s%p", instr->data.branch.false_bblock->label, instr->data.branch.false_bblock); - label.name = strpool_intern(out_asm->strpool, buf); + label.name = strpool_intern(_out_asm->strpool, buf); label.attr = LOCAL; rv32_jal_l(out_asm, REG_X0, &label); break; @@ -177,7 +178,7 @@ static int gen_instr(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_node_t* instr) { case IR_NODE_JUMP: { // TODO rt.snprintf(buf, sizeof(buf), "L%s%p", instr->data.jump.target_bblock->label, instr->data.jump.target_bblock); - label.name = strpool_intern(out_asm->strpool, buf); + label.name = strpool_intern(_out_asm->strpool, buf); label.attr = LOCAL; rv32_jal_l(out_asm, REG_X0, &label); break; @@ -208,7 +209,7 @@ static int gen_instr(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_node_t* instr) { // JALR(REG_X1, REG_X1, offset) */ // TODO CALL - label.name = strpool_intern(out_asm->strpool, instr->data.call.callee->name); + label.name = strpool_intern(_out_asm->strpool, instr->data.call.callee->name); label.attr = GLOBAL; rv32_call_l(out_asm, &label); CALL_END: @@ -228,7 +229,7 @@ static int gen_block(rv32_prog_t* out_asm, gen_ctx_t* ctx, ir_bblock_t* block) { rt.snprintf(buf, sizeof(buf), "L%s%p", block->label, block); label.name = strpool_intern(out_asm->strpool, buf); label.attr = LOCAL; - rv32_append_label(out_asm, &label, out_asm->text.size); + symtab_asm_put(&out_asm->symtab, &label, out_asm->mcode.code.size); for (int i = 0; i < block->instrs.size; i ++) { gen_instr(out_asm, ctx, vector_at(block->instrs, i)); @@ -243,7 +244,7 @@ static int gen_func(rv32_prog_t* out_asm, ir_func_t* func) { .name = strpool_intern(out_asm->strpool, func->name), .attr = GLOBAL, }; - rv32_append_label(out_asm, &label, out_asm->text.size); + symtab_asm_put(&out_asm->symtab, &label, out_asm->mcode.code.size); int stack_base = 4; int stack_offset = stack_base; @@ -259,9 +260,9 @@ static int gen_func(rv32_prog_t* out_asm, ir_func_t* func) { // TODO Alignment by 16 // sp = sp - stack_offset; - rv32_addi(out_asm, REG_SP, REG_SP, -stack_offset); + rv32_addi(&out_asm->mcode, REG_SP, REG_SP, -stack_offset); // M[sp] = ra; - rv32_sw(out_asm, REG_RA, REG_SP, 0); + rv32_sw(&out_asm->mcode, REG_RA, REG_SP, 0); int param_regs[8] = { REG_A0, REG_A1, REG_A2, REG_A3, @@ -273,7 +274,7 @@ static int gen_func(rv32_prog_t* out_asm, ir_func_t* func) { for (int i = 0; i < func->params.size; i++) { int offset = stack_pos(vector_at(func->params, i), &ctx); // M[sp + offset] = param[idx]; - rv32_sw(out_asm, param_regs[i], REG_SP, offset); + rv32_sw(&out_asm->mcode, param_regs[i], REG_SP, offset); } for(int i = 0; i < func->bblocks.size; i ++) { diff --git a/ccompiler/backend/riscv32/riscv32.h b/src/ccompiler/backend/riscv32/riscv32.h similarity index 69% rename from ccompiler/backend/riscv32/riscv32.h rename to src/ccompiler/backend/riscv32/riscv32.h index 44931eb..ff85207 100644 --- a/ccompiler/backend/riscv32/riscv32.h +++ b/src/ccompiler/backend/riscv32/riscv32.h @@ -1,8 +1,7 @@ #ifndef __SMCC_CC_RISCV32_H__ #define __SMCC_CC_RISCV32_H__ -#include -#include +#include #include "../../middleend/ir/ir.h" int gen_rv32_from_ir(ir_prog_t* ir, rv32_prog_t* out_asm); diff --git a/ccompiler/ccompiler.c b/src/ccompiler/ccompiler.c similarity index 100% rename from ccompiler/ccompiler.c rename to src/ccompiler/ccompiler.c diff --git a/ccompiler/ccompiler.h b/src/ccompiler/ccompiler.h similarity index 100% rename from ccompiler/ccompiler.h rename to src/ccompiler/ccompiler.h diff --git a/ccompiler/frontend/Makefile b/src/ccompiler/frontend/Makefile similarity index 100% rename from ccompiler/frontend/Makefile rename to src/ccompiler/frontend/Makefile diff --git a/ccompiler/frontend/frontend.c b/src/ccompiler/frontend/frontend.c similarity index 100% rename from ccompiler/frontend/frontend.c rename to src/ccompiler/frontend/frontend.c diff --git a/ccompiler/frontend/frontend.h b/src/ccompiler/frontend/frontend.h similarity index 100% rename from ccompiler/frontend/frontend.h rename to src/ccompiler/frontend/frontend.h diff --git a/ccompiler/frontend/lexer/README.md b/src/ccompiler/frontend/lexer/README.md similarity index 100% rename from ccompiler/frontend/lexer/README.md rename to src/ccompiler/frontend/lexer/README.md diff --git a/ccompiler/frontend/lexer/lexer.c b/src/ccompiler/frontend/lexer/lexer.c similarity index 100% rename from ccompiler/frontend/lexer/lexer.c rename to src/ccompiler/frontend/lexer/lexer.c diff --git a/ccompiler/frontend/lexer/lexer.h b/src/ccompiler/frontend/lexer/lexer.h similarity index 100% rename from ccompiler/frontend/lexer/lexer.h rename to src/ccompiler/frontend/lexer/lexer.h diff --git a/ccompiler/frontend/lexer/lexer_log.h b/src/ccompiler/frontend/lexer/lexer_log.h similarity index 100% rename from ccompiler/frontend/lexer/lexer_log.h rename to src/ccompiler/frontend/lexer/lexer_log.h diff --git a/ccompiler/frontend/lexer/token.c b/src/ccompiler/frontend/lexer/token.c similarity index 100% rename from ccompiler/frontend/lexer/token.c rename to src/ccompiler/frontend/lexer/token.c diff --git a/ccompiler/frontend/lexer/token.h b/src/ccompiler/frontend/lexer/token.h similarity index 100% rename from ccompiler/frontend/lexer/token.h rename to src/ccompiler/frontend/lexer/token.h diff --git a/ccompiler/middleend/reg_alloc.c b/src/ccompiler/frontend/parser/ast-gdb.py similarity index 100% rename from ccompiler/middleend/reg_alloc.c rename to src/ccompiler/frontend/parser/ast-gdb.py diff --git a/ccompiler/frontend/parser/ast.c b/src/ccompiler/frontend/parser/ast.c similarity index 100% rename from ccompiler/frontend/parser/ast.c rename to src/ccompiler/frontend/parser/ast.c diff --git a/ccompiler/frontend/parser/ast.h b/src/ccompiler/frontend/parser/ast.h similarity index 99% rename from ccompiler/frontend/parser/ast.h rename to src/ccompiler/frontend/parser/ast.h index 0cbe93f..ad254be 100644 --- a/ccompiler/frontend/parser/ast.h +++ b/src/ccompiler/frontend/parser/ast.h @@ -1,8 +1,9 @@ #ifndef __AST_H__ #define __AST_H__ -#include #include "../lexer/lexer.h" +#include +#include "symtab/symtab.h" #include "type.h" typedef enum { diff --git a/ccompiler/frontend/parser/ast/README.md b/src/ccompiler/frontend/parser/ast/README.md similarity index 100% rename from ccompiler/frontend/parser/ast/README.md rename to src/ccompiler/frontend/parser/ast/README.md diff --git a/ccompiler/frontend/parser/ast/block.c b/src/ccompiler/frontend/parser/ast/block.c similarity index 100% rename from ccompiler/frontend/parser/ast/block.c rename to src/ccompiler/frontend/parser/ast/block.c diff --git a/ccompiler/frontend/parser/ast/decl.c b/src/ccompiler/frontend/parser/ast/decl.c similarity index 100% rename from ccompiler/frontend/parser/ast/decl.c rename to src/ccompiler/frontend/parser/ast/decl.c diff --git a/ccompiler/frontend/parser/ast/expr.c b/src/ccompiler/frontend/parser/ast/expr.c similarity index 100% rename from ccompiler/frontend/parser/ast/expr.c rename to src/ccompiler/frontend/parser/ast/expr.c diff --git a/ccompiler/frontend/parser/ast/func.c b/src/ccompiler/frontend/parser/ast/func.c similarity index 100% rename from ccompiler/frontend/parser/ast/func.c rename to src/ccompiler/frontend/parser/ast/func.c diff --git a/ccompiler/frontend/parser/ast/program.c b/src/ccompiler/frontend/parser/ast/program.c similarity index 100% rename from ccompiler/frontend/parser/ast/program.c rename to src/ccompiler/frontend/parser/ast/program.c diff --git a/ccompiler/frontend/parser/ast/stmt.c b/src/ccompiler/frontend/parser/ast/stmt.c similarity index 100% rename from ccompiler/frontend/parser/ast/stmt.c rename to src/ccompiler/frontend/parser/ast/stmt.c diff --git a/ccompiler/frontend/parser/ast/term.c b/src/ccompiler/frontend/parser/ast/term.c similarity index 100% rename from ccompiler/frontend/parser/ast/term.c rename to src/ccompiler/frontend/parser/ast/term.c diff --git a/ccompiler/frontend/parser/ast/type.c b/src/ccompiler/frontend/parser/ast/type.c similarity index 100% rename from ccompiler/frontend/parser/ast/type.c rename to src/ccompiler/frontend/parser/ast/type.c diff --git a/ccompiler/frontend/parser/parser.c b/src/ccompiler/frontend/parser/parser.c similarity index 100% rename from ccompiler/frontend/parser/parser.c rename to src/ccompiler/frontend/parser/parser.c diff --git a/ccompiler/frontend/parser/parser.h b/src/ccompiler/frontend/parser/parser.h similarity index 92% rename from ccompiler/frontend/parser/parser.h rename to src/ccompiler/frontend/parser/parser.h index 79c426a..e244b29 100644 --- a/ccompiler/frontend/parser/parser.h +++ b/src/ccompiler/frontend/parser/parser.h @@ -2,7 +2,7 @@ #define __PARSER_H__ #include "../lexer/lexer.h" -#include +#include "symtab/symtab.h" #include "ast.h" #define PARSER_MAX_TOKEN_QUEUE 16 diff --git a/src/ccompiler/frontend/parser/symtab/symtab.c b/src/ccompiler/frontend/parser/symtab/symtab.c new file mode 100644 index 0000000..8a53194 --- /dev/null +++ b/src/ccompiler/frontend/parser/symtab/symtab.c @@ -0,0 +1,62 @@ +#include "symtab.h" + +static u32_t hash_func(const void* _key) { + const symtab_key_t* key = (symtab_key_t*)_key; + return rt_strhash(key->strp_name); +} + +static int key_cmp(const void* _key1, const void* _key2) { + const symtab_key_t* key1 = (symtab_key_t*)_key1; + const symtab_key_t* key2 = (symtab_key_t*)_key2; + if (rt_strcmp(key1->strp_name, key2->strp_name) == 0) { + return 0; + } + return 1; +} + +void init_symtab(symtab_t* symtab) { + symtab->cur_scope = NULL; + symtab->gid = 1; + init_hashtable(&symtab->global_table); + symtab->global_table.hash_func = hash_func; + symtab->global_table.key_cmp = key_cmp; + init_hashtable(&symtab->local_table); + symtab->local_table.hash_func = hash_func; + symtab->local_table.key_cmp = key_cmp; +} + +void symtab_destroy(symtab_t* symtab) { + // TODO +} + +void symtab_enter_scope(symtab_t* symtab) { + scope_t *scope = (scope_t*)salloc_alloc(sizeof(scope_t)); + scope->parent = symtab->cur_scope; + scope->uid = symtab->gid++; + init_hashtable(&scope->table); + + scope->table.hash_func = hash_func; + scope->table.key_cmp = key_cmp; + symtab->cur_scope = scope; +} + +void symtab_leave_scope(symtab_t* symtab) { + Assert(symtab->cur_scope != NULL); + scope_t *parent = symtab->cur_scope->parent; + hashtable_destory(&symtab->cur_scope->table); + salloc_free(symtab->cur_scope); + symtab->cur_scope = parent; +} + +void* symtab_get(symtab_t* symtab, symtab_key_t* key) { + for (scope_t* scope = symtab->cur_scope; scope != NULL; scope = scope->parent) { + void* val = hashtable_get(&scope->table, key); + if (val != NULL) { + return val; + } + } + return NULL; +} +void* symtab_add(symtab_t* symtab, symtab_key_t* key, void* val) { + return hashtable_set(&symtab->cur_scope->table, key, val); +} diff --git a/src/ccompiler/frontend/parser/symtab/symtab.h b/src/ccompiler/frontend/parser/symtab/symtab.h new file mode 100644 index 0000000..176dd7f --- /dev/null +++ b/src/ccompiler/frontend/parser/symtab/symtab.h @@ -0,0 +1,39 @@ +#ifndef __SMCC_SYMTABL_H__ +#define __SMCC_SYMTABL_H__ + +#include +#include +#include + +// FIXME 架构上可能有更好的方式解决 + +typedef struct symtab_key { + const char* strp_name; + int uid; +} symtab_key_t; + +typedef struct scope { + int uid; + struct scope* parent; + hash_table_t table; +} scope_t; + +typedef struct symtab { + hash_table_t global_table; + hash_table_t local_table; + scope_t* cur_scope; + int gid; // global id for generating unique scope id +} symtab_t; + +void init_symtab(symtab_t* symtab); +void symtab_destroy(symtab_t* symtab); + +void symtab_enter_scope(symtab_t* symtab); +void symtab_leave_scope(symtab_t* symtab); + +void* symtab_get(symtab_t* symtab, symtab_key_t* key); + +// WARNING key and val need you save, especially val +void* symtab_add(symtab_t* symtab, symtab_key_t* key, void* val); + +#endif diff --git a/ccompiler/frontend/parser/type.h b/src/ccompiler/frontend/parser/type.h similarity index 100% rename from ccompiler/frontend/parser/type.h rename to src/ccompiler/frontend/parser/type.h diff --git a/ccompiler/middleend/Makefile b/src/ccompiler/middleend/Makefile similarity index 100% rename from ccompiler/middleend/Makefile rename to src/ccompiler/middleend/Makefile diff --git a/src/ccompiler/middleend/ir/ir.c b/src/ccompiler/middleend/ir/ir.c new file mode 100644 index 0000000..e69de29 diff --git a/ccompiler/middleend/ir/ir.h b/src/ccompiler/middleend/ir/ir.h similarity index 100% rename from ccompiler/middleend/ir/ir.h rename to src/ccompiler/middleend/ir/ir.h diff --git a/ccompiler/middleend/ir/ir_ast.c b/src/ccompiler/middleend/ir/ir_ast.c similarity index 100% rename from ccompiler/middleend/ir/ir_ast.c rename to src/ccompiler/middleend/ir/ir_ast.c diff --git a/ccompiler/middleend/ir/ir_ast.h b/src/ccompiler/middleend/ir/ir_ast.h similarity index 100% rename from ccompiler/middleend/ir/ir_ast.h rename to src/ccompiler/middleend/ir/ir_ast.h diff --git a/ccompiler/middleend/ir/ir_dump.c b/src/ccompiler/middleend/ir/ir_dump.c similarity index 100% rename from ccompiler/middleend/ir/ir_dump.c rename to src/ccompiler/middleend/ir/ir_dump.c diff --git a/ccompiler/middleend/ir/ir_lib.c b/src/ccompiler/middleend/ir/ir_lib.c similarity index 100% rename from ccompiler/middleend/ir/ir_lib.c rename to src/ccompiler/middleend/ir/ir_lib.c diff --git a/ccompiler/middleend/ir/ir_lib.h b/src/ccompiler/middleend/ir/ir_lib.h similarity index 100% rename from ccompiler/middleend/ir/ir_lib.h rename to src/ccompiler/middleend/ir/ir_lib.h diff --git a/ccompiler/middleend/ir/ir_type.c b/src/ccompiler/middleend/ir/ir_type.c similarity index 100% rename from ccompiler/middleend/ir/ir_type.c rename to src/ccompiler/middleend/ir/ir_type.c diff --git a/ccompiler/middleend/ir/ir_type.h b/src/ccompiler/middleend/ir/ir_type.h similarity index 100% rename from ccompiler/middleend/ir/ir_type.h rename to src/ccompiler/middleend/ir/ir_type.h diff --git a/ccompiler/middleend/middleend.c b/src/ccompiler/middleend/middleend.c similarity index 100% rename from ccompiler/middleend/middleend.c rename to src/ccompiler/middleend/middleend.c diff --git a/ccompiler/middleend/middleend.h b/src/ccompiler/middleend/middleend.h similarity index 100% rename from ccompiler/middleend/middleend.h rename to src/ccompiler/middleend/middleend.h diff --git a/src/ccompiler/middleend/reg_alloc.c b/src/ccompiler/middleend/reg_alloc.c new file mode 100644 index 0000000..e69de29 diff --git a/ccompiler/middleend/reg_alloc.h b/src/ccompiler/middleend/reg_alloc.h similarity index 100% rename from ccompiler/middleend/reg_alloc.h rename to src/ccompiler/middleend/reg_alloc.h diff --git a/src/linker/Makefile b/src/linker/Makefile new file mode 100644 index 0000000..dc9711b --- /dev/null +++ b/src/linker/Makefile @@ -0,0 +1,17 @@ +CC = gcc +AR = ar +CFLAGS = -g -Wall -I.. -I../.. +MODULES = . + +EXCLUDE = **/test*.c +SRCS = $(filter-out $(EXCLUDE), $(wildcard $(addsuffix /*.c,$(MODULES)))) +OBJS = $(SRCS:.c=.o) + +liblk.a: $(OBJS) + $(AR) rcs $@ $^ + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f liblk.a $(OBJS) diff --git a/src/linker/header.h b/src/linker/header.h new file mode 100644 index 0000000..f366a27 --- /dev/null +++ b/src/linker/header.h @@ -0,0 +1,10 @@ +#ifndef __HEADER +#define __HEADER +#include +#include +#include + +rv32_prog_t* gen_rv32_crt(); +rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]); + +#endif diff --git a/linker/riscv32_crt.c b/src/linker/riscv32_crt.c similarity index 59% rename from linker/riscv32_crt.c rename to src/linker/riscv32_crt.c index c67cba9..7f27e48 100644 --- a/linker/riscv32_crt.c +++ b/src/linker/riscv32_crt.c @@ -1,9 +1,13 @@ #include "header.h" +#include +#include // #include rv32_prog_t* gen_rv32_crt() { - rv32_prog_t* crt = (rv32_prog_t*)salloc_alloc(sizeof(rv32_prog_t)); - init_rv32_prog(crt, NULL); + rv32_prog_t* _crt = (rv32_prog_t*)salloc_alloc(sizeof(rv32_prog_t)); + init_rv32_prog(_crt, NULL); + + mcode_rv32_t *crt = &_crt->mcode; rv32_li(crt, REG_SP, 0x1000); rv32_li(crt, REG_RA, 0x0); @@ -17,5 +21,5 @@ rv32_prog_t* gen_rv32_crt() { // ecall exit2 rv32_li(crt, REG_A7, 93); rv32_ecall(crt); - return crt; + return _crt; } diff --git a/linker/riscv32_linker.c b/src/linker/riscv32_linker.c similarity index 61% rename from linker/riscv32_linker.c rename to src/linker/riscv32_linker.c index 6425224..bd9ccd4 100644 --- a/linker/riscv32_linker.c +++ b/src/linker/riscv32_linker.c @@ -8,7 +8,6 @@ int append(const void *key, void *value, void *context) { symasm_entry_t* entry = (symasm_entry_t*) key; u32_t* addr = (u32_t*) value; *addr += text_addr; // size to index - salloc_alloc(16); if (entry->attr == GLOBAL) { symtab_asm_put(symtab, entry, *addr); } @@ -24,29 +23,31 @@ rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) { FOREACH_PROGS(progs) { prog->text_base_address = text_addr; - text_addr += prog->text.size; + text_addr += prog->mcode.code.size; } - exe->text.data = salloc_alloc(text_addr * sizeof(u32_t)); - exe->text.cap = text_addr; - exe->text.size = text_addr; + + exe->mcode.code.data = salloc_alloc(text_addr); + exe->mcode.code.cap = text_addr; + exe->mcode.code.size = text_addr; text_addr = 0; FOREACH_PROGS(progs) { - rt_memcpy(exe->text.data + text_addr, prog->text.data, prog->text.size * sizeof(u32_t)); + rt_memcpy(exe->mcode.code.data + text_addr, prog->mcode.code.data, prog->mcode.code.size); // FIXME hashtable_foreach(&prog->symtab.symtab, append, &symtab); - text_addr += prog->text.size; + text_addr += prog->mcode.code.size; } // find by self FOREACH_PROGS(progs) { - for (int i = 0; i < prog->rinstrs.size; i++) { + for (int i = 0; i < prog->mcode.rinstrs.size; i++) { u32_t* paddr; u32_t addr; - paddr = symtab_asm_get(&prog->symtab, &prog->rinstrs.data[i].target); + rotated_instr_t *rinstr = &(prog->mcode.rinstrs.data[i]); + paddr = symtab_asm_get(&prog->symtab, rinstr->target); if (paddr == NULL) { - paddr = symtab_asm_get(&symtab, &prog->rinstrs.data[i].target); + paddr = symtab_asm_get(&symtab, rinstr->target); if (paddr == NULL) { - LOG_FATAL("linker: %s not found", prog->rinstrs.data[i].target.name); + LOG_FATAL("linker: %s not found", ((symasm_entry_t*)rinstr)->name); } addr = *paddr; } else { @@ -54,12 +55,13 @@ rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) { // addr += prog->text_base_address; } // FIXME - int cur_idx = prog->text_base_address + prog->rinstrs.data[i].address; - prog->rinstrs.data[i].instr.imm += (addr - cur_idx) * sizeof(u32_t); - emit_rv32_instr(exe, &prog->rinstrs.data[i].instr, cur_idx, NULL); + int cur_idx = prog->text_base_address + rinstr->pos; + rinstr->instr.imm += addr - cur_idx; + emit_rv32_instr(&exe->mcode, &rinstr->instr, cur_idx, NULL); // symtab_get(&prog->symtab, &prog->rinstrs.data[i].target); } } + return exe; } diff --git a/src/mcode/Makefile b/src/mcode/Makefile new file mode 100644 index 0000000..e2eaed8 --- /dev/null +++ b/src/mcode/Makefile @@ -0,0 +1,17 @@ +CC = gcc +AR = ar +CFLAGS = -g -Wall -I../.. +MODULES = riscv32 + +EXCLUDE = test*.c +SRCS = $(filter-out $(EXCLUDE), $(wildcard $(addsuffix /*.c,$(MODULES)))) +OBJS = $(SRCS:.c=.o) + +libmc.a: $(OBJS) + $(AR) rcs $@ $^ + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f libmc.a $(OBJS) \ No newline at end of file diff --git a/assembler/riscv32/riscv32_def.h b/src/mcode/riscv32/riscv32_def.h similarity index 100% rename from assembler/riscv32/riscv32_def.h rename to src/mcode/riscv32/riscv32_def.h diff --git a/assembler/riscv32/riscv32_instr.h b/src/mcode/riscv32/riscv32_instr.h similarity index 80% rename from assembler/riscv32/riscv32_instr.h rename to src/mcode/riscv32/riscv32_instr.h index 81ea3b1..89f327f 100644 --- a/assembler/riscv32/riscv32_instr.h +++ b/src/mcode/riscv32/riscv32_instr.h @@ -1,9 +1,8 @@ #ifndef __SMCC_RISCV32_INSTR_H__ #define __SMCC_RISCV32_INSTR_H__ -#include "riscv32.h" +#include "riscv32_mcode.h" #include "riscv32_def.h" -#include "symtab_asm.h" #define EMIT_PUSH_BACK (-1) /* base integer instruction */ @@ -16,7 +15,7 @@ * rd = rs1 + rs2 */ static inline int -rv32_add(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_add(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_ADD, .rd = rd, @@ -34,7 +33,7 @@ rv32_add(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 + imm (imm maybe cut) */ static inline int -rv32_addi(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_addi(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_ADDI, .rd = rd, @@ -53,7 +52,7 @@ rv32_addi(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = rs1 & rs2 */ static inline int -rv32_and(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_and(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_AND, .rd = rd, @@ -72,7 +71,7 @@ rv32_and(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 & imm (imm maybe cut) */ static inline int -rv32_andi(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_andi(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_ANDI, .rd = rd, @@ -91,7 +90,7 @@ rv32_andi(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = PC + imm{12} */ static inline int -rv32_auipc(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { +rv32_auipc(mcode_rv32_t* prog, rv_reg_t rd, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_AUIPC, .rd = rd, @@ -110,7 +109,7 @@ rv32_auipc(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { * if (rs1 == rs2) PC += imm{alian2} */ static inline int -rv32_beq(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { +rv32_beq(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_BEQ, .rd = REG_NULL, @@ -130,7 +129,7 @@ rv32_beq(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { * if (rs1 >= rs2) PC += imm{alian2} */ static inline int -rv32_bge(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { +rv32_bge(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_BGE, .rd = REG_NULL, @@ -149,7 +148,7 @@ rv32_bge(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { * if (rs1 >= u rs2) PC += imm{alian2} */ static inline int -rv32_bgeu(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { +rv32_bgeu(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_BGEU, .rd = REG_NULL, @@ -168,7 +167,7 @@ rv32_bgeu(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { * if (rs1 < rs2) PC += imm{alian2} */ static inline int -rv32_blt(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { +rv32_blt(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_BLT, .rd = REG_NULL, @@ -187,7 +186,7 @@ rv32_blt(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { * if (rs1 < u rs2) PC += imm{alian2} */ static inline int -rv32_bltu(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { +rv32_bltu(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_BLTU, .rd = REG_NULL, @@ -206,7 +205,7 @@ rv32_bltu(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { * if (rs1 != rs2) PC += imm{alian2} */ static inline int -rv32_bne(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { +rv32_bne(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_BNE, .rd = REG_NULL, @@ -225,7 +224,7 @@ rv32_bne(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, u32_t imm) { * Transfer control to debugger */ static inline int -rv32_ebreak(rv32_prog_t* prog) { +rv32_ebreak(mcode_rv32_t* prog) { rv32_instr_t instr = { .instr_type = RV_EBREAK, .rd = REG_NULL, @@ -244,7 +243,7 @@ rv32_ebreak(rv32_prog_t* prog) { * Transfer control to operating system */ static inline int -rv32_ecall(rv32_prog_t* prog) { +rv32_ecall(mcode_rv32_t* prog) { rv32_instr_t instr = { .instr_type = RV_ECALL, .rd = REG_NULL, @@ -263,7 +262,7 @@ rv32_ecall(rv32_prog_t* prog) { * rd = PC + 4; PC += imm{alian2} */ static inline int -rv32_jal(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { +rv32_jal(mcode_rv32_t* prog, rv_reg_t rd, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_JAL, .rd = rd, @@ -282,7 +281,7 @@ rv32_jal(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { * rd = PC + 4; PC = rs1 + imm */ static inline int -rv32_jalr(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_jalr(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_JALR, .rd = rd, @@ -301,7 +300,7 @@ rv32_jalr(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (8 bit) M[rs1+imm] */ static inline int -rv32_lb(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_lb(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_LB, .rd = rd, @@ -320,7 +319,7 @@ rv32_lb(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (8 bit) M[rs1+imm] */ static inline int -rv32_lbu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_lbu(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_LBU, .rd = rd, @@ -345,7 +344,7 @@ rv32_lbu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (32 bit) imm */ static inline int -rv32_lui(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { +rv32_lui(mcode_rv32_t* prog, rv_reg_t rd, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_LUI, .rd = rd, @@ -364,7 +363,7 @@ rv32_lui(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { * rd = (32 bit) M[rs1+imm] */ static inline int -rv32_lw(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_lw(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_LW, .rd = rd, @@ -383,7 +382,7 @@ rv32_lw(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (32 bit) u M[rs1+imm] */ // static inline int -// rv32_lwu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +// rv32_lwu(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { // return emit_rv32_instr(prog, RV_LWU, rd, rs1, REG_NULL, imm); // } @@ -395,7 +394,7 @@ rv32_lw(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = rs1 | rs2 */ static inline int -rv32_or(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_or(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_OR, .rd = rd, @@ -414,7 +413,7 @@ rv32_or(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 | imm (imm maybe cut) */ static inline int -rv32_ori(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_ori(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_ORI, .rd = rd, @@ -433,7 +432,7 @@ rv32_ori(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * M[rs1+imm] = rs2 */ static inline int -rv32_sb(rv32_prog_t* prog, rv_reg_t rs2, rv_reg_t rs1, u32_t imm) { +rv32_sb(mcode_rv32_t* prog, rv_reg_t rs2, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SB, .rd = REG_NULL, @@ -456,7 +455,7 @@ rv32_sb(rv32_prog_t* prog, rv_reg_t rs2, rv_reg_t rs1, u32_t imm) { * rd = rs1 << rs2 */ static inline int -rv32_sll(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_sll(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_SLL, .rd = rd, @@ -475,7 +474,7 @@ rv32_sll(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 << imm (maybe cut it) */ static inline int -rv32_slli(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_slli(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SLLI, .rd = rd, @@ -494,7 +493,7 @@ rv32_slli(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (rs1 < rs2) ? 1 : 0 */ static inline int -rv32_slt(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_slt(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_SLT, .rd = rd, @@ -513,7 +512,7 @@ rv32_slt(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = (rs1 < imm) ? 1 : 0 */ static inline int -rv32_slti(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_slti(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SLTI, .rd = rd, @@ -532,7 +531,7 @@ rv32_slti(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (u rs1 < imm) ? 1 : 0 */ static inline int -rv32_sltiu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_sltiu(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SLTIU, .rd = rd, @@ -551,7 +550,7 @@ rv32_sltiu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (u rs1 < u rs2) ? 1 : 0 */ static inline int -rv32_sltu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_sltu(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_SLTU, .rd = rd, @@ -570,7 +569,7 @@ rv32_sltu(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 >> rs2 */ static inline int -rv32_sra(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_sra(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_SRA, .rd = rd, @@ -589,7 +588,7 @@ rv32_sra(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 >> imm (maybe cut it) */ static inline int -rv32_srai(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_srai(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SRAI, .rd = rd, @@ -608,7 +607,7 @@ rv32_srai(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = (u rs1) >> rs2 */ static inline int -rv32_srl(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_srl(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_SRL, .rd = rd, @@ -627,7 +626,7 @@ rv32_srl(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = (u rs1) >> imm (maybe cut it) */ static inline int -rv32_srli(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_srli(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SRLI, .rd = rd, @@ -646,7 +645,7 @@ rv32_srli(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * rd = rs1 - rs2 */ static inline int -rv32_sub(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_sub(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_SUB, .rd = rd, @@ -665,7 +664,7 @@ rv32_sub(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * M[rs1+imm] = rs2 */ static inline int -rv32_sw(rv32_prog_t* prog, rv_reg_t rs2, rv_reg_t rs1, u32_t imm) { +rv32_sw(mcode_rv32_t* prog, rv_reg_t rs2, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_SW, .rd = REG_NULL, @@ -684,7 +683,7 @@ rv32_sw(rv32_prog_t* prog, rv_reg_t rs2, rv_reg_t rs1, u32_t imm) { * rd = rs1 ^ rs2 */ static inline int -rv32_xor(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { +rv32_xor(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { rv32_instr_t instr = { .instr_type = RV_XOR, .rd = rd, @@ -703,7 +702,7 @@ rv32_xor(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, rv_reg_t rs2) { * rd = rs1 ^ imm (maybe cut it) */ static inline int -rv32_xori(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { +rv32_xori(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { rv32_instr_t instr = { .instr_type = RV_XORI, .rd = rd, @@ -724,7 +723,7 @@ rv32_xori(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1, u32_t imm) { * if (rs1 == 0) PC += imm{alian2} */ static inline int -rv32_beqz(rv32_prog_t* prog, rv_reg_t rs1, u32_t imm) { +rv32_beqz(mcode_rv32_t* prog, rv_reg_t rs1, u32_t imm) { return rv32_beq(prog, rs1, REG_X0, imm); } @@ -736,7 +735,7 @@ rv32_beqz(rv32_prog_t* prog, rv_reg_t rs1, u32_t imm) { * if (rs1 != 0) PC += imm{alian2} */ static inline int -rv32_bnez(rv32_prog_t* prog, rv_reg_t rs1, u32_t imm) { +rv32_bnez(mcode_rv32_t* prog, rv_reg_t rs1, u32_t imm) { return rv32_bne(prog, rs1, REG_X0, imm); } @@ -754,7 +753,7 @@ rv32_bnez(rv32_prog_t* prog, rv_reg_t rs1, u32_t imm) { * PC = imm{alian2} */ static inline int -rv32_j(rv32_prog_t* prog, u32_t imm) { +rv32_j(mcode_rv32_t* prog, u32_t imm) { // TODO return rv32_jal(prog, REG_X0, imm); } @@ -767,7 +766,7 @@ rv32_j(rv32_prog_t* prog, u32_t imm) { * PC = rs1 */ static inline int -rv32_jr(rv32_prog_t* prog, rv_reg_t rs1) { +rv32_jr(mcode_rv32_t* prog, rv_reg_t rs1) { // TODO return rv32_jalr(prog, REG_X0, rs1, 0); } @@ -780,7 +779,7 @@ rv32_jr(rv32_prog_t* prog, rv_reg_t rs1) { * rd = address */ static inline int -rv32_la(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { +rv32_la(mcode_rv32_t* prog, rv_reg_t rd, u32_t imm) { // TODO return rv32_auipc(prog, rd, imm); } @@ -793,7 +792,7 @@ rv32_la(rv32_prog_t* prog, rv_reg_t rd, u32_t imm) { * rd = imm */ static inline int -rv32_li(rv32_prog_t* prog, rv_reg_t rd, i32_t imm) { +rv32_li(mcode_rv32_t* prog, rv_reg_t rd, i32_t imm) { if (imm >= -2048 && imm <= 2047) { return rv32_addi(prog, rd, REG_X0, imm); } else { @@ -811,7 +810,7 @@ rv32_li(rv32_prog_t* prog, rv_reg_t rd, i32_t imm) { * rd = rs1 */ static inline int -rv32_mv(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { +rv32_mv(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1) { return rv32_addi(prog, rd, rs1, 0); } @@ -823,7 +822,7 @@ rv32_mv(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { * rd = -rs1 */ static inline int -rv32_neg(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { +rv32_neg(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1) { return rv32_sub(prog, rd, REG_X0, rs1); } @@ -835,7 +834,7 @@ rv32_neg(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { * x0 = x0 */ static inline int -rv32_nop(rv32_prog_t* prog) { +rv32_nop(mcode_rv32_t* prog) { return rv32_addi(prog, REG_X0, REG_X0, 0); } @@ -847,7 +846,7 @@ rv32_nop(rv32_prog_t* prog) { * rd = ~rs1 */ static inline int -rv32_not(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { +rv32_not(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1) { return rv32_xori(prog, rd, rs1, ~0); } @@ -859,7 +858,7 @@ rv32_not(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { * PC = ra */ static inline int -rv32_ret(rv32_prog_t* prog) { +rv32_ret(mcode_rv32_t* prog) { return rv32_jalr(prog, REG_X0, REG_RA, 0); } @@ -871,7 +870,7 @@ rv32_ret(rv32_prog_t* prog) { * rd = (rs1 == 0) ? 1 : 0 */ static inline int -rv32_seqz(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { +rv32_seqz(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1) { // TODO return rv32_sltiu(prog, rd, rs1, 1); } @@ -884,14 +883,14 @@ rv32_seqz(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { * rd = (rs1 != 0) ? 1 : 0 */ static inline int -rv32_snez(rv32_prog_t* prog, rv_reg_t rd, rv_reg_t rs1) { +rv32_snez(mcode_rv32_t* prog, rv_reg_t rd, rv_reg_t rs1) { // TODO return rv32_sltu(prog, rd, rs1, REG_X0); } /* instruction of rotated (using label) */ static inline int -rv32_bne_l(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, symasm_entry_t* label) { +rv32_bne_l(mcode_rv32_t* prog, rv_reg_t rs1, rv_reg_t rs2, void* label) { rv32_instr_t instr = { .instr_type = RV_BNE, .rd = REG_NULL, @@ -903,7 +902,7 @@ rv32_bne_l(rv32_prog_t* prog, rv_reg_t rs1, rv_reg_t rs2, symasm_entry_t* label) } static inline int -rv32_jal_l(rv32_prog_t* prog, rv_reg_t rd, symasm_entry_t* label) { +rv32_jal_l(mcode_rv32_t* prog, rv_reg_t rd, void* label) { rv32_instr_t instr = { .instr_type = RV_JAL, .rd = rd, @@ -915,7 +914,7 @@ rv32_jal_l(rv32_prog_t* prog, rv_reg_t rd, symasm_entry_t* label) { } static inline int -rv32_call_l(rv32_prog_t* prog, symasm_entry_t* label) { +rv32_call_l(mcode_rv32_t* prog, void* label) { rv32_instr_t instr; instr.instr_type = RV_JAL; @@ -937,12 +936,4 @@ rv32_call_l(rv32_prog_t* prog, symasm_entry_t* label) { return ret; } -/* append label */ -static inline int -rv32_append_label(rv32_prog_t* prog, symasm_entry_t* label, u32_t offset) { - // prog->symtab - symtab_asm_put(&prog->symtab, label, offset); - return 0; -} - #endif diff --git a/assembler/riscv32/riscv32.c b/src/mcode/riscv32/riscv32_mcode.c similarity index 66% rename from assembler/riscv32/riscv32.c rename to src/mcode/riscv32/riscv32_mcode.c index 5a0936e..065eafe 100644 --- a/assembler/riscv32/riscv32.c +++ b/src/mcode/riscv32/riscv32_mcode.c @@ -1,6 +1,4 @@ -#include "riscv32.h" -#include "riscv32_def.h" -#include +#include "riscv32_mcode.h" static const rv32_instr_t rv32_instrs[] = { [RV_LUI] = {RV32_I_EXT, RV_U_TYPE, RV_LUI, "lui", 0x37}, @@ -58,66 +56,22 @@ static const rv32_instr_t rv32_instrs[] = { [RV_REM] = {RV32_M_EXT, RV_R_TYPE, RV_REM, "rem", 0x33 | RV_F3(0x0) | RV_F7(0x07)}, }; -void init_rv32_prog(rv32_prog_t* prog, strpool_t* strpool) { - if (strpool == NULL) { - prog->strpool = salloc_alloc(sizeof(strpool_t)); - init_strpool(prog->strpool); - } else { - prog->strpool = strpool; - } - prog->data_base_address = 0; - vector_init(prog->data); - prog->text_base_address = 0; - vector_init(prog->text); - vector_init(prog->rinstrs); - init_symtab_asm(&prog->symtab); -} - static inline int valid_reg(rv_reg_t reg) { // return reg >= REG_X0 && reg <= REG_X31; return !(reg & ~0x1F); } -// static int valid_instr -// (rv_instr_type_t type, u32_t imm, rv_reg_t rs1, rv_reg_t rs2, rv_reg_t rd) { -// Assert(type >= 0 && type < RV_INSTR_TYPE_COUNT); -// rv_fmt_t fmt = rv32_instrs[type].format; -// switch (fmt) { -// case RV_R_TYPE: -// if (valid_reg(rd) && valid_reg(rs1) && valid_reg(rs2)) { -// return 1; -// } -// break; -// case RV_I_TYPE: -// if (valid_reg(rd) && valid_reg(rs1) && rs2 == 0 && (imm & ~0xFFF) == 0) { -// return 1; -// } -// break; -// case RV_S_TYPE: -// if (rd == 0 && valid_reg(rs1) && valid_reg(rs2) && (imm & ~0xFFF) == 0) { -// return 1; -// } -// break; -// case RV_B_TYPE: -// if (rd == 0 && valid_reg(rs1) && valid_reg(rs2) && (imm & ~(0xFFF << 1)) == 0) { -// return 1; -// } -// break; -// case RV_U_TYPE: -// if (valid_reg(rd) && rs1 == 0 && rs2 == 0 && (imm & ~(0xFFFFF << 12)) == 0) { -// return 1; -// } -// break; -// case RV_J_TYPE: -// if (valid_reg(rd) && rs1 == 0 && rs2 == 0 && (imm & ~(0xFFFFF)) == 0) { -// return 1; -// } -// break; -// } -// return 0; -// } +void init_rv32_mcode(mcode_rv32_t* mcode, int target_size) { + vector_init(mcode->code); + vector_init(mcode->rinstrs); + mcode->target_size = target_size; +} -int emit_rv32_instr(rv32_prog_t* prog, rv32_instr_t *instr, u32_t idx, symasm_entry_t *target) { +int decode_rv32_instr(u32_t instr, rv32_instr_t *out) { + return 0; +} + +int emit_rv32_instr(mcode_rv32_t* mcode, rv32_instr_t *instr, u32_t idx, void *target) { // TODO check out input data instr->extention = rv32_instrs[instr->instr_type].extention; instr->format = rv32_instrs[instr->instr_type].format; @@ -158,47 +112,40 @@ int emit_rv32_instr(rv32_prog_t* prog, rv32_instr_t *instr, u32_t idx, symasm_en if (target != NULL) { Assert(idx == -1); + void* ptr; + if (mcode->target_size >= 0) { + ptr = salloc_alloc(mcode->target_size); + if (ptr == NULL) { + LOG_FATAL("malloc failure"); + } + rt_memcpy(ptr, target, mcode->target_size); + } else { + ptr = target; + } rotated_instr_t rinstr = { .instr = *instr, - .address = prog->text.size, - .target = *target, + .pos = mcode->code.size, + .target = ptr, }; - vector_push(prog->rinstrs, rinstr); + vector_push(mcode->rinstrs, rinstr); // GOTO idx == -1 } if (idx == -1) { - vector_push(prog->text, instr->instr); + // 32bit instr + int idx = mcode->code.size; + vector_push(mcode->code, 0); + vector_push(mcode->code, 0); + vector_push(mcode->code, 0); + vector_push(mcode->code, 0); + u32_t* pinstr = (u32_t*)(&vector_at(mcode->code, idx)); + *pinstr = instr->instr; return idx; - } else if (idx >= 0 && idx < prog->text.size) { - vector_at(prog->text, idx) = instr->instr; - return prog->text.size - 1; + } else if (idx >= 0 && idx < mcode->code.size) { + *(u32_t*)&vector_at(mcode->code, idx) = instr->instr; + return mcode->code.size - 1; } else { Panic("Invalid instruction index"); } return -1; } - -// int gen_rv32_instr(rv32_prog_t* prog) { -// vector_header(rinstrs_g, rotated_instr_t); -// vector_init(rinstrs_g); -// for (int i = 0; i < prog->rinstrs.size; i++) { -// rotated_instr_t* rinstr = &prog->rinstrs.data[i]; -// // FIXME address typedef needed -// u32_t* ptr = symtab_get(&prog->symtab, &rinstr->target); -// if (ptr == NULL) { -// vector_push(rinstrs_g, *rinstr); -// continue; -// } -// u32_t target_address = *ptr; - -// rv32_instr_t *back_instr = &rinstr->instr; - -// // FIXME 重定向类别 -// back_instr->imm = target_address; - -// emit_rv32_instr(prog, back_instr, target_address, NULL); -// } -// vector_free(prog->rinstrs); -// prog->rinstrs.cap = rinstrs_g.cap; -// } diff --git a/src/mcode/riscv32/riscv32_mcode.h b/src/mcode/riscv32/riscv32_mcode.h new file mode 100644 index 0000000..11749e7 --- /dev/null +++ b/src/mcode/riscv32/riscv32_mcode.h @@ -0,0 +1,23 @@ +#ifndef __SMCC_ASM_RISCV32_H__ +#define __SMCC_ASM_RISCV32_H__ + +#include +#include +#include "riscv32_def.h" + +typedef struct rotated_instr { + u32_t pos; + void* target; + rv32_instr_t instr; +} rotated_instr_t; + +typedef struct mcode_rv32 { + vector_header(rinstrs, rotated_instr_t); + vector_header(code, u8_t); + int target_size; +} mcode_rv32_t; + +void init_rv32_mcode(mcode_rv32_t* mcode, int target_size); +int emit_rv32_instr(mcode_rv32_t* mcode, rv32_instr_t *instr, u32_t idx, void *target); + +#endif diff --git a/src/pprocesser/main.c b/src/pprocesser/main.c new file mode 100644 index 0000000..e69de29 diff --git a/linker/test_main.c b/src/smcc.c similarity index 75% rename from linker/test_main.c rename to src/smcc.c index 1492788..b97af36 100644 --- a/linker/test_main.c +++ b/src/smcc.c @@ -1,5 +1,5 @@ -#include "header.h" -#include +#include +#include "linker/header.h" #include int main(int argc, char** argv) { @@ -37,19 +37,11 @@ int main(int argc, char** argv) { &prog->rv32, NULL, }; - // rv32_progs[0] = rv32_crt; - // rv32_progs[1] = &prog->rv32; - // rv32_progs[2] = NULL; rv32_prog_t* code = link_rv32_prog(rv32_progs); - - // for (int i = 0; i < code->instrs.size; i++) { - // fwrite(&code->instrs.data[i].instr, 4, 1, out); - // fflush(out); - // } // Flatbin fmt - fwrite(code->text.data, sizeof(u32_t), code->text.size, out); + fwrite(code->mcode.code.data, 1, code->mcode.code.size, out); // fwrite(code->data.data, sizeof(u8_t)code->text.size, 1, out); fclose(in); diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..7f26118 --- /dev/null +++ b/src/test.c @@ -0,0 +1,52 @@ +// int main() { +// int a; +// int b; +// a = 1 + 2 * 3; +// b = 7; +// a = a - b + 1; +// return a; +// } +// // int main() { +// // int x = 10; +// // x = x + 1; +// // return x; +// // } +// int main(void) { +// int a; +// a = 1; +// if (a) { +// a = 1; +// } else { +// a = 2; +// } +// return a; +// } +// int add(int, int); + +// int main(void) { +// return add(1, 2); +// } + +// int add(int a, int b) { +// return a + b; +// } +// int factorial(int num); + +// int main() { +// int num = 5; +// int result = factorial(num); +// // printf("%d", result); +// return result; +// } + +// int factorial(int num) { +// if (num == 0) { +// return 1; +// } else { +// return num * factorial(num - 1); +// } +// } + +int main() { + return 65536; +}