stable 重构文件结构
抽象出Machine Code
This commit is contained in:
parent
74f43a1ab7
commit
b57f21556a
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,6 +3,8 @@
|
||||
|
||||
# smcc compiler generated files
|
||||
*.bin
|
||||
.s
|
||||
.asm
|
||||
|
||||
# linux binary files
|
||||
*.o
|
||||
|
@ -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
|
@ -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
|
@ -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
30
src/Makefile
Normal 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
144
src/assembler/assembler.c
Normal 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
18
src/assembler/assembler.h
Normal 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
|
@ -1,6 +1,6 @@
|
||||
CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -g -Wall -I../..
|
||||
CFLAGS = -g -Wall -I../../..
|
||||
|
||||
# 自动收集所有子模块源文件
|
||||
EXCLUDE = test*.c
|
15
src/assembler/riscv32/riscv32_asm.c
Normal file
15
src/assembler/riscv32/riscv32_asm.c
Normal 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));
|
||||
}
|
18
src/assembler/riscv32/riscv32_asm.h
Normal file
18
src/assembler/riscv32/riscv32_asm.h
Normal 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
|
@ -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);
|
||||
}
|
62
src/assembler/riscv32/test.asm.s
Normal file
62
src/assembler/riscv32/test.asm.s
Normal 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
|
@ -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
|
@ -11,7 +11,7 @@
|
||||
// #endif
|
||||
|
||||
// TODO 统一 汇编器 接口
|
||||
#include <assembler/assembler.h>
|
||||
#include <src/assembler/assembler.h>
|
||||
#include "../middleend/ir/ir.h"
|
||||
typedef enum cc_arch {
|
||||
CC_ARCH_RISCV32,
|
@ -1,5 +1,5 @@
|
||||
#include "riscv32.h"
|
||||
#include <assembler/riscv32/riscv32_instr.h>
|
||||
#include <src/mcode/riscv32/riscv32_instr.h>
|
||||
|
||||
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 ++) {
|
@ -1,8 +1,7 @@
|
||||
#ifndef __SMCC_CC_RISCV32_H__
|
||||
#define __SMCC_CC_RISCV32_H__
|
||||
|
||||
#include <assembler/assembler.h>
|
||||
#include <assembler/riscv32/riscv32.h>
|
||||
#include <src/assembler/assembler.h>
|
||||
#include "../../middleend/ir/ir.h"
|
||||
|
||||
int gen_rv32_from_ir(ir_prog_t* ir, rv32_prog_t* out_asm);
|
@ -1,8 +1,9 @@
|
||||
#ifndef __AST_H__
|
||||
#define __AST_H__
|
||||
|
||||
#include <lib/utils/ds/vector.h>
|
||||
#include "../lexer/lexer.h"
|
||||
#include <lib/utils/ds/vector.h>
|
||||
#include "symtab/symtab.h"
|
||||
#include "type.h"
|
||||
|
||||
typedef enum {
|
@ -2,7 +2,7 @@
|
||||
#define __PARSER_H__
|
||||
|
||||
#include "../lexer/lexer.h"
|
||||
#include <lib/utils/symtab/symtab.h>
|
||||
#include "symtab/symtab.h"
|
||||
#include "ast.h"
|
||||
#define PARSER_MAX_TOKEN_QUEUE 16
|
||||
|
62
src/ccompiler/frontend/parser/symtab/symtab.c
Normal file
62
src/ccompiler/frontend/parser/symtab/symtab.c
Normal 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);
|
||||
}
|
39
src/ccompiler/frontend/parser/symtab/symtab.h
Normal file
39
src/ccompiler/frontend/parser/symtab/symtab.h
Normal 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
|
0
src/ccompiler/middleend/ir/ir.c
Normal file
0
src/ccompiler/middleend/ir/ir.c
Normal file
0
src/ccompiler/middleend/reg_alloc.c
Normal file
0
src/ccompiler/middleend/reg_alloc.c
Normal file
17
src/linker/Makefile
Normal file
17
src/linker/Makefile
Normal 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
10
src/linker/header.h
Normal 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
|
@ -1,9 +1,13 @@
|
||||
#include "header.h"
|
||||
#include <src/mcode/riscv32/riscv32_mcode.h>
|
||||
#include <src/mcode/riscv32/riscv32_instr.h>
|
||||
// #include <assembler/riscv32/riscv32.c>
|
||||
|
||||
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;
|
||||
}
|
@ -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;
|
||||
}
|
17
src/mcode/Makefile
Normal file
17
src/mcode/Makefile
Normal 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)
|
@ -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
|
@ -1,6 +1,4 @@
|
||||
#include "riscv32.h"
|
||||
#include "riscv32_def.h"
|
||||
#include <lib/core.h>
|
||||
#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;
|
||||
// }
|
23
src/mcode/riscv32/riscv32_mcode.h
Normal file
23
src/mcode/riscv32/riscv32_mcode.h
Normal 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
0
src/pprocesser/main.c
Normal file
@ -1,5 +1,5 @@
|
||||
#include "header.h"
|
||||
#include <ccompiler/ccompiler.h>
|
||||
#include <src/ccompiler/ccompiler.h>
|
||||
#include "linker/header.h"
|
||||
#include <stdio.h>
|
||||
|
||||
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);
|
52
src/test.c
Normal file
52
src/test.c
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user