stable 重构文件结构

抽象出Machine Code
This commit is contained in:
ZZY 2025-04-01 23:27:25 +08:00
parent 74f43a1ab7
commit b57f21556a
76 changed files with 657 additions and 260 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@
# smcc compiler generated files # smcc compiler generated files
*.bin *.bin
.s
.asm
# linux binary files # linux binary files
*.o *.o

View File

@ -1,30 +0,0 @@
#ifndef __SMCC_ASM_RISCV32_H__
#define __SMCC_ASM_RISCV32_H__
#include <lib/core.h>
#include <lib/utils/ds/vector.h>
#include <lib/utils/symtab/symtab.h>
#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

View File

@ -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

View File

@ -1,6 +0,0 @@
#include <assembler/riscv32/riscv32.h>
#include <assembler/riscv32/riscv32_instr.h>
#include <lib/core.h>
rv32_prog_t* gen_rv32_crt();
rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]);

30
src/Makefile Normal file
View File

@ -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

144
src/assembler/assembler.c Normal file
View File

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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] == ' ') {
}
}

18
src/assembler/assembler.h Normal file
View File

@ -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 <lib/core.h>
#include "riscv32/riscv32_asm.h"
#include "riscv32/riscv32_asm.h"
typedef union asm_prog {
rv32_prog_t rv32;
} asm_prog_t;
#endif

View File

@ -1,6 +1,6 @@
CC = gcc CC = gcc
AR = ar AR = ar
CFLAGS = -g -Wall -I../.. CFLAGS = -g -Wall -I../../..
# 自动收集所有子模块源文件 # 自动收集所有子模块源文件
EXCLUDE = test*.c EXCLUDE = test*.c

View File

@ -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));
}

View File

@ -0,0 +1,18 @@
#ifndef __SMCC_RISCV32_ASM_H__
#define __SMCC_RISCV32_ASM_H__
#include <lib/utils/strpool/strpool.h>
#include <src/mcode/riscv32/riscv32_mcode.h>
#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

View File

@ -1,5 +1,13 @@
#include "symtab_asm.h" #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) { static u32_t hash_func(const symasm_entry_t* key) {
return rt_strhash(key->name); return rt_strhash(key->name);
} }

View File

@ -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

View File

@ -28,17 +28,17 @@
# 顶层Makefile修改 # 顶层Makefile修改
CC = gcc CC = gcc
AR = ar AR = ar
CFLAGS = -g -Wall -I.. CFLAGS = -g -Wall -I.. -I../..
MODULES = frontend middleend backend MODULES = frontend middleend backend
FRONTEND_SUBDIRS = lexer parser parser/ast FRONTEND_SUBDIRS = lexer parser parser/ast parser/symtab
MODULES += $(addprefix frontend/, $(FRONTEND_SUBDIRS)) MODULES += $(addprefix frontend/, $(FRONTEND_SUBDIRS))
MIDDLEEND_MODULES = ir MIDDLEEND_SUBDIRS = ir
MODULES += middleend/$(MIDDLEEND_MODULES) MODULES += $(addprefix middleend/, $(MIDDLEEND_SUBDIRS))
BACKEND_MODULES = riscv32 BACKEND_SUBDIRS = riscv32
MODULES += backend/$(BACKEND_MODULES) MODULES += $(addprefix backend/, $(BACKEND_SUBDIRS))
# 自动收集所有子模块源文件 # 自动收集所有子模块源文件
EXCLUDE = test*.c EXCLUDE = test*.c

View File

@ -11,7 +11,7 @@
// #endif // #endif
// TODO 统一 汇编器 接口 // TODO 统一 汇编器 接口
#include <assembler/assembler.h> #include <src/assembler/assembler.h>
#include "../middleend/ir/ir.h" #include "../middleend/ir/ir.h"
typedef enum cc_arch { typedef enum cc_arch {
CC_ARCH_RISCV32, CC_ARCH_RISCV32,

View File

@ -1,5 +1,5 @@
#include "riscv32.h" #include "riscv32.h"
#include <assembler/riscv32/riscv32_instr.h> #include <src/mcode/riscv32/riscv32_instr.h>
typedef struct { typedef struct {
ir_func_t* func; ir_func_t* func;
@ -45,7 +45,7 @@ static int system_func(const char* name) {
return -1; 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; int len = 0;
switch (ptr->tag) { switch (ptr->tag) {
case IR_NODE_CONST_INT: { 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; 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 idx = 0;
int offset; int offset;
char buf[1024]; 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); 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); 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; label.attr = LOCAL;
rv32_bne_l(out_asm, REG_T0, REG_X0, &label); 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); 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; label.attr = LOCAL;
rv32_jal_l(out_asm, REG_X0, &label); rv32_jal_l(out_asm, REG_X0, &label);
break; 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: { case IR_NODE_JUMP: {
// TODO // TODO
rt.snprintf(buf, sizeof(buf), "L%s%p", instr->data.jump.target_bblock->label, instr->data.jump.target_bblock); 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; label.attr = LOCAL;
rv32_jal_l(out_asm, REG_X0, &label); rv32_jal_l(out_asm, REG_X0, &label);
break; 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) // JALR(REG_X1, REG_X1, offset)
*/ */
// TODO CALL // 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; label.attr = GLOBAL;
rv32_call_l(out_asm, &label); rv32_call_l(out_asm, &label);
CALL_END: 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); rt.snprintf(buf, sizeof(buf), "L%s%p", block->label, block);
label.name = strpool_intern(out_asm->strpool, buf); label.name = strpool_intern(out_asm->strpool, buf);
label.attr = LOCAL; 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 ++) { for (int i = 0; i < block->instrs.size; i ++) {
gen_instr(out_asm, ctx, vector_at(block->instrs, 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), .name = strpool_intern(out_asm->strpool, func->name),
.attr = GLOBAL, .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_base = 4;
int stack_offset = stack_base; 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 // TODO Alignment by 16
// sp = sp - stack_offset; // 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; // 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] = { int param_regs[8] = {
REG_A0, REG_A1, REG_A2, REG_A3, 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++) { for (int i = 0; i < func->params.size; i++) {
int offset = stack_pos(vector_at(func->params, i), &ctx); int offset = stack_pos(vector_at(func->params, i), &ctx);
// M[sp + offset] = param[idx]; // 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 ++) { for(int i = 0; i < func->bblocks.size; i ++) {

View File

@ -1,8 +1,7 @@
#ifndef __SMCC_CC_RISCV32_H__ #ifndef __SMCC_CC_RISCV32_H__
#define __SMCC_CC_RISCV32_H__ #define __SMCC_CC_RISCV32_H__
#include <assembler/assembler.h> #include <src/assembler/assembler.h>
#include <assembler/riscv32/riscv32.h>
#include "../../middleend/ir/ir.h" #include "../../middleend/ir/ir.h"
int gen_rv32_from_ir(ir_prog_t* ir, rv32_prog_t* out_asm); int gen_rv32_from_ir(ir_prog_t* ir, rv32_prog_t* out_asm);

View File

@ -1,8 +1,9 @@
#ifndef __AST_H__ #ifndef __AST_H__
#define __AST_H__ #define __AST_H__
#include <lib/utils/ds/vector.h>
#include "../lexer/lexer.h" #include "../lexer/lexer.h"
#include <lib/utils/ds/vector.h>
#include "symtab/symtab.h"
#include "type.h" #include "type.h"
typedef enum { typedef enum {

View File

@ -2,7 +2,7 @@
#define __PARSER_H__ #define __PARSER_H__
#include "../lexer/lexer.h" #include "../lexer/lexer.h"
#include <lib/utils/symtab/symtab.h> #include "symtab/symtab.h"
#include "ast.h" #include "ast.h"
#define PARSER_MAX_TOKEN_QUEUE 16 #define PARSER_MAX_TOKEN_QUEUE 16

View File

@ -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);
}

View File

@ -0,0 +1,39 @@
#ifndef __SMCC_SYMTABL_H__
#define __SMCC_SYMTABL_H__
#include <lib/core.h>
#include <lib/utils/ds/hashtable.h>
#include <lib/utils/strpool/strpool.h>
// 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

View File

View File

17
src/linker/Makefile Normal file
View File

@ -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)

10
src/linker/header.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __HEADER
#define __HEADER
#include <src/assembler/riscv32/riscv32_asm.h>
#include <src/mcode/riscv32/riscv32_instr.h>
#include <lib/core.h>
rv32_prog_t* gen_rv32_crt();
rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]);
#endif

View File

@ -1,9 +1,13 @@
#include "header.h" #include "header.h"
#include <src/mcode/riscv32/riscv32_mcode.h>
#include <src/mcode/riscv32/riscv32_instr.h>
// #include <assembler/riscv32/riscv32.c> // #include <assembler/riscv32/riscv32.c>
rv32_prog_t* gen_rv32_crt() { rv32_prog_t* gen_rv32_crt() {
rv32_prog_t* crt = (rv32_prog_t*)salloc_alloc(sizeof(rv32_prog_t)); rv32_prog_t* _crt = (rv32_prog_t*)salloc_alloc(sizeof(rv32_prog_t));
init_rv32_prog(crt, NULL); init_rv32_prog(_crt, NULL);
mcode_rv32_t *crt = &_crt->mcode;
rv32_li(crt, REG_SP, 0x1000); rv32_li(crt, REG_SP, 0x1000);
rv32_li(crt, REG_RA, 0x0); rv32_li(crt, REG_RA, 0x0);
@ -17,5 +21,5 @@ rv32_prog_t* gen_rv32_crt() {
// ecall exit2 // ecall exit2
rv32_li(crt, REG_A7, 93); rv32_li(crt, REG_A7, 93);
rv32_ecall(crt); rv32_ecall(crt);
return crt; return _crt;
} }

View File

@ -8,7 +8,6 @@ int append(const void *key, void *value, void *context) {
symasm_entry_t* entry = (symasm_entry_t*) key; symasm_entry_t* entry = (symasm_entry_t*) key;
u32_t* addr = (u32_t*) value; u32_t* addr = (u32_t*) value;
*addr += text_addr; // size to index *addr += text_addr; // size to index
salloc_alloc(16);
if (entry->attr == GLOBAL) { if (entry->attr == GLOBAL) {
symtab_asm_put(symtab, entry, *addr); symtab_asm_put(symtab, entry, *addr);
} }
@ -24,29 +23,31 @@ rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) {
FOREACH_PROGS(progs) { FOREACH_PROGS(progs) {
prog->text_base_address = text_addr; 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->mcode.code.data = salloc_alloc(text_addr);
exe->text.size = text_addr; exe->mcode.code.cap = text_addr;
exe->mcode.code.size = text_addr;
text_addr = 0; text_addr = 0;
FOREACH_PROGS(progs) { 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 // FIXME
hashtable_foreach(&prog->symtab.symtab, append, &symtab); hashtable_foreach(&prog->symtab.symtab, append, &symtab);
text_addr += prog->text.size; text_addr += prog->mcode.code.size;
} }
// find by self // find by self
FOREACH_PROGS(progs) { 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* paddr;
u32_t addr; 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) { if (paddr == NULL) {
paddr = symtab_asm_get(&symtab, &prog->rinstrs.data[i].target); paddr = symtab_asm_get(&symtab, rinstr->target);
if (paddr == NULL) { 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; addr = *paddr;
} else { } else {
@ -54,12 +55,13 @@ rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) {
// addr += prog->text_base_address; // addr += prog->text_base_address;
} }
// FIXME // FIXME
int cur_idx = prog->text_base_address + prog->rinstrs.data[i].address; int cur_idx = prog->text_base_address + rinstr->pos;
prog->rinstrs.data[i].instr.imm += (addr - cur_idx) * sizeof(u32_t); rinstr->instr.imm += addr - cur_idx;
emit_rv32_instr(exe, &prog->rinstrs.data[i].instr, cur_idx, NULL); emit_rv32_instr(&exe->mcode, &rinstr->instr, cur_idx, NULL);
// symtab_get(&prog->symtab, &prog->rinstrs.data[i].target); // symtab_get(&prog->symtab, &prog->rinstrs.data[i].target);
} }
} }
return exe; return exe;
} }

17
src/mcode/Makefile Normal file
View File

@ -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)

View File

@ -1,9 +1,8 @@
#ifndef __SMCC_RISCV32_INSTR_H__ #ifndef __SMCC_RISCV32_INSTR_H__
#define __SMCC_RISCV32_INSTR_H__ #define __SMCC_RISCV32_INSTR_H__
#include "riscv32.h" #include "riscv32_mcode.h"
#include "riscv32_def.h" #include "riscv32_def.h"
#include "symtab_asm.h"
#define EMIT_PUSH_BACK (-1) #define EMIT_PUSH_BACK (-1)
/* base integer instruction */ /* base integer instruction */
@ -16,7 +15,7 @@
* rd = rs1 + rs2 * rd = rs1 + rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_ADD, .instr_type = RV_ADD,
.rd = rd, .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) * rd = rs1 + imm (imm maybe cut)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_ADDI, .instr_type = RV_ADDI,
.rd = rd, .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 * rd = rs1 & rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_AND, .instr_type = RV_AND,
.rd = rd, .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) * rd = rs1 & imm (imm maybe cut)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_ANDI, .instr_type = RV_ANDI,
.rd = rd, .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} * rd = PC + imm{12}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_AUIPC, .instr_type = RV_AUIPC,
.rd = rd, .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} * if (rs1 == rs2) PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BEQ, .instr_type = RV_BEQ,
.rd = REG_NULL, .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} * if (rs1 >= rs2) PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BGE, .instr_type = RV_BGE,
.rd = REG_NULL, .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} * if (rs1 >= u rs2) PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BGEU, .instr_type = RV_BGEU,
.rd = REG_NULL, .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} * if (rs1 < rs2) PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BLT, .instr_type = RV_BLT,
.rd = REG_NULL, .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} * if (rs1 < u rs2) PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BLTU, .instr_type = RV_BLTU,
.rd = REG_NULL, .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} * if (rs1 != rs2) PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BNE, .instr_type = RV_BNE,
.rd = REG_NULL, .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 * Transfer control to debugger
*/ */
static inline int static inline int
rv32_ebreak(rv32_prog_t* prog) { rv32_ebreak(mcode_rv32_t* prog) {
rv32_instr_t instr = { rv32_instr_t instr = {
.instr_type = RV_EBREAK, .instr_type = RV_EBREAK,
.rd = REG_NULL, .rd = REG_NULL,
@ -244,7 +243,7 @@ rv32_ebreak(rv32_prog_t* prog) {
* Transfer control to operating system * Transfer control to operating system
*/ */
static inline int static inline int
rv32_ecall(rv32_prog_t* prog) { rv32_ecall(mcode_rv32_t* prog) {
rv32_instr_t instr = { rv32_instr_t instr = {
.instr_type = RV_ECALL, .instr_type = RV_ECALL,
.rd = REG_NULL, .rd = REG_NULL,
@ -263,7 +262,7 @@ rv32_ecall(rv32_prog_t* prog) {
* rd = PC + 4; PC += imm{alian2} * rd = PC + 4; PC += imm{alian2}
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_JAL, .instr_type = RV_JAL,
.rd = rd, .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 * rd = PC + 4; PC = rs1 + imm
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_JALR, .instr_type = RV_JALR,
.rd = rd, .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] * rd = (8 bit) M[rs1+imm]
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_LB, .instr_type = RV_LB,
.rd = rd, .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] * rd = (8 bit) M[rs1+imm]
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_LBU, .instr_type = RV_LBU,
.rd = rd, .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 * rd = (32 bit) imm
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_LUI, .instr_type = RV_LUI,
.rd = rd, .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] * rd = (32 bit) M[rs1+imm]
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_LW, .instr_type = RV_LW,
.rd = rd, .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] * rd = (32 bit) u M[rs1+imm]
*/ */
// static inline int // 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); // 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 * rd = rs1 | rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_OR, .instr_type = RV_OR,
.rd = rd, .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) * rd = rs1 | imm (imm maybe cut)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_ORI, .instr_type = RV_ORI,
.rd = rd, .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 * M[rs1+imm] = rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SB, .instr_type = RV_SB,
.rd = REG_NULL, .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 * rd = rs1 << rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SLL, .instr_type = RV_SLL,
.rd = rd, .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) * rd = rs1 << imm (maybe cut it)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SLLI, .instr_type = RV_SLLI,
.rd = rd, .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 * rd = (rs1 < rs2) ? 1 : 0
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SLT, .instr_type = RV_SLT,
.rd = rd, .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 * rd = (rs1 < imm) ? 1 : 0
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SLTI, .instr_type = RV_SLTI,
.rd = rd, .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 * rd = (u rs1 < imm) ? 1 : 0
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SLTIU, .instr_type = RV_SLTIU,
.rd = rd, .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 * rd = (u rs1 < u rs2) ? 1 : 0
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SLTU, .instr_type = RV_SLTU,
.rd = rd, .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 * rd = rs1 >> rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SRA, .instr_type = RV_SRA,
.rd = rd, .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) * rd = rs1 >> imm (maybe cut it)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SRAI, .instr_type = RV_SRAI,
.rd = rd, .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 * rd = (u rs1) >> rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SRL, .instr_type = RV_SRL,
.rd = rd, .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) * rd = (u rs1) >> imm (maybe cut it)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SRLI, .instr_type = RV_SRLI,
.rd = rd, .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 * rd = rs1 - rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SUB, .instr_type = RV_SUB,
.rd = rd, .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 * M[rs1+imm] = rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_SW, .instr_type = RV_SW,
.rd = REG_NULL, .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 * rd = rs1 ^ rs2
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_XOR, .instr_type = RV_XOR,
.rd = rd, .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) * rd = rs1 ^ imm (maybe cut it)
*/ */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_XORI, .instr_type = RV_XORI,
.rd = rd, .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} * if (rs1 == 0) PC += imm{alian2}
*/ */
static inline int 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); 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} * if (rs1 != 0) PC += imm{alian2}
*/ */
static inline int 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); 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} * PC = imm{alian2}
*/ */
static inline int static inline int
rv32_j(rv32_prog_t* prog, u32_t imm) { rv32_j(mcode_rv32_t* prog, u32_t imm) {
// TODO // TODO
return rv32_jal(prog, REG_X0, imm); return rv32_jal(prog, REG_X0, imm);
} }
@ -767,7 +766,7 @@ rv32_j(rv32_prog_t* prog, u32_t imm) {
* PC = rs1 * PC = rs1
*/ */
static inline int static inline int
rv32_jr(rv32_prog_t* prog, rv_reg_t rs1) { rv32_jr(mcode_rv32_t* prog, rv_reg_t rs1) {
// TODO // TODO
return rv32_jalr(prog, REG_X0, rs1, 0); return rv32_jalr(prog, REG_X0, rs1, 0);
} }
@ -780,7 +779,7 @@ rv32_jr(rv32_prog_t* prog, rv_reg_t rs1) {
* rd = address * rd = address
*/ */
static inline int 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 // TODO
return rv32_auipc(prog, rd, imm); 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 * rd = imm
*/ */
static inline int 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) { if (imm >= -2048 && imm <= 2047) {
return rv32_addi(prog, rd, REG_X0, imm); return rv32_addi(prog, rd, REG_X0, imm);
} else { } else {
@ -811,7 +810,7 @@ rv32_li(rv32_prog_t* prog, rv_reg_t rd, i32_t imm) {
* rd = rs1 * rd = rs1
*/ */
static inline int 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); 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 * rd = -rs1
*/ */
static inline int 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); 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 * x0 = x0
*/ */
static inline int static inline int
rv32_nop(rv32_prog_t* prog) { rv32_nop(mcode_rv32_t* prog) {
return rv32_addi(prog, REG_X0, REG_X0, 0); return rv32_addi(prog, REG_X0, REG_X0, 0);
} }
@ -847,7 +846,7 @@ rv32_nop(rv32_prog_t* prog) {
* rd = ~rs1 * rd = ~rs1
*/ */
static inline int 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); 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 * PC = ra
*/ */
static inline int static inline int
rv32_ret(rv32_prog_t* prog) { rv32_ret(mcode_rv32_t* prog) {
return rv32_jalr(prog, REG_X0, REG_RA, 0); return rv32_jalr(prog, REG_X0, REG_RA, 0);
} }
@ -871,7 +870,7 @@ rv32_ret(rv32_prog_t* prog) {
* rd = (rs1 == 0) ? 1 : 0 * rd = (rs1 == 0) ? 1 : 0
*/ */
static inline int 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 // TODO
return rv32_sltiu(prog, rd, rs1, 1); 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 * rd = (rs1 != 0) ? 1 : 0
*/ */
static inline int 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 // TODO
return rv32_sltu(prog, rd, rs1, REG_X0); return rv32_sltu(prog, rd, rs1, REG_X0);
} }
/* instruction of rotated (using label) */ /* instruction of rotated (using label) */
static inline int 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 = { rv32_instr_t instr = {
.instr_type = RV_BNE, .instr_type = RV_BNE,
.rd = REG_NULL, .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 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 = { rv32_instr_t instr = {
.instr_type = RV_JAL, .instr_type = RV_JAL,
.rd = rd, .rd = rd,
@ -915,7 +914,7 @@ rv32_jal_l(rv32_prog_t* prog, rv_reg_t rd, symasm_entry_t* label) {
} }
static inline int 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; rv32_instr_t instr;
instr.instr_type = RV_JAL; instr.instr_type = RV_JAL;
@ -937,12 +936,4 @@ rv32_call_l(rv32_prog_t* prog, symasm_entry_t* label) {
return ret; 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 #endif

View File

@ -1,6 +1,4 @@
#include "riscv32.h" #include "riscv32_mcode.h"
#include "riscv32_def.h"
#include <lib/core.h>
static const rv32_instr_t rv32_instrs[] = { static const rv32_instr_t rv32_instrs[] = {
[RV_LUI] = {RV32_I_EXT, RV_U_TYPE, RV_LUI, "lui", 0x37}, [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)}, [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) { static inline int valid_reg(rv_reg_t reg) {
// return reg >= REG_X0 && reg <= REG_X31; // return reg >= REG_X0 && reg <= REG_X31;
return !(reg & ~0x1F); return !(reg & ~0x1F);
} }
// static int valid_instr void init_rv32_mcode(mcode_rv32_t* mcode, int target_size) {
// (rv_instr_type_t type, u32_t imm, rv_reg_t rs1, rv_reg_t rs2, rv_reg_t rd) { vector_init(mcode->code);
// Assert(type >= 0 && type < RV_INSTR_TYPE_COUNT); vector_init(mcode->rinstrs);
// rv_fmt_t fmt = rv32_instrs[type].format; mcode->target_size = target_size;
// 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;
// }
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 // TODO check out input data
instr->extention = rv32_instrs[instr->instr_type].extention; instr->extention = rv32_instrs[instr->instr_type].extention;
instr->format = rv32_instrs[instr->instr_type].format; 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) { if (target != NULL) {
Assert(idx == -1); 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 = { rotated_instr_t rinstr = {
.instr = *instr, .instr = *instr,
.address = prog->text.size, .pos = mcode->code.size,
.target = *target, .target = ptr,
}; };
vector_push(prog->rinstrs, rinstr); vector_push(mcode->rinstrs, rinstr);
// GOTO idx == -1 // GOTO idx == -1
} }
if (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; return idx;
} else if (idx >= 0 && idx < prog->text.size) { } else if (idx >= 0 && idx < mcode->code.size) {
vector_at(prog->text, idx) = instr->instr; *(u32_t*)&vector_at(mcode->code, idx) = instr->instr;
return prog->text.size - 1; return mcode->code.size - 1;
} else { } else {
Panic("Invalid instruction index"); Panic("Invalid instruction index");
} }
return -1; 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;
// }

View File

@ -0,0 +1,23 @@
#ifndef __SMCC_ASM_RISCV32_H__
#define __SMCC_ASM_RISCV32_H__
#include <lib/core.h>
#include <lib/utils/ds/vector.h>
#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

0
src/pprocesser/main.c Normal file
View File

View File

@ -1,5 +1,5 @@
#include "header.h" #include <src/ccompiler/ccompiler.h>
#include <ccompiler/ccompiler.h> #include "linker/header.h"
#include <stdio.h> #include <stdio.h>
int main(int argc, char** argv) { int main(int argc, char** argv) {
@ -37,19 +37,11 @@ int main(int argc, char** argv) {
&prog->rv32, &prog->rv32,
NULL, NULL,
}; };
// rv32_progs[0] = rv32_crt;
// rv32_progs[1] = &prog->rv32;
// rv32_progs[2] = NULL;
rv32_prog_t* code = link_rv32_prog(rv32_progs); 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 // 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); // fwrite(code->data.data, sizeof(u8_t)code->text.size, 1, out);
fclose(in); fclose(in);

52
src/test.c Normal file
View File

@ -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;
}