aboutsummaryrefslogtreecommitdiff
path: root/basics
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-08-28 13:04:06 +0000
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-12-05 16:02:41 +0100
commit1a36e6211674f1a39c7cc0ddff705357a4add65a (patch)
tree26d82fc4f6c7cc444a5121bb4d0cb71681485bb1 /basics
parent6f0ebbad84419de65a03a0ea6e41cbc6b49d6eb0 (diff)
downloadfarga-1a36e6211674f1a39c7cc0ddff705357a4add65a.tar.gz
farga-1a36e6211674f1a39c7cc0ddff705357a4add65a.zip
basics: Add an example on floating instructions
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'basics')
-rw-r--r--basics/Makefile2
-rw-r--r--basics/float.S40
-rw-r--r--basics/main.c31
3 files changed, 66 insertions, 7 deletions
diff --git a/basics/Makefile b/basics/Makefile
index 90e88ef..6e36dd6 100644
--- a/basics/Makefile
+++ b/basics/Makefile
@@ -13,7 +13,7 @@ all: clean $(EXE)
.PHONY: $(EXE)
$(EXE):
- gcc $(CCFLAGS) -o $(EXE) main.c factorial.S string.S
+ gcc $(CCFLAGS) -o $(EXE) main.c factorial.S string.S float.S
.PHONY: clean
clean:
diff --git a/basics/float.S b/basics/float.S
new file mode 100644
index 0000000..f481f3e
--- /dev/null
+++ b/basics/float.S
@@ -0,0 +1,40 @@
+.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
index 89d4401..4b5f289 100644
--- a/basics/main.c
+++ b/basics/main.c
@@ -11,7 +11,7 @@
*/
int factorial(uint64_t n);
-void test_factorial()
+void test_factorial(void)
{
assert(factorial(0) == 0);
assert(factorial(1) == 1);
@@ -19,7 +19,7 @@ void test_factorial()
assert(factorial(3) == 6);
assert(factorial(4) == 24);
- printf("factorial:\tOK\n");
+ printf("factorial:\t\tOK\n");
}
/*
@@ -30,7 +30,7 @@ void test_factorial()
*/
char * reverse_string(char *str);
-void test_reverse_string()
+void test_reverse_string(void)
{
assert(reverse_string(NULL) == NULL);
assert(reverse_string("") == "");
@@ -41,7 +41,7 @@ void test_reverse_string()
char s2[] = ".";
assert(strcmp(reverse_string(s2), ".") == 0);
- printf("reverse_string:\tOK\n");
+ printf("reverse_string:\t\tOK\n");
}
/*
@@ -51,7 +51,7 @@ void test_reverse_string()
*/
bool is_palindrome(char *str);
-void test_is_palindrome()
+void test_is_palindrome(void)
{
assert(is_palindrome(NULL) == 0);
assert(is_palindrome("") == 0);
@@ -59,7 +59,25 @@ void test_is_palindrome()
assert(is_palindrome("aaa") == 1);
assert(is_palindrome("This is a a si sihT") == 1);
- printf("is_palindrome:\tOK\n");
+ 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()
@@ -67,4 +85,5 @@ int main()
test_factorial();
test_reverse_string();
test_is_palindrome();
+ test_greater_than_ten();
}