Skip to content

Commit

Permalink
Merge branch 'feature/riscv-linker'
Browse files Browse the repository at this point in the history
  • Loading branch information
tyfkda committed May 9, 2024
2 parents 7a75605 + 92ff486 commit bdddc1c
Show file tree
Hide file tree
Showing 17 changed files with 385 additions and 85 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ endif
# CFLAGS+=-DNDEBUG

UNAME:=$(shell uname)
ifeq ("$(UNAME)", "Darwin")
ifeq ("$(UNAME):$(HOST_CC_PREFIX)", "Darwin:")
LIBS:=
else
LIBS:=$(LIB_DIR)/crt0.a $(LIB_DIR)/libc.a
Expand Down Expand Up @@ -167,7 +167,7 @@ ifeq ("$(LIBS)", "")
libs: exes
else
libs: exes
$(MAKE) CC=../xcc -C libsrc
$(MAKE) CC=../xcc HOST_CC_PREFIX=$(HOST_CC_PREFIX) -C libsrc
endif

### Self hosting
Expand Down
3 changes: 3 additions & 0 deletions include/setjmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ typedef uintptr_t jmp_buf[192 / 8];

#elif defined(__x86_64__)
typedef uintptr_t jmp_buf[200 / 8]; // GCC

#elif defined(__riscv)
typedef uintptr_t jmp_buf[208 / 8];
#endif

int setjmp(jmp_buf env);
Expand Down
4 changes: 4 additions & 0 deletions libsrc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ else
CFLAGS:=-I$(INC_DIR) -Wall -Wextra -Werror
endif

ifneq ("$(HOST_CC_PREFIX)", "")
AR:=$(HOST_CC_PREFIX)ar
endif

### Library

CRT0_DIR:=$(SRC_DIR)/crt0
Expand Down
7 changes: 7 additions & 0 deletions libsrc/crt0/_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ void _start(void) {
"mov x1, x2\n"
"mov x2, x3\n"
"b start2");
#elif defined(__riscv)
__asm("lw a0, 0(sp)\n" // argc
"addi a1, sp, 8\n" // argv
"slli a2, a0, 3\n"
"addi a2, a2, 8\n"
"add a2, a2, a1\n" // envp
"j start2\n");
#else
#error unknown target
#endif
Expand Down
21 changes: 21 additions & 0 deletions libsrc/misc/longjmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,26 @@ void longjmp(jmp_buf env, int result) {
"mov w0, #1\n"
".longjmp_0:");
}
#elif defined(__riscv)
void longjmp(jmp_buf env, int result) {
__asm("ld ra, 0(a0)\n"
"ld sp, 8(a0)\n"
"ld fp, 16(a0)\n"
"ld s1, 24(a0)\n"
"ld s2, 32(a0)\n"
"ld s3, 40(a0)\n"
"ld s4, 48(a0)\n"
"ld s5, 56(a0)\n"
"ld s6, 64(a0)\n"
"ld s7, 72(a0)\n"
"ld s8, 80(a0)\n"
"ld s9, 88(a0)\n"
"ld s10, 96(a0)\n"
"ld s11, 104(a0)\n"
"mv a0, a1\n"
"bne a0, zero, .longjmp_0\n"
"li a0, 1\n"
".longjmp_0:");
}
#endif
#endif
18 changes: 18 additions & 0 deletions libsrc/misc/setjmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,23 @@ int setjmp(jmp_buf env) {
"stp d14, d15, [x0, 160]\n"
"mov w0, wzr");
}
#elif defined(__riscv)
int setjmp(jmp_buf env) {
__asm("sd ra, 0(a0)\n"
"sd sp, 8(a0)\n"
"sd fp, 16(a0)\n"
"sd s1, 24(a0)\n"
"sd s2, 32(a0)\n"
"sd s3, 40(a0)\n"
"sd s4, 48(a0)\n"
"sd s5, 56(a0)\n"
"sd s6, 64(a0)\n"
"sd s7, 72(a0)\n"
"sd s8, 80(a0)\n"
"sd s9, 88(a0)\n"
"sd s10, 96(a0)\n"
"sd s11, 104(a0)\n"
"li a0, 0\n");
}
#endif
#endif
13 changes: 13 additions & 0 deletions libsrc/stdio/stdin.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,21 @@
static FILE _stdin = {.iof = IOF, .flush = _fflush, .fd = STDIN_FILENO, .flag = FF_READ};
static FILE _stdout = {.iof = IOF, .flush = _fflush, .fd = STDOUT_FILENO, .flag = FF_WRITE, .wbuf = _stdout.wwork, .ws = sizeof(_stdout.wwork)};
static FILE _stderr = {.iof = IOF, .flush = _fflush, .fd = STDERR_FILENO, .flag = FF_WRITE, .wbuf = _stderr.wwork, .ws = sizeof(_stderr.wwork)};

#if defined(__riscv)
static struct _reent _impure_entity = {
._errno = 0,
._stdin = &_stdin,
._stdout = &_stdout,
._stderr = &_stderr,
};
struct _reent *_impure_ptr = &_impure_entity;

#else

FILE *stdin = &_stdin;
FILE *stdout = &_stdout;
FILE *stderr = &_stderr;
#endif

FILEMAN __fileman;
28 changes: 28 additions & 0 deletions libsrc/unistd/_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,34 @@
#define __NR_clock_gettime 113
#define __NR_newfstatat 79

#elif defined(__riscv)

#define SYSCALL(no) _SYSCALL2(no)
#define _SYSCALL2(no) \
__asm("li a7, " #no "\n" \
"ecall")

#define SYSCALL_RET(no, ret) _SYSCALL_RET2(no, ret)
#define _SYSCALL_RET2(no, ret) \
__asm("li a7, " #no "\n" \
"ecall" \
: "=r"(ret))

#define __NR_getcwd 17
#define __NR_dup 23
#define __NR_chdir 49
#define __NR_openat 56
#define __NR_close 57
#define __NR_lseek 62
#define __NR_read 63
#define __NR_write 64
#define __NR_exit 93
#define __NR_kill 129
#define __NR_brk 214
#define __NR_execve 221
#define __NR_wait4 260
#define __NR_fstat 80

#else
#error unknown
#endif
61 changes: 47 additions & 14 deletions src/as/arch/riscv64/asm_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,42 @@ static unsigned char *asm_2ri(Inst *inst, Code *code) {
}
}
switch (inst->op) {
case ADDI: W_ADDI(rd, rs, imm); break;
case ADDIW: W_ADDIW(rd, rs, imm); break;
case ANDI: W_ANDI(rd, rs, imm); break;
case ORI: W_ORI(rd, rs, imm); break;
case XORI: W_XORI(rd, rs, imm); break;
case SLLI: W_SLLI(rd, rs, imm); break;
case SLLIW: W_SLLIW(rd, rs, imm); break;
case SRLI: W_SRLI(rd, rs, imm); break;
case SRAI: W_SRAI(rd, rs, imm); break;
case SLTI: W_SLTI(rd, rs, imm); break;
case SLTIU: W_SLTIU(rd, rs, imm); break;
case ADDI:
case ADDIW:
case ANDI:
case ORI:
case XORI:
if (imm >= 2048 || imm < -2048)
return NULL;
switch (inst->op) {
case ADDI: W_ADDI(rd, rs, imm); break;
case ADDIW: W_ADDIW(rd, rs, imm); break;
case ANDI: W_ANDI(rd, rs, imm); break;
case ORI: W_ORI(rd, rs, imm); break;
case XORI: W_XORI(rd, rs, imm); break;
default: assert(false); break;
}
break;

case SLLI:
case SLLIW:
case SRLI:
case SRAI:
case SLTI:
case SLTIU:
if (imm >= 64 || (inst->op == SLLIW && imm >= 32) || imm < 0)
return NULL;
switch (inst->op) {
case SLLI: W_SLLI(rd, rs, imm); break;
case SLLIW: W_SLLIW(rd, rs, imm); break;
case SRLI: W_SRLI(rd, rs, imm); break;
case SRAI: W_SRAI(rd, rs, imm); break;
case SLTI: W_SLTI(rd, rs, imm); break;
case SLTIU: W_SLTIU(rd, rs, imm); break;
default: assert(false); break;
}
break;

default: assert(false); return NULL;
}
return code->buf;
Expand Down Expand Up @@ -182,7 +207,10 @@ static unsigned char *asm_noop(Inst *inst, Code *code) {
static unsigned char *asm_mv(Inst *inst, Code *code) {
int rd = inst->opr1.reg.no;
int rs = inst->opr2.reg.no;
C_MV(rd, rs);
if (rs != ZERO)
C_MV(rd, rs);
else
C_LI(rd, 0);
return code->buf;
}

Expand Down Expand Up @@ -329,7 +357,6 @@ static unsigned char *asm_sd(Inst *inst, Code *code) {
}

static unsigned char *asm_j(Inst *inst, Code *code) {
UNUSED(inst);
// imm[11|4|9:8|10|6|7|3:1|5]
C_J();
return code->buf;
Expand Down Expand Up @@ -364,14 +391,14 @@ static unsigned char *asm_bxx(Inst *inst, Code *code) {
default: break;
}
}
code->flag |= INST_LONG_OFFSET;
static const int kFunct3Table[] = { _BEQ, _BNE, _BLT, _BGE, _BLTU, _BGEU };
int funct3 = kFunct3Table[inst->op - BEQ];
W_BXX(funct3, rs1, rs2, 0);
return code->buf;
}

static unsigned char *asm_call_d(Inst *inst, Code *code) {
UNUSED(inst);
W_AUIPC(RA, 0);
W_JALR(RA, RA, 0);
return code->buf;
Expand All @@ -382,6 +409,11 @@ static unsigned char *asm_ret(Inst *inst, Code *code) {
return code->buf;
}

static unsigned char *asm_ecall(Inst *inst, Code *code) {
W_ECALL();
return code->buf;
}

static unsigned char *asm_3fr(Inst *inst, Code *code) {
assert(inst->opr1.type == FREG);
assert(inst->opr2.type == FREG);
Expand Down Expand Up @@ -641,6 +673,7 @@ static const AsmInstTable *table[] = {
[BLTU] = table_bxx, [BGEU] = table_bxx,
[CALL] = (const AsmInstTable[]){ {asm_call_d, DIRECT, NOOPERAND, NOOPERAND}, {NULL} },
[RET] = (const AsmInstTable[]){ {asm_ret, NOOPERAND, NOOPERAND, NOOPERAND}, {NULL} },
[ECALL] = (const AsmInstTable[]){ {asm_ecall, NOOPERAND, NOOPERAND, NOOPERAND}, {NULL} },

[FADD_D] = table_3fr, [FSUB_D] = table_3fr, [FMUL_D] = table_3fr, [FDIV_D] = table_3fr,
[FADD_S] = table_3fr, [FSUB_S] = table_3fr, [FMUL_S] = table_3fr, [FDIV_S] = table_3fr,
Expand Down
1 change: 1 addition & 0 deletions src/as/arch/riscv64/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum Opcode {
BEQ, BNE, BLT, BGE, BLTU, BGEU,
CALL,
RET,
ECALL,

FADD_D, FSUB_D, FMUL_D, FDIV_D,
FADD_S, FSUB_S, FMUL_S, FDIV_S,
Expand Down
Loading

0 comments on commit bdddc1c

Please sign in to comment.