summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fenv/superh/fenv.s74
-rw-r--r--src/internal/superh/syscall.s22
-rw-r--r--src/ldso/superh/dlsym.s10
-rw-r--r--src/ldso/superh/start.s26
-rw-r--r--src/setjmp/superh/longjmp.s26
-rw-r--r--src/setjmp/superh/setjmp.s25
-rw-r--r--src/signal/superh/restore.s24
-rw-r--r--src/signal/superh/sigsetjmp.s27
-rw-r--r--src/thread/superh/__set_thread_area.s5
-rw-r--r--src/thread/superh/__unmapself.s22
-rw-r--r--src/thread/superh/clone.s47
-rw-r--r--src/thread/superh/syscall_cp.s39
-rw-r--r--src/unistd/superh/pipe.s27
13 files changed, 374 insertions, 0 deletions
diff --git a/src/fenv/superh/fenv.s b/src/fenv/superh/fenv.s
new file mode 100644
index 00000000..7f5c6277
--- /dev/null
+++ b/src/fenv/superh/fenv.s
@@ -0,0 +1,74 @@
+.global fegetround
+.type fegetround, @function
+fegetround:
+ sts fpscr, r0
+ rts
+ and #3, r0
+
+.global __fesetround
+.type __fesetround, @function
+__fesetround:
+ sts fpscr, r0
+ or r4, r0
+ lds r0, fpscr
+ rts
+ mov #0, r0
+
+.global fetestexcept
+.type fetestexcept, @function
+fetestexcept:
+ sts fpscr, r0
+ and r4, r0
+ rts
+ and #0x7c, r0
+
+.global feclearexcept
+.type feclearexcept, @function
+feclearexcept:
+ mov r4, r0
+ and #0x7c, r0
+ not r0, r4
+ sts fpscr, r0
+ and r4, r0
+ lds r0, fpscr
+ rts
+ mov #0, r0
+
+.global feraiseexcept
+.type feraiseexcept, @function
+feraiseexcept:
+ mov r4, r0
+ and #0x7c, r0
+ sts fpscr, r4
+ or r4, r0
+ lds r0, fpscr
+ rts
+ mov #0, r0
+
+.global fegetenv
+.type fegetenv, @function
+fegetenv:
+ sts fpscr, r0
+ mov.l r0, @r4
+ rts
+ mov #0, r0
+
+.global fesetenv
+.type fesetenv, @function
+fesetenv:
+ mov r4, r0
+ cmp/eq #-1, r0
+ bf 1f
+
+ ! the default environment is complicated by the fact that we need to
+ ! preserve the current precision bit, which we do not know a priori
+ sts fpscr, r0
+ mov #8, r1
+ swap.w r1, r1
+ bra 2f
+ and r1, r0
+
+1: mov.l @r4, r0 ! non-default environment
+2: lds r0, fpscr
+ rts
+ mov #0, r0
diff --git a/src/internal/superh/syscall.s b/src/internal/superh/syscall.s
new file mode 100644
index 00000000..a8fda1c0
--- /dev/null
+++ b/src/internal/superh/syscall.s
@@ -0,0 +1,22 @@
+.global __syscall
+.type __syscall, @function
+__syscall:
+ ! The kernel syscall entry point documents that the trap number indicates
+ ! the number of arguments being passed, but it then ignores that information.
+ ! Since we do not actually know how many arguments are being passed, we will
+ ! say there are six, since that is the maximum we support here.
+ mov r4, r3
+ mov r5, r4
+ mov r6, r5
+ mov r7, r6
+ mov.l @r15, r7
+ mov.l @(4,r15), r0
+ mov.l @(8,r15), r1
+ trapa #22
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ rts
+ nop
diff --git a/src/ldso/superh/dlsym.s b/src/ldso/superh/dlsym.s
new file mode 100644
index 00000000..8258507f
--- /dev/null
+++ b/src/ldso/superh/dlsym.s
@@ -0,0 +1,10 @@
+.text
+.global dlsym
+.type dlsym, @function
+dlsym:
+ mov.l L1, r0
+ braf r0
+1: mov.l @r15, r6
+
+.align 2
+L1: .long __dlsym@PLT-(1b-.)
diff --git a/src/ldso/superh/start.s b/src/ldso/superh/start.s
new file mode 100644
index 00000000..ca6b7fc9
--- /dev/null
+++ b/src/ldso/superh/start.s
@@ -0,0 +1,26 @@
+.text
+.global _start
+.type _start, @function
+_start:
+ mov.l @r15, r4
+ mov r15, r5
+ mov.l L1, r0
+ bsrf r0
+ add #4, r5
+
+2: mov r0, r2
+ mov.l @r15+, r1
+1: mov.l @r15+, r0
+ cmp/eq #-1, r0
+ bt/s 1b
+ add #-1, r1
+
+ add #1, r1
+ mov.l r0, @-r15
+ mov.l r1, @-r15
+ mov #0, r4
+ jmp @r2
+ nop
+
+.align 2
+L1: .long __dynlink@PLT-(2b-.)
diff --git a/src/setjmp/superh/longjmp.s b/src/setjmp/superh/longjmp.s
new file mode 100644
index 00000000..e9aa4e50
--- /dev/null
+++ b/src/setjmp/superh/longjmp.s
@@ -0,0 +1,26 @@
+.global _longjmp
+.global longjmp
+.type _longjmp, @function
+.type longjmp, @function
+_longjmp:
+longjmp:
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov.l @r4+, r13
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, pr
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+
+ tst r5, r5
+ movt r0
+ add r5, r0
+
+ rts
+ nop
diff --git a/src/setjmp/superh/setjmp.s b/src/setjmp/superh/setjmp.s
new file mode 100644
index 00000000..6127ed90
--- /dev/null
+++ b/src/setjmp/superh/setjmp.s
@@ -0,0 +1,25 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp, @function
+.type _setjmp, @function
+.type setjmp, @function
+__setjmp:
+_setjmp:
+setjmp:
+ add #52, r4
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ sts.l pr, @-r4
+ mov.l r15 @-r4
+ mov.l r14, @-r4
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+ rts
+ mov #0, r0
diff --git a/src/signal/superh/restore.s b/src/signal/superh/restore.s
new file mode 100644
index 00000000..ab26034b
--- /dev/null
+++ b/src/signal/superh/restore.s
@@ -0,0 +1,24 @@
+.global __restore
+.type __restore, @function
+__restore:
+ mov #119, r3 !__NR_sigreturn
+ trapa #16
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+.global __restore_rt
+.type __restore_rt, @function
+__restore_rt:
+ mov #100, r3 !__NR_rt_sigreturn
+ add #73, r3
+ trapa #16
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
diff --git a/src/signal/superh/sigsetjmp.s b/src/signal/superh/sigsetjmp.s
new file mode 100644
index 00000000..f6cae801
--- /dev/null
+++ b/src/signal/superh/sigsetjmp.s
@@ -0,0 +1,27 @@
+.global sigsetjmp
+.type sigsetjmp, @function
+sigsetjmp:
+ mov.l r5, @(36,r4)
+ tst r5, r5
+ bf 2f
+
+ sts.l pr, @-r15
+ mov.l r4, @-r15
+ mov r4, r6
+ add #40, r6
+ mov #0, r5
+ mov #2, r4
+ mov.l L1, r0
+ bsrf r0
+ nop
+1: mov.l @r15+, r4
+ lds.l @r15+, pr
+
+2: mov.l L2, r0
+ braf r0
+ nop
+3:
+
+.align 2
+L1: .long pthread_sigmask@PLT-(1b-.)
+L2: .long setjmp@PLT-(3b-.)
diff --git a/src/thread/superh/__set_thread_area.s b/src/thread/superh/__set_thread_area.s
new file mode 100644
index 00000000..53887e64
--- /dev/null
+++ b/src/thread/superh/__set_thread_area.s
@@ -0,0 +1,5 @@
+.global __set_thread_area
+.type __set_thread_area, @function
+__set_thread_area:
+ rts
+ ldc r4, gbr
diff --git a/src/thread/superh/__unmapself.s b/src/thread/superh/__unmapself.s
new file mode 100644
index 00000000..b34c3c80
--- /dev/null
+++ b/src/thread/superh/__unmapself.s
@@ -0,0 +1,22 @@
+.text
+.global __unmapself
+.type __unmapself, @function
+__unmapself:
+ mov #91, r3 ! SYS_munmap
+ trapa #18
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ mov #1, r3 ! SYS_exit
+ mov #0, r4
+ trapa #17
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
diff --git a/src/thread/superh/clone.s b/src/thread/superh/clone.s
new file mode 100644
index 00000000..d6c9184d
--- /dev/null
+++ b/src/thread/superh/clone.s
@@ -0,0 +1,47 @@
+.text
+.global __clone
+.type __clone, @function
+__clone:
+! incoming: fn stack flags arg ptid tls ctid
+! r4 r5 r6 r7 @r15 @(4,r15) @(8,r15)
+
+ mov #-16, r0
+ and r0, r5
+
+ mov r4, r1 ! r1 = fn
+ mov r7, r2 ! r2 = arg
+
+ mov #120, r3 ! r3 = __NR_clone
+ mov r6, r4 ! r4 = flags
+ !mov r5, r5 ! r5 = stack
+ mov.l @r15, r6 ! r6 = ptid
+ mov.l @(8,r15), r7 ! r7 = ctid
+ mov.l @(4,r15), r0 ! r0 = tls
+ trapa #21
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ cmp/eq #0, r0
+ bt 1f
+
+ ! we are the parent, return
+ rts
+ nop
+
+1: ! we are the child, call fn(arg)
+ jsr @r1
+ mov r2, r4
+
+ mov #1, r3 ! __NR_exit
+ mov r0, r4
+ trapa #17
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
diff --git a/src/thread/superh/syscall_cp.s b/src/thread/superh/syscall_cp.s
new file mode 100644
index 00000000..5677b9c0
--- /dev/null
+++ b/src/thread/superh/syscall_cp.s
@@ -0,0 +1,39 @@
+.text
+.global __syscall_cp_asm
+.type __syscall_cp_asm, @function
+__syscall_cp_asm:
+
+.global __cp_begin
+__cp_begin:
+ mov.l @r4, r4
+ tst r4, r4
+ bt 2f
+
+ mov.l L1, r0
+ braf r0
+ nop
+1:
+
+.align 2
+L1: .long __cancel@PLT-(1b-.)
+
+2: mov r5, r3
+ mov r6, r4
+ mov r7, r5
+ mov.l @r15, r6
+ mov.l @(4,r15), r7
+ mov.l @(8,r15), r0
+ mov.l @(12,r15), r1
+ trapa #22
+
+.global __cp_end
+__cp_end:
+ ! work around hardware bug
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ rts
+ nop
diff --git a/src/unistd/superh/pipe.s b/src/unistd/superh/pipe.s
new file mode 100644
index 00000000..d865ae3a
--- /dev/null
+++ b/src/unistd/superh/pipe.s
@@ -0,0 +1,27 @@
+.global pipe
+.type pipe, @function
+pipe:
+ mov #42, r3
+ trapa #17
+
+ ! work around hardware bug
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ cmp/pz r0
+ bt 1f
+
+ mov.l L1, r1
+ braf r1
+ mov r0, r4
+
+1: mov.l r0, @(0,r4)
+ mov.l r1, @(4,r4)
+ rts
+ mov #0, r0
+
+.align 2
+L1: .long __syscall_ret@PLT-(1b-.)