aboutsummaryrefslogtreecommitdiff
path: root/basics
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-08-28 22:25:56 +0200
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-12-05 16:02:49 +0100
commitab03d3be21f229be8c28dba292d5da237a929a73 (patch)
tree8bc53e3031f644532fec255bb392a90cd4ad59fb /basics
parent1a36e6211674f1a39c7cc0ddff705357a4add65a (diff)
downloadfarga-ab03d3be21f229be8c28dba292d5da237a929a73.tar.gz
farga-ab03d3be21f229be8c28dba292d5da237a929a73.zip
Restructure the whole thing
It will be something more than just messing around with RISC-V stuff. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'basics')
-rw-r--r--basics/Makefile20
-rw-r--r--basics/factorial.S28
-rw-r--r--basics/float.S40
-rw-r--r--basics/main.c89
-rw-r--r--basics/string.S93
5 files changed, 0 insertions, 270 deletions
diff --git a/basics/Makefile b/basics/Makefile
deleted file mode 100644
index 6e36dd6..0000000
--- a/basics/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
-CCFLAGS =
-EXE = basics
-
-DEBUG =
-ifneq ($(strip $(DEBUG)),)
- CCFLAGS += -g
-endif
-
-.PHONY: all
-all: clean $(EXE)
-
-.PHONY: $(EXE)
-$(EXE):
- gcc $(CCFLAGS) -o $(EXE) main.c factorial.S string.S float.S
-
-.PHONY: clean
-clean:
- @rm -f $(EXE)
diff --git a/basics/factorial.S b/basics/factorial.S
deleted file mode 100644
index 7e3df12..0000000
--- a/basics/factorial.S
+++ /dev/null
@@ -1,28 +0,0 @@
-.text
-.globl factorial
-.type factorial, @function
-
-factorial:
- // If input <= 1, just return the given thing.
- addi t0, zero, 1
- bgt a0, t0, else
- jr ra
-else:
- // Preserve the argument and the return address before the call.
- addi sp, sp, -16
- sd a0, 0(sp)
- sd ra, 8(sp)
-
- // Call the same function but with a value of argument-1.
- addi a0, a0, -1
- call factorial
-
- // Restore back the original argument and the return address. Then multiply
- // the original argument with the returned one from the previous call.
- ld t1, 0(sp)
- ld ra, 8(sp)
- addi sp, sp, 16
- mul a0, t1, a0
-
- // And return to the caller.
- jr ra
diff --git a/basics/float.S b/basics/float.S
deleted file mode 100644
index f481f3e..0000000
--- a/basics/float.S
+++ /dev/null
@@ -1,40 +0,0 @@
-.text
-.globl greater_than_ten
-.type greater_than_ten, @function
-
-// bool greater_than_ten(double a, uint64_t b);
-greater_than_ten:
- // Upon entry a -> fa0; and b -> a0. That is, the ABI increments the
- //(f)a<n> register per argument type.
-
- // Change the rounding to "Rounds Towards Zero" (bits: 0b001).
- li t0, 0b001
- fsrm t0
-
- // Convert the second parameter to double.
- fcvt.d.lu ft0, a0
-
- // ret = a + b
- fadd.d fa0, fa0, ft0
-
- // ret = (ret * b) + b
- fmv.d ft1, ft0
- fmadd.d fa0, fa0, ft0, ft1
-
- // Now we need to compare the number with 10.0. There are multiple ways to
- // load a floating point immediate:
- // 1. Loading an integer immediate and then convert it into a double. This
- // is discouraged on the RISC-V assembly manual.
- // 2. Load a double with `fld` from a memory location on the data section.
- // 3. Load a floating point immediate with `fli` (requires the `Zfa`
- // extension).
- // I don't have the `Zfa` extension on my board, so I'm opting for the
- // second way.
- fld ft1, .TEN, t0
- fle.d a0, ft1, fa0
-
- ret
-
-.data
-.TEN:
- .double 10.0
diff --git a/basics/main.c b/basics/main.c
deleted file mode 100644
index 4b5f289..0000000
--- a/basics/main.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-
-/*
- * Returns the factorial for the given unsigned 64-bit integer.
- *
- * Implemented in factorial.S
- */
-int factorial(uint64_t n);
-
-void test_factorial(void)
-{
- assert(factorial(0) == 0);
- assert(factorial(1) == 1);
- assert(factorial(2) == 2);
- assert(factorial(3) == 6);
- assert(factorial(4) == 24);
-
- printf("factorial:\t\tOK\n");
-}
-
-/*
- * Returns a pointer with the same given string but reversed. Note that the
- * string cannot be in read-only space since the reversal is done in-place.
- *
- * Implemented in string.S
- */
-char * reverse_string(char *str);
-
-void test_reverse_string(void)
-{
- assert(reverse_string(NULL) == NULL);
- assert(reverse_string("") == "");
-
- char s1[] = "This is a string.";
- assert(strcmp(reverse_string(s1), ".gnirts a si sihT") == 0);
-
- char s2[] = ".";
- assert(strcmp(reverse_string(s2), ".") == 0);
-
- printf("reverse_string:\t\tOK\n");
-}
-
-/*
- * Returns true if the given string is a palindrome, false otherwise.
- *
- * Implemented in string.S
- */
-bool is_palindrome(char *str);
-
-void test_is_palindrome(void)
-{
- assert(is_palindrome(NULL) == 0);
- assert(is_palindrome("") == 0);
- assert(is_palindrome("aba") == 1);
- assert(is_palindrome("aaa") == 1);
- assert(is_palindrome("This is a a si sihT") == 1);
-
- printf("is_palindrome:\t\tOK\n");
-}
-
-/*
- * This function computes the following: ((a + b) * b) + b. Don't try to make
- * sense of it, that's the computation I ended up while messing with RISC-V
- * floating point instructions. Anyways, with this in mind, it will return if
- * the computed value is greater than 10.
- *
- * Implemented in float.S
- */
-bool greater_than_ten(double a, uint64_t b);
-
-void test_greater_than_ten(void)
-{
- assert(!greater_than_ten(2.3, 1)); // 4.3
- assert(greater_than_ten(2.3, 2)); // 10.6
-
- printf("greater_than_ten:\tOK\n");
-}
-
-int main()
-{
- test_factorial();
- test_reverse_string();
- test_is_palindrome();
- test_greater_than_ten();
-}
diff --git a/basics/string.S b/basics/string.S
deleted file mode 100644
index 0f3bcc1..0000000
--- a/basics/string.S
+++ /dev/null
@@ -1,93 +0,0 @@
-.text
-
-.globl reverse_string
-.type reverse_string, @function
-
-// char * reverse_string(char *str);
-reverse_string:
- // Return early on null pointer.
- beq a0, zero, end
-
- // Preserve the original pointer.
- addi sp, sp, -8
- sd a0, 0(sp)
-
- // Set `t0` to point to the end of the string.
- add t0, a0, zero
-set_end_ptr:
- lbu t2, 0(t0)
- beq t2, zero, end_ptr_done
- addi t0, t0, 1
- j set_end_ptr
-
- // We are done iterating, if `a0` and `t0` are equal, then there's nothing
- // to be done and we can return early. Otherwise decrement `t0` so it points
- // to the byte right before the null termination.
-end_ptr_done:
- beq a0, t0, reverse_done
- addi t0, t0, -1
-
-reverse_loop:
- // Swap values between the two pointers.
- lb t1, 0(a0)
- lb t2, 0(t0)
- sb t1, 0(t0)
- sb t2, 0(a0)
-
- // Move pointers and check whether the pointers have already crossed. If
- // they have not crossed yet there is still looping to be done. Otherwise
- // we are done.
- addi a0, a0, 1
- addi t0, t0, -1
- bltu a0, t0, reverse_loop
-
-reverse_done:
- // Restore things back and return to the caller.
- ld a0, 0(sp)
- addi sp, sp, 8
-end:
- jr ra
-
-.globl is_palindrome
-.type is_palindrome, @function
-
-// bool is_palindrome(char *str);
-is_palindrome:
- // Return early on null pointer.
- beq a0, zero, palindrome_no
-
- // Set `t0` to point to the end of the string.
- add t0, a0, zero
-pal_set_end_ptr:
- lbu t2, 0(t0)
- beq t2, zero, pal_end_ptr_done
- addi t0, t0, 1
- j pal_set_end_ptr
-
- // We are done iterating, if `a0` and `t0` are equal, then there's nothing
- // to be done and we can return early. Otherwise decrement `t0` so it points
- // to the byte right before the null termination.
-pal_end_ptr_done:
- beq a0, t0, palindrome_no
- addi t0, t0, -1
-
-pal_loop:
- // Swap values between the two pointers.
- lb t1, 0(a0)
- lb t2, 0(t0)
- bne t1, t2, palindrome_no
-
- // Move pointers and check whether the pointers have already crossed. If
- // they have not crossed yet there is still looping to be done. Otherwise
- // we are done.
- addi a0, a0, 1
- addi t0, t0, -1
- bleu a0, t0, pal_loop
-
-palindrome_yes:
- li a0, 1
- jr ra
-
-palindrome_no:
- li a0, 0
- jr ra