summaryrefslogtreecommitdiffstats
path: root/src/arch/riscv/fp_asm.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/riscv/fp_asm.S')
-rw-r--r--src/arch/riscv/fp_asm.S362
1 files changed, 362 insertions, 0 deletions
diff --git a/src/arch/riscv/fp_asm.S b/src/arch/riscv/fp_asm.S
new file mode 100644
index 000000000000..9c6cc650d842
--- /dev/null
+++ b/src/arch/riscv/fp_asm.S
@@ -0,0 +1,362 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 HardenedLinux
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This file define some function used to swap value between memory
+ * and float register. This will be used in misaligned access exception
+ * handling.
+ */
+
+#if defined(__riscv_flen)
+#if __riscv_flen >= 32
+
+ .text
+
+/* void read_f32(int regnum, uint32_t* v)
+ * regnum : which register want to read
+ * v : address to hold bits info of reading
+ */
+ .align 1
+ .globl read_f32
+read_f32:
+ la a2, .Lr32_t
+ andi a0, a0, 31
+ slli a0, a0, 1
+ add a0, a0, a2
+ lbu a0, 0(a0)
+ add a0, a0, a2
+ jr a0
+ .align 2
+.Lr32_t:
+ .half .Lr32_f0 - .Lr32_t
+ .half .Lr32_f1 - .Lr32_t
+ .half .Lr32_f2 - .Lr32_t
+ .half .Lr32_f3 - .Lr32_t
+ .half .Lr32_f4 - .Lr32_t
+ .half .Lr32_f5 - .Lr32_t
+ .half .Lr32_f6 - .Lr32_t
+ .half .Lr32_f7 - .Lr32_t
+ .half .Lr32_f8 - .Lr32_t
+ .half .Lr32_f9 - .Lr32_t
+ .half .Lr32_f10 - .Lr32_t
+ .half .Lr32_f11 - .Lr32_t
+ .half .Lr32_f12 - .Lr32_t
+ .half .Lr32_f13 - .Lr32_t
+ .half .Lr32_f14 - .Lr32_t
+ .half .Lr32_f15 - .Lr32_t
+ .half .Lr32_f16 - .Lr32_t
+ .half .Lr32_f17 - .Lr32_t
+ .half .Lr32_f18 - .Lr32_t
+ .half .Lr32_f19 - .Lr32_t
+ .half .Lr32_f20 - .Lr32_t
+ .half .Lr32_f21 - .Lr32_t
+ .half .Lr32_f22 - .Lr32_t
+ .half .Lr32_f23 - .Lr32_t
+ .half .Lr32_f24 - .Lr32_t
+ .half .Lr32_f25 - .Lr32_t
+ .half .Lr32_f26 - .Lr32_t
+ .half .Lr32_f27 - .Lr32_t
+ .half .Lr32_f28 - .Lr32_t
+ .half .Lr32_f29 - .Lr32_t
+ .half .Lr32_f30 - .Lr32_t
+ .half .Lr32_f31 - .Lr32_t
+#define read32(which) .Lr32_##which: fsw which, 0(a1); ret
+ read32(f0)
+ read32(f1)
+ read32(f2)
+ read32(f3)
+ read32(f4)
+ read32(f5)
+ read32(f6)
+ read32(f7)
+ read32(f8)
+ read32(f9)
+ read32(f10)
+ read32(f11)
+ read32(f12)
+ read32(f13)
+ read32(f14)
+ read32(f15)
+ read32(f16)
+ read32(f17)
+ read32(f18)
+ read32(f19)
+ read32(f20)
+ read32(f21)
+ read32(f22)
+ read32(f23)
+ read32(f24)
+ read32(f25)
+ read32(f26)
+ read32(f27)
+ read32(f28)
+ read32(f29)
+ read32(f30)
+ read32(f31)
+
+/* void write_f32(int regnum, uint32_t* v)
+ * regnum: which register want to write
+ * v : address to hold bits info of writing
+ */
+ .align 1
+ .globl write_f32
+write_f32:
+ la a2, .Lw32_t
+ andi a0, a0, 31
+ slli a0, a0, 1
+ add a0, a0, a2
+ lbu a0, 0(a0)
+ add a0, a0, a2
+ jr a0
+ .align 2
+.Lw32_t:
+ .half .Lw32_f0 - .Lw32_t
+ .half .Lw32_f1 - .Lw32_t
+ .half .Lw32_f2 - .Lw32_t
+ .half .Lw32_f3 - .Lw32_t
+ .half .Lw32_f4 - .Lw32_t
+ .half .Lw32_f5 - .Lw32_t
+ .half .Lw32_f6 - .Lw32_t
+ .half .Lw32_f7 - .Lw32_t
+ .half .Lw32_f8 - .Lw32_t
+ .half .Lw32_f9 - .Lw32_t
+ .half .Lw32_f10 - .Lw32_t
+ .half .Lw32_f11 - .Lw32_t
+ .half .Lw32_f12 - .Lw32_t
+ .half .Lw32_f13 - .Lw32_t
+ .half .Lw32_f14 - .Lw32_t
+ .half .Lw32_f15 - .Lw32_t
+ .half .Lw32_f16 - .Lw32_t
+ .half .Lw32_f17 - .Lw32_t
+ .half .Lw32_f18 - .Lw32_t
+ .half .Lw32_f19 - .Lw32_t
+ .half .Lw32_f20 - .Lw32_t
+ .half .Lw32_f21 - .Lw32_t
+ .half .Lw32_f22 - .Lw32_t
+ .half .Lw32_f23 - .Lw32_t
+ .half .Lw32_f24 - .Lw32_t
+ .half .Lw32_f25 - .Lw32_t
+ .half .Lw32_f26 - .Lw32_t
+ .half .Lw32_f27 - .Lw32_t
+ .half .Lw32_f28 - .Lw32_t
+ .half .Lw32_f29 - .Lw32_t
+ .half .Lw32_f30 - .Lw32_t
+ .half .Lw32_f31 - .Lw32_t
+#define write32(which) .Lw32_##which: flw which, 0(a1); ret
+ write32(f0)
+ write32(f1)
+ write32(f2)
+ write32(f3)
+ write32(f4)
+ write32(f5)
+ write32(f6)
+ write32(f7)
+ write32(f8)
+ write32(f9)
+ write32(f10)
+ write32(f11)
+ write32(f12)
+ write32(f13)
+ write32(f14)
+ write32(f15)
+ write32(f16)
+ write32(f17)
+ write32(f18)
+ write32(f19)
+ write32(f20)
+ write32(f21)
+ write32(f22)
+ write32(f23)
+ write32(f24)
+ write32(f25)
+ write32(f26)
+ write32(f27)
+ write32(f28)
+ write32(f29)
+ write32(f30)
+ write32(f31)
+#endif // __riscv_flen >= 32
+
+#if __riscv_flen >= 64
+
+ .text
+
+/* void read_f64(int regnum, uint64_t* v)
+ * regnum : which register want to read
+ * v : address to hold bits info of reading
+ */
+ .align 1
+ .globl read_f64
+read_f64:
+ la a2, .Lr64_t
+ andi a0, a0, 31
+ slli a0, a0, 1
+ add a0, a0, a2
+ lbu a0, 0(a0)
+ add a0, a0, a2
+ jr a0
+ .align 2
+.Lr64_t:
+ .half .Lr64_f0 - .Lr64_t
+ .half .Lr64_f1 - .Lr64_t
+ .half .Lr64_f2 - .Lr64_t
+ .half .Lr64_f3 - .Lr64_t
+ .half .Lr64_f4 - .Lr64_t
+ .half .Lr64_f5 - .Lr64_t
+ .half .Lr64_f6 - .Lr64_t
+ .half .Lr64_f7 - .Lr64_t
+ .half .Lr64_f8 - .Lr64_t
+ .half .Lr64_f9 - .Lr64_t
+ .half .Lr64_f10 - .Lr64_t
+ .half .Lr64_f11 - .Lr64_t
+ .half .Lr64_f12 - .Lr64_t
+ .half .Lr64_f13 - .Lr64_t
+ .half .Lr64_f14 - .Lr64_t
+ .half .Lr64_f15 - .Lr64_t
+ .half .Lr64_f16 - .Lr64_t
+ .half .Lr64_f17 - .Lr64_t
+ .half .Lr64_f18 - .Lr64_t
+ .half .Lr64_f19 - .Lr64_t
+ .half .Lr64_f20 - .Lr64_t
+ .half .Lr64_f21 - .Lr64_t
+ .half .Lr64_f22 - .Lr64_t
+ .half .Lr64_f23 - .Lr64_t
+ .half .Lr64_f24 - .Lr64_t
+ .half .Lr64_f25 - .Lr64_t
+ .half .Lr64_f26 - .Lr64_t
+ .half .Lr64_f27 - .Lr64_t
+ .half .Lr64_f28 - .Lr64_t
+ .half .Lr64_f29 - .Lr64_t
+ .half .Lr64_f30 - .Lr64_t
+ .half .Lr64_f31 - .Lr64_t
+#define read64(which) .Lr64_##which: fsd which, 0(a1); ret
+ read64(f0)
+ read64(f1)
+ read64(f2)
+ read64(f3)
+ read64(f4)
+ read64(f5)
+ read64(f6)
+ read64(f7)
+ read64(f8)
+ read64(f9)
+ read64(f10)
+ read64(f11)
+ read64(f12)
+ read64(f13)
+ read64(f14)
+ read64(f15)
+ read64(f16)
+ read64(f17)
+ read64(f18)
+ read64(f19)
+ read64(f20)
+ read64(f21)
+ read64(f22)
+ read64(f23)
+ read64(f24)
+ read64(f25)
+ read64(f26)
+ read64(f27)
+ read64(f28)
+ read64(f29)
+ read64(f30)
+ read64(f31)
+
+/* void write_f64(int regnum, uint64_t* v)
+ * regnum: which register want to write
+ * v : address to hold bits info of writing
+ */
+ .align 1
+ .globl write_f64
+write_f64:
+ la a2, .Lw64_t
+ andi a0, a0, 31
+ slli a0, a0, 1
+ add a0, a0, a2
+ lbu a0, 0(a0)
+ add a0, a0, a2
+ jr a0
+ .align 2
+.Lw64_t:
+ .half .Lw64_f0 - .Lw64_t
+ .half .Lw64_f1 - .Lw64_t
+ .half .Lw64_f2 - .Lw64_t
+ .half .Lw64_f3 - .Lw64_t
+ .half .Lw64_f4 - .Lw64_t
+ .half .Lw64_f5 - .Lw64_t
+ .half .Lw64_f6 - .Lw64_t
+ .half .Lw64_f7 - .Lw64_t
+ .half .Lw64_f8 - .Lw64_t
+ .half .Lw64_f9 - .Lw64_t
+ .half .Lw64_f10 - .Lw64_t
+ .half .Lw64_f11 - .Lw64_t
+ .half .Lw64_f12 - .Lw64_t
+ .half .Lw64_f13 - .Lw64_t
+ .half .Lw64_f14 - .Lw64_t
+ .half .Lw64_f15 - .Lw64_t
+ .half .Lw64_f16 - .Lw64_t
+ .half .Lw64_f17 - .Lw64_t
+ .half .Lw64_f18 - .Lw64_t
+ .half .Lw64_f19 - .Lw64_t
+ .half .Lw64_f20 - .Lw64_t
+ .half .Lw64_f21 - .Lw64_t
+ .half .Lw64_f22 - .Lw64_t
+ .half .Lw64_f23 - .Lw64_t
+ .half .Lw64_f24 - .Lw64_t
+ .half .Lw64_f25 - .Lw64_t
+ .half .Lw64_f26 - .Lw64_t
+ .half .Lw64_f27 - .Lw64_t
+ .half .Lw64_f28 - .Lw64_t
+ .half .Lw64_f29 - .Lw64_t
+ .half .Lw64_f30 - .Lw64_t
+ .half .Lw64_f31 - .Lw64_t
+#define write64(which) .Lw64_##which: fld which, 0(a1); ret
+ write64(f0)
+ write64(f1)
+ write64(f2)
+ write64(f3)
+ write64(f4)
+ write64(f5)
+ write64(f6)
+ write64(f7)
+ write64(f8)
+ write64(f9)
+ write64(f10)
+ write64(f11)
+ write64(f12)
+ write64(f13)
+ write64(f14)
+ write64(f15)
+ write64(f16)
+ write64(f17)
+ write64(f18)
+ write64(f19)
+ write64(f20)
+ write64(f21)
+ write64(f22)
+ write64(f23)
+ write64(f24)
+ write64(f25)
+ write64(f26)
+ write64(f27)
+ write64(f28)
+ write64(f29)
+ write64(f30)
+ write64(f31)
+
+#endif // __riscv_flen >= 64
+
+#endif // defined(__riscv_flen)