about summary refs log tree commit diff
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-.)