~oriansj/M2libc

de7c75f144176c3b9be77695d9bf94440445aeae — Andrius Štikonas 9 months ago 1139b2b
Switch to lowercase riscv M1 defines.
M riscv32/libc-core.M1 => riscv32/libc-core.M1 +15 -15
@@ 15,30 15,30 @@
## along with stage0.  If not, see <http://www.gnu.org/licenses/>.

:_start
    RD_FP RS1_SP MV        ; Protect stack pointer
    rd_fp rs1_sp mv        ; Protect stack pointer

    ; Prepare argv
    RD_A0 RS1_FP !4 ADDI   ; ARGV_address = FP + 4
    RD_SP RS1_SP !-4 ADDI
    RS1_SP RS2_A0 SW       ; Put argv on the stack
    rd_a0 rs1_fp !4 addi   ; ARGV_address = FP + 4
    rd_sp rs1_sp !-4 addi
    rs1_sp rs2_a0 sw       ; Put argv on the stack

    ; Prepare envp
    RD_A0 RS1_FP MV        ; Address we need to load from
    RD_A0 RS1_A0 LW        ; Get ARGC
    RD_A0 RS1_A0 !2 ADDI   ; OFFSET = ARGC + 2
    RD_A0 RS1_A0 RS2_X3 SLLI ; OFFSET = OFFSET * WORDSIZE
    RD_A0 RS1_FP RS2_A0 ADD ; ENVP_address = RSP + OFFSET
    RD_SP RS1_SP !-4 ADDI
    RS1_SP RS2_A0 SW       ; Put envp on the stack
    rd_a0 rs1_fp mv        ; Address we need to load from
    rd_a0 rs1_a0 lw        ; Get ARGC
    rd_a0 rs1_a0 !2 addi   ; OFFSET = ARGC + 2
    rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
    rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
    rd_sp rs1_sp !-4 addi
    rs1_sp rs2_a0 sw       ; Put envp on the stack

    ; Stack offset
    RD_FP RS1_FP !4 ADDI
    rd_fp rs1_fp !4 addi

    ; Call main function
    RD_RA $FUNCTION_main JAL
    rd_ra $FUNCTION_main jal

    ; Exit to kernel
:FUNCTION_exit
:FUNCTION__exit
    RD_A7 !93 ADDI         ; Syscall for exit
    ECALL                  ; Exit with code in a0
    rd_a7 !93 addi         ; Syscall for exit
    ecall                  ; Exit with code in a0

M riscv32/libc-full.M1 => riscv32/libc-full.M1 +24 -24
@@ 15,48 15,48 @@
## along with stage0.  If not, see <http://www.gnu.org/licenses/>.

:_start
    RD_FP RS1_SP MV        ; Protect stack pointer
    rd_fp rs1_sp mv        ; Protect stack pointer

    ; Prepare argv
    RD_A0 RS1_FP !4 ADDI   ; ARGV_address = FP + 4
    RD_SP RS1_SP !-4 ADDI
    RS1_SP RS2_A0 SW       ; Put argv on the stack
    rd_a0 rs1_fp !4 addi   ; ARGV_address = FP + 4
    rd_sp rs1_sp !-4 addi
    rs1_sp rs2_a0 sw       ; Put argv on the stack

    ; Prepare envp
    RD_A0 RS1_FP MV           ; Address we need to load from
    RD_A0 RS1_A0 LW           ; Get ARGC
    RD_A0 RS1_A0 !2 ADDI      ; OFFSET = ARGC + 2
    RD_A0 RS1_A0 RS2_X2 SLLI  ; OFFSET = OFFSET * WORDSIZE
    RD_A0 RS1_FP RS2_A0 ADD   ; ENVP_address = RSP + OFFSET
    RD_SP RS1_SP !-4 ADDI
    RS1_SP RS2_A0 SW          ; Put envp on the stack
    RD_A1 ~GLOBAL__envp AUIPC ; Get _envp global
    RD_A1 RS1_A1 !GLOBAL__envp ADDI
    RS1_A1 RS2_A0 SW          ; Save environment to _envp
    rd_a0 rs1_fp mv           ; Address we need to load from
    rd_a0 rs1_a0 lw           ; Get ARGC
    rd_a0 rs1_a0 !2 addi      ; OFFSET = ARGC + 2
    rd_a0 rs1_a0 rs2_x2 slli  ; OFFSET = OFFSET * WORDSIZE
    rd_a0 rs1_fp rs2_a0 add   ; ENVP_address = RSP + OFFSET
    rd_sp rs1_sp !-4 addi
    rs1_sp rs2_a0 sw          ; Put envp on the stack
    rd_a1 ~GLOBAL__envp auipc ; Get _envp global
    rd_a1 rs1_a1 !GLOBAL__envp addi
    rs1_a1 rs2_a0 sw          ; Save environment to _envp

    ; Stack offset
    RD_FP RS1_FP !4 ADDI
    rd_fp rs1_fp !4 addi

    ; Setup for malloc
    RD_RA $FUNCTION___init_malloc JAL
    rd_ra $FUNCTION___init_malloc jal

    ; Setup for FILE*
    RD_RA $FUNCTION___init_io JAL
    rd_ra $FUNCTION___init_io jal

    ; Call main function
    RD_RA $FUNCTION_main JAL
    rd_ra $FUNCTION_main jal

    ; Put return value on the stack so that _exit gets it
    RD_SP RS1_SP !-8 ADDI
    RS1_SP RS2_A0 SW
    rd_sp rs1_sp !-8 addi
    rs1_sp rs2_a0 sw

    ; Exit to kernel
:FUNCTION_exit
    RD_RA $FUNCTION___kill_io JAL
    rd_ra $FUNCTION___kill_io jal
:FUNCTION__exit
    RD_A0 RS1_SP LW
    RD_A7 !93 ADDI         ; Syscall for exit
    ECALL                  ; Exit with code in a0
    rd_a0 rs1_sp lw
    rd_a7 !93 addi         ; Syscall for exit
    ecall                  ; Exit with code in a0

:GLOBAL__envp
	NULL

M riscv32/linux/bootstrap.c => riscv32/linux/bootstrap.c +31 -31
@@ 29,26 29,26 @@

int fgetc(FILE* f)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RS1_SP RS2_A0 SW"
	    "RD_A1 RS1_SP MV"
	    "RD_A2 !1 ADDI"
	    "RD_A7 !63 ADDI"
	    "ECALL"
	    "RD_A1 MV"
	    "RD_T0 RS1_A0 MV"
	    "RD_A0 RS1_SP LW"
	    "RS1_T0 @8 BNEZ"
	    "RD_A0 !-1 ADDI");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rs1_sp rs2_a0 sw"
	    "rd_a1 rs1_sp mv"
	    "rd_a2 !1 addi"
	    "rd_a7 !63 addi"
	    "ecall"
	    "rd_a1 mv"
	    "rd_t0 rs1_a0 mv"
	    "rd_a0 rs1_sp lw"
	    "rs1_t0 @8 bnez"
	    "rd_a0 !-1 addi");
}

void fputc(char s, FILE* f)
{
	asm("RD_A0 RS1_FP !-8 LW"
	    "RD_A1 RS1_FP !-4 ADDI"
	    "RD_A2 !1 ADDI"   /* 1 byte */
	    "RD_A7 !64 ADDI"  /* write */
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 lw"
	    "rd_a1 rs1_fp !-4 addi"
	    "rd_a2 !1 addi"   /* 1 byte */
	    "rd_a7 !64 addi"  /* write */
	    "ecall");
}

void fputs(char* s, FILE* f)


@@ 62,12 62,12 @@ void fputs(char* s, FILE* f)

FILE* open(char* name, int flag, int mode)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A3 RS1_FP !-12 LW"
	    "RD_A7 !56 ADDI"   /* openat */
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a3 rs1_fp !-12 lw"
	    "rd_a7 !56 addi"   /* openat */
	    "ecall");
}

FILE* fopen(char* filename, char* mode)


@@ 92,9 92,9 @@ FILE* fopen(char* filename, char* mode)

int close(int fd)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !57 ADDI"    /* close */
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !57 addi"    /* close */
	    "ecall");
}

int fclose(FILE* stream)


@@ 105,9 105,9 @@ int fclose(FILE* stream)

int brk(void *addr)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !214 ADDI"   /* brk */
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !214 addi"   /* brk */
	    "ecall");
}

long _malloc_ptr;


@@ 164,7 164,7 @@ void free(void* l)

void exit(int value)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !93 ADDI"   /* exit */
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !93 addi"   /* exit */
	    "ecall");
}

M riscv32/linux/fcntl.c => riscv32/linux/fcntl.c +6 -6
@@ 35,12 35,12 @@

int _open(char* name, int flag, int mode)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A3 RS1_FP !-12 LW"
	    "RD_A7 !56 ADDI"
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a3 rs1_fp !-12 lw"
	    "rd_a7 !56 addi"
	    "ecall");
}

#define STDIN_FILENO  0

M riscv32/linux/sys/stat.c => riscv32/linux/sys/stat.c +24 -24
@@ 40,50 40,50 @@

int chmod(char *pathname, int mode)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A7 !53 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a7 !53 addi"
	    "ecall");
}


int fchmod(int a, mode_t b)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A7 !52 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a7 !52 addi"
	    "ecall");
}


int mkdir(char const* a, mode_t b)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A7 !34 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a7 !34 addi"
	    "ecall");
}


int mknod(char const* a, mode_t b, dev_t c)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A3 RS1_FP !-12 LW"
	    "RD_A7 !33 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a3 rs1_fp !-12 lw"
	    "rd_a7 !33 addi"
	    "ecall");
}


mode_t umask(mode_t m)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !166 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !166 addi"
	    "ecall");
}

#endif

M riscv32/linux/unistd.c => riscv32/linux/unistd.c +63 -63
@@ 32,47 32,47 @@ void* malloc(unsigned size);

int access(char* pathname, int mode)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 RS1_FP !-8 LW"
	    "RD_A3 ADDI" /* flags = 0 */
	    "RD_A7 !48 ADDI"
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 rs1_fp !-8 lw"
	    "rd_a3 addi" /* flags = 0 */
	    "rd_a7 !48 addi"
	    "ecall");
}

int chdir(char* path)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !49 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !49 addi"
	    "ecall");
}

int fchdir(int fd)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !50 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !50 addi"
	    "ecall");
}

void _exit(int value);

int fork()
{
	asm("RD_A7 !220 ADDI"
	    "RD_A0 !17 ADDI" /* SIGCHLD */
	    "RD_A1 MV"       /* Child uses duplicate of parent's stack */
	    "ECALL");
	asm("rd_a7 !220 addi"
	    "rd_a0 !17 addi" /* SIGCHLD */
	    "rd_a1 mv"       /* Child uses duplicate of parent's stack */
	    "ecall");
}

int waitid(int idtype, int id, struct siginfo_t *infop, int options, void *rusage)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A1 RS1_FP !-8 LW"
	    "RD_A2 RS1_FP !-12 LW"
	    "RD_A3 RS1_FP !-16 LW"
	    "RD_A4 RS1_FP !-20 LW"
	    "RD_A7 !95 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a1 rs1_fp !-8 lw"
	    "rd_a2 rs1_fp !-12 lw"
	    "rd_a3 rs1_fp !-16 lw"
	    "rd_a4 rs1_fp !-20 lw"
	    "rd_a7 !95 addi"
	    "ecall");
}

void* calloc(int count, int size);


@@ 119,40 119,40 @@ int waitpid(int pid, int* status_ptr, int options)

int execve(char* file_name, char** argv, char** envp)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A1 RS1_FP !-8 LW"
	    "RD_A2 RS1_FP !-12 LW"
	    "RD_A7 !221 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a1 rs1_fp !-8 lw"
	    "rd_a2 rs1_fp !-12 lw"
	    "rd_a7 !221 addi"
	    "ecall");
}

int read(int fd, char* buf, unsigned count)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A1 RS1_FP !-8 LW"
	    "RD_A2 RS1_FP !-12 LW"
	    "RD_A7 !63 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a1 rs1_fp !-8 lw"
	    "rd_a2 rs1_fp !-12 lw"
	    "rd_a7 !63 addi"
	    "ecall");
}

int write(int fd, char* buf, unsigned count)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A1 RS1_FP !-8 LW"
	    "RD_A2 RS1_FP !-12 LW"
	    "RD_A7 !64 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a1 rs1_fp !-8 lw"
	    "rd_a2 rs1_fp !-12 lw"
	    "rd_a7 !64 addi"
	    "ecall");
}

int llseek(int fd, int offset_high, int offset_low, int result, int whence)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A1 RS1_FP !-8 LW"
	    "RD_A2 RS1_FP !-12 LW"
	    "RD_A3 RS1_FP !-16 LW"
	    "RD_A4 RS1_FP !-20 LW"
	    "RD_A7 !62 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a1 rs1_fp !-8 lw"
	    "rd_a2 rs1_fp !-12 lw"
	    "rd_a3 rs1_fp !-16 lw"
	    "rd_a4 rs1_fp !-20 lw"
	    "rd_a7 !62 addi"
	    "ecall");
}

int lseek(int fd, int offset, int whence)


@@ 167,28 167,28 @@ int lseek(int fd, int offset, int whence)

int close(int fd)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !57 ADDI"    /* close */
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !57 addi"    /* close */
	    "ecall");
}


int unlink (char* filename)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-4 LW"
	    "RD_A2 !0 ADDI"     /* No flags */
	    "RD_A7 !35 ADDI"    /* unlinkat */
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-4 lw"
	    "rd_a2 !0 addi"     /* No flags */
	    "rd_a7 !35 addi"    /* unlinkat */
	    "ecall");
}


int _getcwd(char* buf, int size)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A1 RS1_FP !-8 LW"
	    "RD_A7 !17 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a1 rs1_fp !-8 lw"
	    "rd_a7 !17 addi"
	    "ecall");
}




@@ 214,9 214,9 @@ char* get_current_dir_name()

int brk(void *addr)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !214 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !214 addi"
	    "ecall");
}

struct utsname


@@ 230,9 230,9 @@ struct utsname

int uname(struct utsname* unameData)
{
	asm("RD_A0 RS1_FP !-4 LW"
	    "RD_A7 !160 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-4 lw"
	    "rd_a7 !160 addi"
	    "ecall");
}

#endif

M riscv32/riscv32_defs.M1 => riscv32/riscv32_defs.M1 +184 -181
@@ 19,198 19,201 @@ DEFINE NULL 00000000
;; Opcodes

;; RV32I Base Instruction Set
DEFINE LUI   37000000
DEFINE AUIPC 17000000
DEFINE JAL   6F000000
DEFINE JALR  67000000
DEFINE BEQ   63000000
DEFINE BNE   63100000
DEFINE BLT   63400000
DEFINE BGE   63500000
DEFINE BLTU  63600000
DEFINE BGEU  63700000
DEFINE LB    03000000
DEFINE LH    03100000
DEFINE LW    03200000
DEFINE LBU   03400000
DEFINE LHU   03500000
DEFINE SB    23000000
DEFINE SH    23100000
DEFINE SW    23200000
DEFINE ADDI  13000000
DEFINE SLTI  13200000
DEFINE SLTIU 13300000
DEFINE XORI  13400000
DEFINE ORI   13600000
DEFINE ANDI  13700000
DEFINE SLLI  13100000
DEFINE SRLI  13500000
DEFINE SRAI  13500040
DEFINE ADD   33000000
DEFINE SUB   33000040
DEFINE SLL   33100000
DEFINE SLT   33200000
DEFINE SLTU  33300000
DEFINE XOR   33400000
DEFINE SRL   33500000
DEFINE SRA   33500040
DEFINE OR    33600000
DEFINE AND   33700000
DEFINE ECALL 73000000
DEFINE lui   37000000
DEFINE auipc 17000000
DEFINE jal   6F000000
DEFINE jalr  67000000
DEFINE beq   63000000
DEFINE bne   63100000
DEFINE blt   63400000
DEFINE bge   63500000
DEFINE bltu  63600000
DEFINE bgeu  63700000
DEFINE lb    03000000
DEFINE lh    03100000
DEFINE lw    03200000
DEFINE lbu   03400000
DEFINE lhu   03500000
DEFINE sb    23000000
DEFINE sh    23100000
DEFINE sw    23200000
DEFINE addi  13000000
DEFINE slti  13200000
DEFINE sltiu 13300000
DEFINE xori  13400000
DEFINE ori   13600000
DEFINE andi  13700000
DEFINE slli  13100000
DEFINE srli  13500000
DEFINE srai  13500040
DEFINE add   33000000
DEFINE sub   33000040
DEFINE sll   33100000
DEFINE slt   33200000
DEFINE sltu  33300000
DEFINE xor   33400000
DEFINE srl   33500000
DEFINE sra   33500040
DEFINE or    33600000
DEFINE and   33700000
DEFINE ecall 73000000
DEFINE ebreak 73001000

;; RV32M Standard Extensions
DEFINE MUL    33000002
DEFINE MULH   33100002
DEFINE MULHSU 33200002
DEFINE MULHU  33300002
DEFINE DIV    33400002
DEFINE DIVU   33500002
DEFINE REM    33600002
DEFINE REMU   33700002
DEFINE mul    33000002
DEFINE mulh   33100002
DEFINE mulhsu 33200002
DEFINE mulhu  33300002
DEFINE div    33400002
DEFINE divu   33500002
DEFINE rem    33600002
DEFINE remu   33700002

;; Pseudoinstructions
DEFINE NOP  13000000   # ADDI
DEFINE MV   13000000   # ADDI
DEFINE NOT  1340F0FF   # XORI, RD, RS, -1
DEFINE BEQZ 63000000   # BEQ
DEFINE BNEZ 63100000   # BNE
DEFINE BLTZ 63400000   # BLT
DEFINE RETURN 67800000 # RS1_RA JALR
DEFINE nop  13000000   # addi
DEFINE mv   13000000   # addi
DEFINE not  1340F0FF   # xori, RD, RS, -1
DEFINE beqz 63000000   # beq
DEFINE bnez 63100000   # bne
DEFINE bltz 63400000   # blt
DEFINE ret  67800000   # rs1_ra jalr

;; Destination registers
;; register_number << 7
DEFINE RD_RA  .80000000
DEFINE RD_SP  .00010000
DEFINE RD_GP  .80010000
DEFINE RD_TP  .00020000
DEFINE RD_T0  .80020000
DEFINE RD_T1  .00030000
DEFINE RD_T2  .80030000
DEFINE RD_S0  .00040000
DEFINE RD_FP  .00040000
DEFINE RD_S1  .80040000
DEFINE RD_A0  .00050000
DEFINE RD_A1  .80050000
DEFINE RD_A2  .00060000
DEFINE RD_A3  .80060000
DEFINE RD_A4  .00070000
DEFINE RD_A5  .80070000
DEFINE RD_A6  .00080000
DEFINE RD_A7  .80080000
DEFINE RD_S2  .00090000
DEFINE RD_S3  .80090000
DEFINE RD_S4  .000A0000
DEFINE RD_S5  .800A0000
DEFINE RD_S6  .000B0000
DEFINE RD_S7  .800B0000
DEFINE RD_S8  .000C0000
DEFINE RD_S9  .800C0000
DEFINE RD_S10 .000D0000
DEFINE RD_S11 .800D0000
DEFINE RD_T3  .000E0000
DEFINE RD_T4  .800E0000
DEFINE RD_T5  .000F0000
DEFINE RD_T6  .800F0000
DEFINE rd_ra  .80000000
DEFINE rd_sp  .00010000
DEFINE rd_gp  .80010000
DEFINE rd_tp  .00020000
DEFINE rd_t0  .80020000
DEFINE rd_t1  .00030000
DEFINE rd_t2  .80030000
DEFINE rd_s0  .00040000
DEFINE rd_fp  .00040000
DEFINE rd_s1  .80040000
DEFINE rd_a0  .00050000
DEFINE rd_a1  .80050000
DEFINE rd_a2  .00060000
DEFINE rd_a3  .80060000
DEFINE rd_a4  .00070000
DEFINE rd_a5  .80070000
DEFINE rd_a6  .00080000
DEFINE rd_a7  .80080000
DEFINE rd_s2  .00090000
DEFINE rd_s3  .80090000
DEFINE rd_s4  .000A0000
DEFINE rd_s5  .800A0000
DEFINE rd_s6  .000B0000
DEFINE rd_s7  .800B0000
DEFINE rd_s8  .000C0000
DEFINE rd_s9  .800C0000
DEFINE rd_s10 .000D0000
DEFINE rd_s11 .800D0000
DEFINE rd_t3  .000E0000
DEFINE rd_t4  .800E0000
DEFINE rd_t5  .000F0000
DEFINE rd_t6  .800F0000

;; First source registers
;; register_number << 15
DEFINE RS1_RA  .00800000
DEFINE RS1_SP  .00000100
DEFINE RS1_GP  .00800100
DEFINE RS1_TP  .00000200
DEFINE RS1_T0  .00800200
DEFINE RS1_T1  .00000300
DEFINE RS1_T2  .00800300
DEFINE RS1_S0  .00000400
DEFINE RS1_FP  .00000400
DEFINE RS1_S1  .00800400
DEFINE RS1_A0  .00000500
DEFINE RS1_A1  .00800500
DEFINE RS1_A2  .00000600
DEFINE RS1_A3  .00800600
DEFINE RS1_A4  .00000700
DEFINE RS1_A5  .00800700
DEFINE RS1_A6  .00000800
DEFINE RS1_A7  .00800800
DEFINE RS1_S2  .00000900
DEFINE RS1_S3  .00800900
DEFINE RS1_S4  .00000A00
DEFINE RS1_S5  .00800A00
DEFINE RS1_S6  .00000B00
DEFINE RS1_S7  .00800B00
DEFINE RS1_S8  .00000C00
DEFINE RS1_S9  .00800C00
DEFINE RS1_S10 .00000D00
DEFINE RS1_S11 .00800D00
DEFINE RS1_T3  .00000E00
DEFINE RS1_T4  .00800E00
DEFINE RS1_T5  .00000F00
DEFINE RS1_T6  .00800F00
DEFINE rs1_ra  .00800000
DEFINE rs1_sp  .00000100
DEFINE rs1_gp  .00800100
DEFINE rs1_tp  .00000200
DEFINE rs1_t0  .00800200
DEFINE rs1_t1  .00000300
DEFINE rs1_t2  .00800300
DEFINE rs1_s0  .00000400
DEFINE rs1_fp  .00000400
DEFINE rs1_s1  .00800400
DEFINE rs1_a0  .00000500
DEFINE rs1_a1  .00800500
DEFINE rs1_a2  .00000600
DEFINE rs1_a3  .00800600
DEFINE rs1_a4  .00000700
DEFINE rs1_a5  .00800700
DEFINE rs1_a6  .00000800
DEFINE rs1_a7  .00800800
DEFINE rs1_s2  .00000900
DEFINE rs1_s3  .00800900
DEFINE rs1_s4  .00000A00
DEFINE rs1_s5  .00800A00
DEFINE rs1_s6  .00000B00
DEFINE rs1_s7  .00800B00
DEFINE rs1_s8  .00000C00
DEFINE rs1_s9  .00800C00
DEFINE rs1_s10 .00000D00
DEFINE rs1_s11 .00800D00
DEFINE rs1_t3  .00000E00
DEFINE rs1_t4  .00800E00
DEFINE rs1_t5  .00000F00
DEFINE rs1_t6  .00800F00

;; Second source registers
;; register_number << 20
DEFINE RS2_RA  .00001000
DEFINE RS2_SP  .00002000
DEFINE RS2_GP  .00003000
DEFINE RS2_TP  .00004000
DEFINE RS2_T0  .00005000
DEFINE RS2_T1  .00006000
DEFINE RS2_T2  .00007000
DEFINE RS2_S0  .00008000
DEFINE RS2_FP  .00008000
DEFINE RS2_S1  .00009000
DEFINE RS2_A0  .0000A000
DEFINE RS2_A1  .0000B000
DEFINE RS2_A2  .0000C000
DEFINE RS2_A3  .0000D000
DEFINE RS2_A4  .0000E000
DEFINE RS2_A5  .0000F000
DEFINE RS2_A6  .00000001
DEFINE RS2_A7  .00001001
DEFINE RS2_S2  .00002001
DEFINE RS2_S3  .00003001
DEFINE RS2_S4  .00004001
DEFINE RS2_S5  .00005001
DEFINE RS2_S6  .00006001
DEFINE RS2_S7  .00007001
DEFINE RS2_S8  .00008001
DEFINE RS2_S9  .00009001
DEFINE RS2_S10 .0000A001
DEFINE RS2_S11 .0000B001
DEFINE RS2_T3  .0000C001
DEFINE RS2_T4  .0000D001
DEFINE RS2_T5  .0000E001
DEFINE RS2_T6  .0000F001
DEFINE rs2_ra  .00001000
DEFINE rs2_sp  .00002000
DEFINE rs2_gp  .00003000
DEFINE rs2_tp  .00004000
DEFINE rs2_t0  .00005000
DEFINE rs2_t1  .00006000
DEFINE rs2_t2  .00007000
DEFINE rs2_s0  .00008000
DEFINE rs2_fp  .00008000
DEFINE rs2_s1  .00009000
DEFINE rs2_a0  .0000A000
DEFINE rs2_a1  .0000B000
DEFINE rs2_a2  .0000C000
DEFINE rs2_a3  .0000D000
DEFINE rs2_a4  .0000E000
DEFINE rs2_a5  .0000F000
DEFINE rs2_a6  .00000001
DEFINE rs2_a7  .00001001
DEFINE rs2_s2  .00002001
DEFINE rs2_s3  .00003001
DEFINE rs2_s4  .00004001
DEFINE rs2_s5  .00005001
DEFINE rs2_s6  .00006001
DEFINE rs2_s7  .00007001
DEFINE rs2_s8  .00008001
DEFINE rs2_s9  .00009001
DEFINE rs2_s10 .0000A001
DEFINE rs2_s11 .0000B001
DEFINE rs2_t3  .0000C001
DEFINE rs2_t4  .0000D001
DEFINE rs2_t5  .0000E001
DEFINE rs2_t6  .0000F001

DEFINE RS2_X0  .00000000
DEFINE RS2_X1  .00001000
DEFINE RS2_X2  .00002000
DEFINE RS2_X3  .00003000
DEFINE RS2_X4  .00004000
DEFINE RS2_X5  .00005000
DEFINE RS2_X6  .00006000
DEFINE RS2_X7  .00007000
DEFINE RS2_X8  .00008000
DEFINE RS2_X9  .00009000
DEFINE RS2_X10 .0000A000
DEFINE RS2_X11 .0000B000
DEFINE RS2_X12 .0000C000
DEFINE RS2_X13 .0000D000
DEFINE RS2_X14 .0000E000
DEFINE RS2_X15 .0000F000
DEFINE RS2_X16 .00000001
DEFINE RS2_X17 .00001001
DEFINE RS2_X18 .00002001
DEFINE RS2_X19 .00003001
DEFINE RS2_X20 .00004001
DEFINE RS2_X21 .00005001
DEFINE RS2_X22 .00006001
DEFINE RS2_X23 .00007001
DEFINE RS2_X24 .00008001
DEFINE RS2_X25 .00009001
DEFINE RS2_X26 .0000A001
DEFINE RS2_X27 .0000B001
DEFINE RS2_X28 .0000C001
DEFINE RS2_X29 .0000D001
DEFINE RS2_X30 .0000E001
DEFINE RS2_X31 .0000F001
DEFINE rs1_x0  .00000000

DEFINE rs2_x0  .00000000
DEFINE rs2_x1  .00001000
DEFINE rs2_x2  .00002000
DEFINE rs2_x3  .00003000
DEFINE rs2_x4  .00004000
DEFINE rs2_x5  .00005000
DEFINE rs2_x6  .00006000
DEFINE rs2_x7  .00007000
DEFINE rs2_x8  .00008000
DEFINE rs2_x9  .00009000
DEFINE rs2_x10 .0000A000
DEFINE rs2_x11 .0000B000
DEFINE rs2_x12 .0000C000
DEFINE rs2_x13 .0000D000
DEFINE rs2_x14 .0000E000
DEFINE rs2_x15 .0000F000
DEFINE rs2_x16 .00000001
DEFINE rs2_x17 .00001001
DEFINE rs2_x18 .00002001
DEFINE rs2_x19 .00003001
DEFINE rs2_x20 .00004001
DEFINE rs2_x21 .00005001
DEFINE rs2_x22 .00006001
DEFINE rs2_x23 .00007001
DEFINE rs2_x24 .00008001
DEFINE rs2_x25 .00009001
DEFINE rs2_x26 .0000A001
DEFINE rs2_x27 .0000B001
DEFINE rs2_x28 .0000C001
DEFINE rs2_x29 .0000D001
DEFINE rs2_x30 .0000E001
DEFINE rs2_x31 .0000F001

M riscv64/libc-core.M1 => riscv64/libc-core.M1 +15 -15
@@ 15,30 15,30 @@
## along with stage0.  If not, see <http://www.gnu.org/licenses/>.

:_start
    RD_FP RS1_SP MV        ; Protect stack pointer
    rd_fp rs1_sp mv        ; Protect stack pointer

    ; Prepare argv
    RD_A0 RS1_FP !8 ADDI   ; ARGV_address = FP + 8
    RD_SP RS1_SP !-8 ADDI
    RS1_SP RS2_A0 SD       ; Put argv on the stack
    rd_a0 rs1_fp !8 addi   ; ARGV_address = FP + 8
    rd_sp rs1_sp !-8 addi
    rs1_sp rs2_a0 sd       ; Put argv on the stack

    ; Prepare envp
    RD_A0 RS1_FP MV        ; Address we need to load from
    RD_A0 RS1_A0 LD        ; Get ARGC
    RD_A0 RS1_A0 !2 ADDI   ; OFFSET = ARGC + 2
    RD_A0 RS1_A0 RS2_X3 SLLI ; OFFSET = OFFSET * WORDSIZE
    RD_A0 RS1_FP RS2_A0 ADD ; ENVP_address = RSP + OFFSET
    RD_SP RS1_SP !-8 ADDI
    RS1_SP RS2_A0 SD       ; Put envp on the stack
    rd_a0 rs1_fp mv        ; Address we need to load from
    rd_a0 rs1_a0 ld        ; Get ARGC
    rd_a0 rs1_a0 !2 addi   ; OFFSET = ARGC + 2
    rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
    rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
    rd_sp rs1_sp !-8 addi
    rs1_sp rs2_a0 sd       ; Put envp on the stack

    ; Stack offset
    RD_FP RS1_FP !8 ADDI
    rd_fp rs1_fp !8 addi

    ; Call main function
    RD_RA $FUNCTION_main JAL
    rd_ra $FUNCTION_main jal

    ; Exit to kernel
:FUNCTION_exit
:FUNCTION__exit
    RD_A7 !93 ADDI         ; Syscall for exit
    ECALL                  ; Exit with code in a0
    rd_a7 !93 addi         ; Syscall for exit
    ecall                  ; Exit with code in a0

M riscv64/libc-full.M1 => riscv64/libc-full.M1 +24 -24
@@ 15,48 15,48 @@
## along with stage0.  If not, see <http://www.gnu.org/licenses/>.

:_start
    RD_FP RS1_SP MV        ; Protect stack pointer
    rd_fp rs1_sp mv        ; Protect stack pointer

    ; Prepare argv
    RD_A0 RS1_FP !8 ADDI   ; ARGV_address = FP + 8
    RD_SP RS1_SP !-8 ADDI
    RS1_SP RS2_A0 SD       ; Put argv on the stack
    rd_a0 rs1_fp !8 addi   ; ARGV_address = FP + 8
    rd_sp rs1_sp !-8 addi
    rs1_sp rs2_a0 sd       ; Put argv on the stack

    ; Prepare envp
    RD_A0 RS1_FP MV           ; Address we need to load from
    RD_A0 RS1_A0 LD           ; Get ARGC
    RD_A0 RS1_A0 !2 ADDI      ; OFFSET = ARGC + 2
    RD_A0 RS1_A0 RS2_X3 SLLI  ; OFFSET = OFFSET * WORDSIZE
    RD_A0 RS1_FP RS2_A0 ADD   ; ENVP_address = RSP + OFFSET
    RD_SP RS1_SP !-8 ADDI
    RS1_SP RS2_A0 SD          ; Put envp on the stack
    RD_A1 ~GLOBAL__envp AUIPC ; Get _envp global
    RD_A1 RS1_A1 !GLOBAL__envp ADDI
    RS1_A1 RS2_A0 SD          ; Save environment to _envp
    rd_a0 rs1_fp mv           ; Address we need to load from
    rd_a0 rs1_a0 ld           ; Get ARGC
    rd_a0 rs1_a0 !2 addi      ; OFFSET = ARGC + 2
    rd_a0 rs1_a0 rs2_x3 slli  ; OFFSET = OFFSET * WORDSIZE
    rd_a0 rs1_fp rs2_a0 add   ; ENVP_address = RSP + OFFSET
    rd_sp rs1_sp !-8 addi
    rs1_sp rs2_a0 sd          ; Put envp on the stack
    rd_a1 ~GLOBAL__envp auipc ; Get _envp global
    rd_a1 rs1_a1 !GLOBAL__envp addi
    rs1_a1 rs2_a0 sd          ; Save environment to _envp

    ; Stack offset
    RD_FP RS1_FP !8 ADDI
    rd_fp rs1_fp !8 addi

    ; Setup for malloc
    RD_RA $FUNCTION___init_malloc JAL
    rd_ra $FUNCTION___init_malloc jal

    ; Setup for FILE*
    RD_RA $FUNCTION___init_io JAL
    rd_ra $FUNCTION___init_io jal

    ; Call main function
    RD_RA $FUNCTION_main JAL
    rd_ra $FUNCTION_main jal

    ; Put return value on the stack so that _exit gets it
    RD_SP RS1_SP !-16 ADDI
    RS1_SP RS2_A0 SD
    rd_sp rs1_sp !-16 addi
    rs1_sp rs2_a0 sd

    ; Exit to kernel
:FUNCTION_exit
    RD_RA $FUNCTION___kill_io JAL
    rd_ra $FUNCTION___kill_io jal
:FUNCTION__exit
    RD_A0 RS1_SP LD
    RD_A7 !93 ADDI         ; Syscall for exit
    ECALL                  ; Exit with code in a0
    rd_a0 rs1_sp ld
    rd_a7 !93 addi         ; Syscall for exit
    ecall                  ; Exit with code in a0

:GLOBAL__envp
	NULL

M riscv64/linux/bootstrap.c => riscv64/linux/bootstrap.c +31 -31
@@ 29,26 29,26 @@

int fgetc(FILE* f)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RS1_SP RS2_A0 SD"
	    "RD_A1 RS1_SP MV"
	    "RD_A2 !1 ADDI"
	    "RD_A7 !63 ADDI"
	    "ECALL"
	    "RD_A1 MV"
	    "RD_T0 RS1_A0 MV"
	    "RD_A0 RS1_SP LD"
	    "RS1_T0 @8 BNEZ"
	    "RD_A0 !-1 ADDI");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rs1_sp rs2_a0 sd"
	    "rd_a1 rs1_sp mv"
	    "rd_a2 !1 addi"
	    "rd_a7 !63 addi"
	    "ecall"
	    "rd_a1 mv"
	    "rd_t0 rs1_a0 mv"
	    "rd_a0 rs1_sp ld"
	    "rs1_t0 @8 bnez"
	    "rd_a0 !-1 addi");
}

void fputc(char s, FILE* f)
{
	asm("RD_A0 RS1_FP !-16 LD"
	    "RD_A1 RS1_FP !-8 ADDI"
	    "RD_A2 !1 ADDI"   /* 1 byte */
	    "RD_A7 !64 ADDI"  /* write */
	    "ECALL");
	asm("rd_a0 rs1_fp !-16 ld"
	    "rd_a1 rs1_fp !-8 addi"
	    "rd_a2 !1 addi"   /* 1 byte */
	    "rd_a7 !64 addi"  /* write */
	    "ecall");
}

void fputs(char* s, FILE* f)


@@ 62,12 62,12 @@ void fputs(char* s, FILE* f)

FILE* open(char* name, int flag, int mode)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A3 RS1_FP !-24 LD"
	    "RD_A7 !56 ADDI"   /* openat */
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a3 rs1_fp !-24 ld"
	    "rd_a7 !56 addi"   /* openat */
	    "ecall");
}

FILE* fopen(char* filename, char* mode)


@@ 92,9 92,9 @@ FILE* fopen(char* filename, char* mode)

int close(int fd)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !57 ADDI"    /* close */
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !57 addi"    /* close */
	    "ecall");
}

int fclose(FILE* stream)


@@ 105,9 105,9 @@ int fclose(FILE* stream)

int brk(void *addr)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !214 ADDI"   /* brk */
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !214 addi"   /* brk */
	    "ecall");
}

long _malloc_ptr;


@@ 164,7 164,7 @@ void free(void* l)

void exit(int value)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !93 ADDI"   /* exit */
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !93 addi"   /* exit */
	    "ecall");
}

M riscv64/linux/fcntl.c => riscv64/linux/fcntl.c +6 -6
@@ 35,12 35,12 @@

int _open(char* name, int flag, int mode)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A3 RS1_FP !-24 LD"
	    "RD_A7 !56 ADDI"
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a3 rs1_fp !-24 ld"
	    "rd_a7 !56 addi"
	    "ecall");
}

#define STDIN_FILENO  0

M riscv64/linux/sys/stat.c => riscv64/linux/sys/stat.c +24 -24
@@ 40,50 40,50 @@

int chmod(char *pathname, int mode)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A7 !53 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a7 !53 addi"
	    "ecall");
}


int fchmod(int a, mode_t b)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A7 !52 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a7 !52 addi"
	    "ecall");
}


int mkdir(char const* a, mode_t b)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A7 !34 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a7 !34 addi"
	    "ecall");
}


int mknod(char const* a, mode_t b, dev_t c)
{
        asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A3 RS1_FP !-24 LD"
	    "RD_A7 !33 ADDI"
	    "ECALL");
        asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a3 rs1_fp !-24 ld"
	    "rd_a7 !33 addi"
	    "ecall");
}


mode_t umask(mode_t m)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !166 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !166 addi"
	    "ecall");
}

#endif

M riscv64/linux/unistd.c => riscv64/linux/unistd.c +60 -60
@@ 27,112 27,112 @@ void* malloc(unsigned size);

int access(char* pathname, int mode)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 RS1_FP !-16 LD"
	    "RD_A3 ADDI" /* flags = 0 */
	    "RD_A7 !48 ADDI"
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 rs1_fp !-16 ld"
	    "rd_a3 addi" /* flags = 0 */
	    "rd_a7 !48 addi"
	    "ecall");
}

int chdir(char* path)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !49 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !49 addi"
	    "ecall");
}

int fchdir(int fd)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !50 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !50 addi"
	    "ecall");
}

void _exit(int value);

int fork()
{
	asm("RD_A7 !220 ADDI"
	    "RD_A0 !17 ADDI" /* SIGCHLD */
	    "RD_A1 MV"       /* Child uses duplicate of parent's stack */
	    "ECALL");
	asm("rd_a7 !220 addi"
	    "rd_a0 !17 addi" /* SIGCHld */
	    "rd_a1 mv"       /* Child uses duplicate of parent's stack */
	    "ecall");
}


int waitpid (int pid, int* status_ptr, int options)
{
	/* Uses wait4 with struct rusage *ru set to NULL */
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A1 RS1_FP !-16 LD"
	    "RD_A2 RS1_FP !-24 LD"
	    "RD_A3 ADDI"
	    "RD_A7 !260 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a1 rs1_fp !-16 ld"
	    "rd_a2 rs1_fp !-24 ld"
	    "rd_a3 addi"
	    "rd_a7 !260 addi"
	    "ecall");
}


int execve(char* file_name, char** argv, char** envp)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A1 RS1_FP !-16 LD"
	    "RD_A2 RS1_FP !-24 LD"
	    "RD_A7 !221 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a1 rs1_fp !-16 ld"
	    "rd_a2 rs1_fp !-24 ld"
	    "rd_a7 !221 addi"
	    "ecall");
}

int read(int fd, char* buf, unsigned count)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A1 RS1_FP !-16 LD"
	    "RD_A2 RS1_FP !-24 LD"
	    "RD_A7 !63 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a1 rs1_fp !-16 ld"
	    "rd_a2 rs1_fp !-24 ld"
	    "rd_a7 !63 addi"
	    "ecall");
}

int write(int fd, char* buf, unsigned count)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A1 RS1_FP !-16 LD"
	    "RD_A2 RS1_FP !-24 LD"
	    "RD_A7 !64 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a1 rs1_fp !-16 ld"
	    "rd_a2 rs1_fp !-24 ld"
	    "rd_a7 !64 addi"
	    "ecall");
}

int lseek(int fd, int offset, int whence)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A1 RS1_FP !-16 LD"
	    "RD_A2 RS1_FP !-24 LD"
	    "RD_A7 !62 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a1 rs1_fp !-16 ld"
	    "rd_a2 rs1_fp !-24 ld"
	    "rd_a7 !62 addi"
	    "ecall");
}


int close(int fd)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !57 ADDI"    /* close */
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !57 addi"    /* close */
	    "ecall");
}


int unlink (char* filename)
{
	asm("RD_A0 !-100 ADDI" /* AT_FDCWD */
	    "RD_A1 RS1_FP !-8 LD"
	    "RD_A2 !0 ADDI"     /* No flags */
	    "RD_A7 !35 ADDI"    /* unlinkat */
	    "ECALL");
	asm("rd_a0 !-100 addi" /* AT_FDCWD */
	    "rd_a1 rs1_fp !-8 ld"
	    "rd_a2 !0 addi"     /* No flags */
	    "rd_a7 !35 addi"    /* unlinkat */
	    "ecall");
}


int _getcwd(char* buf, int size)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A1 RS1_FP !-16 LD"
	    "RD_A7 !17 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a1 rs1_fp !-16 ld"
	    "rd_a7 !17 addi"
	    "ecall");
}




@@ 158,9 158,9 @@ char* get_current_dir_name()

int brk(void *addr)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !214 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !214 addi"
	    "ecall");
}

struct utsname


@@ 174,9 174,9 @@ struct utsname

int uname(struct utsname* unameData)
{
	asm("RD_A0 RS1_FP !-8 LD"
	    "RD_A7 !160 ADDI"
	    "ECALL");
	asm("rd_a0 rs1_fp !-8 ld"
	    "rd_a7 !160 addi"
	    "ecall");
}

#endif

M riscv64/riscv64_defs.M1 => riscv64/riscv64_defs.M1 +201 -198
@@ 19,219 19,222 @@ DEFINE NULL 0000000000000000
;; Opcodes

;; RV32I Base Instruction Set
DEFINE LUI   37000000
DEFINE AUIPC 17000000
DEFINE JAL   6F000000
DEFINE JALR  67000000
DEFINE BEQ   63000000
DEFINE BNE   63100000
DEFINE BLT   63400000
DEFINE BGE   63500000
DEFINE BLTU  63600000
DEFINE BGEU  63700000
DEFINE LB    03000000
DEFINE LH    03100000
DEFINE LW    03200000
DEFINE LBU   03400000
DEFINE LHU   03500000
DEFINE SB    23000000
DEFINE SH    23100000
DEFINE SW    23200000
DEFINE ADDI  13000000
DEFINE SLTI  13200000
DEFINE SLTIU 13300000
DEFINE XORI  13400000
DEFINE ORI   13600000
DEFINE ANDI  13700000
DEFINE SLLI  13100000
DEFINE SRLI  13500000
DEFINE SRAI  13500040
DEFINE ADD   33000000
DEFINE SUB   33000040
DEFINE SLL   33100000
DEFINE SLT   33200000
DEFINE SLTU  33300000
DEFINE XOR   33400000
DEFINE SRL   33500000
DEFINE SRA   33500040
DEFINE OR    33600000
DEFINE AND   33700000
DEFINE ECALL 73000000
DEFINE lui   37000000
DEFINE auipc 17000000
DEFINE jal   6F000000
DEFINE jalr  67000000
DEFINE beq   63000000
DEFINE bne   63100000
DEFINE blt   63400000
DEFINE bge   63500000
DEFINE bltu  63600000
DEFINE bgeu  63700000
DEFINE lb    03000000
DEFINE lh    03100000
DEFINE lw    03200000
DEFINE lbu   03400000
DEFINE lhu   03500000
DEFINE sb    23000000
DEFINE sh    23100000
DEFINE sw    23200000
DEFINE addi  13000000
DEFINE slti  13200000
DEFINE sltiu 13300000
DEFINE xori  13400000
DEFINE ori   13600000
DEFINE andi  13700000
DEFINE slli  13100000
DEFINE srli  13500000
DEFINE srai  13500040
DEFINE add   33000000
DEFINE sub   33000040
DEFINE sll   33100000
DEFINE slt   33200000
DEFINE sltu  33300000
DEFINE xor   33400000
DEFINE srl   33500000
DEFINE sra   33500040
DEFINE or    33600000
DEFINE and   33700000
DEFINE ecall 73000000
DEFINE ebreak 73001000

;; RV64I Base Instruction set
DEFINE LWU   03600000
DEFINE LD    03300000
DEFINE SD    23300000
DEFINE ADDIW 1B000000
DEFINE SLLIW 1B100000
DEFINE SRLIW 1B500000
DEFINE SRAIW 1B500040
DEFINE ADDW  3B000000
DEFINE SUBW  3B000040
DEFINE SLLW  3B100000
DEFINE SRLW  3B500000
DEFINE SRAW  3B500040
DEFINE lwu   03600000
DEFINE ld    03300000
DEFINE sd    23300000
DEFINE addiw 1B000000
DEFINE slliw 1B100000
DEFINE srliw 1B500000
DEFINE sraiw 1B500040
DEFINE addw  3B000000
DEFINE subw  3B000040
DEFINE sllw  3B100000
DEFINE srlw  3B500000
DEFINE sraw  3B500040

;; RV32M Standard Extensions
DEFINE MUL    33000002
DEFINE MULH   33100002
DEFINE MULHSU 33200002
DEFINE MULHU  33300002
DEFINE DIV    33400002
DEFINE DIVU   33500002
DEFINE REM    33600002
DEFINE REMU   33700002
DEFINE mul    33000002
DEFINE mulh   33100002
DEFINE mulhsu 33200002
DEFINE mulhu  33300002
DEFINE div    33400002
DEFINE divu   33500002
DEFINE rem    33600002
DEFINE remu   33700002

;; RV64M Standard Extensions
DEFINE MULW   3B000002
DEFINE DIVW   3B400002
DEFINE DIVUW  3B500002
DEFINE REMW   3B600002
DEFINE REMUW  3B700002
DEFINE mulw   3B000002
DEFINE divw   3B400002
DEFINE divuw  3B500002
DEFINE remw   3B600002
DEFINE remuw  3B700002

;; Pseudoinstructions
DEFINE NOP  13000000   # ADDI
DEFINE MV   13000000   # ADDI
DEFINE NOT  1340F0FF   # XORI, RD, RS, -1
DEFINE BEQZ 63000000   # BEQ
DEFINE BNEZ 63100000   # BNE
DEFINE BLTZ 63400000   # BLT
DEFINE RETURN 67800000 # RS1_RA JALR
DEFINE nop  13000000   # addi
DEFINE mv   13000000   # addi
DEFINE not  1340F0FF   # xori, RD, RS, -1
DEFINE beqz 63000000   # beq
DEFINE bnez 63100000   # bne
DEFINE bltz 63400000   # blt
DEFINE ret  67800000   # rs1_ra jalr

;; Destination registers
;; register_number << 7
DEFINE RD_RA  .80000000
DEFINE RD_SP  .00010000
DEFINE RD_GP  .80010000
DEFINE RD_TP  .00020000
DEFINE RD_T0  .80020000
DEFINE RD_T1  .00030000
DEFINE RD_T2  .80030000
DEFINE RD_S0  .00040000
DEFINE RD_FP  .00040000
DEFINE RD_S1  .80040000
DEFINE RD_A0  .00050000
DEFINE RD_A1  .80050000
DEFINE RD_A2  .00060000
DEFINE RD_A3  .80060000
DEFINE RD_A4  .00070000
DEFINE RD_A5  .80070000
DEFINE RD_A6  .00080000
DEFINE RD_A7  .80080000
DEFINE RD_S2  .00090000
DEFINE RD_S3  .80090000
DEFINE RD_S4  .000A0000
DEFINE RD_S5  .800A0000
DEFINE RD_S6  .000B0000
DEFINE RD_S7  .800B0000
DEFINE RD_S8  .000C0000
DEFINE RD_S9  .800C0000
DEFINE RD_S10 .000D0000
DEFINE RD_S11 .800D0000
DEFINE RD_T3  .000E0000
DEFINE RD_T4  .800E0000
DEFINE RD_T5  .000F0000
DEFINE RD_T6  .800F0000
DEFINE rd_ra  .80000000
DEFINE rd_sp  .00010000
DEFINE rd_gp  .80010000
DEFINE rd_tp  .00020000
DEFINE rd_t0  .80020000
DEFINE rd_t1  .00030000
DEFINE rd_t2  .80030000
DEFINE rd_s0  .00040000
DEFINE rd_fp  .00040000
DEFINE rd_s1  .80040000
DEFINE rd_a0  .00050000
DEFINE rd_a1  .80050000
DEFINE rd_a2  .00060000
DEFINE rd_a3  .80060000
DEFINE rd_a4  .00070000
DEFINE rd_a5  .80070000
DEFINE rd_a6  .00080000
DEFINE rd_a7  .80080000
DEFINE rd_s2  .00090000
DEFINE rd_s3  .80090000
DEFINE rd_s4  .000A0000
DEFINE rd_s5  .800A0000
DEFINE rd_s6  .000B0000
DEFINE rd_s7  .800B0000
DEFINE rd_s8  .000C0000
DEFINE rd_s9  .800C0000
DEFINE rd_s10 .000D0000
DEFINE rd_s11 .800D0000
DEFINE rd_t3  .000E0000
DEFINE rd_t4  .800E0000
DEFINE rd_t5  .000F0000
DEFINE rd_t6  .800F0000

;; First source registers
;; register_number << 15
DEFINE RS1_RA  .00800000
DEFINE RS1_SP  .00000100
DEFINE RS1_GP  .00800100
DEFINE RS1_TP  .00000200
DEFINE RS1_T0  .00800200
DEFINE RS1_T1  .00000300
DEFINE RS1_T2  .00800300
DEFINE RS1_S0  .00000400
DEFINE RS1_FP  .00000400
DEFINE RS1_S1  .00800400
DEFINE RS1_A0  .00000500
DEFINE RS1_A1  .00800500
DEFINE RS1_A2  .00000600
DEFINE RS1_A3  .00800600
DEFINE RS1_A4  .00000700
DEFINE RS1_A5  .00800700
DEFINE RS1_A6  .00000800
DEFINE RS1_A7  .00800800
DEFINE RS1_S2  .00000900
DEFINE RS1_S3  .00800900
DEFINE RS1_S4  .00000A00
DEFINE RS1_S5  .00800A00
DEFINE RS1_S6  .00000B00
DEFINE RS1_S7  .00800B00
DEFINE RS1_S8  .00000C00
DEFINE RS1_S9  .00800C00
DEFINE RS1_S10 .00000D00
DEFINE RS1_S11 .00800D00
DEFINE RS1_T3  .00000E00
DEFINE RS1_T4  .00800E00
DEFINE RS1_T5  .00000F00
DEFINE RS1_T6  .00800F00
DEFINE rs1_ra  .00800000
DEFINE rs1_sp  .00000100
DEFINE rs1_gp  .00800100
DEFINE rs1_tp  .00000200
DEFINE rs1_t0  .00800200
DEFINE rs1_t1  .00000300
DEFINE rs1_t2  .00800300
DEFINE rs1_s0  .00000400
DEFINE rs1_fp  .00000400
DEFINE rs1_s1  .00800400
DEFINE rs1_a0  .00000500
DEFINE rs1_a1  .00800500
DEFINE rs1_a2  .00000600
DEFINE rs1_a3  .00800600
DEFINE rs1_a4  .00000700
DEFINE rs1_a5  .00800700
DEFINE rs1_a6  .00000800
DEFINE rs1_a7  .00800800
DEFINE rs1_s2  .00000900
DEFINE rs1_s3  .00800900
DEFINE rs1_s4  .00000A00
DEFINE rs1_s5  .00800A00
DEFINE rs1_s6  .00000B00
DEFINE rs1_s7  .00800B00
DEFINE rs1_s8  .00000C00
DEFINE rs1_s9  .00800C00
DEFINE rs1_s10 .00000D00
DEFINE rs1_s11 .00800D00
DEFINE rs1_t3  .00000E00
DEFINE rs1_t4  .00800E00
DEFINE rs1_t5  .00000F00
DEFINE rs1_t6  .00800F00

;; Second source registers
;; register_number << 20
DEFINE RS2_RA  .00001000
DEFINE RS2_SP  .00002000
DEFINE RS2_GP  .00003000
DEFINE RS2_TP  .00004000
DEFINE RS2_T0  .00005000
DEFINE RS2_T1  .00006000
DEFINE RS2_T2  .00007000
DEFINE RS2_S0  .00008000
DEFINE RS2_FP  .00008000
DEFINE RS2_S1  .00009000
DEFINE RS2_A0  .0000A000
DEFINE RS2_A1  .0000B000
DEFINE RS2_A2  .0000C000
DEFINE RS2_A3  .0000D000
DEFINE RS2_A4  .0000E000
DEFINE RS2_A5  .0000F000
DEFINE RS2_A6  .00000001
DEFINE RS2_A7  .00001001
DEFINE RS2_S2  .00002001
DEFINE RS2_S3  .00003001
DEFINE RS2_S4  .00004001
DEFINE RS2_S5  .00005001
DEFINE RS2_S6  .00006001
DEFINE RS2_S7  .00007001
DEFINE RS2_S8  .00008001
DEFINE RS2_S9  .00009001
DEFINE RS2_S10 .0000A001
DEFINE RS2_S11 .0000B001
DEFINE RS2_T3  .0000C001
DEFINE RS2_T4  .0000D001
DEFINE RS2_T5  .0000E001
DEFINE RS2_T6  .0000F001
DEFINE rs2_ra  .00001000
DEFINE rs2_sp  .00002000
DEFINE rs2_gp  .00003000
DEFINE rs2_tp  .00004000
DEFINE rs2_t0  .00005000
DEFINE rs2_t1  .00006000
DEFINE rs2_t2  .00007000
DEFINE rs2_s0  .00008000
DEFINE rs2_fp  .00008000
DEFINE rs2_s1  .00009000
DEFINE rs2_a0  .0000A000
DEFINE rs2_a1  .0000B000
DEFINE rs2_a2  .0000C000
DEFINE rs2_a3  .0000D000
DEFINE rs2_a4  .0000E000
DEFINE rs2_a5  .0000F000
DEFINE rs2_a6  .00000001
DEFINE rs2_a7  .00001001
DEFINE rs2_s2  .00002001
DEFINE rs2_s3  .00003001
DEFINE rs2_s4  .00004001
DEFINE rs2_s5  .00005001
DEFINE rs2_s6  .00006001
DEFINE rs2_s7  .00007001
DEFINE rs2_s8  .00008001
DEFINE rs2_s9  .00009001
DEFINE rs2_s10 .0000A001
DEFINE rs2_s11 .0000B001
DEFINE rs2_t3  .0000C001
DEFINE rs2_t4  .0000D001
DEFINE rs2_t5  .0000E001
DEFINE rs2_t6  .0000F001

DEFINE RS2_X0  .00000000
DEFINE RS2_X1  .00001000
DEFINE RS2_X2  .00002000
DEFINE RS2_X3  .00003000
DEFINE RS2_X4  .00004000
DEFINE RS2_X5  .00005000
DEFINE RS2_X6  .00006000
DEFINE RS2_X7  .00007000
DEFINE RS2_X8  .00008000
DEFINE RS2_X9  .00009000
DEFINE RS2_X10 .0000A000
DEFINE RS2_X11 .0000B000
DEFINE RS2_X12 .0000C000
DEFINE RS2_X13 .0000D000
DEFINE RS2_X14 .0000E000
DEFINE RS2_X15 .0000F000
DEFINE RS2_X16 .00000001
DEFINE RS2_X17 .00001001
DEFINE RS2_X18 .00002001
DEFINE RS2_X19 .00003001
DEFINE RS2_X20 .00004001
DEFINE RS2_X21 .00005001
DEFINE RS2_X22 .00006001
DEFINE RS2_X23 .00007001
DEFINE RS2_X24 .00008001
DEFINE RS2_X25 .00009001
DEFINE RS2_X26 .0000A001
DEFINE RS2_X27 .0000B001
DEFINE RS2_X28 .0000C001
DEFINE RS2_X29 .0000D001
DEFINE RS2_X30 .0000E001
DEFINE RS2_X31 .0000F001
DEFINE rs1_x0  .00000000

DEFINE rs2_x0  .00000000
DEFINE rs2_x1  .00001000
DEFINE rs2_x2  .00002000
DEFINE rs2_x3  .00003000
DEFINE rs2_x4  .00004000
DEFINE rs2_x5  .00005000
DEFINE rs2_x6  .00006000
DEFINE rs2_x7  .00007000
DEFINE rs2_x8  .00008000
DEFINE rs2_x9  .00009000
DEFINE rs2_x10 .0000A000
DEFINE rs2_x11 .0000B000
DEFINE rs2_x12 .0000C000
DEFINE rs2_x13 .0000D000
DEFINE rs2_x14 .0000E000
DEFINE rs2_x15 .0000F000
DEFINE rs2_x16 .00000001
DEFINE rs2_x17 .00001001
DEFINE rs2_x18 .00002001
DEFINE rs2_x19 .00003001
DEFINE rs2_x20 .00004001
DEFINE rs2_x21 .00005001
DEFINE rs2_x22 .00006001
DEFINE rs2_x23 .00007001
DEFINE rs2_x24 .00008001
DEFINE rs2_x25 .00009001
DEFINE rs2_x26 .0000A001
DEFINE rs2_x27 .0000B001
DEFINE rs2_x28 .0000C001
DEFINE rs2_x29 .0000D001
DEFINE rs2_x30 .0000E001
DEFINE rs2_x31 .0000F001