From 8d49fc09eb79337ac9cdf97c5e51724bfb42625e Mon Sep 17 00:00:00 2001 From: Pavel Pisa <pisa@cmp.felk.cvut.cz> Date: Thu, 27 Apr 2023 02:22:17 +0200 Subject: [PATCH] seminaries/qtrvsim/call-syscall: add examples matching the lecture. Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz> --- .../call-syscall/lec10-01-call4-clobber.S | 43 +++++++++++ .../call-syscall/lec10-02-call4-save.S | 46 ++++++++++++ .../call-syscall/lec10-03-fact-buggy.S | 42 +++++++++++ .../qtrvsim/call-syscall/lec10-04-fact-ok.S | 44 ++++++++++++ .../call-syscall/lec10-06-linus-hello.S | 71 +++++++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 seminaries/qtrvsim/call-syscall/lec10-01-call4-clobber.S create mode 100644 seminaries/qtrvsim/call-syscall/lec10-02-call4-save.S create mode 100644 seminaries/qtrvsim/call-syscall/lec10-03-fact-buggy.S create mode 100644 seminaries/qtrvsim/call-syscall/lec10-04-fact-ok.S create mode 100644 seminaries/qtrvsim/call-syscall/lec10-06-linus-hello.S diff --git a/seminaries/qtrvsim/call-syscall/lec10-01-call4-clobber.S b/seminaries/qtrvsim/call-syscall/lec10-01-call4-clobber.S new file mode 100644 index 0000000..453f482 --- /dev/null +++ b/seminaries/qtrvsim/call-syscall/lec10-01-call4-clobber.S @@ -0,0 +1,43 @@ +.globl _start +.option norelax + +#pragma qtrvsim show registers +#pragma qtrvsim show memory +#pragma qtrvsim show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +_start: + +main: + li sp, STACK_INIT + li s0, 0x12345678 + + addi a0, zero, 2 + addi a1, zero, 3 + addi a2, zero, 4 + addi a3, zero, 5 + jal fun + add s0, a0, zero + + li t0, SPILED_REG_LED_LINE + sw s0, 0(t0) +final: + ebreak + beq zero, zero, final + nop + +// int fun(int g, h, i, j) +// g→a0, h→a1, i→a2, j→a3, a0 – ret. val, sX – save, tX – temp, ra – ret. addr +// return (g + h) – (i + j) +fun: + add t0, a0, a1 + add t1, a2, a3 + // Clobbers caller guaranteed + // to be saved register s0 + sub s0, t0, t1 + add a0, s0, zero + ret // jr ra + +#pragma qtrvsim focus memory STACK_INIT-4*8 diff --git a/seminaries/qtrvsim/call-syscall/lec10-02-call4-save.S b/seminaries/qtrvsim/call-syscall/lec10-02-call4-save.S new file mode 100644 index 0000000..795b125 --- /dev/null +++ b/seminaries/qtrvsim/call-syscall/lec10-02-call4-save.S @@ -0,0 +1,46 @@ +.globl _start +.option norelax + +#pragma qtrvsim show registers +#pragma qtrvsim show memory +#pragma qtrvsim show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +_start: + +main: + li sp, STACK_INIT + li s0, 0x12345678 + + addi a0, zero, 2 + addi a1, zero, 3 + addi a2, zero, 4 + addi a3, zero, 5 + jal fun + add s0, a0, zero + + li t0, SPILED_REG_LED_LINE + sw s0, 0(t0) +final: + ebreak + beq zero, zero, final + nop + +// int fun(int g, h, i, j) +// g→a0, h→a1, i→a2, j→a3, a0 – ret. val, sX – save, tX – temp, ra – ret. addr +// return (g + h) – (i + j) +fun: + addi sp, sp, -4 // allocate space on stack + sw s0, 0(sp) // save s0 on stack + add t0, a0, a1 + add t0, a0, a1 + add t1, a2, a3 + sub s0, t0, t1 // s0 is used + add a0, s0, zero + lw s0, 0(sp) // s0 is restored + addi sp, sp, 4 // space on stack is release + ret // jr ra + +#pragma qtrvsim focus memory STACK_INIT-4*8 diff --git a/seminaries/qtrvsim/call-syscall/lec10-03-fact-buggy.S b/seminaries/qtrvsim/call-syscall/lec10-03-fact-buggy.S new file mode 100644 index 0000000..d9eb5f1 --- /dev/null +++ b/seminaries/qtrvsim/call-syscall/lec10-03-fact-buggy.S @@ -0,0 +1,42 @@ +.globl _start + +#pragma qtrvsim show registers +#pragma qtrvsim show memory +#pragma qtrvsim show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.option norelax +.text + +_start: +main: + li sp, STACK_INIT + addi a0, zero, 4 // 4! -> 24 + jal fact + addi t0, a0, 0 + + li t1, SPILED_REG_LED_LINE + sw t0, 0(t1) +final: + ebreak + beq zero, zero, final + nop + +fact: + addi sp, sp, -4 // adjust stack for 1 item + sw a0, 0(sp) // save argument + slti t0, a0, 1 // test for n < 1 + beq t0, zero, L1 + addi a0, zero, 1 // if so, result is 1 + addi sp, sp, 4 // pop 1 item from stack + ret // and return (jr ra) +L1: addi a0, a0, -1 // else decrement n + jal fact // recursive call + lw t0, 0(sp) // restore original n + addi sp, sp, 4 // pop 2 items from stack + mul a0, a0, t0 // multiply to get result + jr ra // and return + +#pragma qtrvsim focus memory STACK_INIT-4*8 diff --git a/seminaries/qtrvsim/call-syscall/lec10-04-fact-ok.S b/seminaries/qtrvsim/call-syscall/lec10-04-fact-ok.S new file mode 100644 index 0000000..2dfe529 --- /dev/null +++ b/seminaries/qtrvsim/call-syscall/lec10-04-fact-ok.S @@ -0,0 +1,44 @@ +.globl _start + +#pragma qtrvsim show registers +#pragma qtrvsim show memory +#pragma qtrvsim show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.option norelax +.text + +_start: +main: + li sp, STACK_INIT + addi a0, zero, 4 // 4! -> 24 + jal fact + addi t0, a0, 0 + + li t1, SPILED_REG_LED_LINE + sw t0, 0(t1) +final: + ebreak + beq zero, zero, final + nop + +fact: + addi sp, sp, -8 // adjust stack for 2 items + sw ra, 4(sp) // save return address + sw a0, 0(sp) // save argument + slti t0, a0, 1 // test for n < 1 + beq t0, zero, L1 + addi a0, zero, 1 // if so, result is 1 + addi sp, sp, 8 // pop 2 items from stack + ret // and return (jr ra) +L1: addi a0, a0, -1 // else decrement n + jal fact // recursive call + lw t0, 0(sp) // restore original n + lw ra, 4(sp) // and return address + addi sp, sp, 8 // pop 2 items from stack + mul a0, a0, t0 // multiply to get result + jr ra // and return + +#pragma qtrvsim focus memory STACK_INIT-4*8 diff --git a/seminaries/qtrvsim/call-syscall/lec10-06-linus-hello.S b/seminaries/qtrvsim/call-syscall/lec10-06-linus-hello.S new file mode 100644 index 0000000..4c4b158 --- /dev/null +++ b/seminaries/qtrvsim/call-syscall/lec10-06-linus-hello.S @@ -0,0 +1,71 @@ +// The simple program to run on RISC-V Linux kernel port + +.globl _start + +// select core without pipeline but with delay slot + +#pragma qtrvsim show registers +#pragma qtrvsim show memory +#pragma qtrvsim show terminal + +// #include <asm/unistd.h> +// #include <asm/asm.h> +// #include <sys/syscall.h> + +.equ O_RDWR, 02 + +// Linux kernel compatible system calls subset + +// Linux kernel compatible system calls subset + +.equ __NR_exit, 93 // void exit(int status) +.equ __NR_read, 63 // ssize_t read(int fd, void *buf, size_t count) +.equ __NR_write, 64 // ssize_t write(int fd, const void *buf, size_t count) +.equ __NR_close, 57 // int close(int fd) +.equ __NR_openat, 56 // int openat(int fd, const char *pathname, int flags, mode_t mode) + // use fd = -100 for normal open behaviour. Full openat not supported. +.equ __NR_brk, 214 // void * brk(void *addr) +.equ __NR_ftruncate64, 46 // int ftruncate64(int fd, off_t length) +.equ __NR_readv, 65 // ssize_t readv(int fd, const struct iovec *iov, int iovcnt) +.equ __NR_writev, 66 // ssize_t writev(int fd, const struct iovec *iov, int iovcnt) + +.option norelax +.text + +_start: +main: +// LEAF(main) +// fd = openat(AT_EMPTY_PATH, "/dev/tty1", O_RDWR, 0); + addi a0, zero, -100 + la a1, tty + li a2, O_RDWR + li a3, 0 + li a7, __NR_openat + ecall + blt a0, zero, quit + addi s0, a0, 0 // delay slot +// write(fd, "hello, world.\n", 14); + addi a0, s0, 0 + la a1, hello + li a2, 14 + li a7, __NR_write + ecall +// close(fd); + addi a0, s0, 0 + li a7, __NR_close + ecall + +quit: + li a0, 0 + li a7, __NR_exit + ecall + + ebreak + j quit + nop + +// END(main) + + .data +tty: .asciz "/dev/tty" +hello: .ascii "Hello, world.\n" -- GitLab