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