mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 11:43:34 +08:00
Remove bitrotten / unmaintained CPU and OS ports.
This commit is contained in:
parent
61b01ec689
commit
01abd38ff2
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
2011-11-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* bare, sysdeps/am29k, sysdeps/i860, sysdeps/i960, sysdeps/m88k,
|
||||
sysdeps/mach, sysdeps/rs6000, sysdeps/standalone, sysdeps/tahoe,
|
||||
sysdeps/unix/bsd, sysdeps/unix/sysv/hpux, sysdeps/unix/sysv/i386,
|
||||
sysdeps/unix/sysv/irix4, sysdeps/unix/sysv/isc2.2,
|
||||
sysdeps/unix/sysv/minix, sysdeps/unix/sysv/sco3.2,
|
||||
sysdeps/unix/sysv/sco3.2.4, sysdeps/unix/sysv/sysv4, sysdeps/vax,
|
||||
sysdeps/z8000: Remove.
|
||||
|
||||
2010-04-14 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* libc-abis: Remove.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2011-11-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/unix/sysv/aix: Remove.
|
||||
|
||||
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* sysdeps/unix/sysv/aix/bits/fcntl.h: Comment fix.
|
||||
|
@ -1,55 +0,0 @@
|
||||
# Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
# On-Line Applications Research Corporation.
|
||||
#
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
# The GNU C Library 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
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with the GNU C Library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
# 02111-1307 USA.
|
||||
|
||||
subdir := bare
|
||||
|
||||
bare-routines := brdinit console strtsupp
|
||||
routines = $(bare-routines)
|
||||
elided-routines = $(bare-routines)
|
||||
extra-objs = $(bare-routines:%=%.o)
|
||||
|
||||
install-lib = lib$(config-vendor).a
|
||||
|
||||
include ../Rules
|
||||
|
||||
#
|
||||
# For bare targets, the $(config-vendor) is the name of the board.
|
||||
# We will place the board dependent code ONLY in a library which
|
||||
# is board dependent. This way many target boards can share a
|
||||
# single libc.a. To resolve all symbols and successfully link
|
||||
# a program, the application must link against libc.a and libMY_TARGET.a.
|
||||
# For example, the target specific library for the Motorola MVME135
|
||||
# board will be named libmvme135.a. To link a program for the
|
||||
# MVME135, one must link against -lc and -lmvme135.
|
||||
#
|
||||
|
||||
lib: $(objpfx)lib$(config-vendor).a
|
||||
|
||||
$(objpfx)lib$(config-vendor).a: $(bare-routines:%=$(objpfx)%.o)
|
||||
# This library is small enough that it's simplest to recreate the archive
|
||||
# from scratch each time.
|
||||
rm -f $@
|
||||
ifdef objdir
|
||||
cd $(objpfx); $(AR) cq$(verbose) $(@:$(objpfx)%=%) $(^:$(objpfx)%=%)
|
||||
else
|
||||
$(AR) cq$(verbose) $@ $^
|
||||
endif
|
||||
$(RANLIB) $@
|
@ -1,32 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
|
||||
/* This file is only required when a "bare" board is configured. */
|
||||
|
||||
/* _Board_Initialize
|
||||
|
||||
This routine normally performs board specific initialization. */
|
||||
|
||||
void
|
||||
_Board_Initialize ()
|
||||
{
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
|
||||
/* This file is only required when a "bare" board is configured. */
|
||||
|
||||
/* These routines provide console IO routines for your embedded target. */
|
||||
|
||||
int
|
||||
_Console_Putc (ch)
|
||||
char ch;
|
||||
{
|
||||
/* eat the character */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_Console_Getc (poll)
|
||||
int poll;
|
||||
{
|
||||
/* boring user, never types anything */
|
||||
return -1;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
|
||||
/* This file is only required when a "bare" board is configured. */
|
||||
|
||||
/* Start Support Routines
|
||||
|
||||
The start code for some CPUs (e.g. i386) require target dependent
|
||||
support. For more info, consult the start file for your CPU. */
|
@ -1,43 +0,0 @@
|
||||
/* ffs -- find first set bit in a word, counted from least significant end.
|
||||
For Amd 290x0.
|
||||
Copyright (C) 1991, 1992, 1997, 2004, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <bstring.h>
|
||||
|
||||
#undef ffs
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
int
|
||||
__ffs (x)
|
||||
int x;
|
||||
{
|
||||
int cnt;
|
||||
|
||||
asm ("clz %0,%1" : "=r" (cnt) : "r" (x & -x));
|
||||
|
||||
return 32 - cnt;
|
||||
}
|
||||
weak_alias (__ffs, ffs)
|
||||
libc_hidden_builtin_def (ffs)
|
||||
|
||||
#else
|
||||
#include <string/ffs.c>
|
||||
#endif
|
@ -1,33 +0,0 @@
|
||||
/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdeps/generic/memcopy.h>
|
||||
|
||||
#if 0
|
||||
#undef MERGE
|
||||
/* In order to make this work properly, an 's' constraint need to be added
|
||||
to tm-i860.h, to mean the SC register. */
|
||||
#define MERGE(w0, sh_1, w1, sh_2) \
|
||||
({ \
|
||||
unsigned int __merge; \
|
||||
asm("shrd %2,%1,%0" : \
|
||||
"=r" (__merge) : \
|
||||
"r" (w0), "r" (w1), "s" (sh_1)); \
|
||||
__merge; \
|
||||
})
|
||||
#endif
|
@ -1,3 +0,0 @@
|
||||
# i960 family uses IEEE 754 floating point.
|
||||
ieee754/flt-32
|
||||
ieee754/dbl-64
|
@ -1,21 +0,0 @@
|
||||
.text
|
||||
.align 4
|
||||
.globl ___mpn_add_n
|
||||
___mpn_add_n:
|
||||
mov 0,g6 # clear carry-save register
|
||||
cmpo 1,0 # clear cy
|
||||
|
||||
Loop: subo 1,g3,g3 # update loop counter
|
||||
ld (g1),g5 # load from s1_ptr
|
||||
addo 4,g1,g1 # s1_ptr++
|
||||
ld (g2),g4 # load from s2_ptr
|
||||
addo 4,g2,g2 # s2_ptr++
|
||||
cmpo g6,1 # restore cy from g6, relies on cy being 0
|
||||
addc g4,g5,g4 # main add
|
||||
subc 0,0,g6 # save cy in g6
|
||||
st g4,(g0) # store result to res_ptr
|
||||
addo 4,g0,g0 # res_ptr++
|
||||
cmpobne 0,g3,Loop # when branch is taken, clears C bit
|
||||
|
||||
mov g6,g0
|
||||
ret
|
@ -1,26 +0,0 @@
|
||||
.text
|
||||
.align 4
|
||||
.globl ___mpn_mul_1
|
||||
___mpn_mul_1:
|
||||
subo g2,0,g2
|
||||
shlo 2,g2,g4
|
||||
subo g4,g1,g1
|
||||
subo g4,g0,g13
|
||||
mov 0,g0
|
||||
|
||||
cmpo 1,0 # clear C bit on AC.cc
|
||||
|
||||
Loop: ld (g1)[g2*4],g5
|
||||
emul g3,g5,g6
|
||||
ld (g13)[g2*4],g5
|
||||
|
||||
addc g0,g6,g6 # relies on that C bit is clear
|
||||
addc 0,g7,g7
|
||||
addc g5,g6,g6 # relies on that C bit is clear
|
||||
st g6,(g13)[g2*4]
|
||||
addc 0,g7,g0
|
||||
|
||||
addo g2,1,g2
|
||||
cmpobne 0,g2,Loop # when branch is taken, clears C bit
|
||||
|
||||
ret
|
@ -1,46 +0,0 @@
|
||||
/* ffs -- find first set bit in a word, counted from least significant end.
|
||||
For i960 Core architecture
|
||||
This file is part of the GNU C Library.
|
||||
Copyright (C) 1994, 1997, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef ffs
|
||||
|
||||
#if defined (__GNUC__) && defined (__i960__)
|
||||
|
||||
int
|
||||
__ffs (x)
|
||||
int x;
|
||||
{
|
||||
int cnt;
|
||||
|
||||
asm ("scanbit %1,%0" : "=d" (cnt) : "rm" (x & -x));
|
||||
|
||||
return cnt;
|
||||
}
|
||||
weak_alias (__ffs, ffs)
|
||||
libc_hidden_builtin_def (ffs)
|
||||
|
||||
#else
|
||||
|
||||
#include <string/ffs.c>
|
||||
|
||||
#endif
|
@ -1,23 +0,0 @@
|
||||
.text
|
||||
.align 4
|
||||
.globl ___mpn_mul_1
|
||||
___mpn_mul_1:
|
||||
subo g2,0,g2
|
||||
shlo 2,g2,g4
|
||||
subo g4,g1,g1
|
||||
subo g4,g0,g13
|
||||
mov 0,g0
|
||||
|
||||
cmpo 1,0 # clear C bit on AC.cc
|
||||
|
||||
Loop: ld (g1)[g2*4],g5
|
||||
emul g3,g5,g6
|
||||
|
||||
addc g0,g6,g6 # relies on that C bit is clear
|
||||
st g6,(g13)[g2*4]
|
||||
addc 0,g7,g0
|
||||
|
||||
addo g2,1,g2
|
||||
cmpobne 0,g2,Loop # when branch is taken, clears C bit
|
||||
|
||||
ret
|
@ -1,21 +0,0 @@
|
||||
.text
|
||||
.align 4
|
||||
.globl ___mpn_sub_n
|
||||
___mpn_sub_n:
|
||||
mov 1,g6 # set carry-save register
|
||||
cmpo 1,0 # clear cy
|
||||
|
||||
Loop: subo 1,g3,g3 # update loop counter
|
||||
ld (g1),g5 # load from s1_ptr
|
||||
addo 4,g1,g1 # s1_ptr++
|
||||
ld (g2),g4 # load from s2_ptr
|
||||
addo 4,g2,g2 # s2_ptr++
|
||||
cmpo g6,1 # restore cy from g6, relies on cy being 0
|
||||
subc g4,g5,g4 # main subtract
|
||||
subc 0,0,g6 # save cy in g6
|
||||
st g4,(g0) # store result to res_ptr
|
||||
addo 4,g0,g0 # res_ptr++
|
||||
cmpobne 0,g3,Loop # when branch is taken, cy will be 0
|
||||
|
||||
mov g6,g0
|
||||
ret
|
@ -1,104 +0,0 @@
|
||||
; mc88100 __mpn_add -- Add two limb vectors of the same length > 0 and store
|
||||
; sum in a third limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; s2_ptr r4
|
||||
; size r5
|
||||
|
||||
; This code has been optimized to run one instruction per clock, avoiding
|
||||
; load stalls and writeback contention. As a result, the instruction
|
||||
; order is not always natural.
|
||||
|
||||
; The speed is about 4.6 clocks/limb + 18 clocks/limb-vector on an 88100,
|
||||
; but on the 88110, it seems to run much slower, 6.6 clocks/limb.
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_add_n
|
||||
___mpn_add_n:
|
||||
ld r6,r3,0 ; read first limb from s1_ptr
|
||||
extu r10,r5,3
|
||||
ld r7,r4,0 ; read first limb from s2_ptr
|
||||
|
||||
subu.co r5,r0,r5 ; (clear carry as side effect)
|
||||
mak r5,r5,3<4>
|
||||
bcnd eq0,r5,Lzero
|
||||
|
||||
or r12,r0,lo16(Lbase)
|
||||
or.u r12,r12,hi16(Lbase)
|
||||
addu r12,r12,r5 ; r12 is address for entering in loop
|
||||
|
||||
extu r5,r5,2 ; divide by 4
|
||||
subu r2,r2,r5 ; adjust res_ptr
|
||||
subu r3,r3,r5 ; adjust s1_ptr
|
||||
subu r4,r4,r5 ; adjust s2_ptr
|
||||
|
||||
or r8,r6,r0
|
||||
|
||||
jmp.n r12
|
||||
or r9,r7,r0
|
||||
|
||||
Loop: addu r3,r3,32
|
||||
st r8,r2,28
|
||||
addu r4,r4,32
|
||||
ld r6,r3,0
|
||||
addu r2,r2,32
|
||||
ld r7,r4,0
|
||||
Lzero: subu r10,r10,1 ; add 0 + 8r limbs (adj loop cnt)
|
||||
Lbase: ld r8,r3,4
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,4
|
||||
st r6,r2,0
|
||||
ld r6,r3,8 ; add 7 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,8
|
||||
st r8,r2,4
|
||||
ld r8,r3,12 ; add 6 + 8r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,12
|
||||
st r6,r2,8
|
||||
ld r6,r3,16 ; add 5 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,16
|
||||
st r8,r2,12
|
||||
ld r8,r3,20 ; add 4 + 8r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,20
|
||||
st r6,r2,16
|
||||
ld r6,r3,24 ; add 3 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,24
|
||||
st r8,r2,20
|
||||
ld r8,r3,28 ; add 2 + 8r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,28
|
||||
st r6,r2,24
|
||||
bcnd.n ne0,r10,Loop ; add 1 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
|
||||
st r8,r2,28 ; store most significant limb
|
||||
|
||||
jmp.n r1
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
@ -1,45 +0,0 @@
|
||||
/* ffs -- find first set bit in a word, counted from least significant end.
|
||||
For Motorola 88000.
|
||||
This file is part of the GNU C Library.
|
||||
Copyright (C) 1991, 1992, 1997, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <bstring.h>
|
||||
|
||||
#undef ffs
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
int
|
||||
__ffs (x)
|
||||
int x;
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if (x == 0)
|
||||
return 0;
|
||||
|
||||
asm ("ff1 %0,%1" : "=r" (cnt) : "r" (x & -x));
|
||||
return cnt + 1;
|
||||
}
|
||||
weak_alias (__ffs, ffs)
|
||||
libc_hidden_builtin_def (ffs)
|
||||
|
||||
#else
|
||||
#include <string/ffs.c>
|
||||
#endif
|
@ -1,133 +0,0 @@
|
||||
; mc88100 __mpn_add -- Add two limb vectors of the same length > 0 and store
|
||||
; sum in a third limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library 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; either version 2, or (at your option)
|
||||
; any later version.
|
||||
|
||||
; The GNU MP Library 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.
|
||||
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with the GNU MP Library; see the file COPYING. If not, write to
|
||||
; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; s2_ptr r4
|
||||
; size r5
|
||||
|
||||
; This code has been optimized to run one instruction per clock, avoiding
|
||||
; load stalls and writeback contention. As a result, the instruction
|
||||
; order is not always natural.
|
||||
|
||||
; The speed is approximately 4.3 clocks/limb + 18 clocks/limb-vector.
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
ENTRY (__mpn_add_n)
|
||||
ld r6,r3,0 ; read first limb from s1_ptr
|
||||
extu r10,r5,4
|
||||
ld r7,r4,0 ; read first limb from s2_ptr
|
||||
|
||||
subu.co r5,r0,r5 ; (clear carry as side effect)
|
||||
mak r5,r5,4<4>
|
||||
bcnd eq0,r5,Lzero
|
||||
|
||||
or r12,r0,lo16(Lbase)
|
||||
or.u r12,r12,hi16(Lbase)
|
||||
addu r12,r12,r5 ; r12 is address for entering in loop
|
||||
|
||||
extu r5,r5,2 ; divide by 4
|
||||
subu r2,r2,r5 ; adjust res_ptr
|
||||
subu r3,r3,r5 ; adjust s1_ptr
|
||||
subu r4,r4,r5 ; adjust s2_ptr
|
||||
|
||||
or r8,r6,r0
|
||||
|
||||
jmp.n r12
|
||||
or r9,r7,r0
|
||||
|
||||
Loop: addu r3,r3,64
|
||||
st r8,r2,60
|
||||
addu r4,r4,64
|
||||
ld r6,r3,0
|
||||
addu r2,r2,64
|
||||
ld r7,r4,0
|
||||
Lzero: subu r10,r10,1 ; add 0 + 16r limbs (adjust loop counter)
|
||||
Lbase: ld r8,r3,4
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,4
|
||||
st r6,r2,0
|
||||
ld r6,r3,8 ; add 15 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,8
|
||||
st r8,r2,4
|
||||
ld r8,r3,12 ; add 14 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,12
|
||||
st r6,r2,8
|
||||
ld r6,r3,16 ; add 13 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,16
|
||||
st r8,r2,12
|
||||
ld r8,r3,20 ; add 12 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,20
|
||||
st r6,r2,16
|
||||
ld r6,r3,24 ; add 11 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,24
|
||||
st r8,r2,20
|
||||
ld r8,r3,28 ; add 10 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,28
|
||||
st r6,r2,24
|
||||
ld r6,r3,32 ; add 9 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,32
|
||||
st r8,r2,28
|
||||
ld r8,r3,36 ; add 8 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,36
|
||||
st r6,r2,32
|
||||
ld r6,r3,40 ; add 7 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,40
|
||||
st r8,r2,36
|
||||
ld r8,r3,44 ; add 6 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,44
|
||||
st r6,r2,40
|
||||
ld r6,r3,48 ; add 5 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,48
|
||||
st r8,r2,44
|
||||
ld r8,r3,52 ; add 4 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,52
|
||||
st r6,r2,48
|
||||
ld r6,r3,56 ; add 3 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,56
|
||||
st r8,r2,52
|
||||
ld r8,r3,60 ; add 2 + 16r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,60
|
||||
st r6,r2,56
|
||||
bcnd.n ne0,r10,Loop ; add 1 + 16r limbs
|
||||
addu.cio r8,r8,r9
|
||||
|
||||
st r8,r2,60 ; store most significant limb
|
||||
|
||||
jmp.n r1
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
@ -1,103 +0,0 @@
|
||||
; mc88100 __mpn_add -- Add two limb vectors of the same length > 0 and store
|
||||
; sum in a third limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; s2_ptr r4
|
||||
; size r5
|
||||
|
||||
; This code has been optimized to run one instruction per clock, avoiding
|
||||
; load stalls and writeback contention. As a result, the instruction
|
||||
; order is not always natural.
|
||||
|
||||
; The speed is about 4.6 clocks/limb + 18 clocks/limb-vector on an 88100,
|
||||
; but on the 88110, it seems to run much slower, 6.6 clocks/limb.
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_add_n
|
||||
___mpn_add_n:
|
||||
ld r6,r3,0 ; read first limb from s1_ptr
|
||||
extu r10,r5,3
|
||||
ld r7,r4,0 ; read first limb from s2_ptr
|
||||
|
||||
subu.co r5,r0,r5 ; (clear carry as side effect)
|
||||
mak r5,r5,3<4>
|
||||
bcnd eq0,r5,Lzero
|
||||
|
||||
or r12,r0,lo16(Lbase)
|
||||
or.u r12,r12,hi16(Lbase)
|
||||
addu r12,r12,r5 ; r12 is address for entering in loop
|
||||
|
||||
extu r5,r5,2 ; divide by 4
|
||||
subu r2,r2,r5 ; adjust res_ptr
|
||||
subu r3,r3,r5 ; adjust s1_ptr
|
||||
subu r4,r4,r5 ; adjust s2_ptr
|
||||
|
||||
or r8,r6,r0
|
||||
|
||||
jmp.n r12
|
||||
or r9,r7,r0
|
||||
|
||||
Loop: addu r3,r3,32
|
||||
st r8,r2,28
|
||||
addu r4,r4,32
|
||||
ld r6,r3,0
|
||||
addu r2,r2,32
|
||||
ld r7,r4,0
|
||||
Lzero: subu r10,r10,1 ; add 0 + 8r limbs (adj loop cnt)
|
||||
Lbase: ld r8,r3,4
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,4
|
||||
st r6,r2,0
|
||||
ld r6,r3,8 ; add 7 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,8
|
||||
st r8,r2,4
|
||||
ld r8,r3,12 ; add 6 + 8r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,12
|
||||
st r6,r2,8
|
||||
ld r6,r3,16 ; add 5 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,16
|
||||
st r8,r2,12
|
||||
ld r8,r3,20 ; add 4 + 8r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,20
|
||||
st r6,r2,16
|
||||
ld r6,r3,24 ; add 3 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
ld r7,r4,24
|
||||
st r8,r2,20
|
||||
ld r8,r3,28 ; add 2 + 8r limbs
|
||||
addu.cio r6,r6,r7
|
||||
ld r9,r4,28
|
||||
st r6,r2,24
|
||||
bcnd.n ne0,r10,Loop ; add 1 + 8r limbs
|
||||
addu.cio r8,r8,r9
|
||||
|
||||
st r8,r2,28 ; store most significant limb
|
||||
|
||||
jmp.n r1
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
@ -1,127 +0,0 @@
|
||||
; mc88100 __mpn_mul_1 -- Multiply a limb vector with a single limb and
|
||||
; store the product in a second limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library 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; either version 2, or (at your option)
|
||||
; any later version.
|
||||
|
||||
; The GNU MP Library 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.
|
||||
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with the GNU MP Library; see the file COPYING. If not, write to
|
||||
; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; size r4
|
||||
; s2_limb r5
|
||||
|
||||
; Common overhead is about 11 cycles/invocation.
|
||||
|
||||
; The speed for S2_LIMB >= 0x10000 is approximately 21 cycles/limb. (The
|
||||
; pipeline stalls 2 cycles due to WB contention.)
|
||||
|
||||
; The speed for S2_LIMB < 0x10000 is approximately 16 cycles/limb. (The
|
||||
; pipeline stalls 2 cycles due to WB contention and 1 cycle due to latency.)
|
||||
|
||||
; To enhance speed:
|
||||
; 1. Unroll main loop 4-8 times.
|
||||
; 2. Schedule code to avoid WB contention. It might be tempting to move the
|
||||
; ld instruction in the loops down to save 2 cycles (less WB contention),
|
||||
; but that looses because the ultimate value will be read from outside
|
||||
; the allocated space. But if we handle the ultimate multiplication in
|
||||
; the tail, we can do this.
|
||||
; 3. Make the multiplication with less instructions. I think the code for
|
||||
; (S2_LIMB >= 0x10000) is not minimal.
|
||||
; With these techniques the (S2_LIMB >= 0x10000) case would run in 17 or
|
||||
; less cycles/limb; the (S2_LIMB < 0x10000) case would run in 11
|
||||
; cycles/limb. (Assuming infinite unrolling.)
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
ENTRY (__mpn_mul_1)
|
||||
|
||||
; Make S1_PTR and RES_PTR point at the end of their blocks
|
||||
; and negate SIZE.
|
||||
lda r3,r3[r4]
|
||||
lda r6,r2[r4] ; RES_PTR in r6 since r2 is retval
|
||||
subu r4,r0,r4
|
||||
|
||||
addu.co r2,r0,r0 ; r2 = cy = 0
|
||||
ld r9,r3[r4]
|
||||
mask r7,r5,0xffff ; r7 = lo(S2_LIMB)
|
||||
extu r8,r5,16 ; r8 = hi(S2_LIMB)
|
||||
bcnd.n eq0,r8,Lsmall ; jump if (hi(S2_LIMB) == 0)
|
||||
subu r6,r6,4
|
||||
|
||||
; General code for any value of S2_LIMB.
|
||||
|
||||
; Make a stack frame and save r25 and r26
|
||||
subu r31,r31,16
|
||||
st.d r25,r31,8
|
||||
|
||||
; Enter the loop in the middle
|
||||
br.n L1
|
||||
addu r4,r4,1
|
||||
|
||||
Loop:
|
||||
ld r9,r3[r4]
|
||||
st r26,r6[r4]
|
||||
; bcnd ne0,r0,0 ; bubble
|
||||
addu r4,r4,1
|
||||
L1: mul r26,r9,r5 ; low word of product mul_1 WB ld
|
||||
mask r12,r9,0xffff ; r12 = lo(s1_limb) mask_1
|
||||
mul r11,r12,r7 ; r11 = prod_0 mul_2 WB mask_1
|
||||
mul r10,r12,r8 ; r10 = prod_1a mul_3
|
||||
extu r13,r9,16 ; r13 = hi(s1_limb) extu_1 WB mul_1
|
||||
mul r12,r13,r7 ; r12 = prod_1b mul_4 WB extu_1
|
||||
mul r25,r13,r8 ; r25 = prod_2 mul_5 WB mul_2
|
||||
extu r11,r11,16 ; r11 = hi(prod_0) extu_2 WB mul_3
|
||||
addu r10,r10,r11 ; addu_1 WB extu_2
|
||||
; bcnd ne0,r0,0 ; bubble WB addu_1
|
||||
addu.co r10,r10,r12 ; WB mul_4
|
||||
mask.u r10,r10,0xffff ; move the 16 most significant bits...
|
||||
addu.ci r10,r10,r0 ; ...to the low half of the word...
|
||||
rot r10,r10,16 ; ...and put carry in pos 16.
|
||||
addu.co r26,r26,r2 ; add old carry limb
|
||||
bcnd.n ne0,r4,Loop
|
||||
addu.ci r2,r25,r10 ; compute new carry limb
|
||||
|
||||
st r26,r6[r4]
|
||||
ld.d r25,r31,8
|
||||
jmp.n r1
|
||||
addu r31,r31,16
|
||||
|
||||
; Fast code for S2_LIMB < 0x10000
|
||||
Lsmall:
|
||||
; Enter the loop in the middle
|
||||
br.n SL1
|
||||
addu r4,r4,1
|
||||
|
||||
SLoop:
|
||||
ld r9,r3[r4] ;
|
||||
st r8,r6[r4] ;
|
||||
addu r4,r4,1 ;
|
||||
SL1: mul r8,r9,r5 ; low word of product
|
||||
mask r12,r9,0xffff ; r12 = lo(s1_limb)
|
||||
extu r13,r9,16 ; r13 = hi(s1_limb)
|
||||
mul r11,r12,r7 ; r11 = prod_0
|
||||
mul r12,r13,r7 ; r12 = prod_1b
|
||||
addu.cio r8,r8,r2 ; add old carry limb
|
||||
extu r10,r11,16 ; r11 = hi(prod_0)
|
||||
addu r10,r10,r12 ;
|
||||
bcnd.n ne0,r4,SLoop
|
||||
extu r2,r10,16 ; r2 = new carry limb
|
||||
|
||||
jmp.n r1
|
||||
st r8,r6[r4]
|
@ -1,128 +0,0 @@
|
||||
; mc88100 __mpn_mul_1 -- Multiply a limb vector with a single limb and
|
||||
; store the product in a second limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; size r4
|
||||
; s2_limb r5
|
||||
|
||||
; Common overhead is about 11 cycles/invocation.
|
||||
|
||||
; The speed for S2_LIMB >= 0x10000 is approximately 21 cycles/limb. (The
|
||||
; pipeline stalls 2 cycles due to WB contention.)
|
||||
|
||||
; The speed for S2_LIMB < 0x10000 is approximately 16 cycles/limb. (The
|
||||
; pipeline stalls 2 cycles due to WB contention and 1 cycle due to latency.)
|
||||
|
||||
; To enhance speed:
|
||||
; 1. Unroll main loop 4-8 times.
|
||||
; 2. Schedule code to avoid WB contention. It might be tempting to move the
|
||||
; ld instruction in the loops down to save 2 cycles (less WB contention),
|
||||
; but that looses because the ultimate value will be read from outside
|
||||
; the allocated space. But if we handle the ultimate multiplication in
|
||||
; the tail, we can do this.
|
||||
; 3. Make the multiplication with less instructions. I think the code for
|
||||
; (S2_LIMB >= 0x10000) is not minimal.
|
||||
; With these techniques the (S2_LIMB >= 0x10000) case would run in 17 or
|
||||
; less cycles/limb; the (S2_LIMB < 0x10000) case would run in 11
|
||||
; cycles/limb. (Assuming infinite unrolling.)
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_mul_1
|
||||
___mpn_mul_1:
|
||||
|
||||
; Make S1_PTR and RES_PTR point at the end of their blocks
|
||||
; and negate SIZE.
|
||||
lda r3,r3[r4]
|
||||
lda r6,r2[r4] ; RES_PTR in r6 since r2 is retval
|
||||
subu r4,r0,r4
|
||||
|
||||
addu.co r2,r0,r0 ; r2 = cy = 0
|
||||
ld r9,r3[r4]
|
||||
mask r7,r5,0xffff ; r7 = lo(S2_LIMB)
|
||||
extu r8,r5,16 ; r8 = hi(S2_LIMB)
|
||||
bcnd.n eq0,r8,Lsmall ; jump if (hi(S2_LIMB) == 0)
|
||||
subu r6,r6,4
|
||||
|
||||
; General code for any value of S2_LIMB.
|
||||
|
||||
; Make a stack frame and save r25 and r26
|
||||
subu r31,r31,16
|
||||
st.d r25,r31,8
|
||||
|
||||
; Enter the loop in the middle
|
||||
br.n L1
|
||||
addu r4,r4,1
|
||||
|
||||
Loop:
|
||||
ld r9,r3[r4]
|
||||
st r26,r6[r4]
|
||||
; bcnd ne0,r0,0 ; bubble
|
||||
addu r4,r4,1
|
||||
L1: mul r26,r9,r5 ; low word of product mul_1 WB ld
|
||||
mask r12,r9,0xffff ; r12 = lo(s1_limb) mask_1
|
||||
mul r11,r12,r7 ; r11 = prod_0 mul_2 WB mask_1
|
||||
mul r10,r12,r8 ; r10 = prod_1a mul_3
|
||||
extu r13,r9,16 ; r13 = hi(s1_limb) extu_1 WB mul_1
|
||||
mul r12,r13,r7 ; r12 = prod_1b mul_4 WB extu_1
|
||||
mul r25,r13,r8 ; r25 = prod_2 mul_5 WB mul_2
|
||||
extu r11,r11,16 ; r11 = hi(prod_0) extu_2 WB mul_3
|
||||
addu r10,r10,r11 ; addu_1 WB extu_2
|
||||
; bcnd ne0,r0,0 ; bubble WB addu_1
|
||||
addu.co r10,r10,r12 ; WB mul_4
|
||||
mask.u r10,r10,0xffff ; move the 16 most significant bits...
|
||||
addu.ci r10,r10,r0 ; ...to the low half of the word...
|
||||
rot r10,r10,16 ; ...and put carry in pos 16.
|
||||
addu.co r26,r26,r2 ; add old carry limb
|
||||
bcnd.n ne0,r4,Loop
|
||||
addu.ci r2,r25,r10 ; compute new carry limb
|
||||
|
||||
st r26,r6[r4]
|
||||
ld.d r25,r31,8
|
||||
jmp.n r1
|
||||
addu r31,r31,16
|
||||
|
||||
; Fast code for S2_LIMB < 0x10000
|
||||
Lsmall:
|
||||
; Enter the loop in the middle
|
||||
br.n SL1
|
||||
addu r4,r4,1
|
||||
|
||||
SLoop:
|
||||
ld r9,r3[r4] ;
|
||||
st r8,r6[r4] ;
|
||||
addu r4,r4,1 ;
|
||||
SL1: mul r8,r9,r5 ; low word of product
|
||||
mask r12,r9,0xffff ; r12 = lo(s1_limb)
|
||||
extu r13,r9,16 ; r13 = hi(s1_limb)
|
||||
mul r11,r12,r7 ; r11 = prod_0
|
||||
mul r12,r13,r7 ; r12 = prod_1b
|
||||
addu.cio r8,r8,r2 ; add old carry limb
|
||||
extu r10,r11,16 ; r11 = hi(prod_0)
|
||||
addu r10,r10,r12 ;
|
||||
bcnd.n ne0,r4,SLoop
|
||||
extu r2,r10,16 ; r2 = new carry limb
|
||||
|
||||
jmp.n r1
|
||||
st r8,r6[r4]
|
@ -1,134 +0,0 @@
|
||||
; mc88100 __mpn_sub -- Subtract two limb vectors of the same length > 0 and
|
||||
; store difference in a third limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library 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; either version 2, or (at your option)
|
||||
; any later version.
|
||||
|
||||
; The GNU MP Library 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.
|
||||
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with the GNU MP Library; see the file COPYING. If not, write to
|
||||
; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; s2_ptr r4
|
||||
; size r5
|
||||
|
||||
; This code has been optimized to run one instruction per clock, avoiding
|
||||
; load stalls and writeback contention. As a result, the instruction
|
||||
; order is not always natural.
|
||||
|
||||
; The speed is approximately 4.3 clocks/limb + 18 clocks/limb-vector.
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
ENTRY (__mpn_sub_n)
|
||||
ld r6,r3,0 ; read first limb from s1_ptr
|
||||
extu r10,r5,4
|
||||
ld r7,r4,0 ; read first limb from s2_ptr
|
||||
|
||||
subu.co r5,r0,r5 ; (clear carry as side effect)
|
||||
mak r5,r5,4<4>
|
||||
bcnd eq0,r5,Lzero
|
||||
|
||||
or r12,r0,lo16(Lbase)
|
||||
or.u r12,r12,hi16(Lbase)
|
||||
addu r12,r12,r5 ; r12 is address for entering in loop
|
||||
|
||||
extu r5,r5,2 ; divide by 4
|
||||
subu r2,r2,r5 ; adjust res_ptr
|
||||
subu r3,r3,r5 ; adjust s1_ptr
|
||||
subu r4,r4,r5 ; adjust s2_ptr
|
||||
|
||||
or r8,r6,r0
|
||||
|
||||
jmp.n r12
|
||||
or r9,r7,r0
|
||||
|
||||
Loop: addu r3,r3,64
|
||||
st r8,r2,60
|
||||
addu r4,r4,64
|
||||
ld r6,r3,0
|
||||
addu r2,r2,64
|
||||
ld r7,r4,0
|
||||
Lzero: subu r10,r10,1 ; subtract 0 + 16r limbs (adjust loop counter)
|
||||
Lbase: ld r8,r3,4
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,4
|
||||
st r6,r2,0
|
||||
ld r6,r3,8 ; subtract 15 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,8
|
||||
st r8,r2,4
|
||||
ld r8,r3,12 ; subtract 14 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,12
|
||||
st r6,r2,8
|
||||
ld r6,r3,16 ; subtract 13 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,16
|
||||
st r8,r2,12
|
||||
ld r8,r3,20 ; subtract 12 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,20
|
||||
st r6,r2,16
|
||||
ld r6,r3,24 ; subtract 11 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,24
|
||||
st r8,r2,20
|
||||
ld r8,r3,28 ; subtract 10 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,28
|
||||
st r6,r2,24
|
||||
ld r6,r3,32 ; subtract 9 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,32
|
||||
st r8,r2,28
|
||||
ld r8,r3,36 ; subtract 8 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,36
|
||||
st r6,r2,32
|
||||
ld r6,r3,40 ; subtract 7 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,40
|
||||
st r8,r2,36
|
||||
ld r8,r3,44 ; subtract 6 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,44
|
||||
st r6,r2,40
|
||||
ld r6,r3,48 ; subtract 5 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,48
|
||||
st r8,r2,44
|
||||
ld r8,r3,52 ; subtract 4 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,52
|
||||
st r6,r2,48
|
||||
ld r6,r3,56 ; subtract 3 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,56
|
||||
st r8,r2,52
|
||||
ld r8,r3,60 ; subtract 2 + 16r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,60
|
||||
st r6,r2,56
|
||||
bcnd.n ne0,r10,Loop ; subtract 1 + 16r limbs
|
||||
subu.cio r8,r8,r9
|
||||
|
||||
st r8,r2,60 ; store most significant limb
|
||||
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
jmp.n r1
|
||||
xor r2,r2,1
|
@ -1,104 +0,0 @@
|
||||
; mc88100 __mpn_sub -- Subtract two limb vectors of the same length > 0 and
|
||||
; store difference in a third limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; s2_ptr r4
|
||||
; size r5
|
||||
|
||||
; This code has been optimized to run one instruction per clock, avoiding
|
||||
; load stalls and writeback contention. As a result, the instruction
|
||||
; order is not always natural.
|
||||
|
||||
; The speed is about 4.6 clocks/limb + 18 clocks/limb-vector on an 88100,
|
||||
; but on the 88110, it seems to run much slower, 6.6 clocks/limb.
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_sub_n
|
||||
___mpn_sub_n:
|
||||
ld r6,r3,0 ; read first limb from s1_ptr
|
||||
extu r10,r5,3
|
||||
ld r7,r4,0 ; read first limb from s2_ptr
|
||||
|
||||
subu.co r5,r0,r5 ; (clear carry as side effect)
|
||||
mak r5,r5,3<4>
|
||||
bcnd eq0,r5,Lzero
|
||||
|
||||
or r12,r0,lo16(Lbase)
|
||||
or.u r12,r12,hi16(Lbase)
|
||||
addu r12,r12,r5 ; r12 is address for entering in loop
|
||||
|
||||
extu r5,r5,2 ; divide by 4
|
||||
subu r2,r2,r5 ; adjust res_ptr
|
||||
subu r3,r3,r5 ; adjust s1_ptr
|
||||
subu r4,r4,r5 ; adjust s2_ptr
|
||||
|
||||
or r8,r6,r0
|
||||
|
||||
jmp.n r12
|
||||
or r9,r7,r0
|
||||
|
||||
Loop: addu r3,r3,32
|
||||
st r8,r2,28
|
||||
addu r4,r4,32
|
||||
ld r6,r3,0
|
||||
addu r2,r2,32
|
||||
ld r7,r4,0
|
||||
Lzero: subu r10,r10,1 ; subtract 0 + 8r limbs (adj loop cnt)
|
||||
Lbase: ld r8,r3,4
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,4
|
||||
st r6,r2,0
|
||||
ld r6,r3,8 ; subtract 7 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,8
|
||||
st r8,r2,4
|
||||
ld r8,r3,12 ; subtract 6 + 8r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,12
|
||||
st r6,r2,8
|
||||
ld r6,r3,16 ; subtract 5 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,16
|
||||
st r8,r2,12
|
||||
ld r8,r3,20 ; subtract 4 + 8r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,20
|
||||
st r6,r2,16
|
||||
ld r6,r3,24 ; subtract 3 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,24
|
||||
st r8,r2,20
|
||||
ld r8,r3,28 ; subtract 2 + 8r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,28
|
||||
st r6,r2,24
|
||||
bcnd.n ne0,r10,Loop ; subtract 1 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
|
||||
st r8,r2,28 ; store most significant limb
|
||||
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
jmp.n r1
|
||||
xor r2,r2,1
|
@ -1,200 +0,0 @@
|
||||
; mc88110 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
|
||||
; sum in a third limb vector.
|
||||
|
||||
; Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
#define res_ptr r2
|
||||
#define s1_ptr r3
|
||||
#define s2_ptr r4
|
||||
#define size r5
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
text
|
||||
align 16
|
||||
global C_SYMBOL_NAME(__mpn_add_n)
|
||||
C_SYMBOL_NAME(__mpn_add_n):
|
||||
addu.co r0,r0,r0 ; clear cy flag
|
||||
xor r12,s2_ptr,res_ptr
|
||||
bb1 2,r12,L1
|
||||
; ** V1a **
|
||||
L0: bb0 2,res_ptr,L_v1 ; branch if res_ptr is aligned?
|
||||
/* Add least significant limb separately to align res_ptr and s2_ptr */
|
||||
ld r10,s1_ptr,0
|
||||
addu s1_ptr,s1_ptr,4
|
||||
ld r8,s2_ptr,0
|
||||
addu s2_ptr,s2_ptr,4
|
||||
subu size,size,1
|
||||
addu.co r6,r10,r8
|
||||
st r6,res_ptr,0
|
||||
addu res_ptr,res_ptr,4
|
||||
L_v1: cmp r12,size,2
|
||||
bb1 lt,r12,Lend2
|
||||
|
||||
ld r10,s1_ptr,0
|
||||
ld r12,s1_ptr,4
|
||||
ld.d r8,s2_ptr,0
|
||||
subu size,size,10
|
||||
bcnd lt0,size,Lfin1
|
||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||
align 8
|
||||
Loop1: subu size,size,8
|
||||
addu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,8
|
||||
addu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,12
|
||||
ld.d r8,s2_ptr,8
|
||||
st.d r6,res_ptr,0
|
||||
addu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,16
|
||||
addu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,20
|
||||
ld.d r8,s2_ptr,16
|
||||
st.d r6,res_ptr,8
|
||||
addu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,24
|
||||
addu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,28
|
||||
ld.d r8,s2_ptr,24
|
||||
st.d r6,res_ptr,16
|
||||
addu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,32
|
||||
addu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,36
|
||||
addu s1_ptr,s1_ptr,32
|
||||
ld.d r8,s2_ptr,32
|
||||
addu s2_ptr,s2_ptr,32
|
||||
st.d r6,res_ptr,24
|
||||
addu res_ptr,res_ptr,32
|
||||
bcnd ge0,size,Loop1
|
||||
|
||||
Lfin1: addu size,size,8-2
|
||||
bcnd lt0,size,Lend1
|
||||
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
||||
Loope1: addu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,8
|
||||
addu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,12
|
||||
ld.d r8,s2_ptr,8
|
||||
st.d r6,res_ptr,0
|
||||
subu size,size,2
|
||||
addu s1_ptr,s1_ptr,8
|
||||
addu s2_ptr,s2_ptr,8
|
||||
addu res_ptr,res_ptr,8
|
||||
bcnd ge0,size,Loope1
|
||||
Lend1: addu.cio r6,r10,r8
|
||||
addu.cio r7,r12,r9
|
||||
st.d r6,res_ptr,0
|
||||
|
||||
bb0 0,size,Lret1
|
||||
/* Add last limb */
|
||||
ld r10,s1_ptr,8
|
||||
ld r8,s2_ptr,8
|
||||
addu.cio r6,r10,r8
|
||||
st r6,res_ptr,8
|
||||
|
||||
Lret1: jmp.n r1
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
|
||||
L1: xor r12,s1_ptr,res_ptr
|
||||
bb1 2,r12,L2
|
||||
; ** V1b **
|
||||
or r12,r0,s2_ptr
|
||||
or s2_ptr,r0,s1_ptr
|
||||
or s1_ptr,r0,r12
|
||||
br L0
|
||||
|
||||
; ** V2 **
|
||||
/* If we come here, the alignment of s1_ptr and res_ptr as well as the
|
||||
alignment of s2_ptr and res_ptr differ. Since there are only two ways
|
||||
things can be aligned (that we care about) we now know that the alignment
|
||||
of s1_ptr and s2_ptr are the same. */
|
||||
|
||||
L2: cmp r12,size,1
|
||||
bb1 eq,r12,Ljone
|
||||
bb0 2,s1_ptr,L_v2 ; branch if s1_ptr is aligned
|
||||
/* Add least significant limb separately to align res_ptr and s2_ptr */
|
||||
ld r10,s1_ptr,0
|
||||
addu s1_ptr,s1_ptr,4
|
||||
ld r8,s2_ptr,0
|
||||
addu s2_ptr,s2_ptr,4
|
||||
subu size,size,1
|
||||
addu.co r6,r10,r8
|
||||
st r6,res_ptr,0
|
||||
addu res_ptr,res_ptr,4
|
||||
|
||||
L_v2: subu size,size,8
|
||||
bcnd lt0,size,Lfin2
|
||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||
align 8
|
||||
Loop2: subu size,size,8
|
||||
ld.d r8,s1_ptr,0
|
||||
ld.d r6,s2_ptr,0
|
||||
addu.cio r8,r8,r6
|
||||
st r8,res_ptr,0
|
||||
addu.cio r9,r9,r7
|
||||
st r9,res_ptr,4
|
||||
ld.d r8,s1_ptr,8
|
||||
ld.d r6,s2_ptr,8
|
||||
addu.cio r8,r8,r6
|
||||
st r8,res_ptr,8
|
||||
addu.cio r9,r9,r7
|
||||
st r9,res_ptr,12
|
||||
ld.d r8,s1_ptr,16
|
||||
ld.d r6,s2_ptr,16
|
||||
addu.cio r8,r8,r6
|
||||
st r8,res_ptr,16
|
||||
addu.cio r9,r9,r7
|
||||
st r9,res_ptr,20
|
||||
ld.d r8,s1_ptr,24
|
||||
ld.d r6,s2_ptr,24
|
||||
addu.cio r8,r8,r6
|
||||
st r8,res_ptr,24
|
||||
addu.cio r9,r9,r7
|
||||
st r9,res_ptr,28
|
||||
addu s1_ptr,s1_ptr,32
|
||||
addu s2_ptr,s2_ptr,32
|
||||
addu res_ptr,res_ptr,32
|
||||
bcnd ge0,size,Loop2
|
||||
|
||||
Lfin2: addu size,size,8-2
|
||||
bcnd lt0,size,Lend2
|
||||
Loope2: ld.d r8,s1_ptr,0
|
||||
ld.d r6,s2_ptr,0
|
||||
addu.cio r8,r8,r6
|
||||
st r8,res_ptr,0
|
||||
addu.cio r9,r9,r7
|
||||
st r9,res_ptr,4
|
||||
subu size,size,2
|
||||
addu s1_ptr,s1_ptr,8
|
||||
addu s2_ptr,s2_ptr,8
|
||||
addu res_ptr,res_ptr,8
|
||||
bcnd ge0,size,Loope2
|
||||
Lend2: bb0 0,size,Lret2
|
||||
/* Add last limb */
|
||||
Ljone: ld r10,s1_ptr,0
|
||||
ld r8,s2_ptr,0
|
||||
addu.cio r6,r10,r8
|
||||
st r6,res_ptr,0
|
||||
|
||||
Lret2: jmp.n r1
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
@ -1,61 +0,0 @@
|
||||
; mc88110 __mpn_addmul_1 -- Multiply a limb vector with a single limb and
|
||||
; store the product in a second limb vector.
|
||||
|
||||
; Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; size r4
|
||||
; s2_limb r5
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_addmul_1
|
||||
___mpn_addmul_1:
|
||||
lda r3,r3[r4]
|
||||
lda r8,r2[r4] ; RES_PTR in r8 since r2 is retval
|
||||
subu r4,r0,r4
|
||||
addu.co r2,r0,r0 ; r2 = cy = 0
|
||||
|
||||
ld r6,r3[r4]
|
||||
addu r4,r4,1
|
||||
subu r8,r8,4
|
||||
bcnd.n eq0,r4,Lend
|
||||
mulu.d r10,r6,r5
|
||||
|
||||
Loop: ld r7,r8[r4]
|
||||
ld r6,r3[r4]
|
||||
addu.cio r9,r11,r2
|
||||
addu.ci r2,r10,r0
|
||||
addu.co r9,r9,r7
|
||||
st r9,r8[r4]
|
||||
addu r4,r4,1
|
||||
mulu.d r10,r6,r5
|
||||
bcnd ne0,r4,Loop
|
||||
|
||||
Lend: ld r7,r8,0
|
||||
addu.cio r9,r11,r2
|
||||
addu.ci r2,r10,r0
|
||||
addu.co r9,r9,r7
|
||||
st r9,r8,0
|
||||
jmp.n r1
|
||||
addu.ci r2,r2,r0
|
@ -1,80 +0,0 @@
|
||||
; mc88110 __mpn_mul_1 -- Multiply a limb vector with a single limb and
|
||||
; store the product in a second limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library 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; either version 2, or (at your option)
|
||||
; any later version.
|
||||
|
||||
; The GNU MP Library 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.
|
||||
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with the GNU MP Library; see the file COPYING. If not, write to
|
||||
; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; size r4
|
||||
; s2_limb r5
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
ENTRY (__mpn_mul_1)
|
||||
ld r6,r3,0
|
||||
sub r4,r0,r4
|
||||
sub r3,r3,r4 ; r3 is offset s1_ptr
|
||||
sub r2,r2,r4
|
||||
sub r8,r2,8 ; r8 is offset res_ptr
|
||||
mulu.d r10,r6,r5
|
||||
|
||||
addu r4,r4,1
|
||||
bcnd eq0,r4,Lend
|
||||
addu.co r2,r0,0 ; clear cy_limb
|
||||
|
||||
Loop: ld r6,r3[r4]
|
||||
addu.cio r9,r11,r2
|
||||
or r2,r10,r0 ; could be avoided if unrolled
|
||||
addu r4,r4,1
|
||||
mulu.d r10,r6,r5
|
||||
bcnd ne0,r4,Loop
|
||||
st r9,r8[r4]
|
||||
|
||||
Lend: addu.cio r9,r11,r2
|
||||
st r9,r8,4
|
||||
jmp.n r1
|
||||
addu.ci r2,r10,r0
|
||||
|
||||
; This is the Right Way to do this on '110. 4 cycles / 64-bit limb.
|
||||
; ld.d r10,
|
||||
; mulu.d
|
||||
; addu.cio
|
||||
; addu.cio
|
||||
; st.d
|
||||
; mulu.d ,r11,r5
|
||||
; ld.d r12,
|
||||
; mulu.d ,r10,r5
|
||||
; addu.cio
|
||||
; addu.cio
|
||||
; st.d
|
||||
; mulu.d
|
||||
; ld.d r10,
|
||||
; mulu.d
|
||||
; addu.cio
|
||||
; addu.cio
|
||||
; st.d
|
||||
; mulu.d
|
||||
; ld.d r10,
|
||||
; mulu.d
|
||||
; addu.cio
|
||||
; addu.cio
|
||||
; st.d
|
||||
; mulu.d
|
@ -1,59 +0,0 @@
|
||||
; mc88110 __mpn_mul_1 -- Multiply a limb vector with a single limb and
|
||||
; store the product in a second limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; size r4
|
||||
; s2_limb r5
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_mul_1
|
||||
___mpn_mul_1:
|
||||
; Make S1_PTR and RES_PTR point at the end of their blocks
|
||||
; and negate SIZE.
|
||||
lda r3,r3[r4]
|
||||
lda r8,r2[r4] ; RES_PTR in r8 since r2 is retval
|
||||
subu r4,r0,r4
|
||||
|
||||
addu.co r2,r0,r0 ; r2 = cy = 0
|
||||
|
||||
ld r6,r3[r4]
|
||||
addu r4,r4,1
|
||||
mulu.d r10,r6,r5
|
||||
bcnd.n eq0,r4,Lend
|
||||
subu r8,r8,8
|
||||
|
||||
Loop: ld r6,r3[r4]
|
||||
addu.cio r9,r11,r2
|
||||
or r2,r10,r0 ; could be avoided if unrolled
|
||||
addu r4,r4,1
|
||||
mulu.d r10,r6,r5
|
||||
bcnd.n ne0,r4,Loop
|
||||
st r9,r8[r4]
|
||||
|
||||
Lend: addu.cio r9,r11,r2
|
||||
st r9,r8,4
|
||||
jmp.n r1
|
||||
addu.ci r2,r10,r0
|
@ -1,276 +0,0 @@
|
||||
; mc88110 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
|
||||
; store difference in a third limb vector.
|
||||
|
||||
; Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
#define res_ptr r2
|
||||
#define s1_ptr r3
|
||||
#define s2_ptr r4
|
||||
#define size r5
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
text
|
||||
align 16
|
||||
global C_SYMBOL_NAME(__mpn_sub_n)
|
||||
C_SYMBOL_NAME(__mpn_sub_n):
|
||||
subu.co r0,r0,r0 ; set cy flag
|
||||
xor r12,s2_ptr,res_ptr
|
||||
bb1 2,r12,L1
|
||||
; ** V1a **
|
||||
L0: bb0 2,res_ptr,L_v1 ; branch if res_ptr is aligned
|
||||
/* Add least significant limb separately to align res_ptr and s2_ptr */
|
||||
ld r10,s1_ptr,0
|
||||
addu s1_ptr,s1_ptr,4
|
||||
ld r8,s2_ptr,0
|
||||
addu s2_ptr,s2_ptr,4
|
||||
subu size,size,1
|
||||
subu.co r6,r10,r8
|
||||
st r6,res_ptr,0
|
||||
addu res_ptr,res_ptr,4
|
||||
L_v1: cmp r12,size,2
|
||||
bb1 lt,r12,Lend2
|
||||
|
||||
ld r10,s1_ptr,0
|
||||
ld r12,s1_ptr,4
|
||||
ld.d r8,s2_ptr,0
|
||||
subu size,size,10
|
||||
bcnd lt0,size,Lfin1
|
||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||
align 8
|
||||
Loop1: subu size,size,8
|
||||
subu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,8
|
||||
subu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,12
|
||||
ld.d r8,s2_ptr,8
|
||||
st.d r6,res_ptr,0
|
||||
subu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,16
|
||||
subu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,20
|
||||
ld.d r8,s2_ptr,16
|
||||
st.d r6,res_ptr,8
|
||||
subu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,24
|
||||
subu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,28
|
||||
ld.d r8,s2_ptr,24
|
||||
st.d r6,res_ptr,16
|
||||
subu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,32
|
||||
subu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,36
|
||||
addu s1_ptr,s1_ptr,32
|
||||
ld.d r8,s2_ptr,32
|
||||
addu s2_ptr,s2_ptr,32
|
||||
st.d r6,res_ptr,24
|
||||
addu res_ptr,res_ptr,32
|
||||
bcnd ge0,size,Loop1
|
||||
|
||||
Lfin1: addu size,size,8-2
|
||||
bcnd lt0,size,Lend1
|
||||
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
||||
Loope1: subu.cio r6,r10,r8
|
||||
ld r10,s1_ptr,8
|
||||
subu.cio r7,r12,r9
|
||||
ld r12,s1_ptr,12
|
||||
ld.d r8,s2_ptr,8
|
||||
st.d r6,res_ptr,0
|
||||
subu size,size,2
|
||||
addu s1_ptr,s1_ptr,8
|
||||
addu s2_ptr,s2_ptr,8
|
||||
addu res_ptr,res_ptr,8
|
||||
bcnd ge0,size,Loope1
|
||||
Lend1: subu.cio r6,r10,r8
|
||||
subu.cio r7,r12,r9
|
||||
st.d r6,res_ptr,0
|
||||
|
||||
bb0 0,size,Lret1
|
||||
/* Add last limb */
|
||||
ld r10,s1_ptr,8
|
||||
ld r8,s2_ptr,8
|
||||
subu.cio r6,r10,r8
|
||||
st r6,res_ptr,8
|
||||
|
||||
Lret1: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
jmp.n r1
|
||||
xor r2,r2,1
|
||||
|
||||
L1: xor r12,s1_ptr,res_ptr
|
||||
bb1 2,r12,L2
|
||||
; ** V1b **
|
||||
bb0 2,res_ptr,L_v1b ; branch if res_ptr is aligned
|
||||
/* Add least significant limb separately to align res_ptr and s1_ptr */
|
||||
ld r10,s2_ptr,0
|
||||
addu s2_ptr,s2_ptr,4
|
||||
ld r8,s1_ptr,0
|
||||
addu s1_ptr,s1_ptr,4
|
||||
subu size,size,1
|
||||
subu.co r6,r8,r10
|
||||
st r6,res_ptr,0
|
||||
addu res_ptr,res_ptr,4
|
||||
L_v1b: cmp r12,size,2
|
||||
bb1 lt,r12,Lend2
|
||||
|
||||
ld r10,s2_ptr,0
|
||||
ld r12,s2_ptr,4
|
||||
ld.d r8,s1_ptr,0
|
||||
subu size,size,10
|
||||
bcnd lt0,size,Lfin1b
|
||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||
align 8
|
||||
Loop1b: subu size,size,8
|
||||
subu.cio r6,r8,r10
|
||||
ld r10,s2_ptr,8
|
||||
subu.cio r7,r9,r12
|
||||
ld r12,s2_ptr,12
|
||||
ld.d r8,s1_ptr,8
|
||||
st.d r6,res_ptr,0
|
||||
subu.cio r6,r8,r10
|
||||
ld r10,s2_ptr,16
|
||||
subu.cio r7,r9,r12
|
||||
ld r12,s2_ptr,20
|
||||
ld.d r8,s1_ptr,16
|
||||
st.d r6,res_ptr,8
|
||||
subu.cio r6,r8,r10
|
||||
ld r10,s2_ptr,24
|
||||
subu.cio r7,r9,r12
|
||||
ld r12,s2_ptr,28
|
||||
ld.d r8,s1_ptr,24
|
||||
st.d r6,res_ptr,16
|
||||
subu.cio r6,r8,r10
|
||||
ld r10,s2_ptr,32
|
||||
subu.cio r7,r9,r12
|
||||
ld r12,s2_ptr,36
|
||||
addu s2_ptr,s2_ptr,32
|
||||
ld.d r8,s1_ptr,32
|
||||
addu s1_ptr,s1_ptr,32
|
||||
st.d r6,res_ptr,24
|
||||
addu res_ptr,res_ptr,32
|
||||
bcnd ge0,size,Loop1b
|
||||
|
||||
Lfin1b: addu size,size,8-2
|
||||
bcnd lt0,size,Lend1b
|
||||
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
||||
Loope1b:subu.cio r6,r8,r10
|
||||
ld r10,s2_ptr,8
|
||||
subu.cio r7,r9,r12
|
||||
ld r12,s2_ptr,12
|
||||
ld.d r8,s1_ptr,8
|
||||
st.d r6,res_ptr,0
|
||||
subu size,size,2
|
||||
addu s1_ptr,s1_ptr,8
|
||||
addu s2_ptr,s2_ptr,8
|
||||
addu res_ptr,res_ptr,8
|
||||
bcnd ge0,size,Loope1b
|
||||
Lend1b: subu.cio r6,r8,r10
|
||||
subu.cio r7,r9,r12
|
||||
st.d r6,res_ptr,0
|
||||
|
||||
bb0 0,size,Lret1b
|
||||
/* Add last limb */
|
||||
ld r10,s2_ptr,8
|
||||
ld r8,s1_ptr,8
|
||||
subu.cio r6,r8,r10
|
||||
st r6,res_ptr,8
|
||||
|
||||
Lret1b: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
jmp.n r1
|
||||
xor r2,r2,1
|
||||
|
||||
; ** V2 **
|
||||
/* If we come here, the alignment of s1_ptr and res_ptr as well as the
|
||||
alignment of s2_ptr and res_ptr differ. Since there are only two ways
|
||||
things can be aligned (that we care about) we now know that the alignment
|
||||
of s1_ptr and s2_ptr are the same. */
|
||||
|
||||
L2: cmp r12,size,1
|
||||
bb1 eq,r12,Ljone
|
||||
bb0 2,s1_ptr,L_v2 ; branch if s1_ptr is aligned
|
||||
/* Add least significant limb separately to align res_ptr and s2_ptr */
|
||||
ld r10,s1_ptr,0
|
||||
addu s1_ptr,s1_ptr,4
|
||||
ld r8,s2_ptr,0
|
||||
addu s2_ptr,s2_ptr,4
|
||||
subu size,size,1
|
||||
subu.co r6,r10,r8
|
||||
st r6,res_ptr,0
|
||||
addu res_ptr,res_ptr,4
|
||||
|
||||
L_v2: subu size,size,8
|
||||
bcnd lt0,size,Lfin2
|
||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||
align 8
|
||||
Loop2: subu size,size,8
|
||||
ld.d r8,s1_ptr,0
|
||||
ld.d r6,s2_ptr,0
|
||||
subu.cio r8,r8,r6
|
||||
st r8,res_ptr,0
|
||||
subu.cio r9,r9,r7
|
||||
st r9,res_ptr,4
|
||||
ld.d r8,s1_ptr,8
|
||||
ld.d r6,s2_ptr,8
|
||||
subu.cio r8,r8,r6
|
||||
st r8,res_ptr,8
|
||||
subu.cio r9,r9,r7
|
||||
st r9,res_ptr,12
|
||||
ld.d r8,s1_ptr,16
|
||||
ld.d r6,s2_ptr,16
|
||||
subu.cio r8,r8,r6
|
||||
st r8,res_ptr,16
|
||||
subu.cio r9,r9,r7
|
||||
st r9,res_ptr,20
|
||||
ld.d r8,s1_ptr,24
|
||||
ld.d r6,s2_ptr,24
|
||||
subu.cio r8,r8,r6
|
||||
st r8,res_ptr,24
|
||||
subu.cio r9,r9,r7
|
||||
st r9,res_ptr,28
|
||||
addu s1_ptr,s1_ptr,32
|
||||
addu s2_ptr,s2_ptr,32
|
||||
addu res_ptr,res_ptr,32
|
||||
bcnd ge0,size,Loop2
|
||||
|
||||
Lfin2: addu size,size,8-2
|
||||
bcnd lt0,size,Lend2
|
||||
Loope2: ld.d r8,s1_ptr,0
|
||||
ld.d r6,s2_ptr,0
|
||||
subu.cio r8,r8,r6
|
||||
st r8,res_ptr,0
|
||||
subu.cio r9,r9,r7
|
||||
st r9,res_ptr,4
|
||||
subu size,size,2
|
||||
addu s1_ptr,s1_ptr,8
|
||||
addu s2_ptr,s2_ptr,8
|
||||
addu res_ptr,res_ptr,8
|
||||
bcnd ge0,size,Loope2
|
||||
Lend2: bb0 0,size,Lret2
|
||||
/* Add last limb */
|
||||
Ljone: ld r10,s1_ptr,0
|
||||
ld r8,s2_ptr,0
|
||||
subu.cio r6,r10,r8
|
||||
st r6,res_ptr,0
|
||||
|
||||
Lret2: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
jmp.n r1
|
||||
xor r2,r2,1
|
@ -1,127 +0,0 @@
|
||||
; mc88100 __mpn_mul_1 -- Multiply a limb vector with a single limb and
|
||||
; store the product in a second limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; size r4
|
||||
; s2_limb r5
|
||||
|
||||
; Common overhead is about 11 cycles/invocation.
|
||||
|
||||
; The speed for S2_LIMB >= 0x10000 is approximately 21 cycles/limb. (The
|
||||
; pipeline stalls 2 cycles due to WB contention.)
|
||||
|
||||
; The speed for S2_LIMB < 0x10000 is approximately 16 cycles/limb. (The
|
||||
; pipeline stalls 2 cycles due to WB contention and 1 cycle due to latency.)
|
||||
|
||||
; To enhance speed:
|
||||
; 1. Unroll main loop 4-8 times.
|
||||
; 2. Schedule code to avoid WB contention. It might be tempting to move the
|
||||
; ld instruction in the loops down to save 2 cycles (less WB contention),
|
||||
; but that looses because the ultimate value will be read from outside
|
||||
; the allocated space. But if we handle the ultimate multiplication in
|
||||
; the tail, we can do this.
|
||||
; 3. Make the multiplication with less instructions. I think the code for
|
||||
; (S2_LIMB >= 0x10000) is not minimal.
|
||||
; With these techniques the (S2_LIMB >= 0x10000) case would run in 17 or
|
||||
; less cycles/limb; the (S2_LIMB < 0x10000) case would run in 11
|
||||
; cycles/limb. (Assuming infinite unrolling.)
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_mul_1
|
||||
___mpn_mul_1:
|
||||
|
||||
; Make S1_PTR and RES_PTR point at the end of their blocks
|
||||
; and negate SIZE.
|
||||
lda r3,r3[r4]
|
||||
lda r6,r2[r4] ; RES_PTR in r6 since r2 is retval
|
||||
subu r4,r0,r4
|
||||
|
||||
addu.co r2,r0,r0 ; r2 = cy = 0
|
||||
ld r9,r3[r4]
|
||||
mask r7,r5,0xffff ; r7 = lo(S2_LIMB)
|
||||
extu r8,r5,16 ; r8 = hi(S2_LIMB)
|
||||
bcnd.n eq0,r8,Lsmall ; jump if (hi(S2_LIMB) == 0)
|
||||
subu r6,r6,4
|
||||
|
||||
; General code for any value of S2_LIMB.
|
||||
|
||||
; Make a stack frame and save r25 and r26
|
||||
subu r31,r31,16
|
||||
st.d r25,r31,8
|
||||
|
||||
; Enter the loop in the middle
|
||||
br.n L1
|
||||
addu r4,r4,1
|
||||
|
||||
Loop: ld r9,r3[r4]
|
||||
st r26,r6[r4]
|
||||
; bcnd ne0,r0,0 ; bubble
|
||||
addu r4,r4,1
|
||||
L1: mul r26,r9,r5 ; low word of product mul_1 WB ld
|
||||
mask r12,r9,0xffff ; r12 = lo(s1_limb) mask_1
|
||||
mul r11,r12,r7 ; r11 = prod_0 mul_2 WB mask_1
|
||||
mul r10,r12,r8 ; r10 = prod_1a mul_3
|
||||
extu r13,r9,16 ; r13 = hi(s1_limb) extu_1 WB mul_1
|
||||
mul r12,r13,r7 ; r12 = prod_1b mul_4 WB extu_1
|
||||
mul r25,r13,r8 ; r25 = prod_2 mul_5 WB mul_2
|
||||
extu r11,r11,16 ; r11 = hi(prod_0) extu_2 WB mul_3
|
||||
addu r10,r10,r11 ; addu_1 WB extu_2
|
||||
; bcnd ne0,r0,0 ; bubble WB addu_1
|
||||
addu.co r10,r10,r12 ; WB mul_4
|
||||
mask.u r10,r10,0xffff ; move the 16 most significant bits...
|
||||
addu.ci r10,r10,r0 ; ...to the low half of the word...
|
||||
rot r10,r10,16 ; ...and put carry in pos 16.
|
||||
addu.co r26,r26,r2 ; add old carry limb
|
||||
bcnd.n ne0,r4,Loop
|
||||
addu.ci r2,r25,r10 ; compute new carry limb
|
||||
|
||||
st r26,r6[r4]
|
||||
ld.d r25,r31,8
|
||||
jmp.n r1
|
||||
addu r31,r31,16
|
||||
|
||||
; Fast code for S2_LIMB < 0x10000
|
||||
Lsmall:
|
||||
; Enter the loop in the middle
|
||||
br.n SL1
|
||||
addu r4,r4,1
|
||||
|
||||
SLoop: ld r9,r3[r4] ;
|
||||
st r8,r6[r4] ;
|
||||
addu r4,r4,1 ;
|
||||
SL1: mul r8,r9,r5 ; low word of product
|
||||
mask r12,r9,0xffff ; r12 = lo(s1_limb)
|
||||
extu r13,r9,16 ; r13 = hi(s1_limb)
|
||||
mul r11,r12,r7 ; r11 = prod_0
|
||||
mul r12,r13,r7 ; r12 = prod_1b
|
||||
addu.cio r8,r8,r2 ; add old carry limb
|
||||
extu r10,r11,16 ; r11 = hi(prod_0)
|
||||
addu r10,r10,r12 ;
|
||||
bcnd.n ne0,r4,SLoop
|
||||
extu r2,r10,16 ; r2 = new carry limb
|
||||
|
||||
jmp.n r1
|
||||
st r8,r6[r4]
|
@ -1,106 +0,0 @@
|
||||
; mc88100 __mpn_sub -- Subtract two limb vectors of the same length > 0 and
|
||||
; store difference in a third limb vector.
|
||||
|
||||
; Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
; This file is part of the GNU MP Library.
|
||||
|
||||
; The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU Lesser General Public License as published by
|
||||
; the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
; option) any later version.
|
||||
|
||||
; The GNU MP Library 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 Lesser General Public
|
||||
; License for more details.
|
||||
|
||||
; You should have received a copy of the GNU Lesser General Public License
|
||||
; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
; MA 02111-1307, USA.
|
||||
|
||||
|
||||
; INPUT PARAMETERS
|
||||
; res_ptr r2
|
||||
; s1_ptr r3
|
||||
; s2_ptr r4
|
||||
; size r5
|
||||
|
||||
; This code has been optimized to run one instruction per clock, avoiding
|
||||
; load stalls and writeback contention. As a result, the instruction
|
||||
; order is not always natural.
|
||||
|
||||
; The speed is about 4.6 clocks/limb + 18 clocks/limb-vector on an 88100,
|
||||
; but on the 88110, it seems to run much slower, 6.6 clocks/limb.
|
||||
|
||||
text
|
||||
align 16
|
||||
global ___mpn_sub_n
|
||||
___mpn_sub_n:
|
||||
ld r6,r3,0 ; read first limb from s1_ptr
|
||||
extu r10,r5,3
|
||||
ld r7,r4,0 ; read first limb from s2_ptr
|
||||
|
||||
subu r5,r0,r5
|
||||
mak r5,r5,3<4>
|
||||
bcnd.n eq0,r5,Lzero
|
||||
subu.co r0,r0,r0 ; initialize carry
|
||||
|
||||
or r12,r0,lo16(Lbase)
|
||||
or.u r12,r12,hi16(Lbase)
|
||||
addu r12,r12,r5 ; r12 is address for entering in loop
|
||||
|
||||
extu r5,r5,2 ; divide by 4
|
||||
subu r2,r2,r5 ; adjust res_ptr
|
||||
subu r3,r3,r5 ; adjust s1_ptr
|
||||
subu r4,r4,r5 ; adjust s2_ptr
|
||||
|
||||
or r8,r6,r0
|
||||
|
||||
jmp.n r12
|
||||
or r9,r7,r0
|
||||
|
||||
Loop: addu r3,r3,32
|
||||
st r8,r2,28
|
||||
addu r4,r4,32
|
||||
ld r6,r3,0
|
||||
addu r2,r2,32
|
||||
ld r7,r4,0
|
||||
Lzero: subu r10,r10,1 ; subtract 0 + 8r limbs (adj loop cnt)
|
||||
Lbase: ld r8,r3,4
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,4
|
||||
st r6,r2,0
|
||||
ld r6,r3,8 ; subtract 7 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,8
|
||||
st r8,r2,4
|
||||
ld r8,r3,12 ; subtract 6 + 8r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,12
|
||||
st r6,r2,8
|
||||
ld r6,r3,16 ; subtract 5 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,16
|
||||
st r8,r2,12
|
||||
ld r8,r3,20 ; subtract 4 + 8r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,20
|
||||
st r6,r2,16
|
||||
ld r6,r3,24 ; subtract 3 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
ld r7,r4,24
|
||||
st r8,r2,20
|
||||
ld r8,r3,28 ; subtract 2 + 8r limbs
|
||||
subu.cio r6,r6,r7
|
||||
ld r9,r4,28
|
||||
st r6,r2,24
|
||||
bcnd.n ne0,r10,Loop ; subtract 1 + 8r limbs
|
||||
subu.cio r8,r8,r9
|
||||
|
||||
st r8,r2,28 ; store most significant limb
|
||||
|
||||
addu.ci r2,r0,r0 ; return carry-out from most sign. limb
|
||||
jmp.n r1
|
||||
xor r2,r2,1
|
@ -1,80 +0,0 @@
|
||||
/* Machine-specific definition for spin locks. Alpha version.
|
||||
Copyright (C) 1994, 1997, 2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MACHINE_LOCK_H
|
||||
#define _MACHINE_LOCK_H
|
||||
|
||||
/* The type of a spin lock variable. */
|
||||
|
||||
typedef __volatile long int __spin_lock_t;
|
||||
|
||||
/* Value to initialize `__spin_lock_t' variables to. */
|
||||
|
||||
#define __SPIN_LOCK_INITIALIZER 0L
|
||||
|
||||
|
||||
#ifndef _EXTERN_INLINE
|
||||
#define _EXTERN_INLINE __extern_inline
|
||||
#endif
|
||||
|
||||
/* Unlock LOCK. */
|
||||
|
||||
_EXTERN_INLINE void
|
||||
__spin_unlock (__spin_lock_t *__lock)
|
||||
{
|
||||
__asm__ __volatile__ ("mb; stq $31, %0; mb"
|
||||
: "=m" (__lock));
|
||||
}
|
||||
|
||||
/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
|
||||
|
||||
_EXTERN_INLINE int
|
||||
__spin_try_lock (register __spin_lock_t *__lock)
|
||||
{
|
||||
register long int __rtn, __tmp;
|
||||
|
||||
do
|
||||
{
|
||||
__asm__ __volatile__ ("mb; ldq_l %0,%1" /* Load lock value into TMP. */
|
||||
: "=r" (__tmp) : "m" (*__lock));
|
||||
__rtn = 2; /* Load locked value into RTN. */
|
||||
if (__tmp)
|
||||
/* The lock is already taken. */
|
||||
return 0;
|
||||
|
||||
/* The lock is not taken; try to get it now. */
|
||||
__asm__ __volatile__ ("stq_c %0,%1"
|
||||
: "=r" (__rtn), "=m" (*__lock)
|
||||
: "0" (__rtn), "1" (*__lock));
|
||||
/* RTN is clear if stq_c was interrupted; loop to try the lock again. */
|
||||
} while (! __rtn);
|
||||
/* RTN is now nonzero; we have the lock. */
|
||||
return __rtn;
|
||||
}
|
||||
|
||||
/* Return nonzero if LOCK is locked. */
|
||||
|
||||
_EXTERN_INLINE int
|
||||
__spin_lock_locked (__spin_lock_t *__lock)
|
||||
{
|
||||
return *__lock != 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* machine-lock.h */
|
@ -1,36 +0,0 @@
|
||||
/* Machine-specific function to return the stack pointer. Alpha version.
|
||||
Copyright (C) 1994, 1997, 2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MACHINE_SP_H
|
||||
#define _MACHINE_SP_H
|
||||
|
||||
/* Return the current stack pointer. */
|
||||
|
||||
#ifndef _EXTERN_INLINE
|
||||
#define _EXTERN_INLINE __extern_inline
|
||||
#endif
|
||||
|
||||
_EXTERN_INLINE void *
|
||||
__thread_stack_pointer (void)
|
||||
{
|
||||
register void *__sp__ __asm__ ("$30");
|
||||
return __sp__;
|
||||
}
|
||||
|
||||
#endif /* machine-sp.h */
|
@ -1,69 +0,0 @@
|
||||
/* Set FP exception mask and rounding mode. Mach/Alpha version.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <fpu_control.h>
|
||||
|
||||
|
||||
#define FPCR_DYN_SHIFT 58 /* first dynamic rounding mode bit */
|
||||
#define FPCR_DYN_CHOPPED (0x0UL << FPCR_DYN_SHIFT) /* towards 0 */
|
||||
#define FPCR_DYN_MINUS (0x1UL << FPCR_DYN_SHIFT) /* towards -INF */
|
||||
#define FPCR_DYN_NORMAL (0x2UL << FPCR_DYN_SHIFT) /* towards nearest */
|
||||
#define FPCR_DYN_PLUS (0x3UL << FPCR_DYN_SHIFT) /* towards +INF */
|
||||
#define FPCR_DYN_MASK (0x3UL << FPCR_DYN_SHIFT)
|
||||
|
||||
static inline unsigned long
|
||||
rdfpcr (void)
|
||||
{
|
||||
unsigned long fpcr;
|
||||
asm ("excb; mf_fpcr %0" : "=f"(fpcr));
|
||||
return fpcr;
|
||||
}
|
||||
|
||||
static inline void
|
||||
wrfpcr (unsigned long fpcr)
|
||||
{
|
||||
asm volatile ("mt_fpcr %0; excb" : : "f"(fpcr));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__setfpucw (fpu_control_t fpu_control)
|
||||
{
|
||||
unsigned long fpcr;
|
||||
|
||||
if (!fpu_control)
|
||||
fpu_control = _FPU_DEFAULT;
|
||||
|
||||
/* first, set dynamic rounding mode: */
|
||||
|
||||
fpcr = rdfpcr();
|
||||
fpcr &= ~FPCR_DYN_MASK;
|
||||
switch (fpu_control & 0xc00)
|
||||
{
|
||||
case _FPU_RC_NEAREST: fpcr |= FPCR_DYN_NORMAL; break;
|
||||
case _FPU_RC_DOWN: fpcr |= FPCR_DYN_MINUS; break;
|
||||
case _FPU_RC_UP: fpcr |= FPCR_DYN_PLUS; break;
|
||||
case _FPU_RC_ZERO: fpcr |= FPCR_DYN_CHOPPED; break;
|
||||
}
|
||||
wrfpcr(fpcr);
|
||||
|
||||
/* XXX trap bits? */
|
||||
|
||||
__fpu_control = fpu_control; /* update global copy */
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/* Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
ENTRY (syscall)
|
||||
mov a0, v0 /* Load system call number from first arg. */
|
||||
mov a1, a0
|
||||
mov a2, a1
|
||||
mov a3, a2
|
||||
mov a4, a3
|
||||
mov a5, a4
|
||||
/* Load the remaining possible args (up to 11) from the stack. */
|
||||
ldq a5,0(sp)
|
||||
ldq t0,8(sp)
|
||||
ldq t1,16(sp)
|
||||
ldq t2,24(sp)
|
||||
ldq t3,32(sp)
|
||||
ldq t4,40(sp)
|
||||
callsys
|
||||
ret
|
||||
END (syscall)
|
@ -1,59 +0,0 @@
|
||||
/* Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define MOVE(x,y) mov x, y
|
||||
|
||||
#define LOSE asm volatile ("call_pal 0") /* halt */
|
||||
|
||||
#define START_MACHDEP \
|
||||
asm ("_start: mov $30, $16\n" /* Put initial SP in a0. */ \
|
||||
" br $27, 1f\n" /* Load GP from PC. */ \
|
||||
"1: ldgp $29, 0($27)\n" \
|
||||
" jmp $26, _start0"); /* Jump to _start0; don't return. */
|
||||
#define START_ARGS char **sparg
|
||||
#define SNARF_ARGS(argc, argv, envp) \
|
||||
(envp = &(argv = &sparg[1])[(argc = *(int *) sparg) + 1])
|
||||
|
||||
#define CALL_WITH_SP(fn, sp) \
|
||||
({ register long int __fn = (long int) fn, __sp = (long int) sp; \
|
||||
asm volatile ("mov %0,$30; jmp $31, (%1); ldgp $29, 0(%1)" \
|
||||
: : "r" (__sp), "r" (__fn)); })
|
||||
|
||||
#define STACK_GROWTH_DOWN
|
||||
|
||||
#define RETURN_TO(sp, pc, retval) \
|
||||
asm volatile ("mov %0,$30; jmp $31, (%1); mov %2,$0" \
|
||||
: : "r" (sp), "r" (pc), "r" ((long int) (retval)));
|
||||
|
||||
#define ALIGN 3
|
||||
#include <sysdeps/mach/sysdep.h>
|
||||
|
||||
/* Alpha needs the .ent and .frame magic that the generic version lacks. */
|
||||
#undef ENTRY
|
||||
#define ENTRY(name) \
|
||||
.globl name; \
|
||||
.align 3; \
|
||||
.ent name, 0; \
|
||||
name##: \
|
||||
.frame sp, 0, ra
|
||||
|
||||
#include <mach/alpha/asm.h>
|
||||
#undef at
|
||||
#define at 28
|
||||
#define AT $28
|
||||
#define fp s6
|
@ -1,39 +0,0 @@
|
||||
/* Mach thread state definitions for machine-independent code. Alpha version.
|
||||
Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <mach/machine/thread_status.h>
|
||||
|
||||
#define MACHINE_THREAD_STATE_FLAVOR ALPHA_THREAD_STATE
|
||||
#define MACHINE_THREAD_STATE_COUNT ALPHA_THREAD_STATE_COUNT
|
||||
|
||||
#define machine_thread_state alpha_thread_state
|
||||
|
||||
#define PC pc
|
||||
#define SP r30
|
||||
#define SYSRETURN r0
|
||||
|
||||
struct machine_thread_all_state
|
||||
{
|
||||
int set; /* Mask of bits (1 << FLAVOR). */
|
||||
struct alpha_thread_state basic;
|
||||
struct alpha_exc_state exc;
|
||||
struct alpha_float_state fpu;
|
||||
};
|
||||
|
||||
#include <sysdeps/mach/thread_state.h>
|
@ -1,63 +0,0 @@
|
||||
/* Machine-specific definition for spin locks. HPPA version.
|
||||
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MACHINE_LOCK_H
|
||||
#define _MACHINE_LOCK_H
|
||||
|
||||
/* The type of a spin lock variable. */
|
||||
|
||||
typedef __volatile int __spin_lock_t __attribute__ ((__aligned__ (16)));
|
||||
|
||||
/* Value to initialize `__spin_lock_t' variables to. */
|
||||
|
||||
#define __SPIN_LOCK_INITIALIZER -1
|
||||
|
||||
|
||||
#ifndef _EXTERN_INLINE
|
||||
#define _EXTERN_INLINE extern __inline
|
||||
#endif
|
||||
|
||||
/* Unlock LOCK. */
|
||||
|
||||
_EXTERN_INLINE void
|
||||
__spin_unlock (__spin_lock_t *__lock)
|
||||
{
|
||||
*__lock = -1;
|
||||
}
|
||||
|
||||
/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
|
||||
|
||||
_EXTERN_INLINE int
|
||||
__spin_try_lock (__spin_lock_t *__lock)
|
||||
{
|
||||
register int __result;
|
||||
__asm__ __volatile__ ("ldcws %0, %1" : "=m" (*__lock), "=r" (__result));
|
||||
return __result != 0;
|
||||
}
|
||||
|
||||
/* Return nonzero if LOCK is locked. */
|
||||
|
||||
_EXTERN_INLINE int
|
||||
__spin_lock_locked (__spin_lock_t *__lock)
|
||||
{
|
||||
return *__lock == 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* machine-lock.h */
|
@ -1,73 +0,0 @@
|
||||
/* Machine-dependent signal context structure for GNU Hurd. Alpha version.
|
||||
Copyright (C) 1994,97,2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
|
||||
# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef sc_alpha_thread_state
|
||||
|
||||
/* Signal handlers are actually called:
|
||||
void handler (int sig, int code, struct sigcontext *scp); */
|
||||
|
||||
/* State of this thread when the signal was taken. */
|
||||
struct sigcontext
|
||||
{
|
||||
/* These first members are machine-independent. */
|
||||
|
||||
long int sc_onstack; /* Nonzero if running on sigstack. */
|
||||
__sigset_t sc_mask; /* Blocked signals to restore. */
|
||||
|
||||
/* MiG reply port this thread is using. */
|
||||
unsigned long int sc_reply_port;
|
||||
|
||||
/* Port this thread is doing an interruptible RPC on. */
|
||||
unsigned long int sc_intr_port;
|
||||
|
||||
/* Error code associated with this signal (interpreted as `error_t'). */
|
||||
int sc_error;
|
||||
|
||||
/* All following members are machine-dependent. The rest of this
|
||||
structure is written to be laid out identically to:
|
||||
{
|
||||
struct alpha_thread_state basic;
|
||||
struct alpha_exc_state exc;
|
||||
struct alpha_float_state fpu;
|
||||
}
|
||||
trampoline.c knows this, so it must be changed if this changes. */
|
||||
|
||||
#define sc_alpha_thread_state sc_regs /* Beginning of correspondence. */
|
||||
long int sc_regs[31]; /* General registers $0..$30. */
|
||||
long int sc_pc; /* Program counter. */
|
||||
|
||||
/* struct alpha_exc_state */
|
||||
#define sc_alpha_exc_state sc_badvaddr
|
||||
unsigned long int sc_badvaddr;
|
||||
unsigned int sc_cause; /* Machine-level trap code. */
|
||||
#define SC_CAUSE_SET_SSTEP 1
|
||||
int sc_used_fpa; /* Nonzero if FPU was used. */
|
||||
|
||||
/* struct alpha_float_state
|
||||
This is only filled in if sc_used_fpa is nonzero. */
|
||||
#define sc_alpha_float_state sc_fpregs
|
||||
double sc_fpregs[31]; /* Floating point registers $f0..$f30. */
|
||||
long int sc_fpcsr; /* Floating point control/status register. */
|
||||
};
|
||||
|
||||
#endif /* sc_alpha_thread_state */
|
@ -1,75 +0,0 @@
|
||||
/* Translate Mach exception codes into signal numbers. Alpha version.
|
||||
Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
#include <mach/exception.h>
|
||||
|
||||
/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
|
||||
into a signal number and signal subcode. */
|
||||
|
||||
void
|
||||
_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
|
||||
{
|
||||
detail->error = 0;
|
||||
|
||||
switch (detail->exc)
|
||||
{
|
||||
default:
|
||||
*signo = SIGIOT;
|
||||
detail->code = detail->exc;
|
||||
break;
|
||||
|
||||
case EXC_BAD_ACCESS:
|
||||
if (detail->exc_code == KERN_PROTECTION_FAILURE)
|
||||
*signo = SIGSEGV;
|
||||
else
|
||||
*signo = SIGBUS;
|
||||
detail->code = detail->exc_subcode;
|
||||
detail->error = detail->exc_code;
|
||||
break;
|
||||
|
||||
case EXC_BAD_INSTRUCTION:
|
||||
*signo = SIGILL;
|
||||
detail->code = detail->exc_code;
|
||||
break;
|
||||
|
||||
case EXC_ARITHMETIC:
|
||||
*signo = SIGFPE;
|
||||
detail->code = detail->exc_code;
|
||||
break;
|
||||
break;
|
||||
|
||||
case EXC_EMULATION:
|
||||
/* 3.0 doesn't give this one, why, I don't know. */
|
||||
*signo = SIGEMT;
|
||||
detail->code = detail->exc_code;
|
||||
break;
|
||||
|
||||
case EXC_SOFTWARE:
|
||||
*signo = SIGEMT;
|
||||
detail->code = detail->exc_code;
|
||||
break;
|
||||
|
||||
case EXC_BREAKPOINT:
|
||||
*signo = SIGTRAP;
|
||||
detail->code = detail->exc_code;
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,302 +0,0 @@
|
||||
/* Initialization code run first thing by the ELF startup code. Alpha/Hurd.
|
||||
Copyright (C) 1995,96,97,98,99,2000,01,02,03 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <hurd.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sysdep.h>
|
||||
#include <set-hooks.h>
|
||||
#include "hurdstartup.h"
|
||||
#include "hurdmalloc.h" /* XXX */
|
||||
|
||||
extern void __mach_init (void);
|
||||
extern void __init_misc (int, char **, char **);
|
||||
#ifdef USE_NONOPTION_FLAGS
|
||||
extern void __getopt_clean_environment (char **);
|
||||
#endif
|
||||
#ifndef SHARED
|
||||
extern void _dl_non_dynamic_init (void) internal_function;
|
||||
#endif
|
||||
extern void __libc_global_ctors (void);
|
||||
|
||||
unsigned int __hurd_threadvar_max;
|
||||
unsigned long int __hurd_threadvar_stack_offset;
|
||||
unsigned long int __hurd_threadvar_stack_mask;
|
||||
|
||||
#ifndef SHARED
|
||||
int __libc_enable_secure;
|
||||
#endif
|
||||
int __libc_multiple_libcs attribute_hidden = 1;
|
||||
|
||||
extern int __libc_argc attribute_hidden;
|
||||
extern char **__libc_argv attribute_hidden;
|
||||
extern char **_dl_argv;
|
||||
|
||||
void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
|
||||
void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
|
||||
|
||||
/* Things that want to be run before _hurd_init or much anything else.
|
||||
Importantly, these are called before anything tries to use malloc. */
|
||||
DEFINE_HOOK (_hurd_preinit_hook, (void));
|
||||
|
||||
|
||||
/* We call this once the Hurd magic is all set up and we are ready to be a
|
||||
Posixoid program. This does the same things the generic version does. */
|
||||
static void
|
||||
posixland_init (int argc, char **argv, char **envp)
|
||||
{
|
||||
__libc_argc = argc;
|
||||
__libc_argv = argv;
|
||||
__environ = envp;
|
||||
|
||||
#ifndef SHARED
|
||||
_dl_non_dynamic_init ();
|
||||
#endif
|
||||
__init_misc (argc, argv, envp);
|
||||
|
||||
#ifdef USE_NONOPTION_FLAGS
|
||||
/* This is a hack to make the special getopt in GNU libc working. */
|
||||
__getopt_clean_environment (envp);
|
||||
#endif
|
||||
|
||||
#ifdef SHARED
|
||||
__libc_global_ctors ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init1 (intptr_t *data)
|
||||
{
|
||||
int argc = (intptr_t) *data;
|
||||
char **argv = (char **) &data[1];
|
||||
char **envp = &argv[argc + 1];
|
||||
struct hurd_startup_data *d;
|
||||
|
||||
while (*envp)
|
||||
++envp;
|
||||
d = (void *) ++envp;
|
||||
|
||||
/* If we are the bootstrap task started by the kernel,
|
||||
then after the environment pointers there is no Hurd
|
||||
data block; the argument strings start there. */
|
||||
/* OSF Mach starts the bootstrap task with argc == 0.
|
||||
XXX This fails if a non-bootstrap task gets started
|
||||
with argc == 0. */
|
||||
if (argc && (void *) d != argv[0])
|
||||
{
|
||||
_hurd_init_dtable = d->dtable;
|
||||
_hurd_init_dtablesize = d->dtablesize;
|
||||
|
||||
{
|
||||
/* Check if the stack we are now on is different from
|
||||
the one described by _hurd_stack_{base,size}. */
|
||||
|
||||
char dummy;
|
||||
const vm_address_t newsp = (vm_address_t) &dummy;
|
||||
|
||||
if (d->stack_size != 0 && (newsp < d->stack_base ||
|
||||
newsp - d->stack_base > d->stack_size))
|
||||
/* The new stack pointer does not intersect with the
|
||||
stack the exec server set up for us, so free that stack. */
|
||||
__vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size);
|
||||
}
|
||||
}
|
||||
|
||||
if ((void *) d != argv[0] && (d->portarray || d->intarray))
|
||||
/* Initialize library data structures, start signal processing, etc. */
|
||||
_hurd_init (d->flags, argv,
|
||||
d->portarray, d->portarraysize,
|
||||
d->intarray, d->intarraysize);
|
||||
|
||||
#ifndef SHARED
|
||||
__libc_enable_secure = d->flags & EXEC_SECURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
init (intptr_t *data)
|
||||
{
|
||||
int argc = *data;
|
||||
char **argv = (void *) (data + 1);
|
||||
char **envp = &argv[argc + 1];
|
||||
struct hurd_startup_data *d;
|
||||
unsigned long int threadvars[_HURD_THREADVAR_MAX];
|
||||
|
||||
/* Provide temporary storage for thread-specific variables on the
|
||||
startup stack so the cthreads initialization code can use them
|
||||
for malloc et al, or so we can use malloc below for the real
|
||||
threadvars array. */
|
||||
memset (threadvars, 0, sizeof threadvars);
|
||||
__hurd_threadvar_stack_offset = (unsigned long int) threadvars;
|
||||
|
||||
/* Since the cthreads initialization code uses malloc, and the
|
||||
malloc initialization code needs to get at the environment, make
|
||||
sure we can find it. We'll need to do this again later on since
|
||||
switching stacks changes the location where the environment is
|
||||
stored. */
|
||||
__environ = envp;
|
||||
|
||||
while (*envp)
|
||||
++envp;
|
||||
d = (void *) ++envp;
|
||||
|
||||
/* The user might have defined a value for this, to get more variables.
|
||||
Otherwise it will be zero on startup. We must make sure it is set
|
||||
properly before before cthreads initialization, so cthreads can know
|
||||
how much space to leave for thread variables. */
|
||||
if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
|
||||
__hurd_threadvar_max = _HURD_THREADVAR_MAX;
|
||||
|
||||
|
||||
/* After possibly switching stacks, call `init1' (above) with the user
|
||||
code as the return address, and the argument data immediately above
|
||||
that on the stack. */
|
||||
|
||||
if (_cthread_init_routine)
|
||||
{
|
||||
/* Initialize cthreads, which will allocate us a new stack to run on. */
|
||||
void *newsp = (*_cthread_init_routine) ();
|
||||
struct hurd_startup_data *od;
|
||||
|
||||
void switch_stacks (void);
|
||||
|
||||
/* Copy per-thread variables from that temporary
|
||||
area onto the new cthread stack. */
|
||||
memcpy (__hurd_threadvar_location_from_sp (0, newsp),
|
||||
threadvars, sizeof threadvars);
|
||||
|
||||
/* Copy the argdata from the old stack to the new one. */
|
||||
newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
|
||||
(char *) d - (char *) data);
|
||||
|
||||
#ifdef SHARED
|
||||
/* And readjust the dynamic linker's idea of where the argument
|
||||
vector lives. */
|
||||
assert (_dl_argv == argv);
|
||||
_dl_argv = (void *) ((int *) newsp + 1);
|
||||
#endif
|
||||
|
||||
/* Set up the Hurd startup data block immediately following
|
||||
the argument and environment pointers on the new stack. */
|
||||
od = (newsp + ((char *) d - (char *) data));
|
||||
if ((void *) argv[0] == d)
|
||||
/* We were started up by the kernel with arguments on the stack.
|
||||
There is no Hurd startup data, so zero the block. */
|
||||
memset (od, 0, sizeof *od);
|
||||
else
|
||||
/* Copy the Hurd startup data block to the new stack. */
|
||||
*od = *d;
|
||||
|
||||
/*
|
||||
Force NEWSP into sp and &init1 into pv, then branch to pv (call init1).
|
||||
*/
|
||||
asm volatile ("lda $30,0(%0); lda $27,0(%1); jsr $26,($27)"
|
||||
: : "r" (newsp), "r" (&init1));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are not using cthreads, so we will have just a single allocated
|
||||
area for the per-thread variables of the main user thread. */
|
||||
unsigned long int *array;
|
||||
unsigned int i;
|
||||
|
||||
array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
|
||||
if (array == NULL)
|
||||
__libc_fatal ("Can't allocate single-threaded thread variables.");
|
||||
|
||||
/* Copy per-thread variables from the temporary array into the
|
||||
newly malloc'd space. */
|
||||
memcpy (array, threadvars, sizeof threadvars);
|
||||
__hurd_threadvar_stack_offset = (unsigned long int) array;
|
||||
for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
|
||||
array[i] = 0;
|
||||
|
||||
init1 (data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Do the first essential initializations that must precede all else. */
|
||||
static inline void
|
||||
first_init (void)
|
||||
{
|
||||
/* Initialize data structures so we can do RPCs. */
|
||||
__mach_init ();
|
||||
|
||||
RUN_HOOK (_hurd_preinit_hook, ());
|
||||
}
|
||||
|
||||
#ifdef SHARED
|
||||
/* This function is called specially by the dynamic linker to do early
|
||||
initialization of the shared C library before normal initializers
|
||||
expecting a Posixoid environment can run. It gets called with the
|
||||
stack set up just as the user will see it, so it can switch stacks. */
|
||||
|
||||
void
|
||||
_dl_init_first (intptr_t argc, ...)
|
||||
{
|
||||
first_init ();
|
||||
|
||||
init (&argc);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SHARED
|
||||
/* The regular posixland initialization is what goes into libc's
|
||||
normal initializer. */
|
||||
/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
|
||||
pointer in the dynamic section based solely on that. It is convention
|
||||
for this function to be in the `.init' section, but the symbol name is
|
||||
the only thing that really matters!! */
|
||||
strong_alias (posixland_init, _init);
|
||||
|
||||
void
|
||||
__libc_init_first (int argc, char **argv, char **envp)
|
||||
{
|
||||
/* Everything was done in the shared library initializer, _init. */
|
||||
}
|
||||
#else
|
||||
strong_alias (posixland_init, __libc_init_first);
|
||||
|
||||
|
||||
void
|
||||
_hurd_stack_setup (volatile intptr_t argc, ...)
|
||||
{
|
||||
first_init ();
|
||||
|
||||
_hurd_startup ((void **) &argc, &init);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* This function is defined here so that if this file ever gets into
|
||||
ld.so we will get a link error. Having this file silently included
|
||||
in ld.so causes disaster, because the _init definition above will
|
||||
cause ld.so to gain an init function, which is not a cool thing. */
|
||||
|
||||
void
|
||||
_dl_start (void)
|
||||
{
|
||||
abort ();
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/* Machine-dependent details of interruptible RPC messaging. Alpha version.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
|
||||
({ \
|
||||
error_t err; \
|
||||
asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
|
||||
".globl _hurd_intr_rpc_msg_in_trap\n" \
|
||||
" mov %1, $16\n" \
|
||||
" mov %2, $17\n" \
|
||||
" mov %3, $18\n" \
|
||||
" mov %4, $19\n" \
|
||||
" mov %5, $20\n" \
|
||||
" mov %6, $21\n" \
|
||||
" mov %7, $1\n" \
|
||||
" lda $0, -25\n" \
|
||||
"_hurd_intr_rpc_msg_do_trap: callsys\n" \
|
||||
"_hurd_intr_rpc_msg_in_trap: ret\n" \
|
||||
: "=r" (err) \
|
||||
: "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \
|
||||
"r" (rcv_name), "r" (timeout), "r" (notify) \
|
||||
: "16", "17", "18", "19", "20", "21", "1", "0"); \
|
||||
err; \
|
||||
})
|
||||
|
||||
static void inline
|
||||
INTR_MSG_BACK_OUT (struct alpha_thread_state *state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#include "hurdfault.h"
|
||||
|
||||
/* This cannot be an inline function because it calls setjmp. */
|
||||
#define SYSCALL_EXAMINE(state, callno) \
|
||||
({ \
|
||||
u_int32_t *p = (void *) ((state)->pc - 4); \
|
||||
int result; \
|
||||
_hurdsig_catch_memory_fault (p) ? 0 : \
|
||||
({ \
|
||||
result = (*p == 0x00000083); \
|
||||
_hurdsig_end_catch_fault (); \
|
||||
if (result) \
|
||||
/* The PC is just after a `callsys' instruction. \
|
||||
This is a system call in progress; v0 holds the call number. */ \
|
||||
*(callno) = (state)->r0; \
|
||||
result; \
|
||||
}); \
|
||||
})
|
||||
|
||||
struct mach_msg_trap_args
|
||||
{
|
||||
/* This is the order of arguments to mach_msg_trap. */
|
||||
mach_msg_header_t *msg;
|
||||
mach_msg_option_t option;
|
||||
mach_msg_size_t send_size;
|
||||
mach_msg_size_t rcv_size;
|
||||
mach_port_t rcv_name;
|
||||
mach_msg_timeout_t timeout;
|
||||
mach_port_t notify;
|
||||
};
|
||||
|
||||
/* This cannot be an inline function because it calls setjmp. */
|
||||
#define MSG_EXAMINE(state, msgid, rcv_name, send_name, option, timeout) \
|
||||
({ \
|
||||
mach_msg_header_t *msg = (mach_msg_header_t *) (state)->r16; \
|
||||
*(option) = (mach_msg_option_t) (state)->r17; \
|
||||
*(rcv_name) = (mach_port_t) (state)->r18; \
|
||||
*(timeout) = (mach_msg_timeout_t) (state)->r19; \
|
||||
(msg == 0) ? \
|
||||
({ \
|
||||
*(send_name) = MACH_PORT_NULL; \
|
||||
*(msgid) = 0; \
|
||||
0; \
|
||||
}) : \
|
||||
(_hurdsig_catch_memory_fault (msg) ? -1 : \
|
||||
({ \
|
||||
*(send_name) = msg->msgh_remote_port; \
|
||||
*(msgid) = msg->msgh_id; \
|
||||
_hurdsig_end_catch_fault (); \
|
||||
0; \
|
||||
}) \
|
||||
); \
|
||||
})
|
@ -1,49 +0,0 @@
|
||||
/* Perform a `longjmp' on a Mach thread_state. Alpha version.
|
||||
Copyright (C) 2002, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd/signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <jmpbuf-offsets.h>
|
||||
#include <mach/thread_status.h>
|
||||
|
||||
|
||||
/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */
|
||||
|
||||
void
|
||||
_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
|
||||
{
|
||||
struct alpha_thread_state *const ts = state;
|
||||
|
||||
ts->r9 = env[0].__jmpbuf[JB_S0];
|
||||
ts->r10 = env[0].__jmpbuf[JB_S1];
|
||||
ts->r11 = env[0].__jmpbuf[JB_S2];
|
||||
ts->r12 = env[0].__jmpbuf[JB_S3];
|
||||
ts->r13 = env[0].__jmpbuf[JB_S4];
|
||||
ts->r13 = env[0].__jmpbuf[JB_S5];
|
||||
ts->pc = env[0].__jmpbuf[JB_PC];
|
||||
ts->r15 = env[0].__jmpbuf[JB_FP];
|
||||
ts->r30 = env[0].__jmpbuf[JB_SP];
|
||||
ts->r0 = val ?: 1;
|
||||
|
||||
/* XXX
|
||||
To mimic longjmp we ought to restore some fp registers too.
|
||||
But those registers are in struct alpha_float_state.
|
||||
The only use of this is in fork, and it probably won't matter.
|
||||
*/
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
/* Return from signal handler in GNU C library for Hurd. Alpha version.
|
||||
Copyright (C) 1994,95,97,98,2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
#include <hurd/threadvar.h>
|
||||
#include <hurd/msg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
__sigreturn (struct sigcontext *scp)
|
||||
{
|
||||
struct hurd_sigstate *ss;
|
||||
mach_port_t *reply_port;
|
||||
|
||||
if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ss = _hurd_self_sigstate ();
|
||||
__spin_lock (&ss->lock);
|
||||
|
||||
/* Restore the set of blocked signals, and the intr_port slot. */
|
||||
ss->blocked = scp->sc_mask;
|
||||
ss->intr_port = scp->sc_intr_port;
|
||||
|
||||
/* Check for pending signals that were blocked by the old set. */
|
||||
if (ss->pending & ~ss->blocked)
|
||||
{
|
||||
/* There are pending signals that just became unblocked. Wake up the
|
||||
signal thread to deliver them. But first, squirrel away SCP where
|
||||
the signal thread will notice it if it runs another handler, and
|
||||
arrange to have us called over again in the new reality. */
|
||||
ss->context = scp;
|
||||
/* Clear the intr_port slot, since we are not in fact doing
|
||||
an interruptible RPC right now. If SS->intr_port is not null,
|
||||
the SCP context is doing an interruptible RPC, but the signal
|
||||
thread will examine us while we are blocked in the sig_post RPC. */
|
||||
ss->intr_port = MACH_PORT_NULL;
|
||||
__spin_unlock (&ss->lock);
|
||||
__msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
|
||||
/* If a pending signal was handled, sig_post never returned. */
|
||||
__spin_lock (&ss->lock);
|
||||
}
|
||||
|
||||
if (scp->sc_onstack)
|
||||
{
|
||||
ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
|
||||
/* XXX cannot unlock until off sigstack */
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
__spin_unlock (&ss->lock);
|
||||
|
||||
/* Destroy the MiG reply port used by the signal handler, and restore the
|
||||
reply port in use by the thread when interrupted. */
|
||||
reply_port =
|
||||
(mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
|
||||
if (*reply_port)
|
||||
__mach_port_destroy (__mach_task_self (), *reply_port);
|
||||
*reply_port = scp->sc_reply_port;
|
||||
|
||||
if (scp->sc_used_fpa)
|
||||
{
|
||||
/* Restore FPU state. */
|
||||
|
||||
/* Restore the floating-point control/status register.
|
||||
We must do this first because the compiler will need
|
||||
a temporary FP register for the load. */
|
||||
asm volatile ("mt_fpcr %0" : : "f" (scp->sc_fpcsr));
|
||||
|
||||
/* Restore floating-point registers. */
|
||||
#define restore_fpr(n) \
|
||||
asm volatile ("ldt $f" #n ",%0" : : "m" (scp->sc_fpregs[n]))
|
||||
restore_fpr (0);
|
||||
restore_fpr (1);
|
||||
restore_fpr (2);
|
||||
restore_fpr (3);
|
||||
restore_fpr (4);
|
||||
restore_fpr (5);
|
||||
restore_fpr (6);
|
||||
restore_fpr (7);
|
||||
restore_fpr (8);
|
||||
restore_fpr (9);
|
||||
restore_fpr (10);
|
||||
restore_fpr (11);
|
||||
restore_fpr (12);
|
||||
restore_fpr (13);
|
||||
restore_fpr (14);
|
||||
restore_fpr (15);
|
||||
restore_fpr (16);
|
||||
restore_fpr (17);
|
||||
restore_fpr (18);
|
||||
restore_fpr (19);
|
||||
restore_fpr (20);
|
||||
restore_fpr (21);
|
||||
restore_fpr (22);
|
||||
restore_fpr (23);
|
||||
restore_fpr (24);
|
||||
restore_fpr (25);
|
||||
restore_fpr (26);
|
||||
restore_fpr (27);
|
||||
restore_fpr (28);
|
||||
restore_fpr (29);
|
||||
restore_fpr (30);
|
||||
}
|
||||
|
||||
/* Load all the registers from the sigcontext. */
|
||||
#define restore_gpr(n) \
|
||||
asm volatile ("ldq $" #n ",%0" : : "m" (scpreg->sc_regs[n]))
|
||||
|
||||
{
|
||||
/* The `rei' PAL pseudo-instruction restores registers $2..$7, the PC
|
||||
and processor status. So we can use these few registers for our
|
||||
working variables. Unfortunately, it finds its data on the stack
|
||||
and merely pops the SP ($30) over the words of state restored,
|
||||
allowing no other option for the new SP value. So we must push the
|
||||
registers and PSW it will to restore, onto the user's stack and let
|
||||
it pop them from there. */
|
||||
register const struct sigcontext *const scpreg asm ("$2") = scp;
|
||||
register integer_t *usp asm ("$3") = (integer_t *) scpreg->sc_regs[30];
|
||||
register integer_t usp_align asm ("$4");
|
||||
|
||||
/* Push an 8-word "trap frame" onto the user stack for `rei':
|
||||
registers $2..$7, the PC, and the PSW. */
|
||||
|
||||
register struct rei_frame
|
||||
{
|
||||
integer_t regs[5], pc, ps;
|
||||
} *rei_frame asm ("$5");
|
||||
|
||||
usp -= 8;
|
||||
/* `rei' demands that the stack be aligned to a 64 byte (8 word)
|
||||
boundary; bits 61..56 of the PSW are OR'd back into the SP value
|
||||
after popping the 8-word trap frame, so we store (sp % 64)
|
||||
there and this restores the original user SP. */
|
||||
usp_align = (integer_t) usp & 63L;
|
||||
rei_frame = (void *) ((integer_t) usp & ~63L);
|
||||
|
||||
/* Copy the registers and PC from the sigcontext. */
|
||||
memcpy (rei_frame->regs, &scpreg->sc_regs[2], sizeof rei_frame->regs);
|
||||
rei_frame->pc = scpreg->sc_pc;
|
||||
|
||||
/* Compute the new PS value to be restored. `rei' adds the value at
|
||||
bits 61..56 to the SP to compensate for the alignment above that
|
||||
cleared the low 6 bits; bits 5..3 are the new mode/privilege level
|
||||
(must be >= current mode; 3 == user mode); bits 2..0 are "software",
|
||||
unused by the processor or kernel (XXX should trampoline save these?
|
||||
How?); in user mode, `rei' demands that all other bits be zero. */
|
||||
rei_frame->ps = (usp_align << 56) | (3 << 3); /* XXX low 3 bits??? */
|
||||
|
||||
/* Restore the other general registers: everything except $2..$7, which
|
||||
are in the `rei' trap frame we set up above, and $30, which is the
|
||||
SP which is popped by `rei'. */
|
||||
restore_gpr (1);
|
||||
restore_gpr (8);
|
||||
restore_gpr (9);
|
||||
restore_gpr (10);
|
||||
restore_gpr (11);
|
||||
restore_gpr (12);
|
||||
restore_gpr (13);
|
||||
restore_gpr (14);
|
||||
restore_gpr (15);
|
||||
restore_gpr (16);
|
||||
restore_gpr (17);
|
||||
restore_gpr (18);
|
||||
restore_gpr (19);
|
||||
restore_gpr (20);
|
||||
restore_gpr (21);
|
||||
restore_gpr (22);
|
||||
restore_gpr (23);
|
||||
restore_gpr (24);
|
||||
restore_gpr (25);
|
||||
restore_gpr (26);
|
||||
restore_gpr (27);
|
||||
restore_gpr (28);
|
||||
restore_gpr (29);
|
||||
|
||||
/* Switch the stack pointer to the trap frame set up on
|
||||
the user stack and do the magical `rei' PAL call. */
|
||||
asm volatile ("mov %0, $30\n"
|
||||
"call_pal %1"
|
||||
: : "r" (rei_frame), "i" (63)); /* PAL_rti */
|
||||
/* Firewall. */
|
||||
asm volatile ("halt");
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
return -1;
|
||||
}
|
||||
|
||||
weak_alias (__sigreturn, sigreturn)
|
@ -1,30 +0,0 @@
|
||||
/* Startup code for statically linked Hurd/Alpha binaries.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.text
|
||||
.align 3
|
||||
.globl _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
jsr ra, _hurd_stack_setup
|
||||
|
||||
#define _start _start1
|
||||
#include <sysdeps/alpha/elf/start.S>
|
@ -1,249 +0,0 @@
|
||||
/* Set thread_state for sighandler, and sigcontext to recover. Alpha version.
|
||||
Copyright (C) 1994,95,97,98,2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd/signal.h>
|
||||
#include "thread_state.h"
|
||||
#include "hurdfault.h"
|
||||
#include <assert.h>
|
||||
|
||||
struct mach_msg_trap_args
|
||||
{
|
||||
/* This is the order of arguments to mach_msg_trap. */
|
||||
mach_msg_header_t *msg;
|
||||
mach_msg_option_t option;
|
||||
mach_msg_size_t send_size;
|
||||
mach_msg_size_t rcv_size;
|
||||
mach_port_t rcv_name;
|
||||
mach_msg_timeout_t timeout;
|
||||
mach_port_t notify;
|
||||
};
|
||||
|
||||
|
||||
struct sigcontext *
|
||||
_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
|
||||
int signo, struct hurd_signal_detail *detail,
|
||||
int rpc_wait, struct machine_thread_all_state *state)
|
||||
{
|
||||
__label__ trampoline, rpc_wait_trampoline;
|
||||
void *sigsp;
|
||||
struct sigcontext *scp;
|
||||
|
||||
if (ss->context)
|
||||
{
|
||||
/* We have a previous sigcontext that sigreturn was about
|
||||
to restore when another signal arrived. We will just base
|
||||
our setup on that. */
|
||||
if (! _hurdsig_catch_memory_fault (ss->context))
|
||||
{
|
||||
memcpy (&state->basic, &ss->context->sc_alpha_thread_state,
|
||||
sizeof (state->basic));
|
||||
memcpy (&state->exc, &ss->context->sc_alpha_exc_state,
|
||||
sizeof (state->exc));
|
||||
state->set = (1 << ALPHA_THREAD_STATE) | (1 << ALPHA_EXC_STATE);
|
||||
if (state->exc.used_fpa)
|
||||
{
|
||||
memcpy (&state->fpu, &ss->context->sc_alpha_float_state,
|
||||
sizeof (state->fpu));
|
||||
state->set |= (1 << ALPHA_FLOAT_STATE);
|
||||
}
|
||||
assert (! rpc_wait);
|
||||
/* The intr_port slot was cleared before sigreturn sent us the
|
||||
sig_post that made us notice this pending signal, so
|
||||
_hurd_internal_post_signal wouldn't do interrupt_operation.
|
||||
After we return, our caller will set SCP->sc_intr_port (in the
|
||||
new context) from SS->intr_port and clear SS->intr_port. Now
|
||||
that we are restoring this old context recorded by sigreturn,
|
||||
we want to restore its intr_port too; so store it in
|
||||
SS->intr_port now, so it will end up in SCP->sc_intr_port
|
||||
later. */
|
||||
ss->intr_port = ss->context->sc_intr_port;
|
||||
}
|
||||
_hurdsig_end_catch_fault ();
|
||||
|
||||
/* If the sigreturn context was bogus, just ignore it. */
|
||||
ss->context = NULL;
|
||||
}
|
||||
else if (! machine_get_basic_state (ss->thread, state))
|
||||
return NULL;
|
||||
|
||||
if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
|
||||
!(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
|
||||
{
|
||||
sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
|
||||
ss->sigaltstack.ss_flags |= SS_ONSTACK;
|
||||
/* XXX need to set up base of new stack for
|
||||
per-thread variables, cthreads. */
|
||||
}
|
||||
else
|
||||
sigsp = (char *) state->basic.SP;
|
||||
|
||||
/* Set up the sigcontext structure on the stack. This is all the stack
|
||||
needs, since the args are passed in registers (below). */
|
||||
sigsp -= sizeof (*scp);
|
||||
scp = sigsp;
|
||||
|
||||
if (_hurdsig_catch_memory_fault (scp))
|
||||
{
|
||||
/* We got a fault trying to write the stack frame.
|
||||
We cannot set up the signal handler.
|
||||
Returning NULL tells our caller, who will nuke us with a SIGILL. */
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set up the sigcontext from the current state of the thread. */
|
||||
|
||||
scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
|
||||
|
||||
/* struct sigcontext is laid out so that starting at sc_regs
|
||||
mimics a struct alpha_thread_state. */
|
||||
memcpy (&scp->sc_alpha_thread_state,
|
||||
&state->basic, sizeof (state->basic));
|
||||
|
||||
/* struct sigcontext is laid out so that starting at sc_badvaddr
|
||||
mimics a struct mips_exc_state. */
|
||||
if (! machine_get_state (ss->thread, state, ALPHA_EXC_STATE,
|
||||
&state->exc, &scp->sc_alpha_exc_state,
|
||||
sizeof (state->exc)))
|
||||
return NULL;
|
||||
|
||||
if (state->exc.used_fpa &&
|
||||
/* struct sigcontext is laid out so that starting at sc_fpregs
|
||||
mimics a struct alpha_float_state. This state
|
||||
is only meaningful if the coprocessor was used. */
|
||||
! machine_get_state (ss->thread, state, ALPHA_FLOAT_STATE,
|
||||
&state->fpu,
|
||||
&scp->sc_alpha_float_state,
|
||||
sizeof (state->fpu)))
|
||||
return NULL;
|
||||
|
||||
_hurdsig_end_catch_fault ();
|
||||
}
|
||||
|
||||
/* Modify the thread state to call the trampoline code on the new stack. */
|
||||
if (rpc_wait)
|
||||
{
|
||||
/* The signalee thread was blocked in a mach_msg_trap system call,
|
||||
still waiting for a reply. We will have it run the special
|
||||
trampoline code which retries the message receive before running
|
||||
the signal handler.
|
||||
|
||||
To do this we change the OPTION argument in its registers to
|
||||
enable only message reception, since the request message has
|
||||
already been sent. */
|
||||
|
||||
/* The system call arguments are stored in consecutive registers
|
||||
starting with a0 ($16). */
|
||||
struct mach_msg_trap_args *args = (void *) &state->basic.r16;
|
||||
|
||||
assert (args->option & MACH_RCV_MSG);
|
||||
/* Disable the message-send, since it has already completed. The
|
||||
calls we retry need only wait to receive the reply message. */
|
||||
args->option &= ~MACH_SEND_MSG;
|
||||
|
||||
/* Limit the time to receive the reply message, in case the server
|
||||
claimed that `interrupt_operation' succeeded but in fact the RPC
|
||||
is hung. */
|
||||
args->option |= MACH_RCV_TIMEOUT;
|
||||
args->timeout = _hurd_interrupted_rpc_timeout;
|
||||
|
||||
state->basic.pc = (long int) &&rpc_wait_trampoline;
|
||||
/* After doing the message receive, the trampoline code will need to
|
||||
update the v0 ($0) value to be restored by sigreturn. To simplify
|
||||
the assembly code, we pass the address of its slot in SCP to the
|
||||
trampoline code in at ($28). */
|
||||
state->basic.r28 = (long int) &scp->sc_regs[0];
|
||||
/* We must preserve the mach_msg_trap args in a0..a5 and t0
|
||||
($16..$21, $1). Pass the handler args to the trampoline code in
|
||||
t8..t10 ($22.$24). */
|
||||
state->basic.r22 = signo;
|
||||
state->basic.r23 = detail->code;
|
||||
state->basic.r24 = (long int) scp;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->basic.pc = (long int) &&trampoline;
|
||||
state->basic.r16 = signo;
|
||||
state->basic.r17 = detail->code;
|
||||
state->basic.r18 = (long int) scp;
|
||||
}
|
||||
|
||||
state->basic.r30 = (long int) sigsp; /* $30 is the stack pointer. */
|
||||
|
||||
/* We pass the handler function to the trampoline code in ra ($26). */
|
||||
state->basic.r26 = (long int) handler;
|
||||
/* In the callee-saved register t12/pv ($27), we store the
|
||||
address of __sigreturn itself, for the trampoline code to use. */
|
||||
state->basic.r27 = (long int) &__sigreturn;
|
||||
/* In the callee-saved register t11/ai ($25), we save the SCP value to pass
|
||||
to __sigreturn after the handler returns. */
|
||||
state->basic.r25 = (long int) scp;
|
||||
|
||||
return scp;
|
||||
|
||||
/* The trampoline code follows. This is not actually executed as part of
|
||||
this function, it is just convenient to write it that way. */
|
||||
|
||||
rpc_wait_trampoline:
|
||||
/* This is the entry point when we have an RPC reply message to receive
|
||||
before running the handler. The MACH_MSG_SEND bit has already been
|
||||
cleared in the OPTION argument in our registers. For our convenience,
|
||||
at ($28) points to the sc_regs[0] member of the sigcontext (saved v0
|
||||
($0)). */
|
||||
asm volatile
|
||||
(/* Retry the interrupted mach_msg system call. */
|
||||
"lda $0, -25($31)\n" /* mach_msg_trap */
|
||||
"callsys\n" /* Magic system call instruction. */
|
||||
/* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED. But
|
||||
now the message receive has completed and the original caller of
|
||||
the RPC (i.e. the code running when the signal arrived) needs to
|
||||
see the final return value of the message receive in v0. So
|
||||
store the new v0 value into the sc_regs[0] member of the sigcontext
|
||||
(whose address is in at to make this code simpler). */
|
||||
"stq $0, 0($28)\n"
|
||||
/* Since the argument registers needed to have the mach_msg_trap
|
||||
arguments, we've stored the arguments to the handler function
|
||||
in registers t8..t10 ($22..$24). */
|
||||
"mov $22, $16\n"
|
||||
"mov $23, $17\n"
|
||||
"mov $24, $18\n");
|
||||
|
||||
trampoline:
|
||||
/* Entry point for running the handler normally. The arguments to the
|
||||
handler function are already in the standard registers:
|
||||
|
||||
a0 SIGNO
|
||||
a1 SIGCODE
|
||||
a2 SCP
|
||||
|
||||
t12 also contains SCP; this value is callee-saved (and so should not get
|
||||
clobbered by running the handler). We use this saved value to pass to
|
||||
__sigreturn, so the handler can clobber the argument registers if it
|
||||
likes. */
|
||||
/* Call the handler function, saving return address in ra ($26). */
|
||||
asm volatile ("jsr $26, ($26)");
|
||||
/* Reset gp ($29) from the return address (here) in ra ($26). */
|
||||
asm volatile ("ldgp $29, 0($26)");
|
||||
asm volatile ("mov $25, $16"); /* Move saved SCP to argument register. */
|
||||
/* Call __sigreturn (SCP); this cannot return. */
|
||||
asm volatile ("jmp $31, ($27)");
|
||||
|
||||
/* NOTREACHED */
|
||||
return NULL;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/* Machine-dependent signal context structure for GNU Hurd. HPPA version.
|
||||
Copyright (C) 1995,97,2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
|
||||
# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef sc_parisc_thread_state
|
||||
|
||||
/* Signal handlers are actually called:
|
||||
void handler (int sig, int code, struct sigcontext *scp); */
|
||||
|
||||
/* State of this thread when the signal was taken. */
|
||||
struct sigcontext
|
||||
{
|
||||
/* These first members are machine-independent. */
|
||||
|
||||
int sc_onstack; /* Nonzero if running on sigstack. */
|
||||
__sigset_t sc_mask; /* Blocked signals to restore. */
|
||||
|
||||
/* MiG reply port this thread is using. */
|
||||
unsigned int sc_reply_port;
|
||||
|
||||
/* Port this thread is doing an interruptible RPC on. */
|
||||
unsigned int sc_intr_port;
|
||||
|
||||
/* Error code associated with this signal (interpreted as `error_t'). */
|
||||
int sc_error;
|
||||
|
||||
/* All following members are machine-dependent. The rest of this
|
||||
structure is written to be laid out identically to a `struct
|
||||
parisc_thread_state'. trampoline.c knows this, so it must be
|
||||
changed if this changes. */
|
||||
|
||||
#define sc_parisc_thread_state sc_flags /* Beginning of correspondence. */
|
||||
/* "General" registers $1..$31. */
|
||||
unsigned int sc_regs[31];
|
||||
|
||||
/* Control registers. */
|
||||
unsigned int sc_cr11; /* sar */
|
||||
/* These four registers make up the PC. */
|
||||
unsigned int iioq_head;
|
||||
unsigned int iisq_head;
|
||||
unsigned int iioq_tail;
|
||||
unsigned int iisq_tail;
|
||||
unsigned int sc_cr15;
|
||||
unsigned int sc_cr19;
|
||||
unsigned int sc_cr20;
|
||||
unsigned int sc_cr21;
|
||||
unsigned int sc_cr22; /* ipsw */
|
||||
unsigned int sc_bsd_goto; /* unused */
|
||||
unsigned int sc_sr4;
|
||||
unsigned int sc_sr0;
|
||||
unsigned int sc_sr1;
|
||||
unsigned int sc_sr2;
|
||||
unsigned int sc_sr3;
|
||||
unsigned int sc_sr5;
|
||||
unsigned int sc_sr6;
|
||||
unsigned int sc_sr7;
|
||||
unsigned int sc_cr0;
|
||||
unsigned int sc_cr8;
|
||||
unsigned int sc_cr9;
|
||||
unsigned int sc_cr10; /* unused */
|
||||
unsigned int sc_cr12;
|
||||
unsigned int sc_cr13;
|
||||
unsigned int sc_cr24; /* unused */
|
||||
unsigned int sc_cr25; /* unused */
|
||||
unsigned int sc_cr26; /* unused */
|
||||
unsigned sc_mpsfu_high; /* unused */
|
||||
unsigned sc_mpsfu_low; /* unused */
|
||||
unsigned sc_mpsfu_ovflo; /* unused */
|
||||
int sc_pad;
|
||||
|
||||
/* Floating point registers $f0..$f31. */
|
||||
double sc_fpregs[32];
|
||||
};
|
||||
|
||||
#endif /* sc_parisc_thread_state */
|
@ -1,230 +0,0 @@
|
||||
/* Set thread_state for sighandler, and sigcontext to recover. HPPA version.
|
||||
Copyright (C) 1995, 1997, 1998, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd/signal.h>
|
||||
#include <thread_state.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include "hurdfault.h"
|
||||
|
||||
|
||||
struct mach_msg_trap_regargs
|
||||
{
|
||||
/* These first four arguments are in registers 26..23. */
|
||||
mach_msg_size_t rcv_size; /* arg3 */
|
||||
mach_msg_size_t send_size; /* arg2 */
|
||||
mach_msg_option_t option; /* arg1 */
|
||||
mach_msg_header_t *msg; /* arg0 */
|
||||
};
|
||||
|
||||
struct sigcontext *
|
||||
_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
|
||||
int signo, long int sigcode,
|
||||
volatile int rpc_wait,
|
||||
struct machine_thread_all_state *state)
|
||||
{
|
||||
__label__ trampoline, rpc_wait_trampoline;
|
||||
void *volatile sigsp;
|
||||
struct sigcontext *scp;
|
||||
|
||||
if (ss->context)
|
||||
{
|
||||
/* We have a previous sigcontext that sigreturn was about
|
||||
to restore when another signal arrived. We will just base
|
||||
our setup on that. */
|
||||
if (_hurdsig_catch_fault (SIGSEGV))
|
||||
assert (_hurdsig_fault_sigcode >= (long int) ss->context &&
|
||||
_hurdsig_fault_sigcode < (long int) (ss->context + 1));
|
||||
else
|
||||
{
|
||||
memcpy (&state->basic, &ss->context->sc_parisc_thread_state,
|
||||
sizeof (state->basic));
|
||||
state->set = (1 << PARISC_THREAD_STATE);
|
||||
assert (! rpc_wait);
|
||||
/* The intr_port slot was cleared before sigreturn sent us the
|
||||
sig_post that made us notice this pending signal, so
|
||||
_hurd_internal_post_signal wouldn't do interrupt_operation.
|
||||
After we return, our caller will set SCP->sc_intr_port (in the
|
||||
new context) from SS->intr_port and clear SS->intr_port. Now
|
||||
that we are restoring this old context recorded by sigreturn,
|
||||
we want to restore its intr_port too; so store it in
|
||||
SS->intr_port now, so it will end up in SCP->sc_intr_port
|
||||
later. */
|
||||
ss->intr_port = ss->context->sc_intr_port;
|
||||
}
|
||||
/* If the sigreturn context was bogus, just ignore it. */
|
||||
ss->context = NULL;
|
||||
}
|
||||
else if (! machine_get_basic_state (ss->thread, state))
|
||||
return NULL;
|
||||
|
||||
if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
|
||||
!(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
|
||||
{
|
||||
sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
|
||||
ss->sigaltstack.ss_flags |= SS_ONSTACK;
|
||||
/* XXX need to set up base of new stack for
|
||||
per-thread variables, cthreads. */
|
||||
}
|
||||
else
|
||||
sigsp = (char *) state->basic.uesp;
|
||||
|
||||
/* Push the signal context on the stack. */
|
||||
sigsp -= sizeof (*scp);
|
||||
scp = sigsp;
|
||||
|
||||
if (_hurdsig_catch_fault (SIGSEGV))
|
||||
{
|
||||
assert (_hurdsig_fault_sigcode >= (long int) scp &&
|
||||
_hurdsig_fault_sigcode <= (long int) (scp + 1));
|
||||
/* We got a fault trying to write the stack frame.
|
||||
We cannot set up the signal handler.
|
||||
Returning NULL tells our caller, who will nuke us with a SIGILL. */
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ok;
|
||||
|
||||
/* Set up the sigcontext from the current state of the thread. */
|
||||
|
||||
scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
|
||||
|
||||
/* struct sigcontext is laid out so that starting at sc_regs mimics a
|
||||
struct parisc_thread_state. */
|
||||
memcpy (&scp->sc_parisc_thread_state,
|
||||
&state->basic, sizeof (state->basic));
|
||||
|
||||
_hurdsig_end_catch_fault ();
|
||||
|
||||
if (! ok)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Modify the thread state to call the trampoline code on the new stack. */
|
||||
if (rpc_wait)
|
||||
{
|
||||
/* The signalee thread was blocked in a mach_msg_trap system call,
|
||||
still waiting for a reply. We will have it run the special
|
||||
trampoline code which retries the message receive before running
|
||||
the signal handler.
|
||||
|
||||
To do this we change the OPTION argument on its stack to enable only
|
||||
message reception, since the request message has already been
|
||||
sent. */
|
||||
|
||||
struct mach_msg_trap_regargs *args = (void *) &state->basic.r23;
|
||||
|
||||
if (_hurdsig_catch_fault (SIGSEGV))
|
||||
{
|
||||
assert (_hurdsig_fault_sigcode >= (long int) args &&
|
||||
_hurdsig_fault_sigcode < (long int) (args + 1));
|
||||
/* Faulted accessing ARGS. Bomb. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (args->option & MACH_RCV_MSG);
|
||||
/* Disable the message-send, since it has already completed. The
|
||||
calls we retry need only wait to receive the reply message. */
|
||||
args->option &= ~MACH_SEND_MSG;
|
||||
|
||||
/* Limit the time to receive the reply message, in case the server
|
||||
claimed that `interrupt_operation' succeeded but in fact the RPC
|
||||
is hung. */
|
||||
args->option |= MACH_RCV_TIMEOUT;
|
||||
args->timeout = _hurd_interrupted_rpc_timeout;
|
||||
|
||||
_hurdsig_end_catch_fault ();
|
||||
|
||||
MACHINE_THREAD_STATE_SET_PC (&state->basic, &&rpc_wait_trampoline);
|
||||
/* The reply-receiving trampoline code runs initially on the original
|
||||
user stack. We pass it the signal stack pointer in %r5. */
|
||||
state->basic.r5 = (int) sigsp;
|
||||
/* After doing the message receive, the trampoline code will need to
|
||||
update the %r28 value to be restored by sigreturn. To simplify
|
||||
the assembly code, we pass the address of its slot in SCP to the
|
||||
trampoline code in %r4. */
|
||||
state->basic.r4 = (unsigned int) &scp->sc_regs[27];
|
||||
/* Set up the arguments for the handler function in callee-saved
|
||||
registers that we will move to the argument registers after
|
||||
mach_msg_trap returns. */
|
||||
state->basic.r6 = signo;
|
||||
state->basic.r7 = sigcode;
|
||||
state->basic.r8 = (unsigned int) scp;
|
||||
}
|
||||
else
|
||||
{
|
||||
MACHINE_THREAD_STATE_SET_PC (&state->basic, &&trampoline);
|
||||
state->basic.r20 = (unsigned int) sigsp;
|
||||
/* Set up the arguments for the handler function. */
|
||||
state->basic.r26 = signo;
|
||||
state->basic.r25 = sigcode;
|
||||
state->basic.r24 = (unsigned int) scp;
|
||||
}
|
||||
|
||||
/* We pass the handler function to the trampoline code in %r9. */
|
||||
state->basic.r9 = (unsigned int) handler;
|
||||
/* For convenience, we pass the address of __sigreturn in %r10. */
|
||||
state->basic.r10 = (unsigned int) &__sigreturn;
|
||||
/* The extra copy of SCP for the __sigreturn arg goes in %r8. */
|
||||
state->basic.r10 = (unsigned int) scp;
|
||||
|
||||
return scp;
|
||||
|
||||
/* The trampoline code follows. This is not actually executed as part of
|
||||
this function, it is just convenient to write it that way. */
|
||||
|
||||
rpc_wait_trampoline:
|
||||
/* This is the entry point when we have an RPC reply message to receive
|
||||
before running the handler. The MACH_MSG_SEND bit has already been
|
||||
cleared in the OPTION argument on our stack. The interrupted user
|
||||
stack pointer has not been changed, so the system call can find its
|
||||
arguments; the signal stack pointer is in %ebx. For our convenience,
|
||||
%ecx points to the sc_eax member of the sigcontext. */
|
||||
asm volatile
|
||||
(/* Retry the interrupted mach_msg system call. */
|
||||
"ldil L%0xC0000000,%r1\nble 4(%sr7,%r1)\n"
|
||||
"ldi -25, %r22\n" /* mach_msg_trap */
|
||||
/* When the sigcontext was saved, %r28 was MACH_RCV_INTERRUPTED. But
|
||||
now the message receive has completed and the original caller of
|
||||
the RPC (i.e. the code running when the signal arrived) needs to
|
||||
see the final return value of the message receive in %r28. So
|
||||
store the new %r28 value into the sc_regs[27] member of the sigcontext
|
||||
(whose address is in %r4 to make this code simpler). */
|
||||
"stw (%r4), %r28\n"
|
||||
/* Switch to the signal stack. */
|
||||
"copy %r5, %r30\n"
|
||||
/* Copy the handler arguments to the argument registers. */
|
||||
"copy %r6, %r26\n"
|
||||
"copy %r7, %r25\n"
|
||||
"copy %r8, %r24\n"
|
||||
);
|
||||
|
||||
trampoline:
|
||||
/* Entry point for running the handler normally. The arguments to the
|
||||
handler function are already in the argument registers. */
|
||||
asm volatile
|
||||
("bv (%r9); nop" /* Call the handler function. */
|
||||
"bv (%r10)\n" /* Call __sigreturn (SCP); never returns. */
|
||||
"copy %r8, %r26" /* Set up arg in delay slot. */
|
||||
: : "i" (&__sigreturn));
|
||||
|
||||
/* NOTREACHED */
|
||||
return NULL;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/* Machine-dependent signal context structure for GNU Hurd. MIPS version.
|
||||
Copyright (C) 1994,97,2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
|
||||
# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef sc_mips_thread_state
|
||||
|
||||
/* Signal handlers are actually called:
|
||||
void handler (int sig, int code, struct sigcontext *scp); */
|
||||
|
||||
/* State of this thread when the signal was taken. */
|
||||
struct sigcontext
|
||||
{
|
||||
/* These first members are machine-independent. */
|
||||
|
||||
int sc_onstack; /* Nonzero if running on sigstack. */
|
||||
__sigset_t sc_mask; /* Blocked signals to restore. */
|
||||
|
||||
/* MiG reply port this thread is using. */
|
||||
unsigned int sc_reply_port;
|
||||
|
||||
/* Port this thread is doing an interruptible RPC on. */
|
||||
unsigned int sc_intr_port;
|
||||
|
||||
/* Error code associated with this signal (interpreted as `error_t'). */
|
||||
int sc_error;
|
||||
|
||||
/* All following members are machine-dependent. The rest of this
|
||||
structure is written to be laid out identically to:
|
||||
{
|
||||
struct mips_thread_state ts;
|
||||
struct mips_exc_state es;
|
||||
struct mips_float_state fs;
|
||||
}
|
||||
trampoline.c knows this, so it must be changed if this changes. */
|
||||
#define sc_mips_thread_state sc_gpr /* Beginning of correspondence. */
|
||||
int sc_gpr[31]; /* "General" registers; [0] is r1. */
|
||||
int sc_mdlo, sc_mdhi; /* Low and high multiplication results. */
|
||||
int sc_pc; /* Instruction pointer. */
|
||||
|
||||
/* struct mips_exc_state */
|
||||
#define sc_mips_exc_state sc_cause
|
||||
unsigned int sc_cause; /* Machine-level trap code. */
|
||||
#define SC_CAUSE_SST 0x00000044
|
||||
unsigned int sc_badvaddr;
|
||||
unsigned int sc_coproc_used; /* Which coprocessors the thread has used. */
|
||||
#define SC_COPROC_USE_COP0 1 /* (by definition) */
|
||||
#define SC_COPROC_USE_COP1 2 /* FPA */
|
||||
#define SC_COPROC_USE_FPU SC_COPROC_USE_COP1
|
||||
#define SC_COPROC_USE_COP2 4
|
||||
#define SC_COPROC_USE_COP3 8
|
||||
|
||||
/* struct mips_float_state
|
||||
This is only filled in if the SC_COPROC_USE_FPU bit
|
||||
is set in sc_coproc_used. */
|
||||
#define sc_mips_float_state sc_fpr
|
||||
int sc_fpr[32]; /* FP registers. */
|
||||
int sc_fpcsr; /* FPU status register. */
|
||||
int sc_fpeir; /* FP exception instruction register. */
|
||||
};
|
||||
|
||||
#endif /* sc_mips_thread_state */
|
@ -1,132 +0,0 @@
|
||||
/* Operating system support for run-time dynamic linker. MIPS specific
|
||||
stuffs on Hurd.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd.h>
|
||||
#include <link.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <assert.h>
|
||||
#include <sysdep.h>
|
||||
#include <mach/mig_support.h>
|
||||
#include "../stdio-common/_itoa.h"
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libintl.h>
|
||||
|
||||
void weak_function
|
||||
abort (void)
|
||||
{
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <mach/error.h>
|
||||
#include <errorlib.h>
|
||||
|
||||
#undef _
|
||||
#define _(x) x
|
||||
|
||||
/* Return a string describing the errno code in ERRNUM. */
|
||||
char * weak_function
|
||||
_strerror_internal (int errnum, char *buf, size_t buflen)
|
||||
{
|
||||
int system;
|
||||
int sub;
|
||||
int code;
|
||||
const struct error_system *es;
|
||||
extern void __mach_error_map_compat (int *);
|
||||
|
||||
__mach_error_map_compat (&errnum);
|
||||
|
||||
system = err_get_system (errnum);
|
||||
sub = err_get_sub (errnum);
|
||||
code = err_get_code (errnum);
|
||||
|
||||
if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
|
||||
{
|
||||
const char *unk = _("Error in unknown error system: ");
|
||||
const size_t unklen = strlen (unk);
|
||||
char *p = buf + buflen;
|
||||
*--p = '\0';
|
||||
p = _itoa (errnum, p, 16, 1);
|
||||
return memcpy (p - unklen, unk, unklen);
|
||||
}
|
||||
|
||||
es = &__mach_error_systems[system];
|
||||
|
||||
if (sub >= es->max_sub)
|
||||
return (char *) es->bad_sub;
|
||||
|
||||
if (code >= es->subsystem[sub].max_code)
|
||||
{
|
||||
const char *unk = _("Unknown error ");
|
||||
const size_t unklen = strlen (unk);
|
||||
char *p = buf + buflen;
|
||||
size_t len = strlen (es->subsystem[sub].subsys_name);
|
||||
*--p = '\0';
|
||||
p = _itoa (errnum, p, 16, 1);
|
||||
*p-- = ' ';
|
||||
p = memcpy (p - len, es->subsystem[sub].subsys_name, len);
|
||||
return memcpy (p - unklen, unk, unklen);
|
||||
}
|
||||
|
||||
return (char *) _(es->subsystem[sub].codes[code]);
|
||||
}
|
||||
|
||||
/* Read the whole contents of FILE into new mmap'd space with given
|
||||
protections. The size of the file is returned in SIZE. */
|
||||
void *
|
||||
_dl_sysdep_read_whole_file (const char *file, size_t *size, int prot)
|
||||
{
|
||||
struct stat stat;
|
||||
mach_port_t memobj_rd;
|
||||
void *contents;
|
||||
error_t err;
|
||||
|
||||
memobj_rd = __open (file, O_RDONLY, 0);
|
||||
if (memobj_rd)
|
||||
{
|
||||
err = __io_stat ((file_t) memobj_rd, &stat);
|
||||
if (err)
|
||||
{
|
||||
__hurd_fail (err);
|
||||
contents = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Map a copy of the file contents. */
|
||||
contents = __mmap (0, stat.st_size, prot, MAP_COPY, memobj_rd, 0);
|
||||
if (contents == (void *)-1)
|
||||
contents = 0;
|
||||
else
|
||||
*size = stat.st_size;
|
||||
}
|
||||
|
||||
__mach_port_deallocate (__mach_task_self (), memobj_rd);
|
||||
}
|
||||
else
|
||||
contents = 0;
|
||||
|
||||
return contents;
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/* Translate Mach exception codes into signal numbers. MIPS version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
#include <mach/exception.h>
|
||||
|
||||
/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
|
||||
into a signal number and signal subcode. */
|
||||
|
||||
void
|
||||
_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
|
||||
{
|
||||
detail->error = 0;
|
||||
|
||||
switch (detail->exc)
|
||||
{
|
||||
default:
|
||||
*signo = SIGIOT;
|
||||
detail->code = detail->exc;
|
||||
break;
|
||||
|
||||
case EXC_BAD_ACCESS:
|
||||
if (detail->exc_code == KERN_PROTECTION_FAILURE)
|
||||
*signo = SIGSEGV;
|
||||
else
|
||||
*signo = SIGBUS;
|
||||
detail->code = detail->exc_subcode;
|
||||
detail->error = detail->exc_code;
|
||||
break;
|
||||
|
||||
case EXC_BAD_INSTRUCTION:
|
||||
*signo = SIGILL;
|
||||
if (detail->exc_code == EXC_MIPS_II)
|
||||
detail->code = detail->exc_subcode;
|
||||
else
|
||||
detail->code = 0;
|
||||
break;
|
||||
|
||||
case EXC_ARITHMETIC:
|
||||
switch (detail->exc_code)
|
||||
{
|
||||
case EXC_MIPS_OV: /* integer overflow */
|
||||
*signo = SIGFPE;
|
||||
detail->code = detail->exc_subcode;
|
||||
break;
|
||||
|
||||
default:
|
||||
*signo = SIGFPE;
|
||||
detail->code = 0;
|
||||
break;
|
||||
|
||||
case EXC_MIPS_INT:
|
||||
/* Subcode is the fp_status word saved by the hardware.
|
||||
Give an error code corresponding to the first bit set. */
|
||||
if (detail->exc_subcode == EXC_MIPS_FLT_UNIMP)
|
||||
*signo = SIGILL;
|
||||
else
|
||||
*signo = SIGFPE;
|
||||
detail->code = detail->exc_subcode;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXC_EMULATION:
|
||||
/* 3.0 doesn't give this one, why, I don't know. */
|
||||
*signo = SIGEMT;
|
||||
detail->code = 0;
|
||||
break;
|
||||
|
||||
case EXC_SOFTWARE:
|
||||
*signo = SIGEMT;
|
||||
detail->code = 0;
|
||||
break;
|
||||
|
||||
case EXC_BREAKPOINT:
|
||||
*signo = SIGTRAP;
|
||||
detail->code = 0;
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/* Set up a thread_state for proc_handle_exceptions. MIPS version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd/signal.h>
|
||||
#include <mach/thread_status.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
extern jmp_buf _hurd_sigthread_fault_env;
|
||||
|
||||
static char fault_stack[32];
|
||||
static volatile void
|
||||
faulted (void)
|
||||
{
|
||||
__longjmp (_hurd_sigthread_fault_env, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_hurd_initialize_fault_recovery_state (void *state)
|
||||
{
|
||||
struct mips_thread_state *ts = state;
|
||||
memset (ts, 0, sizeof (*ts));
|
||||
ts->r29 = (int) &fault_stack[sizeof (fault_stack)];
|
||||
ts->pc = (int) &faulted;
|
||||
}
|
@ -1,414 +0,0 @@
|
||||
/* Initialization code run first thing by the ELF startup code. For Mips/Hurd.
|
||||
Copyright (C) 1996,1997,1998,2000,01,02,03,10 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "hurdstartup.h"
|
||||
#include "set-hooks.h"
|
||||
#include "hurdmalloc.h" /* XXX */
|
||||
|
||||
extern void __mach_init (void);
|
||||
extern void __init_misc (int, char **, char **);
|
||||
#ifdef USE_NONOPTION_FLAGS
|
||||
extern void __getopt_clean_environment (char **);
|
||||
#endif
|
||||
#ifndef SHARED
|
||||
extern void _dl_non_dynamic_init (void) internal_function;
|
||||
#endif
|
||||
extern void __libc_global_ctors (void);
|
||||
|
||||
unsigned int __hurd_threadvar_max;
|
||||
unsigned long int __hurd_threadvar_stack_offset;
|
||||
unsigned long int __hurd_threadvar_stack_mask;
|
||||
|
||||
int __libc_multiple_libcs attribute_hidden = 1;
|
||||
|
||||
int __libc_argc attribute_hidden;
|
||||
char **__libc_argv attribute_hidden;
|
||||
|
||||
void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
|
||||
void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
|
||||
|
||||
|
||||
/* Things that want to be run before _hurd_init or much anything else.
|
||||
Importantly, these are called before anything tries to use malloc. */
|
||||
DEFINE_HOOK (_hurd_preinit_hook, (void));
|
||||
|
||||
static void
|
||||
init1 (int argc, char *arg0, ...)
|
||||
{
|
||||
char **argv = &arg0;
|
||||
char **envp = &argv[argc + 1];
|
||||
struct hurd_startup_data *d;
|
||||
|
||||
__libc_argc = argc;
|
||||
__libc_argv = argv;
|
||||
__environ = envp;
|
||||
while (*envp)
|
||||
++envp;
|
||||
d = (void *) ++envp;
|
||||
|
||||
/* If we are the bootstrap task started by the kernel,
|
||||
then after the environment pointers there is no Hurd
|
||||
data block; the argument strings start there. */
|
||||
if ((void *) d != argv[0])
|
||||
{
|
||||
_hurd_init_dtable = d->dtable;
|
||||
_hurd_init_dtablesize = d->dtablesize;
|
||||
|
||||
{
|
||||
/* Check if the stack we are now on is different from
|
||||
the one described by _hurd_stack_{base,size}. */
|
||||
|
||||
char dummy;
|
||||
const vm_address_t newsp = (vm_address_t) &dummy;
|
||||
|
||||
if (d->stack_size != 0 && (newsp < d->stack_base ||
|
||||
newsp - d->stack_base > d->stack_size))
|
||||
/* The new stack pointer does not intersect with the
|
||||
stack the exec server set up for us, so free that stack. */
|
||||
__vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (__hurd_threadvar_stack_mask == 0)
|
||||
{
|
||||
/* We are not using cthreads, so we will have just a single allocated
|
||||
area for the per-thread variables of the main user thread. */
|
||||
unsigned long int i;
|
||||
__hurd_threadvar_stack_offset
|
||||
= (unsigned long int) malloc (__hurd_threadvar_max *
|
||||
sizeof (unsigned long int));
|
||||
if (__hurd_threadvar_stack_offset == 0)
|
||||
__libc_fatal ("Can't allocate single-threaded per-thread variables.");
|
||||
for (i = 0; i < __hurd_threadvar_max; ++i)
|
||||
((unsigned long int *) __hurd_threadvar_stack_offset)[i] = 0;
|
||||
}
|
||||
|
||||
if ((void *) d != argv[0] && (d->portarray || d->intarray))
|
||||
/* Initialize library data structures, start signal processing, etc. */
|
||||
_hurd_init (d->flags, argv,
|
||||
d->portarray, d->portarraysize,
|
||||
d->intarray, d->intarraysize);
|
||||
|
||||
#ifndef SHARED
|
||||
_dl_non_dynamic_init ();
|
||||
#endif
|
||||
__init_misc (argc, argv, __environ);
|
||||
|
||||
#ifdef USE_NONOPTION_FLAGS
|
||||
/* This is a hack to make the special getopt in GNU libc working. */
|
||||
__getopt_clean_environment (envp);
|
||||
#endif
|
||||
|
||||
#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
|
||||
__libc_global_ctors ();
|
||||
#endif
|
||||
|
||||
(void) &init1;
|
||||
}
|
||||
|
||||
static void *
|
||||
__init (int *data)
|
||||
{
|
||||
int argc = *data;
|
||||
char **argv = (void *) (data + 1);
|
||||
char **envp = &argv[argc + 1];
|
||||
struct hurd_startup_data *d;
|
||||
|
||||
__environ = envp;
|
||||
while (*envp)
|
||||
++envp;
|
||||
d = (void *) ++envp;
|
||||
|
||||
/* The user might have defined a value for this, to get more variables.
|
||||
Otherwise it will be zero on startup. We must make sure it is set
|
||||
properly before before cthreads initialization, so cthreads can know
|
||||
how much space to leave for thread variables. */
|
||||
if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
|
||||
__hurd_threadvar_max = _HURD_THREADVAR_MAX;
|
||||
|
||||
|
||||
/* After possibly switching stacks, call `init1' (above) with the user
|
||||
code as the return address, and the argument data immediately above
|
||||
that on the stack. */
|
||||
|
||||
if (_cthread_init_routine)
|
||||
{
|
||||
/* Initialize cthreads, which will allocate us a new stack to run on. */
|
||||
void *newsp = (*_cthread_init_routine) ();
|
||||
struct hurd_startup_data *od;
|
||||
|
||||
/* Copy the argdata from the old stack to the new one. */
|
||||
newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
|
||||
(char *) d - (char *) data);
|
||||
|
||||
/* Set up the Hurd startup data block immediately following
|
||||
the argument and environment pointers on the new stack. */
|
||||
od = (newsp + ((char *) d - (char *) data));
|
||||
if ((void *) argv[0] == d)
|
||||
/* We were started up by the kernel with arguments on the stack.
|
||||
There is no Hurd startup data, so zero the block. */
|
||||
memset (od, 0, sizeof *od);
|
||||
else
|
||||
/* Copy the Hurd startup data block to the new stack. */
|
||||
*od = *d;
|
||||
|
||||
/* Push the user code address on the top of the new stack. It will
|
||||
be the return address for `init1'; we will jump there with NEWSP
|
||||
as the stack pointer. */
|
||||
return newsp;
|
||||
}
|
||||
|
||||
/* The argument data is just above the stack frame we will unwind by
|
||||
returning. */
|
||||
return (void *) data;
|
||||
|
||||
(void) &__init;
|
||||
}
|
||||
|
||||
#ifdef SHARED
|
||||
/* This function is called to initialize the shared C library.
|
||||
It is called just before the user _start code from mips/elf/start.S,
|
||||
with the stack set up as that code gets it. */
|
||||
|
||||
/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
|
||||
pointer in the dynamic section based solely on that. It is convention
|
||||
for this function to be in the `.init' section, but the symbol name is
|
||||
the only thing that really matters!! */
|
||||
/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
|
||||
|
||||
#if __mips64
|
||||
asm ("\
|
||||
.section .init,\"ax\",@progbits\n\
|
||||
.align 3\n\
|
||||
.globl _init\n\
|
||||
.type _init,@function\n\
|
||||
.ent _init\n\
|
||||
_init:\n\
|
||||
.set noreorder\n\
|
||||
.cpload $25\n\
|
||||
.set reorder\n\
|
||||
dsubu $29, 8*8\n\
|
||||
.cprestore 6*8\n\
|
||||
sd $16, 4*8($29)\n\
|
||||
sd $31, 5*8($29)\n\
|
||||
jal preinit\n\
|
||||
sd $28, 6*8($29)\n\
|
||||
move $16, $29 # Save the old stack pointer to s0 ($16)\n\
|
||||
daddu $4, $29, 4*8\n\
|
||||
jal __init\n\
|
||||
# Restore saved registers from the old stack.\n\
|
||||
ld $28, 6*8($16)\n\
|
||||
ld $31, 5*8($16)\n\
|
||||
ld $16, 4*8($16)\n\
|
||||
move $29, $2 # set new sp to SP\n\
|
||||
call_init1:\n\
|
||||
ld $4, 0($29)\n\
|
||||
ld $5, 1*8($29)\n\
|
||||
ld $6, 2*8($29)\n\
|
||||
ld $7, 3*8($29)\n\
|
||||
dla $25, init1\n\
|
||||
jr $25\n\
|
||||
.end _init\n\
|
||||
.text\n\
|
||||
");
|
||||
#else
|
||||
asm ("\
|
||||
.section .init,\"ax\",@progbits\n\
|
||||
.align 2\n\
|
||||
.globl _init\n\
|
||||
.type _init,@function\n\
|
||||
.ent _init\n\
|
||||
_init:\n\
|
||||
.set noreorder\n\
|
||||
.cpload $25\n\
|
||||
.set reorder\n\
|
||||
subu $29, 32\n\
|
||||
.cprestore 24\n\
|
||||
sw $16, 16($29)\n\
|
||||
sw $31, 20($29)\n\
|
||||
jal preinit\n\
|
||||
sw $28, 24($29)\n\
|
||||
move $16, $29 # Save the old stack pointer to s0 ($16)\n\
|
||||
addu $4, $29, 32\n\
|
||||
jal __init\n\
|
||||
# Restore saved registers from the old stack.\n\
|
||||
lw $28, 24($16)\n\
|
||||
lw $31, 20($16)\n\
|
||||
lw $16, 16($16)\n\
|
||||
move $29, $2 # set new sp to SP\n\
|
||||
call_init1:\n\
|
||||
lw $4, 0($29)\n\
|
||||
lw $5, 4($29)\n\
|
||||
lw $6, 8($29)\n\
|
||||
lw $7, 12($29)\n\
|
||||
la $25, init1\n\
|
||||
jr $25\n\
|
||||
.end _init\n\
|
||||
.text\n\
|
||||
");
|
||||
#endif
|
||||
|
||||
static void
|
||||
preinit (void)
|
||||
{
|
||||
/* Initialize data structures so we can do RPCs. */
|
||||
__mach_init ();
|
||||
|
||||
RUN_HOOK (_hurd_preinit_hook, ());
|
||||
|
||||
(void) &preinit;
|
||||
}
|
||||
|
||||
void __libc_init_first (int argc, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SHARED
|
||||
/* An assembler code wrapping c function __init. */
|
||||
#ifdef __mips64
|
||||
asm ("\
|
||||
.text\n\
|
||||
.align 3\n\
|
||||
init:\n\
|
||||
dsubu $29, 8*8\n\
|
||||
sd $16, 4*8($29)\n\
|
||||
sd $31, 5*8($29)\n\
|
||||
move $16, $29\n\
|
||||
jal __init\n\
|
||||
ld $31, 5*8($16)\n\
|
||||
ld $16, 4*8($16)\n\
|
||||
move $29, $2 # set new sp to SP\n\
|
||||
call_init1:\n\
|
||||
ld $4, 0($29)\n\
|
||||
ld $5, 1*8($29)\n\
|
||||
ld $6, 2*8($29)\n\
|
||||
ld $7, 3*8($29)\n\
|
||||
dla $25, init1\n\
|
||||
jr $25\n\
|
||||
");
|
||||
#else
|
||||
asm ("\
|
||||
.text\n\
|
||||
.align 2\n\
|
||||
init:\n\
|
||||
subu $29, 32\n\
|
||||
sw $16, 16($29)\n\
|
||||
sw $31, 20($29)\n\
|
||||
move $16, $29\n\
|
||||
jal __init\n\
|
||||
lw $31, 20($16)\n\
|
||||
lw $16, 16($16)\n\
|
||||
move $29, $2 # set new sp to SP\n\
|
||||
call_init1:\n\
|
||||
lw $4, 0($29)\n\
|
||||
lw $5, 4($29)\n\
|
||||
lw $6, 8($29)\n\
|
||||
lw $7, 12($29)\n\
|
||||
la $25, init1\n\
|
||||
jr $25\n\
|
||||
");
|
||||
#endif
|
||||
|
||||
/* An assembler code wrapping c function ___libc_init_first.
|
||||
___libc_init_first does an RPC call to flush cache to put doinit
|
||||
function on the stack, so we should call __mach_init first in
|
||||
this wrap. */
|
||||
#ifdef __mips64
|
||||
asm ("\
|
||||
.text\n\
|
||||
.align 3\n\
|
||||
.globl __libc_init_first\n\
|
||||
__libc_init_first:\n\
|
||||
dsubu $29, 8\n\
|
||||
sd $31, 0($29)\n\
|
||||
jal __mach_init\n\
|
||||
ld $4, 0($29)\n\
|
||||
ld $5, 1*8($29)\n\
|
||||
ld $6, 2*8($29)\n\
|
||||
ld $7, 3*8($29)\n\
|
||||
j ___libc_init_first\n\
|
||||
");
|
||||
#else
|
||||
asm ("\
|
||||
.text\n\
|
||||
.align 2\n\
|
||||
.globl __libc_init_first\n\
|
||||
__libc_init_first:\n\
|
||||
subu $29, 4\n\
|
||||
sw $31, 0($29)\n\
|
||||
jal __mach_init\n\
|
||||
lw $4, 0($29)\n\
|
||||
lw $5, 4($29)\n\
|
||||
lw $6, 8($29)\n\
|
||||
lw $7, 12($29)\n\
|
||||
j ___libc_init_first\n\
|
||||
");
|
||||
#endif
|
||||
|
||||
static void
|
||||
___libc_init_first (int return_addr, int argc, ...)
|
||||
{
|
||||
void doinit (int *data)
|
||||
{
|
||||
#if 0
|
||||
/* This function gets called with the argument data at TOS. */
|
||||
void doinit1 (int argc, ...)
|
||||
{
|
||||
init (&argc);
|
||||
}
|
||||
#endif
|
||||
extern void init (int *data);
|
||||
|
||||
/* Push the user return address after the argument data, and then
|
||||
jump to `doinit1' (above), so it is as if __libc_init_first's
|
||||
caller had called `init' with the argument data already on the
|
||||
stack. */
|
||||
*--data = return_addr;
|
||||
|
||||
#ifdef __mips64
|
||||
asm volatile ("ld $31, 0(%0)\n" /* Load the original return address. */
|
||||
"daddu $29, %0, 8\n" /* Switch to new outermost stack. */
|
||||
"move $4, $29\n"
|
||||
"jr %1" : : "r" (data), "r" (&init));
|
||||
#else
|
||||
asm volatile ("lw $31, 0(%0)\n" /* Load the original return address. */
|
||||
"addu $29, %0, 4\n" /* Switch to new outermost stack. */
|
||||
"move $4, $29\n"
|
||||
"jr %1" : : "r" (data), "r" (&init));
|
||||
#endif
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Initialize data structures so we can do RPCs. */
|
||||
__mach_init ();
|
||||
#endif
|
||||
|
||||
RUN_HOOK (_hurd_preinit_hook, ());
|
||||
|
||||
_hurd_startup ((void **) &argc, &doinit);
|
||||
|
||||
(void) &___libc_init_first;
|
||||
}
|
||||
#endif
|
@ -1,127 +0,0 @@
|
||||
/* Machine-dependent details of interruptible RPC messaging. Mips version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
|
||||
#ifdef __mips64
|
||||
#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
|
||||
({ \
|
||||
error_t err; \
|
||||
mach_port_t __rcv_name = (rcv_name); \
|
||||
mach_msg_timeout_t __timeout = (timeout); \
|
||||
mach_port_t __notify = (notify); \
|
||||
asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
|
||||
".globl _hurd_intr_rpc_msg_in_trap\n" \
|
||||
" move $4, %1\n" \
|
||||
" move $5, %2\n" \
|
||||
" move $6, %3\n" \
|
||||
" move $7, %4\n" \
|
||||
" move $8, %5\n" \
|
||||
" move $9, %6\n" \
|
||||
" move $10, %7\n" \
|
||||
" dli $2, -25\n" \
|
||||
"_hurd_intr_rpc_msg_do_trap: syscall\n" \
|
||||
"_hurd_intr_rpc_msg_in_trap: move %0, $2\n" \
|
||||
: "=r" (err) \
|
||||
: "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \
|
||||
"r" (__rcv_name), "r" (__timeout), "r" (__notify) \
|
||||
: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", \
|
||||
"$11", "$12", "$13", "$14", "$15", "$24", "$25", "$28"); \
|
||||
err; \
|
||||
})
|
||||
#else
|
||||
#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
|
||||
({ \
|
||||
error_t err; \
|
||||
mach_port_t __rcv_name = (rcv_name); \
|
||||
mach_msg_timeout_t __timeout = (timeout); \
|
||||
mach_port_t __notify = (notify); \
|
||||
asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
|
||||
".globl _hurd_intr_rpc_msg_in_trap\n" \
|
||||
" move $4, %1\n" \
|
||||
" move $5, %2\n" \
|
||||
" move $6, %3\n" \
|
||||
" move $7, %4\n" \
|
||||
" move $8, %5\n" \
|
||||
" move $9, %6\n" \
|
||||
" move $10, %7\n" \
|
||||
" li $2, -25\n" \
|
||||
"_hurd_intr_rpc_msg_do_trap: syscall\n" \
|
||||
"_hurd_intr_rpc_msg_in_trap: move %0, $2\n" \
|
||||
: "=r" (err) \
|
||||
: "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \
|
||||
"r" (__rcv_name), "r" (__timeout), "r" (__notify) \
|
||||
: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", \
|
||||
"$11", "$12", "$13", "$14", "$15", "$24", "$25", "$28"); \
|
||||
err; \
|
||||
})
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
INTR_MSG_BACK_OUT (struct mips_thread_state *state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#include "hurdfault.h"
|
||||
|
||||
static inline int
|
||||
SYSCALL_EXAMINE (struct mips_thread_state *state, int *callno)
|
||||
{
|
||||
u_int32_t *p = (void *) (state->pc - 4);
|
||||
int result;
|
||||
if (_hurdsig_catch_memory_fault (p))
|
||||
return 0;
|
||||
if (result = (*p == 0x0000000c))
|
||||
/* The PC is just after a `syscall' instruction.
|
||||
This is a system call in progress; v0($2) holds the call number. */
|
||||
*callno = state->r2;
|
||||
_hurdsig_end_catch_fault ();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct mach_msg_trap_args
|
||||
{
|
||||
/* This is the order of arguments to mach_msg_trap. */
|
||||
mach_msg_header_t *msg;
|
||||
mach_msg_option_t option;
|
||||
mach_msg_size_t send_size;
|
||||
mach_msg_size_t rcv_size;
|
||||
mach_port_t rcv_name;
|
||||
mach_msg_timeout_t timeout;
|
||||
mach_port_t notify;
|
||||
};
|
||||
|
||||
|
||||
static inline mach_port_t
|
||||
MSG_EXAMINE (struct mips_thread_state *state, int *msgid)
|
||||
{
|
||||
mach_msg_header_t *msg;
|
||||
mach_port_t send_port;
|
||||
|
||||
msg = (mach_msg_header_t *) state->r4;
|
||||
|
||||
if (_hurdsig_catch_memory_fault (msg))
|
||||
return MACH_PORT_NULL;
|
||||
send_port = msg->msgh_remote_port;
|
||||
*msgid = msg->msgh_id;
|
||||
_hurdsig_end_catch_fault ();
|
||||
|
||||
return send_port;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/* Perform a `longjmp' on a `struct sigcontext'. MIPS version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <hurd/signal.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval)
|
||||
{
|
||||
scp->sc_gpr[16] = env[0].__regs[0];
|
||||
scp->sc_gpr[17] = env[0].__regs[1];
|
||||
scp->sc_gpr[18] = env[0].__regs[2];
|
||||
scp->sc_gpr[19] = env[0].__regs[3];
|
||||
scp->sc_gpr[20] = env[0].__regs[4];
|
||||
scp->sc_gpr[21] = env[0].__regs[5];
|
||||
scp->sc_gpr[22] = env[0].__regs[6];
|
||||
scp->sc_gpr[23] = env[0].__regs[7];
|
||||
|
||||
scp->sc_gpr[28] = (int) env[0].__gp;
|
||||
scp->sc_fp = (int) env[0].__fp;
|
||||
scp->sc_sp = (int) env[0].__sp;
|
||||
scp->sc_pc = (int) env[0].__pc;
|
||||
scp->sc_gpr[2] = retval ?: 1;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/* Perform a `longjmp' on a Mach thread_state. MIPS version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd/signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <mach/thread_status.h>
|
||||
|
||||
|
||||
/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */
|
||||
|
||||
void
|
||||
_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
|
||||
{
|
||||
struct mips_thread_state *ts = state;
|
||||
|
||||
ts->r16 = env[0].__jmpbuf[0].__regs[0];
|
||||
ts->r17 = env[0].__jmpbuf[0].__regs[1];
|
||||
ts->r18 = env[0].__jmpbuf[0].__regs[2];
|
||||
ts->r19 = env[0].__jmpbuf[0].__regs[3];
|
||||
ts->r20 = env[0].__jmpbuf[0].__regs[4];
|
||||
ts->r21 = env[0].__jmpbuf[0].__regs[5];
|
||||
ts->r22 = env[0].__jmpbuf[0].__regs[6];
|
||||
ts->r23 = env[0].__jmpbuf[0].__regs[7];
|
||||
ts->r28 = (int) env[0].__jmpbuf[0].__gp;
|
||||
ts->r29 = (int) env[0].__jmpbuf[0].__sp;
|
||||
ts->r30 = (int) env[0].__jmpbuf[0].__fp;
|
||||
ts->pc = (int) env[0].__jmpbuf[0].__pc;
|
||||
ts->r2 = val ?: 1;
|
||||
}
|
@ -1,223 +0,0 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
#include <hurd/threadvar.h>
|
||||
#include <stdlib.h>
|
||||
#include <mach/mips/mips_instruction.h>
|
||||
|
||||
int
|
||||
__sigreturn (struct sigcontext *scp)
|
||||
{
|
||||
struct hurd_sigstate *ss;
|
||||
struct hurd_userlink *link = (void *) &scp[1];
|
||||
mach_port_t *reply_port;
|
||||
|
||||
if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ss = _hurd_self_sigstate ();
|
||||
__spin_lock (&ss->lock);
|
||||
|
||||
/* Remove the link on the `active resources' chain added by
|
||||
_hurd_setup_sighandler. Its purpose was to make sure
|
||||
that we got called; now we have, it is done. */
|
||||
_hurd_userlink_unlink (link);
|
||||
|
||||
/* Restore the set of blocked signals, and the intr_port slot. */
|
||||
ss->blocked = scp->sc_mask;
|
||||
ss->intr_port = scp->sc_intr_port;
|
||||
|
||||
/* Check for pending signals that were blocked by the old set. */
|
||||
if (ss->pending & ~ss->blocked)
|
||||
{
|
||||
/* There are pending signals that just became unblocked. Wake up the
|
||||
signal thread to deliver them. But first, squirrel away SCP where
|
||||
the signal thread will notice it if it runs another handler, and
|
||||
arrange to have us called over again in the new reality. */
|
||||
ss->context = scp;
|
||||
__spin_unlock (&ss->lock);
|
||||
__msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
|
||||
/* If a pending signal was handled, sig_post never returned. */
|
||||
__spin_lock (&ss->lock);
|
||||
ss->context = NULL;
|
||||
}
|
||||
|
||||
if (scp->sc_onstack)
|
||||
{
|
||||
ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
|
||||
/* XXX cannot unlock until off sigstack */
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
__spin_unlock (&ss->lock);
|
||||
|
||||
/* Destroy the MiG reply port used by the signal handler, and restore the
|
||||
reply port in use by the thread when interrupted. */
|
||||
reply_port =
|
||||
(mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
|
||||
if (*reply_port)
|
||||
{
|
||||
mach_port_t port = *reply_port;
|
||||
|
||||
/* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
|
||||
get another reply port, but avoids mig_dealloc_reply_port trying to
|
||||
deallocate it after the receive fails (which it will, because the
|
||||
reply port will be bogus, whether we do this or not). */
|
||||
*reply_port = MACH_PORT_DEAD;
|
||||
|
||||
__mach_port_destroy (__mach_task_self (), port);
|
||||
}
|
||||
*reply_port = scp->sc_reply_port;
|
||||
|
||||
if (scp->sc_coproc_used & SC_COPROC_USE_FPU)
|
||||
{
|
||||
/* Restore FPU state. */
|
||||
#define restore_fpr(n) \
|
||||
asm volatile ("l.d $f" #n ",%0" : : "m" (scp->sc_fpr[n]))
|
||||
|
||||
/* Restore floating-point registers. */
|
||||
#ifdef __mips64
|
||||
restore_fpr (0);
|
||||
restore_fpr (1);
|
||||
restore_fpr (2);
|
||||
restore_fpr (3);
|
||||
restore_fpr (4);
|
||||
restore_fpr (5);
|
||||
restore_fpr (6);
|
||||
restore_fpr (7);
|
||||
restore_fpr (8);
|
||||
restore_fpr (9);
|
||||
restore_fpr (10);
|
||||
restore_fpr (11);
|
||||
restore_fpr (12);
|
||||
restore_fpr (13);
|
||||
restore_fpr (14);
|
||||
restore_fpr (15);
|
||||
restore_fpr (16);
|
||||
restore_fpr (17);
|
||||
restore_fpr (18);
|
||||
restore_fpr (19);
|
||||
restore_fpr (20);
|
||||
restore_fpr (21);
|
||||
restore_fpr (22);
|
||||
restore_fpr (23);
|
||||
restore_fpr (24);
|
||||
restore_fpr (25);
|
||||
restore_fpr (26);
|
||||
restore_fpr (27);
|
||||
restore_fpr (28);
|
||||
restore_fpr (29);
|
||||
restore_fpr (30);
|
||||
restore_fpr (31);
|
||||
#else
|
||||
restore_fpr (0);
|
||||
restore_fpr (2);
|
||||
restore_fpr (4);
|
||||
restore_fpr (6);
|
||||
restore_fpr (8);
|
||||
restore_fpr (10);
|
||||
restore_fpr (12);
|
||||
restore_fpr (14);
|
||||
restore_fpr (16);
|
||||
restore_fpr (18);
|
||||
restore_fpr (20);
|
||||
restore_fpr (22);
|
||||
restore_fpr (24);
|
||||
restore_fpr (26);
|
||||
restore_fpr (28);
|
||||
restore_fpr (30);
|
||||
#endif
|
||||
|
||||
/* Restore the floating-point control/status register ($f31). */
|
||||
asm volatile ("ctc1 %0,$f31" : : "r" (scp->sc_fpcsr));
|
||||
}
|
||||
|
||||
/* Load all the registers from the sigcontext. */
|
||||
#ifdef __mips64
|
||||
#define restore_gpr(n) \
|
||||
asm volatile ("ld $" #n ",%0" : : "m" (scpreg->sc_gpr[n - 1]))
|
||||
#else
|
||||
#define restore_gpr(n) \
|
||||
asm volatile ("lw $" #n ",%0" : : "m" (scpreg->sc_gpr[n - 1]))
|
||||
#endif
|
||||
|
||||
{
|
||||
register const struct sigcontext *const scpreg asm ("$1") = scp;
|
||||
register int *at asm ("$1");
|
||||
|
||||
/* First restore the multiplication result registers. The compiler
|
||||
will use some temporary registers, so we do this before restoring
|
||||
the general registers. */
|
||||
asm volatile ("mtlo %0" : : "r" (scpreg->sc_mdlo));
|
||||
asm volatile ("mthi %0" : : "r" (scpreg->sc_mdhi));
|
||||
|
||||
/* In the word after the saved PC, store the saved $1 value. */
|
||||
(&scpreg->sc_pc)[1] = scpreg->sc_gpr[0];
|
||||
|
||||
asm volatile (".set noreorder; .set noat;");
|
||||
|
||||
/* Restore the normal registers. */
|
||||
restore_gpr (2);
|
||||
restore_gpr (3);
|
||||
restore_gpr (4);
|
||||
restore_gpr (5);
|
||||
restore_gpr (6);
|
||||
restore_gpr (7);
|
||||
restore_gpr (8);
|
||||
restore_gpr (9);
|
||||
restore_gpr (10);
|
||||
restore_gpr (11);
|
||||
restore_gpr (12);
|
||||
restore_gpr (13);
|
||||
restore_gpr (14);
|
||||
restore_gpr (15);
|
||||
restore_gpr (16);
|
||||
restore_gpr (17);
|
||||
restore_gpr (18);
|
||||
restore_gpr (19);
|
||||
restore_gpr (20);
|
||||
restore_gpr (21);
|
||||
restore_gpr (22);
|
||||
restore_gpr (23);
|
||||
restore_gpr (24);
|
||||
restore_gpr (25);
|
||||
/* Registers 26-27 are kernel-only. */
|
||||
restore_gpr (28);
|
||||
restore_gpr (29); /* Stack pointer. */
|
||||
restore_gpr (30); /* Frame pointer. */
|
||||
restore_gpr (31); /* Return address. */
|
||||
|
||||
at = &scpreg->sc_pc;
|
||||
/* This is an emulated instruction that will find at the address in $1
|
||||
two words: the PC value to restore, and the $1 value to restore. */
|
||||
asm volatile (".word %0" : : "i" (op_sigreturn));
|
||||
asm volatile (".set reorder; .set at;");
|
||||
/* NOTREACHED */
|
||||
return at; /* To prevent optimization. */
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
return -1;
|
||||
}
|
||||
|
||||
weak_alias (__sigreturn, sigreturn)
|
@ -1,292 +0,0 @@
|
||||
/* Set thread_state for sighandler, and sigcontext to recover. MIPS version.
|
||||
Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <hurd/signal.h>
|
||||
#include <hurd/userlink.h>
|
||||
#include <thread_state.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include "hurdfault.h"
|
||||
#include <intr-msg.h>
|
||||
|
||||
|
||||
struct sigcontext *
|
||||
_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
|
||||
int signo, struct hurd_signal_detail *detail,
|
||||
volatile int rpc_wait,
|
||||
struct machine_thread_all_state *state)
|
||||
{
|
||||
__label__ trampoline, rpc_wait_trampoline, firewall;
|
||||
void *volatile sigsp;
|
||||
struct sigcontext *scp;
|
||||
struct
|
||||
{
|
||||
int signo;
|
||||
long int sigcode;
|
||||
struct sigcontext *scp; /* Points to ctx, below. */
|
||||
void *sigreturn_addr;
|
||||
void *sigreturn_returns_here;
|
||||
struct sigcontext *return_scp; /* Same; arg to sigreturn. */
|
||||
struct sigcontext ctx;
|
||||
struct hurd_userlink link;
|
||||
} *stackframe;
|
||||
|
||||
if (ss->context)
|
||||
{
|
||||
/* We have a previous sigcontext that sigreturn was about
|
||||
to restore when another signal arrived. We will just base
|
||||
our setup on that. */
|
||||
if (! _hurdsig_catch_memory_fault (ss->context))
|
||||
{
|
||||
memcpy (&state->basic, &ss->context->sc_mips_thread_state,
|
||||
sizeof (state->basic));
|
||||
memcpy (&state->exc, &ss->context->sc_mips_exc_state,
|
||||
sizeof (state->exc));
|
||||
state->set = (1 << MIPS_THREAD_STATE) | (1 << MIPS_EXC_STATE);
|
||||
if (state->exc.coproc_state & SC_COPROC_USE_FPU)
|
||||
{
|
||||
memcpy (&state->fpu, &ss->context->sc_mips_float_state,
|
||||
sizeof (state->fpu));
|
||||
state->set |= (1 << MIPS_FLOAT_STATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! machine_get_basic_state (ss->thread, state))
|
||||
return NULL;
|
||||
|
||||
/* Save the original SP in the gratuitous s0 ($16) slot.
|
||||
We may need to reset the SP (the `r29' slot) to avoid clobbering an
|
||||
interrupted RPC frame. */
|
||||
state->basic.r16 = state->basic.r29;
|
||||
|
||||
if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
|
||||
!(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
|
||||
{
|
||||
sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
|
||||
ss->sigaltstack.ss_flags |= SS_ONSTACK;
|
||||
/* XXX need to set up base of new stack for
|
||||
per-thread variables, cthreads. */
|
||||
}
|
||||
else
|
||||
sigsp = (char *) state->basic.r29;
|
||||
|
||||
/* Push the arguments to call `trampoline' on the stack. */
|
||||
sigsp -= sizeof (*stackframe);
|
||||
stackframe = sigsp;
|
||||
|
||||
if (_hurdsig_catch_memory_fault (stackframe))
|
||||
{
|
||||
/* We got a fault trying to write the stack frame.
|
||||
We cannot set up the signal handler.
|
||||
Returning NULL tells our caller, who will nuke us with a SIGILL. */
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ok;
|
||||
|
||||
extern void _hurdsig_longjmp_from_handler (void *, jmp_buf, int);
|
||||
|
||||
/* Add a link to the thread's active-resources list. We mark this as
|
||||
the only user of the "resource", so the cleanup function will be
|
||||
called by any longjmp which is unwinding past the signal frame.
|
||||
The cleanup function (in sigunwind.c) will make sure that all the
|
||||
appropriate cleanups done by sigreturn are taken care of. */
|
||||
stackframe->link.cleanup = &_hurdsig_longjmp_from_handler;
|
||||
stackframe->link.cleanup_data = &stackframe->ctx;
|
||||
stackframe->link.resource.next = NULL;
|
||||
stackframe->link.resource.prevp = NULL;
|
||||
stackframe->link.thread.next = ss->active_resources;
|
||||
stackframe->link.thread.prevp = &ss->active_resources;
|
||||
if (stackframe->link.thread.next)
|
||||
stackframe->link.thread.next->thread.prevp
|
||||
= &stackframe->link.thread.next;
|
||||
ss->active_resources = &stackframe->link;
|
||||
|
||||
/* Set up the arguments for the signal handler. */
|
||||
stackframe->signo = signo;
|
||||
stackframe->sigcode = detail->code;
|
||||
stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
|
||||
stackframe->sigreturn_addr = &__sigreturn;
|
||||
stackframe->sigreturn_returns_here = &&firewall; /* Crash on return. */
|
||||
|
||||
/* Set up the sigcontext from the current state of the thread. */
|
||||
|
||||
scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
|
||||
|
||||
/* struct sigcontext is laid out so that starting at sc_gpr
|
||||
mimics a struct mips_thread_state. */
|
||||
memcpy (&scp->sc_mips_thread_state,
|
||||
&state->basic, sizeof (state->basic));
|
||||
|
||||
/* struct sigcontext is laid out so that starting at sc_cause
|
||||
mimics a struct mips_exc_state. */
|
||||
ok = machine_get_state (ss->thread, state, MIPS_EXC_STATE,
|
||||
&state->exc, &scp->sc_cause,
|
||||
sizeof (state->exc));
|
||||
|
||||
if (ok && (scp->sc_coproc_used & SC_COPROC_USE_FPU))
|
||||
/* struct sigcontext is laid out so that starting at sc_fpr
|
||||
mimics a struct mips_float_state. This state
|
||||
is only meaningful if the coprocessor was used. */
|
||||
ok = machine_get_state (ss->thread, state, MIPS_FLOAT_STATE,
|
||||
&state->fpu, &scp->sc_mips_float_state,
|
||||
sizeof (state->fpu));
|
||||
|
||||
_hurdsig_end_catch_fault ();
|
||||
|
||||
if (! ok)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Modify the thread state to call the trampoline code on the new stack. */
|
||||
if (rpc_wait)
|
||||
{
|
||||
/* The signalee thread was blocked in a mach_msg_trap system call,
|
||||
still waiting for a reply. We will have it run the special
|
||||
trampoline code which retries the message receive before running
|
||||
the signal handler.
|
||||
|
||||
To do this we change the OPTION argument in its registers to
|
||||
enable only message reception, since the request message has
|
||||
already been sent. */
|
||||
|
||||
/* The system call arguments are stored in consecutive registers
|
||||
starting with a0 ($4). */
|
||||
struct mach_msg_trap_args *args = (void *) &state->basic.r4;
|
||||
|
||||
if (_hurdsig_catch_memory_fault (args))
|
||||
{
|
||||
/* Faulted accessing ARGS. Bomb. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (args->option & MACH_RCV_MSG);
|
||||
/* Disable the message-send, since it has already completed. The
|
||||
calls we retry need only wait to receive the reply message. */
|
||||
args->option &= ~MACH_SEND_MSG;
|
||||
|
||||
/* Limit the time to receive the reply message, in case the server
|
||||
claimed that `interrupt_operation' succeeded but in fact the RPC
|
||||
is hung. */
|
||||
args->option |= MACH_RCV_TIMEOUT;
|
||||
args->timeout = _hurd_interrupted_rpc_timeout;
|
||||
|
||||
_hurdsig_end_catch_fault ();
|
||||
|
||||
state->basic.pc = (int) &&rpc_wait_trampoline;
|
||||
/* The reply-receiving trampoline code runs initially on the original
|
||||
user stack. We pass it the signal stack pointer in s4 ($20). */
|
||||
state->basic.r29 = state->basic.r16; /* Restore mach_msg syscall SP. */
|
||||
state->basic.r20 = (int) sigsp;
|
||||
/* After doing the message receive, the trampoline code will need to
|
||||
update the v0 ($2) value to be restored by sigreturn. To simplify
|
||||
the assembly code, we pass the address of its slot in SCP to the
|
||||
trampoline code in s5 ($21). */
|
||||
state->basic.r21 = (int) &scp->sc_gpr[1];
|
||||
/* We must preserve the mach_msg_trap args in a0..t2 ($4..$10).
|
||||
Pass the handler args to the trampoline code in s1..s3 ($17..$19). */
|
||||
state->basic.r17 = signo;
|
||||
state->basic.r18 = detail->code;
|
||||
state->basic.r19 = (int) scp;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->basic.pc = (int) &&trampoline;
|
||||
state->basic.r29 = (int) sigsp;
|
||||
state->basic.r4 = signo;
|
||||
state->basic.r5 = detail->code;
|
||||
state->basic.r6 = (int) scp;
|
||||
}
|
||||
|
||||
/* We pass the handler function to the trampoline code in s6 ($22). */
|
||||
state->basic.r22 = (int) handler;
|
||||
/* In the callee-saved register s0 ($16), we save the SCP value to pass
|
||||
to __sigreturn after the handler returns. */
|
||||
state->basic.r16 = (int) scp;
|
||||
|
||||
return scp;
|
||||
|
||||
/* The trampoline code follows. This is not actually executed as part of
|
||||
this function, it is just convenient to write it that way. */
|
||||
|
||||
rpc_wait_trampoline:
|
||||
/* This is the entry point when we have an RPC reply message to receive
|
||||
before running the handler. The MACH_MSG_SEND bit has already been
|
||||
cleared in the OPTION argument in our registers. For our convenience,
|
||||
$3 points to the sc_gpr[1] member of the sigcontext (saved v0 ($2)). */
|
||||
asm volatile
|
||||
(".set noat; .set noreorder; .set nomacro\n"
|
||||
/* Retry the interrupted mach_msg system call. */
|
||||
#ifdef __mips64
|
||||
"dli $2, -25\n" /* mach_msg_trap */
|
||||
#else
|
||||
"li $2, -25\n" /* mach_msg_trap */
|
||||
#endif
|
||||
"syscall\n"
|
||||
/* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED. But
|
||||
now the message receive has completed and the original caller of
|
||||
the RPC (i.e. the code running when the signal arrived) needs to
|
||||
see the final return value of the message receive in v0. So
|
||||
store the new v0 value into the sc_gpr[1] member of the sigcontext
|
||||
(whose address is in s5 to make this code simpler). */
|
||||
#ifdef __mips64
|
||||
"sd $2, ($21)\n"
|
||||
#else
|
||||
"sw $2, ($21)\n"
|
||||
#endif
|
||||
/* Since the argument registers needed to have the mach_msg_trap
|
||||
arguments, we've stored the arguments to the handler function
|
||||
in registers s1..s3 ($17..$19). */
|
||||
"move $4, $17\n"
|
||||
"move $5, $18\n"
|
||||
"move $6, $19\n"
|
||||
/* Switch to the signal stack. */
|
||||
"move $29, $20\n");
|
||||
|
||||
trampoline:
|
||||
/* Entry point for running the handler normally. The arguments to the
|
||||
handler function are already in the standard registers:
|
||||
|
||||
a0 SIGNO
|
||||
a1 SIGCODE
|
||||
a2 SCP
|
||||
*/
|
||||
asm volatile
|
||||
("move $25, $22\n" /* Copy s6 to t9 for MIPS ABI. */
|
||||
"jal $25; nop\n" /* Call the handler function. */
|
||||
/* Call __sigreturn (SCP); this cannot return. */
|
||||
#ifdef __mips64
|
||||
"dla $1,%0\n"
|
||||
#else
|
||||
"la $1,%0\n"
|
||||
#endif
|
||||
"j $1\n"
|
||||
"move $4, $16" /* Set up arg from saved SCP in delay slot. */
|
||||
: : "i" (&__sigreturn));
|
||||
|
||||
/* NOTREACHED */
|
||||
asm volatile (".set reorder; .set at; .set macro");
|
||||
|
||||
firewall:
|
||||
asm volatile ("hlt: j hlt");
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
ifeq ($(subdir),gnulib)
|
||||
sysdep_routines += cacheflush
|
||||
endif
|
@ -1,44 +0,0 @@
|
||||
/* Flush the insn cache after GCC writes a closure on the stack. Mach/MIPS.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <mach.h>
|
||||
#include <mach/vm_attributes.h>
|
||||
|
||||
/* Stupid name, but this is what GCC generates (config/mips/mips.h). */
|
||||
void
|
||||
cacheflush (void *addr, unsigned size, int flag)
|
||||
{
|
||||
vm_machine_attribute_val_t val;
|
||||
|
||||
switch (flag)
|
||||
{
|
||||
case 0: /* ? */
|
||||
val = MATTR_VAL_DCACHE_FLUSH;
|
||||
case 1: /* This is the only value GCC uses. */
|
||||
val = MATTR_VAL_ICACHE_FLUSH;
|
||||
break;
|
||||
default:
|
||||
val = MATTR_VAL_CACHE_FLUSH;
|
||||
}
|
||||
|
||||
__vm_machine_attribute (__mach_task_self (),
|
||||
(vm_address_t) addr, size,
|
||||
MATTR_CACHE,
|
||||
&val);
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/* Machine-specific definition for spin locks. MIPS version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MACHINE_LOCK_H
|
||||
#define _MACHINE_LOCK_H
|
||||
|
||||
/* To get the TAS pseudo-instruction. */
|
||||
#include <mach/mips/mips_instruction.h>
|
||||
|
||||
/* The type of a spin lock variable. */
|
||||
|
||||
typedef __volatile int __spin_lock_t;
|
||||
|
||||
/* Value to initialize `__spin_lock_t' variables to. */
|
||||
|
||||
#define __SPIN_LOCK_INITIALIZER 0
|
||||
|
||||
|
||||
#ifndef _EXTERN_INLINE
|
||||
#define _EXTERN_INLINE extern __inline
|
||||
#endif
|
||||
|
||||
/* Unlock LOCK. */
|
||||
|
||||
_EXTERN_INLINE void
|
||||
__spin_unlock (__spin_lock_t *__lock)
|
||||
{
|
||||
*__lock = 0;
|
||||
}
|
||||
|
||||
/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
|
||||
|
||||
_EXTERN_INLINE int
|
||||
__spin_try_lock (register __spin_lock_t *__lock)
|
||||
{
|
||||
#if (__mips >= 2)
|
||||
int __rtn;
|
||||
|
||||
__asm__ __volatile (".set noreorder");
|
||||
#if (__mips64)
|
||||
__asm__ __volatile ("lld %0,0(%1)" : "=r" (__rtn) : "r" (__lock));
|
||||
#else
|
||||
__asm__ __volatile ("ll %0,0(%1)" : "=r" (__rtn) : "r" (__lock));
|
||||
#endif
|
||||
if (__rtn)
|
||||
return 0;
|
||||
__asm__ __volatile ("move %0,%1" : "=r" (__rtn) : "r" (__lock));
|
||||
#if (__mips64)
|
||||
__asm__ __volatile ("scd %0,0(%1)" : "=r" (__rtn) : "r" (__lock));
|
||||
#else
|
||||
__asm__ __volatile ("sc %0,0(%1)" : "=r" (__rtn) : "r" (__lock));
|
||||
#endif
|
||||
__asm__ __volatile (".set reorder");
|
||||
return __rtn;
|
||||
#else
|
||||
register int __rtn __asm__ ("a0");
|
||||
|
||||
/* Use the Mach microkernel's emulated TAS pseudo-instruction. */
|
||||
__asm__ __volatile (".set noreorder");
|
||||
__asm__ __volatile (".word %1" : "=r" (__rtn) : "i" (op_tas), "0" (__lock));
|
||||
__asm__ __volatile ("nop");
|
||||
__asm__ __volatile (".set reorder");
|
||||
return __rtn ^ (int) __lock;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return nonzero if LOCK is locked. */
|
||||
|
||||
_EXTERN_INLINE int
|
||||
__spin_lock_locked (__spin_lock_t *__lock)
|
||||
{
|
||||
return *__lock != 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* machine-lock.h */
|
@ -1,38 +0,0 @@
|
||||
/* Machine-specific function to return the stack pointer. MIPS version.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MACHINE_SP_H
|
||||
#define _MACHINE_SP_H
|
||||
|
||||
/* Return the current stack pointer. */
|
||||
|
||||
#ifndef _EXTERN_INLINE
|
||||
#define _EXTERN_INLINE extern __inline
|
||||
#endif
|
||||
|
||||
_EXTERN_INLINE void *
|
||||
__thread_stack_pointer (void)
|
||||
{
|
||||
void *__sp__;
|
||||
__asm__ ("move %0,$29" : "=r" (__sp__));
|
||||
return __sp__;
|
||||
}
|
||||
|
||||
#endif /* machine-sp.h */
|
||||
|
@ -1,48 +0,0 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
#ifdef PIC
|
||||
.option pic2
|
||||
#endif
|
||||
ENTRY (syscall)
|
||||
move v0, a0 /* Load system call number from first arg. */
|
||||
move a0, a1 /* Move the next three args up a register. */
|
||||
move a1, a2
|
||||
move a2, a3
|
||||
/* Load the remaining possible args (up to 11) from the stack. */
|
||||
#ifdef __mips64
|
||||
ld t0,4*8(sp)
|
||||
ld t1,5*8(sp)
|
||||
ld t2,6*8(sp)
|
||||
ld t3,7*8(sp)
|
||||
ld t4,8*8(sp)
|
||||
ld t5,9*8(sp)
|
||||
ld t6,10*8(sp)
|
||||
#else
|
||||
lw t0,4*4(sp)
|
||||
lw t1,5*4(sp)
|
||||
lw t2,6*4(sp)
|
||||
lw t3,7*4(sp)
|
||||
lw t4,8*4(sp)
|
||||
lw t5,9*4(sp)
|
||||
lw t6,10*4(sp)
|
||||
#endif
|
||||
syscall /* Do the system call. */
|
||||
j ra /* Return to caller. */
|
@ -1,83 +0,0 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define LOSE asm volatile ("1: b 1b")
|
||||
|
||||
#define START_MACHDEP asm ("\
|
||||
.text\n\
|
||||
.globl _start\n\
|
||||
.ent _start\n\
|
||||
_start:\n\
|
||||
# Put initial SP in a0.\n\
|
||||
move $4, $29\n\
|
||||
# Jump to _start0; don't return.\n\
|
||||
j _start0\n\
|
||||
.end _start\n\
|
||||
");
|
||||
#define START_ARGS int *entry_sp
|
||||
#define SNARF_ARGS(argc, argv, envp) \
|
||||
do \
|
||||
{ \
|
||||
register char **p; \
|
||||
\
|
||||
argc = *entry_sp; \
|
||||
argv = (char **) (entry_sp + 1); \
|
||||
p = argv; \
|
||||
while (*p++ != NULL) \
|
||||
; \
|
||||
if (p >= (char **) argv[0]) \
|
||||
--p; \
|
||||
envp = p; \
|
||||
} while (0)
|
||||
|
||||
#define CALL_WITH_SP(fn, sp) \
|
||||
({ register int __fn = fn, __sp = (int) sp; \
|
||||
asm volatile ("move $sp,%0; j %1" : : "r" (__sp), "r" (__fn));})
|
||||
|
||||
#define RETURN_TO(sp, pc, retval) \
|
||||
asm volatile ("move $29, %0; move $2, %2; move $25, %1; jr $25" \
|
||||
: : "r" (sp), "r" (pc), "r" (retval))
|
||||
|
||||
#define STACK_GROWTH_DOWN
|
||||
|
||||
#include <syscall.h>
|
||||
|
||||
#if defined (__ASSEMBLER__)
|
||||
|
||||
#define ALIGN 2
|
||||
|
||||
#define MOVE(x,y) move y , x
|
||||
|
||||
#define SYSCALL(name, args) \
|
||||
.globl syscall_error; \
|
||||
kernel_trap(name,SYS_##name,args); \
|
||||
beq $1,$0,1f; \
|
||||
j syscall_error; \
|
||||
1:
|
||||
|
||||
#define SYSCALL__(name, args) \
|
||||
.globl syscall_error; \
|
||||
kernel_trap(__##name,SYS_##name,args); \
|
||||
beq $1,$0,1f; \
|
||||
j syscall_error; \
|
||||
1:
|
||||
|
||||
#define ret j ra; nop
|
||||
#endif
|
||||
|
||||
#include <sysdeps/mach/sysdep.h>
|
@ -1,42 +0,0 @@
|
||||
/* Mach thread state definitions for machine-independent code. MIPS version.
|
||||
Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define MACHINE_THREAD_STATE_FLAVOR MIPS_THREAD_STATE
|
||||
#define MACHINE_THREAD_STATE_COUNT MIPS_THREAD_STATE_COUNT
|
||||
|
||||
#ifdef __PIC__
|
||||
#define MACHINE_THREAD_STATE_SET_PC(ts, pc) \
|
||||
((ts)->PC = (ts)->r25 = (unsigned long int) (pc))
|
||||
#endif
|
||||
|
||||
#define machine_thread_state mips_thread_state
|
||||
|
||||
#define PC pc
|
||||
#define SP r29
|
||||
#define SYSRETURN r2
|
||||
|
||||
struct machine_thread_all_state
|
||||
{
|
||||
int set; /* Mask of bits (1 << FLAVOR). */
|
||||
struct mips_thread_state basic;
|
||||
struct mips_exc_state exc;
|
||||
struct mips_float_state fpu;
|
||||
};
|
||||
|
||||
#include <sysdeps/mach/thread_state.h>
|
@ -1,81 +0,0 @@
|
||||
# IBM POWER __mpn_add_n -- Add two limb vectors of equal, non-zero length.
|
||||
|
||||
# Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s1_ptr r4
|
||||
# s2_ptr r5
|
||||
# size r6
|
||||
|
||||
.toc
|
||||
.extern __mpn_add_n[DS]
|
||||
.extern .__mpn_add_n
|
||||
.csect [PR]
|
||||
.align 2
|
||||
.globl __mpn_add_n
|
||||
.globl .__mpn_add_n
|
||||
.csect __mpn_add_n[DS]
|
||||
__mpn_add_n:
|
||||
.long .__mpn_add_n, TOC[tc0], 0
|
||||
.csect [PR]
|
||||
.__mpn_add_n:
|
||||
andil. 10,6,1 # odd or even number of limbs?
|
||||
l 8,0(4) # load least significant s1 limb
|
||||
l 0,0(5) # load least significant s2 limb
|
||||
cal 3,-4(3) # offset res_ptr, it's updated before it's used
|
||||
sri 10,6,1 # count for unrolled loop
|
||||
a 7,0,8 # add least significant limbs, set cy
|
||||
mtctr 10 # copy count into CTR
|
||||
beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
|
||||
|
||||
# We have an odd # of limbs. Add the first limbs separately.
|
||||
cmpi 1,10,0 # is count for unrolled loop zero?
|
||||
bne 1,L1 # branch if not
|
||||
st 7,4(3)
|
||||
aze 3,10 # use the fact that r10 is zero...
|
||||
br # return
|
||||
|
||||
# We added least significant limbs. Now reload the next limbs to enter loop.
|
||||
L1: lu 8,4(4) # load s1 limb and update s1_ptr
|
||||
lu 0,4(5) # load s2 limb and update s2_ptr
|
||||
stu 7,4(3)
|
||||
ae 7,0,8 # add limbs, set cy
|
||||
Leven: lu 9,4(4) # load s1 limb and update s1_ptr
|
||||
lu 10,4(5) # load s2 limb and update s2_ptr
|
||||
bdz Lend # If done, skip loop
|
||||
|
||||
Loop: lu 8,4(4) # load s1 limb and update s1_ptr
|
||||
lu 0,4(5) # load s2 limb and update s2_ptr
|
||||
ae 11,9,10 # add previous limbs with cy, set cy
|
||||
stu 7,4(3) #
|
||||
lu 9,4(4) # load s1 limb and update s1_ptr
|
||||
lu 10,4(5) # load s2 limb and update s2_ptr
|
||||
ae 7,0,8 # add previous limbs with cy, set cy
|
||||
stu 11,4(3) #
|
||||
bdn Loop # decrement CTR and loop back
|
||||
|
||||
Lend: ae 11,9,10 # add limbs with cy, set cy
|
||||
st 7,4(3) #
|
||||
st 11,8(3) #
|
||||
lil 3,0 # load cy into ...
|
||||
aze 3,3 # ... return value register
|
||||
br
|
@ -1,123 +0,0 @@
|
||||
# IBM POWER __mpn_addmul_1 -- Multiply a limb vector with a limb and add
|
||||
# the result to a second limb vector.
|
||||
|
||||
# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s1_ptr r4
|
||||
# size r5
|
||||
# s2_limb r6
|
||||
|
||||
# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
|
||||
# obtain that operation, we have to use the 32x32->64 signed multiplication
|
||||
# instruction, and add the appropriate compensation to the high limb of the
|
||||
# result. We add the multiplicand if the multiplier has its most significant
|
||||
# bit set, and we add the multiplier if the multiplicand has its most
|
||||
# significant bit set. We need to preserve the carry flag between each
|
||||
# iteration, so we have to compute the compensation carefully (the natural,
|
||||
# srai+and doesn't work). Since the POWER architecture has a branch unit
|
||||
# we can branch in zero cycles, so that's how we perform the additions.
|
||||
|
||||
.toc
|
||||
.csect .__mpn_addmul_1[PR]
|
||||
.align 2
|
||||
.globl __mpn_addmul_1
|
||||
.globl .__mpn_addmul_1
|
||||
.csect __mpn_addmul_1[DS]
|
||||
__mpn_addmul_1:
|
||||
.long .__mpn_addmul_1[PR], TOC[tc0], 0
|
||||
.csect .__mpn_addmul_1[PR]
|
||||
.__mpn_addmul_1:
|
||||
|
||||
cal 3,-4(3)
|
||||
l 0,0(4)
|
||||
cmpi 0,6,0
|
||||
mtctr 5
|
||||
mul 9,0,6
|
||||
srai 7,0,31
|
||||
and 7,7,6
|
||||
mfmq 8
|
||||
cax 9,9,7
|
||||
l 7,4(3)
|
||||
a 8,8,7 # add res_limb
|
||||
blt Lneg
|
||||
Lpos: bdz Lend
|
||||
|
||||
Lploop: lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 10,0,6
|
||||
mfmq 0
|
||||
ae 8,0,9 # low limb + old_cy_limb + old cy
|
||||
l 7,4(3)
|
||||
aze 10,10 # propagate cy to new cy_limb
|
||||
a 8,8,7 # add res_limb
|
||||
bge Lp0
|
||||
cax 10,10,6 # adjust high limb for negative limb from s1
|
||||
Lp0: bdz Lend0
|
||||
lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 9,0,6
|
||||
mfmq 0
|
||||
ae 8,0,10
|
||||
l 7,4(3)
|
||||
aze 9,9
|
||||
a 8,8,7
|
||||
bge Lp1
|
||||
cax 9,9,6 # adjust high limb for negative limb from s1
|
||||
Lp1: bdn Lploop
|
||||
|
||||
b Lend
|
||||
|
||||
Lneg: cax 9,9,0
|
||||
bdz Lend
|
||||
Lnloop: lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 10,0,6
|
||||
mfmq 7
|
||||
ae 8,7,9
|
||||
l 7,4(3)
|
||||
ae 10,10,0 # propagate cy to new cy_limb
|
||||
a 8,8,7 # add res_limb
|
||||
bge Ln0
|
||||
cax 10,10,6 # adjust high limb for negative limb from s1
|
||||
Ln0: bdz Lend0
|
||||
lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 9,0,6
|
||||
mfmq 7
|
||||
ae 8,7,10
|
||||
l 7,4(3)
|
||||
ae 9,9,0 # propagate cy to new cy_limb
|
||||
a 8,8,7 # add res_limb
|
||||
bge Ln1
|
||||
cax 9,9,6 # adjust high limb for negative limb from s1
|
||||
Ln1: bdn Lnloop
|
||||
b Lend
|
||||
|
||||
Lend0: cal 9,0(10)
|
||||
Lend: st 8,4(3)
|
||||
aze 3,9
|
||||
br
|
@ -1,42 +0,0 @@
|
||||
/* ffs -- find first set bit in a word, counted from least significant end.
|
||||
For IBM rs6000.
|
||||
Copyright (C) 1991, 1992, 1997, 2004, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef ffs
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
int
|
||||
__ffs (x)
|
||||
int x;
|
||||
{
|
||||
int cnt;
|
||||
|
||||
asm ("cntlz %0,%1" : "=r" (cnt) : "r" (x & -x));
|
||||
return 32 - cnt;
|
||||
}
|
||||
weak_alias (__ffs, ffs)
|
||||
libc_hidden_builtin_def (ffs)
|
||||
|
||||
#else
|
||||
#include <string/ffs.c>
|
||||
#endif
|
@ -1,59 +0,0 @@
|
||||
# IBM POWER __mpn_lshift --
|
||||
|
||||
# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s_ptr r4
|
||||
# size r5
|
||||
# cnt r6
|
||||
|
||||
.toc
|
||||
.extern __mpn_lshift[DS]
|
||||
.extern .__mpn_lshift
|
||||
.csect [PR]
|
||||
.align 2
|
||||
.globl __mpn_lshift
|
||||
.globl .__mpn_lshift
|
||||
.csect __mpn_lshift[DS]
|
||||
__mpn_lshift:
|
||||
.long .__mpn_lshift, TOC[tc0], 0
|
||||
.csect [PR]
|
||||
.__mpn_lshift:
|
||||
sli 0,5,2
|
||||
cax 9,3,0
|
||||
cax 4,4,0
|
||||
sfi 8,6,32
|
||||
mtctr 5 # put limb count in CTR loop register
|
||||
lu 0,-4(4) # read most significant limb
|
||||
sre 3,0,8 # compute carry out limb, and init MQ register
|
||||
bdz Lend2 # if just one limb, skip loop
|
||||
lu 0,-4(4) # read 2:nd most significant limb
|
||||
sreq 7,0,8 # compute most significant limb of result
|
||||
bdz Lend # if just two limb, skip loop
|
||||
Loop: lu 0,-4(4) # load next lower limb
|
||||
stu 7,-4(9) # store previous result during read latency
|
||||
sreq 7,0,8 # compute result limb
|
||||
bdn Loop # loop back until CTR is zero
|
||||
Lend: stu 7,-4(9) # store 2:nd least significant limb
|
||||
Lend2: sle 7,0,6 # compute least significant limb
|
||||
st 7,-4(9) # store it" \
|
||||
br
|
@ -1,86 +0,0 @@
|
||||
/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdeps/generic/memcopy.h>
|
||||
|
||||
#undef OP_T_THRES
|
||||
#define OP_T_THRES 32
|
||||
|
||||
#undef BYTE_COPY_FWD
|
||||
#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
size_t __nbytes = nbytes; \
|
||||
asm volatile("mtspr 1,%2\n" \
|
||||
"lsx 6,0,%1\n" \
|
||||
"stsx 6,0,%0" : /* No outputs. */ : \
|
||||
"b" (dst_bp), "b" (src_bp), "r" (__nbytes) : \
|
||||
"6", "7", "8", "9", "10", "11", "12", "13"); \
|
||||
dst_bp += __nbytes; \
|
||||
src_bp += __nbytes; \
|
||||
} while (0)
|
||||
|
||||
#undef BYTE_COPY_BWD
|
||||
#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
size_t __nbytes = (nbytes); \
|
||||
dst_ep -= __nbytes; \
|
||||
src_ep -= __nbytes; \
|
||||
asm volatile("mtspr 1,%2\n" \
|
||||
"lsx 6,0,%1\n" \
|
||||
"stsx 6,0,%0" : /* No outputs. */ : \
|
||||
"b" (dst_ep), "b" (src_ep), "r" (__nbytes) : \
|
||||
"6", "7", "8", "9", "10", "11", "12", "13"); \
|
||||
} while (0)
|
||||
|
||||
#undef WORD_COPY_FWD
|
||||
#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
size_t __nblocks = (nbytes) / 32; \
|
||||
if (__nblocks != 0) \
|
||||
asm volatile("mtctr %4\n" \
|
||||
"lsi 6,%1,32\n" \
|
||||
"ai %1,%1,32\n" \
|
||||
"stsi 6,%0,32\n" \
|
||||
"ai %0,%0,32\n" \
|
||||
"bdn $-16" : \
|
||||
"=b" (dst_bp), "=b" (src_bp) : \
|
||||
"0" (dst_bp), "1" (src_bp), "r" (__nblocks) : \
|
||||
"6", "7", "8", "9", "10", "11", "12", "13"); \
|
||||
(nbytes_left) = (nbytes) % 32; \
|
||||
} while (0)
|
||||
|
||||
#undef WORD_COPY_BWD
|
||||
#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
size_t __nblocks = (nbytes) / 32; \
|
||||
if (__nblocks != 0) \
|
||||
asm volatile("mtctr %4\n" \
|
||||
"ai %1,%1,-32\n" \
|
||||
"lsi 6,%1,32\n" \
|
||||
"ai %0,%0,-32\n" \
|
||||
"stsi 6,%0,32\n" \
|
||||
"bdn $-16" : \
|
||||
"=b" (dst_ep), "=b" (src_ep) : \
|
||||
"0" (dst_ep), "1" (src_ep), "r" (__nblocks) : \
|
||||
"6", "7", "8", "9", "10", "11", "12", "13"); \
|
||||
(nbytes_left) = (nbytes) % 32; \
|
||||
} while (0)
|
@ -1,110 +0,0 @@
|
||||
# IBM POWER __mpn_mul_1 -- Multiply a limb vector with a limb and store
|
||||
# the result in a second limb vector.
|
||||
|
||||
# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s1_ptr r4
|
||||
# size r5
|
||||
# s2_limb r6
|
||||
|
||||
# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
|
||||
# obtain that operation, we have to use the 32x32->64 signed multiplication
|
||||
# instruction, and add the appropriate compensation to the high limb of the
|
||||
# result. We add the multiplicand if the multiplier has its most significant
|
||||
# bit set, and we add the multiplier if the multiplicand has its most
|
||||
# significant bit set. We need to preserve the carry flag between each
|
||||
# iteration, so we have to compute the compensation carefully (the natural,
|
||||
# srai+and doesn't work). Since the POWER architecture has a branch unit
|
||||
# we can branch in zero cycles, so that's how we perform the additions.
|
||||
|
||||
.toc
|
||||
.csect .__mpn_mul_1[PR]
|
||||
.align 2
|
||||
.globl __mpn_mul_1
|
||||
.globl .__mpn_mul_1
|
||||
.csect __mpn_mul_1[DS]
|
||||
__mpn_mul_1:
|
||||
.long .__mpn_mul_1[PR], TOC[tc0], 0
|
||||
.csect .__mpn_mul_1[PR]
|
||||
.__mpn_mul_1:
|
||||
|
||||
cal 3,-4(3)
|
||||
l 0,0(4)
|
||||
cmpi 0,6,0
|
||||
mtctr 5
|
||||
mul 9,0,6
|
||||
srai 7,0,31
|
||||
and 7,7,6
|
||||
mfmq 8
|
||||
ai 0,0,0 # reset carry
|
||||
cax 9,9,7
|
||||
blt Lneg
|
||||
Lpos: bdz Lend
|
||||
Lploop: lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 10,0,6
|
||||
mfmq 0
|
||||
ae 8,0,9
|
||||
bge Lp0
|
||||
cax 10,10,6 # adjust high limb for negative limb from s1
|
||||
Lp0: bdz Lend0
|
||||
lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 9,0,6
|
||||
mfmq 0
|
||||
ae 8,0,10
|
||||
bge Lp1
|
||||
cax 9,9,6 # adjust high limb for negative limb from s1
|
||||
Lp1: bdn Lploop
|
||||
b Lend
|
||||
|
||||
Lneg: cax 9,9,0
|
||||
bdz Lend
|
||||
Lnloop: lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 10,0,6
|
||||
cax 10,10,0 # adjust high limb for negative s2_limb
|
||||
mfmq 0
|
||||
ae 8,0,9
|
||||
bge Ln0
|
||||
cax 10,10,6 # adjust high limb for negative limb from s1
|
||||
Ln0: bdz Lend0
|
||||
lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 9,0,6
|
||||
cax 9,9,0 # adjust high limb for negative s2_limb
|
||||
mfmq 0
|
||||
ae 8,0,10
|
||||
bge Ln1
|
||||
cax 9,9,6 # adjust high limb for negative limb from s1
|
||||
Ln1: bdn Lnloop
|
||||
b Lend
|
||||
|
||||
Lend0: cal 9,0(10)
|
||||
Lend: st 8,4(3)
|
||||
aze 3,9
|
||||
br
|
@ -1,57 +0,0 @@
|
||||
# IBM POWER __mpn_rshift --
|
||||
|
||||
# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s_ptr r4
|
||||
# size r5
|
||||
# cnt r6
|
||||
|
||||
.toc
|
||||
.extern __mpn_rshift[DS]
|
||||
.extern .__mpn_rshift
|
||||
.csect [PR]
|
||||
.align 2
|
||||
.globl __mpn_rshift
|
||||
.globl .__mpn_rshift
|
||||
.csect __mpn_rshift[DS]
|
||||
__mpn_rshift:
|
||||
.long .__mpn_rshift, TOC[tc0], 0
|
||||
.csect [PR]
|
||||
.__mpn_rshift:
|
||||
sfi 8,6,32
|
||||
mtctr 5 # put limb count in CTR loop register
|
||||
l 0,0(4) # read least significant limb
|
||||
ai 9,3,-4 # adjust res_ptr since it's offset in the stu:s
|
||||
sle 3,0,8 # compute carry limb, and init MQ register
|
||||
bdz Lend2 # if just one limb, skip loop
|
||||
lu 0,4(4) # read 2:nd least significant limb
|
||||
sleq 7,0,8 # compute least significant limb of result
|
||||
bdz Lend # if just two limb, skip loop
|
||||
Loop: lu 0,4(4) # load next higher limb
|
||||
stu 7,4(9) # store previous result during read latency
|
||||
sleq 7,0,8 # compute result limb
|
||||
bdn Loop # loop back until CTR is zero
|
||||
Lend: stu 7,4(9) # store 2:nd most significant limb
|
||||
Lend2: sre 7,0,6 # compute most significant limb
|
||||
st 7,4(9) # store it" \
|
||||
br
|
@ -1,82 +0,0 @@
|
||||
# IBM POWER __mpn_sub_n -- Subtract two limb vectors of equal, non-zero length.
|
||||
|
||||
# Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s1_ptr r4
|
||||
# s2_ptr r5
|
||||
# size r6
|
||||
|
||||
.toc
|
||||
.extern __mpn_sub_n[DS]
|
||||
.extern .__mpn_sub_n
|
||||
.csect [PR]
|
||||
.align 2
|
||||
.globl __mpn_sub_n
|
||||
.globl .__mpn_sub_n
|
||||
.csect __mpn_sub_n[DS]
|
||||
__mpn_sub_n:
|
||||
.long .__mpn_sub_n, TOC[tc0], 0
|
||||
.csect [PR]
|
||||
.__mpn_sub_n:
|
||||
andil. 10,6,1 # odd or even number of limbs?
|
||||
l 8,0(4) # load least significant s1 limb
|
||||
l 0,0(5) # load least significant s2 limb
|
||||
cal 3,-4(3) # offset res_ptr, it's updated before it's used
|
||||
sri 10,6,1 # count for unrolled loop
|
||||
sf 7,0,8 # subtract least significant limbs, set cy
|
||||
mtctr 10 # copy count into CTR
|
||||
beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
|
||||
|
||||
# We have an odd # of limbs. Add the first limbs separately.
|
||||
cmpi 1,10,0 # is count for unrolled loop zero?
|
||||
bne 1,L1 # branch if not
|
||||
st 7,4(3)
|
||||
sfe 3,0,0 # load !cy into ...
|
||||
sfi 3,3,0 # ... return value register
|
||||
br # return
|
||||
|
||||
# We added least significant limbs. Now reload the next limbs to enter loop.
|
||||
L1: lu 8,4(4) # load s1 limb and update s1_ptr
|
||||
lu 0,4(5) # load s2 limb and update s2_ptr
|
||||
stu 7,4(3)
|
||||
sfe 7,0,8 # subtract limbs, set cy
|
||||
Leven: lu 9,4(4) # load s1 limb and update s1_ptr
|
||||
lu 10,4(5) # load s2 limb and update s2_ptr
|
||||
bdz Lend # If done, skip loop
|
||||
|
||||
Loop: lu 8,4(4) # load s1 limb and update s1_ptr
|
||||
lu 0,4(5) # load s2 limb and update s2_ptr
|
||||
sfe 11,10,9 # subtract previous limbs with cy, set cy
|
||||
stu 7,4(3) #
|
||||
lu 9,4(4) # load s1 limb and update s1_ptr
|
||||
lu 10,4(5) # load s2 limb and update s2_ptr
|
||||
sfe 7,0,8 # subtract previous limbs with cy, set cy
|
||||
stu 11,4(3) #
|
||||
bdn Loop # decrement CTR and loop back
|
||||
|
||||
Lend: sfe 11,10,9 # subtract limbs with cy, set cy
|
||||
st 7,4(3) #
|
||||
st 11,8(3) #
|
||||
sfe 3,0,0 # load !cy into ...
|
||||
sfi 3,3,0 # ... return value register
|
||||
br
|
@ -1,128 +0,0 @@
|
||||
# IBM POWER __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
|
||||
# the result from a second limb vector.
|
||||
|
||||
# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of the GNU MP Library.
|
||||
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
|
||||
# The GNU MP Library 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 Lesser General Public
|
||||
# License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
|
||||
# INPUT PARAMETERS
|
||||
# res_ptr r3
|
||||
# s1_ptr r4
|
||||
# size r5
|
||||
# s2_limb r6
|
||||
|
||||
# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
|
||||
# obtain that operation, we have to use the 32x32->64 signed multiplication
|
||||
# instruction, and add the appropriate compensation to the high limb of the
|
||||
# result. We add the multiplicand if the multiplier has its most significant
|
||||
# bit set, and we add the multiplier if the multiplicand has its most
|
||||
# significant bit set. We need to preserve the carry flag between each
|
||||
# iteration, so we have to compute the compensation carefully (the natural,
|
||||
# srai+and doesn't work). Since the POWER architecture has a branch unit
|
||||
# we can branch in zero cycles, so that's how we perform the additions.
|
||||
|
||||
.toc
|
||||
.csect .__mpn_submul_1[PR]
|
||||
.align 2
|
||||
.globl __mpn_submul_1
|
||||
.globl .__mpn_submul_1
|
||||
.csect __mpn_submul_1[DS]
|
||||
__mpn_submul_1:
|
||||
.long .__mpn_submul_1[PR], TOC[tc0], 0
|
||||
.csect .__mpn_submul_1[PR]
|
||||
.__mpn_submul_1:
|
||||
|
||||
cal 3,-4(3)
|
||||
l 0,0(4)
|
||||
cmpi 0,6,0
|
||||
mtctr 5
|
||||
mul 9,0,6
|
||||
srai 7,0,31
|
||||
and 7,7,6
|
||||
mfmq 11
|
||||
cax 9,9,7
|
||||
l 7,4(3)
|
||||
sf 8,11,7 # add res_limb
|
||||
a 11,8,11 # invert cy (r11 is junk)
|
||||
blt Lneg
|
||||
Lpos: bdz Lend
|
||||
|
||||
Lploop: lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 10,0,6
|
||||
mfmq 0
|
||||
ae 11,0,9 # low limb + old_cy_limb + old cy
|
||||
l 7,4(3)
|
||||
aze 10,10 # propagate cy to new cy_limb
|
||||
sf 8,11,7 # add res_limb
|
||||
a 11,8,11 # invert cy (r11 is junk)
|
||||
bge Lp0
|
||||
cax 10,10,6 # adjust high limb for negative limb from s1
|
||||
Lp0: bdz Lend0
|
||||
lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 9,0,6
|
||||
mfmq 0
|
||||
ae 11,0,10
|
||||
l 7,4(3)
|
||||
aze 9,9
|
||||
sf 8,11,7
|
||||
a 11,8,11 # invert cy (r11 is junk)
|
||||
bge Lp1
|
||||
cax 9,9,6 # adjust high limb for negative limb from s1
|
||||
Lp1: bdn Lploop
|
||||
|
||||
b Lend
|
||||
|
||||
Lneg: cax 9,9,0
|
||||
bdz Lend
|
||||
Lnloop: lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 10,0,6
|
||||
mfmq 7
|
||||
ae 11,7,9
|
||||
l 7,4(3)
|
||||
ae 10,10,0 # propagate cy to new cy_limb
|
||||
sf 8,11,7 # add res_limb
|
||||
a 11,8,11 # invert cy (r11 is junk)
|
||||
bge Ln0
|
||||
cax 10,10,6 # adjust high limb for negative limb from s1
|
||||
Ln0: bdz Lend0
|
||||
lu 0,4(4)
|
||||
stu 8,4(3)
|
||||
cmpi 0,0,0
|
||||
mul 9,0,6
|
||||
mfmq 7
|
||||
ae 11,7,10
|
||||
l 7,4(3)
|
||||
ae 9,9,0 # propagate cy to new cy_limb
|
||||
sf 8,11,7 # add res_limb
|
||||
a 11,8,11 # invert cy (r11 is junk)
|
||||
bge Ln1
|
||||
cax 9,9,6 # adjust high limb for negative limb from s1
|
||||
Ln1: bdn Lnloop
|
||||
b Lend
|
||||
|
||||
Lend0: cal 9,0(10)
|
||||
Lend: st 8,4(3)
|
||||
aze 3,9
|
||||
br
|
@ -1,4 +0,0 @@
|
||||
# The `bare' subdirectory defines some structure for a target-specific
|
||||
# library of functions which are actually implemented in
|
||||
# sysdeps/standalone/CPU/TARGET.
|
||||
bare
|
@ -1,65 +0,0 @@
|
||||
/* Copyright (C) 1991,1994,1996,1997,1998,2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* This file defines the `errno' constants for standalone ARM machines.
|
||||
These constants are essentially arbitrary. */
|
||||
|
||||
#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)
|
||||
# undef __need_Emath
|
||||
# define __Emath_defined 1
|
||||
|
||||
# define EDOM 1
|
||||
# define ERANGE 2
|
||||
#endif
|
||||
|
||||
#ifdef _ERRNO_H
|
||||
# define ENOSYS 3
|
||||
# define EINVAL 4
|
||||
# define ESPIPE 5
|
||||
# define EBADF 6
|
||||
# define ENOMEM 7
|
||||
# define EACCES 8
|
||||
# define ENFILE 9
|
||||
# define EMFILE 10
|
||||
# define ENAMETOOLONG 11 /* File name too long */
|
||||
# define ELOOP 12 /* Too many symbolic links encountered */
|
||||
# define ENOMSG 13 /* No message of desired type */
|
||||
# define E2BIG 14 /* Arg list too long */
|
||||
# define EINTR 15
|
||||
# define EILSEQ 16
|
||||
# define ENOEXEC 17
|
||||
# define ENOENT 18
|
||||
# define EPROTOTYPE 19
|
||||
# define ESRCH 20
|
||||
# define EPERM 21
|
||||
# define ENOTDIR 22
|
||||
# define ESTALE 23
|
||||
# define EISDIR 24
|
||||
# define EOPNOTSUPP 25 /* Operation not supported. */
|
||||
# define ENOTTY 26
|
||||
# define EAGAIN 27
|
||||
# define EIO 28
|
||||
# define ENOSPC 29
|
||||
# define EEXIST 30
|
||||
# define EBUSY 31
|
||||
# define EOVERFLOW 32
|
||||
#endif
|
||||
|
||||
|
||||
/* Function to get address of global `errno' variable. */
|
||||
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
|
@ -1,32 +0,0 @@
|
||||
/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
/* errno has to be defined somewhere, and it might as well be here. */
|
||||
int errno = 0;
|
||||
|
||||
/* The same goes for these magic signal functions. This is a standalone
|
||||
environment so we do nothing. */
|
||||
void _sig_dfl(int sig)
|
||||
{
|
||||
}
|
||||
|
||||
void _sig_ign(int sig)
|
||||
{
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/* Copyright (C) 1991, 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* This file defines the `errno' constants. */
|
||||
|
||||
#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)
|
||||
#undef __need_Emath
|
||||
#define __Emath_defined 1
|
||||
|
||||
# define EDOM 1
|
||||
# define EILSEQ 17
|
||||
# define ERANGE 2
|
||||
#endif
|
||||
|
||||
#ifdef _ERRNO_H
|
||||
# define ENOSYS 3
|
||||
# define EINVAL 4
|
||||
# define ESPIPE 5
|
||||
# define EBADF 6
|
||||
# define ENOMEM 7
|
||||
# define EACCES 8
|
||||
# define ENFILE 9
|
||||
# define EMFILE 10
|
||||
# define ENOMSG 11
|
||||
# define ENAMETOOLONG 12
|
||||
# define ELOOP 13
|
||||
# define E2BIG 15
|
||||
# define EINTR 16
|
||||
# define ENOEXEC 18
|
||||
# define ENOENT 19
|
||||
# define EPROTOTYPE 20
|
||||
# define ESRCH 21
|
||||
# define EPERM 22
|
||||
# define EEXIST 23
|
||||
# define ENOTDIR 24
|
||||
# define ESTALE 25
|
||||
# define ENOTTY 26
|
||||
# define EISDIR 27
|
||||
# define EOPNOTSUPP 28
|
||||
# define EAGAIN 29
|
||||
# define EIO 30
|
||||
# define ENOSPC 31
|
||||
# define EBUSY 32
|
||||
#endif
|
@ -1,66 +0,0 @@
|
||||
/* Copyright (C) 1991, 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil,
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *__curbrk;
|
||||
void *__rorig;
|
||||
void *__rlimit;
|
||||
|
||||
int
|
||||
__brk (inaddr)
|
||||
void *inaddr;
|
||||
{
|
||||
|
||||
if ( ( (void *)inaddr > (void *)__rlimit ) ||
|
||||
( (void *)inaddr < (void *)__rorig ) )
|
||||
return -1;
|
||||
|
||||
__curbrk = inaddr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialization Code for Memory Allocation */
|
||||
|
||||
void *__C_heap_start;
|
||||
int __C_heap_size;
|
||||
|
||||
#ifdef HAVE_GNU_LD
|
||||
static
|
||||
#endif
|
||||
void
|
||||
__NONE_set_memvals (argc, argv, envp)
|
||||
int argc;
|
||||
char **argv;
|
||||
char **envp;
|
||||
{
|
||||
|
||||
__rorig =
|
||||
__curbrk = __C_heap_start;
|
||||
__rlimit = __curbrk + __C_heap_size;
|
||||
|
||||
(void) &__NONE_set_memvals; /* Avoid "defined but not used" warning. */
|
||||
}
|
||||
|
||||
#ifdef HAVE_GNU_LD
|
||||
text_set_element (__libc_subinit, __NONE_set_memvals);
|
||||
#endif
|
||||
|
||||
weak_alias (__brk, brk)
|
@ -1,43 +0,0 @@
|
||||
/* Copyright (C) 1994, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
|
||||
Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil,
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define _STDIO_H
|
||||
#include <bits/stdio_lim.h>
|
||||
#include "filedesc.h"
|
||||
|
||||
/* Close the file descriptor FD. */
|
||||
int
|
||||
__close (fd)
|
||||
int fd;
|
||||
{
|
||||
if ( !__FD_Is_valid( fd ) || !__FD_Table[ fd ].in_use )
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__FD_Table[ fd ].in_use = 0;
|
||||
return 0;
|
||||
}
|
||||
libc_hidden_def (__close)
|
||||
weak_alias (__close, close)
|
@ -1,43 +0,0 @@
|
||||
/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DIRSTREAM_H
|
||||
|
||||
#define _DIRSTREAM_H 1
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
/* Directory stream type.
|
||||
|
||||
The miscellaneous Unix `readdir' implementations read directory data
|
||||
into a buffer and fill in a `struct dirent' copy in the `DIR' object. */
|
||||
|
||||
struct __dirstream
|
||||
{
|
||||
int __fd; /* File descriptor. */
|
||||
|
||||
char *__data; /* Directory block. */
|
||||
size_t __allocation; /* Space allocated for the block. */
|
||||
size_t __offset; /* Current offset into the block. */
|
||||
size_t __size; /* Total valid data in the block. */
|
||||
|
||||
struct dirent __entry; /* Returned by `readdir'. */
|
||||
};
|
||||
|
||||
#endif /* dirstream.h */
|
@ -1,48 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc.
|
||||
Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil,
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/*
|
||||
* This is the file descriptor used by the no OS implementation
|
||||
* of __open, __read, __write, and __close.
|
||||
*/
|
||||
|
||||
#ifndef __FILEDESC_h
|
||||
#define __FILEDESC_h
|
||||
|
||||
#define __need_FOPEN_MAX
|
||||
#include <bits/stdio_lim.h>
|
||||
|
||||
#ifndef __DECLARE_FILE_DESCRIPTORS__
|
||||
#define FILEDESC_EXTERN extern
|
||||
#else
|
||||
#define FILEDESC_EXTERN
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int in_use; /* 1 if in use, 0 otherwise */
|
||||
int flags; /* Flags from open */
|
||||
} __no_os_file_descriptor;
|
||||
|
||||
#define __FD_Is_valid( _fd ) \
|
||||
( (_fd) >= 0 && (_fd) < FOPEN_MAX )
|
||||
|
||||
FILEDESC_EXTERN __no_os_file_descriptor __FD_Table[ FOPEN_MAX ];
|
||||
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
# Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
# On-Line Applications Research Corporation.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
# The GNU C Library 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
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with the GNU C Library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
# 02111-1307 USA.
|
||||
|
||||
ifeq (bare,$(subdir))
|
||||
install-others += $(inst_libdir)/force_cpu386.ld
|
||||
$(inst_libdir)/force_cpu386.ld: $(sysdep_dir)/standalone/i386/target.ld \
|
||||
$(+force)
|
||||
$(do-install)
|
||||
endif
|
@ -1,47 +0,0 @@
|
||||
/* Copyright (C) 1991, 1997, 1999, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This returns control to FORCEbug. */
|
||||
|
||||
void Bsp_cleanup (void);
|
||||
|
||||
/* The function `_exit' should take a status argument and simply
|
||||
terminate program execution, using the low-order 8 bits of the
|
||||
given integer as status. */
|
||||
|
||||
__NORETURN void
|
||||
_exit (status)
|
||||
int status;
|
||||
{
|
||||
/* status is ignored */
|
||||
Bsp_cleanup();
|
||||
}
|
||||
weak_alias (_exit, _Exit)
|
||||
|
||||
#ifdef HAVE_GNU_LD
|
||||
|
||||
#include <gnu-stabs.h>
|
||||
|
||||
stub_warning(_exit);
|
||||
|
||||
#endif /* GNU stabs. */
|
@ -1,42 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
#include "i386.h"
|
||||
|
||||
/* _Board_Initialize()
|
||||
|
||||
This routine initializes the FORCE CPU386 board. */
|
||||
|
||||
void _Console_Initialize (void);
|
||||
|
||||
void
|
||||
_Board_Initialize ()
|
||||
{
|
||||
/*
|
||||
* FORCE documentation incorrectly states that the bus request
|
||||
* level is initialized to 3. It is actually initialized by
|
||||
* FORCEbug to 0.
|
||||
*/
|
||||
|
||||
outport_byte (0x00, 0x3f); /* resets VMEbus request level */
|
||||
|
||||
_Console_Initialize ();
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
#include "i386.h"
|
||||
|
||||
/* Console IO routines for a FORCE CPU386 board. */
|
||||
|
||||
/* Force CPU/386 specific IO addressing
|
||||
*
|
||||
* The following determines whether Port B or the Console should
|
||||
* be used for console I/O. Setting ONE (and only ONE) of these to 1
|
||||
* enables I/O on that port.
|
||||
*
|
||||
* PORT A - DUSCC MC68562 Channel A (*** not supported here ***)
|
||||
* PORT B - DUSCC MC68562 Channel B
|
||||
* PORT C - MFP MC68901 Channel (*** FORCEbug console ***)
|
||||
*/
|
||||
|
||||
#define PORTB 1 /* use port b as console */
|
||||
#define PORTC 0 /* use console port as console */
|
||||
|
||||
#if ( PORTB == 1 )
|
||||
#define TX_STATUS 0x1b6 /* DUSCC General Status Register */
|
||||
#define RX_STATUS 0x1b6 /* DUSCC General Status Register */
|
||||
#define TX_BUFFER 0x1e0 /* DUSCC Transmitter Channel B */
|
||||
#define RX_BUFFER 0x1e8 /* DUSCC Receiver Channel B */
|
||||
#define Is_tx_ready( _status ) ( (_status) & 0x20 )
|
||||
#define Is_rx_ready( _status ) ( (_status) & 0x10 )
|
||||
#endif
|
||||
|
||||
#if ( PORTC == 1 )
|
||||
#define TX_STATUS 0x12c /* MFP Transmit Status Register */
|
||||
#define RX_STATUS 0x12a /* MFP Receive Status Register */
|
||||
#define TX_BUFFER 0x12e /* MFP Transmitter Channel */
|
||||
#define RX_BUFFER 0x12e /* MFP Receiver Channel */
|
||||
#define Is_tx_ready( _status ) ( (_status) & 0x80 )
|
||||
#define Is_rx_ready( _status ) ( (_status) & 0x80 )
|
||||
#endif
|
||||
|
||||
/* _Console_Initialize
|
||||
|
||||
On the Force board the console require some initialization. */
|
||||
|
||||
void
|
||||
_Console_Initialize ()
|
||||
{
|
||||
register unsigned8 ignored;
|
||||
|
||||
/* FORCE technical support mentioned that it may be necessary to
|
||||
read the DUSCC RX_BUFFER port four times to remove all junk.
|
||||
This code is a little more paranoid. */
|
||||
|
||||
inport_byte( RX_BUFFER, ignored );
|
||||
inport_byte( RX_BUFFER, ignored );
|
||||
inport_byte( RX_BUFFER, ignored );
|
||||
inport_byte( RX_BUFFER, ignored );
|
||||
inport_byte( RX_BUFFER, ignored );
|
||||
}
|
||||
|
||||
/* Miscellaneous support for console IO */
|
||||
|
||||
static inline int _Force386_is_rx_ready ()
|
||||
{
|
||||
register unsigned8 status;
|
||||
|
||||
inport_byte( RX_STATUS, status );
|
||||
|
||||
if ( Is_rx_ready( status ) ) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static inline int _Force386_is_tx_ready ()
|
||||
{
|
||||
register unsigned8 status;
|
||||
|
||||
inport_byte( TX_STATUS, status );
|
||||
|
||||
if ( Is_tx_ready( status ) ) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int _Force386_read_data ()
|
||||
{
|
||||
register unsigned8 ch;
|
||||
|
||||
#if ( PORTB == 1 )
|
||||
/* Force example code resets the Channel B Receiver here.
|
||||
* It appears to cause XON's to be lost.
|
||||
*/
|
||||
|
||||
/* outport_byte( RX_STATUS, 0x10 ); */
|
||||
#endif
|
||||
|
||||
inport_byte( RX_BUFFER, ch );
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* _Console_Putc
|
||||
|
||||
This routine transmits a character. It supports XON/XOFF flow control. */
|
||||
|
||||
#define XON 0x11 /* control-Q */
|
||||
#define XOFF 0x13 /* control-S */
|
||||
|
||||
int
|
||||
_Console_Putc (ch)
|
||||
char ch;
|
||||
{
|
||||
register unsigned8 inch;
|
||||
|
||||
while ( !_Force386_is_tx_ready() );
|
||||
|
||||
while ( _Force386_is_rx_ready() == 1 ) { /* must be an XOFF */
|
||||
inch = _Force386_read_data();
|
||||
if ( inch == XOFF )
|
||||
do {
|
||||
while ( _Force386_is_rx_ready() == 0 );
|
||||
inch = _Force386_read_data();
|
||||
} while ( inch != XON );
|
||||
}
|
||||
|
||||
outport_byte( TX_BUFFER, ch );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* _Console_Getc
|
||||
|
||||
This routine reads a character from the UART and returns it. */
|
||||
|
||||
int
|
||||
_Console_Getc (poll)
|
||||
int poll;
|
||||
{
|
||||
if ( poll ) {
|
||||
if ( !_Force386_is_rx_ready() )
|
||||
return -1;
|
||||
else
|
||||
return _Force386_read_data();
|
||||
} else {
|
||||
while ( !_Force386_is_rx_ready() );
|
||||
return _Force386_read_data();
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* This file assists the board independent startup code by
|
||||
* loading the proper segment register values. The values
|
||||
* loaded are dependent on the FORCEBUG.
|
||||
*
|
||||
* NOTE: No stack has been established when this routine
|
||||
* is invoked. It returns by jumping back to the start code.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FORCEBUG loads us into a virtual address space which
|
||||
* really starts at PHYSICAL_ADDRESS_BASE.
|
||||
*
|
||||
*/
|
||||
|
||||
.set PHYSICAL_ADDRESS_BASE, 0x00002000
|
||||
|
||||
/*
|
||||
* At reset time, FORCEBUG normally has the segment selectors preloaded.
|
||||
* If a human resets the instruction pointer, this will not have occurred.
|
||||
* However, no guarantee can be made of the other registers if cs:ip was
|
||||
* modified to restart the program. Because of this, the BSP reloads all
|
||||
* segment registers (except cs) with the values they have following
|
||||
* a reset.
|
||||
*/
|
||||
|
||||
|
||||
.set RESET_SS, 0x40 # initial value of stack segment register
|
||||
.set RESET_DS, 0x40 # initial value of data segment register
|
||||
.set RESET_ES, 0x40 # initial value of extra segment register
|
||||
.set RESET_FS, 0x40 # initial value of "f" segment register
|
||||
.set RESET_GS, 0x30 # initial value of "g" segment register
|
||||
|
||||
|
||||
#define LOAD_SEGMENTS(_value,_segreg) \
|
||||
movw $_value##,%ax ; \
|
||||
movw %ax,##_segreg
|
||||
|
||||
|
||||
.global _load_segments
|
||||
|
||||
.global _establish_stack
|
||||
|
||||
_load_segments:
|
||||
|
||||
LOAD_SEGMENTS( RESET_SS, %ss )
|
||||
LOAD_SEGMENTS( RESET_DS, %ds )
|
||||
LOAD_SEGMENTS( RESET_ES, %es )
|
||||
LOAD_SEGMENTS( RESET_FS, %fs )
|
||||
LOAD_SEGMENTS( RESET_GS, %gs )
|
||||
|
||||
jmp _establish_stack # return to the bsp entry code
|
||||
|
||||
.global _return_to_monitor
|
||||
_return_to_monitor:
|
||||
|
||||
movb $0,%al
|
||||
int $0x20 # restart FORCEbug
|
||||
jmp start # FORCEbug does not reset PC
|
||||
|
||||
.data
|
||||
|
||||
.global _Do_Load_IDT
|
||||
_Do_Load_IDT: .byte 1
|
||||
|
||||
.global _Do_Load_GDT
|
||||
_Do_Load_GDT: .byte 0
|
@ -1,58 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* This file contains directives for the GNU linker which are specific
|
||||
to the FORCE CPU386 board. */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : org = 0x0, l = 1M
|
||||
}
|
||||
|
||||
/* This value is also when the space is allocated. If you change
|
||||
this one, change the other one!!! */
|
||||
|
||||
heap_size = 0x20000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x0 :
|
||||
{
|
||||
_text_start = ABSOLUTE(.) ;
|
||||
*(.text)
|
||||
_etext = ALIGN( 0x10 ) ;
|
||||
}
|
||||
.data ADDR( .text ) + SIZEOF( .text ):
|
||||
{
|
||||
_data_start = . ;
|
||||
*(.data)
|
||||
_edata = ALIGN( 0x10 ) ;
|
||||
}
|
||||
.bss ADDR( .data ) + SIZEOF( .data ):
|
||||
{
|
||||
_bss_start = . ;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
heap_memory = .;
|
||||
. += 0x20000;
|
||||
_end = . ;
|
||||
__end = . ;
|
||||
}
|
||||
}
|
@ -1,326 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* i386.h
|
||||
*
|
||||
* This file contains macros which are used to access i80386
|
||||
* registers which are not addressable by C. This file contains
|
||||
* functions which are useful to those developing target
|
||||
* specific support routines.
|
||||
*/
|
||||
|
||||
#ifndef i386_h__
|
||||
#define i386_h__
|
||||
|
||||
typedef unsigned char unsigned8;
|
||||
typedef unsigned short unsigned16;
|
||||
typedef unsigned int unsigned32;
|
||||
|
||||
#define disable_intr( isrlevel ) \
|
||||
{ (isrlevel) = 0; \
|
||||
asm volatile ( "pushf ; \
|
||||
pop %0 ; \
|
||||
cli " \
|
||||
: "=r" ((isrlevel)) : "0" ((isrlevel)) ); \
|
||||
}
|
||||
|
||||
|
||||
#define enable_intr( isrlevel ) \
|
||||
{ asm volatile ( "push %0 ; \
|
||||
popf " \
|
||||
: "=r" ((isrlevel)) : "0" ((isrlevel)) ); \
|
||||
}
|
||||
|
||||
#define delay( _microseconds ) \
|
||||
{ \
|
||||
unsigned32 _counter; \
|
||||
\
|
||||
_counter = (_microseconds); \
|
||||
\
|
||||
asm volatile ( "0: nop;" \
|
||||
" mov %0,%0 ;" \
|
||||
" loop 0" : "=c" (_counter) \
|
||||
: "0" (_counter) \
|
||||
); \
|
||||
\
|
||||
}
|
||||
|
||||
/* segment access functions */
|
||||
|
||||
static inline unsigned16 get_cs()
|
||||
{
|
||||
register unsigned16 segment = 0;
|
||||
|
||||
asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
static inline unsigned16 get_ds()
|
||||
{
|
||||
register unsigned16 segment = 0;
|
||||
|
||||
asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
static inline unsigned16 get_es()
|
||||
{
|
||||
register unsigned16 segment = 0;
|
||||
|
||||
asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
static inline unsigned16 get_ss()
|
||||
{
|
||||
register unsigned16 segment = 0;
|
||||
|
||||
asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
static inline unsigned16 get_fs()
|
||||
{
|
||||
register unsigned16 segment = 0;
|
||||
|
||||
asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
static inline unsigned16 get_gs()
|
||||
{
|
||||
register unsigned16 segment = 0;
|
||||
|
||||
asm volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
/* i80x86 I/O instructions */
|
||||
|
||||
#define outport_byte( _port, _value ) \
|
||||
{ register unsigned16 __port = _port; \
|
||||
register unsigned8 __value = _value; \
|
||||
\
|
||||
asm volatile ( "outb %0,%1" : "=a" (__value), "=d" (__port) \
|
||||
: "0" (__value), "1" (__port) \
|
||||
); \
|
||||
}
|
||||
|
||||
#define outport_word( _port, _value ) \
|
||||
{ register unsigned16 __port = _port; \
|
||||
register unsigned16 __value = _value; \
|
||||
\
|
||||
asm volatile ( "outw %0,%1" : "=a" (__value), "=d" (__port) \
|
||||
: "0" (__value), "1" (__port) \
|
||||
); \
|
||||
}
|
||||
|
||||
#define outport_long( _port, _value ) \
|
||||
{ register unsigned16 __port = _port; \
|
||||
register unsigned32 __value = _value; \
|
||||
\
|
||||
asm volatile ( "outl %0,%1" : "=a" (__value), "=d" (__port) \
|
||||
: "0" (__value), "1" (__port) \
|
||||
); \
|
||||
}
|
||||
|
||||
#define inport_byte( _port, _value ) \
|
||||
{ register unsigned16 __port = _port; \
|
||||
register unsigned8 __value = 0; \
|
||||
\
|
||||
asm volatile ( "inb %1,%0" : "=a" (__value), "=d" (__port) \
|
||||
: "0" (__value), "1" (__port) \
|
||||
); \
|
||||
_value = __value; \
|
||||
}
|
||||
|
||||
#define inport_word( _port, _value ) \
|
||||
{ register unsigned16 __port = _port; \
|
||||
register unsigned16 __value = 0; \
|
||||
\
|
||||
asm volatile ( "inw %1,%0" : "=a" (__value), "=d" (__port) \
|
||||
: "0" (__value), "1" (__port) \
|
||||
); \
|
||||
_value = __value; \
|
||||
}
|
||||
|
||||
#define inport_long( _port, _value ) \
|
||||
{ register unsigned16 __port = _port; \
|
||||
register unsigned32 __value = 0; \
|
||||
\
|
||||
asm volatile ( "inl %1,%0" : "=a" (__value), "=d" (__port) \
|
||||
: "0" (__value), "1" (__port) \
|
||||
); \
|
||||
_value = __value; \
|
||||
}
|
||||
|
||||
/* structures */
|
||||
|
||||
/* See Chapter 5 - Memory Management in i386 manual */
|
||||
|
||||
struct GDT_slot {
|
||||
unsigned16 limit_0_15;
|
||||
unsigned16 base_0_15;
|
||||
unsigned8 base_16_23;
|
||||
unsigned8 type_dt_dpl_p;
|
||||
unsigned8 limit_16_19_granularity;
|
||||
unsigned8 base_24_31;
|
||||
};
|
||||
|
||||
/* See Chapter 9 - Exceptions and Interrupts in i386 manual
|
||||
*
|
||||
* NOTE: This is the IDT entry for interrupt gates ONLY.
|
||||
*/
|
||||
|
||||
struct IDT_slot {
|
||||
unsigned16 offset_0_15;
|
||||
unsigned16 segment_selector;
|
||||
unsigned8 reserved;
|
||||
unsigned8 p_dpl;
|
||||
unsigned16 offset_16_31;
|
||||
};
|
||||
|
||||
struct DTR_load_save_format {
|
||||
unsigned16 limit;
|
||||
unsigned32 physical_address;
|
||||
};
|
||||
|
||||
/* variables */
|
||||
|
||||
extern struct IDT_slot Interrupt_descriptor_table[ 256 ];
|
||||
extern struct GDT_slot Global_descriptor_table[ 8192 ];
|
||||
|
||||
/* functions */
|
||||
|
||||
#ifdef CPU_INITIALIZE
|
||||
#define EXTERN
|
||||
#else
|
||||
#undef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
void *Logical_to_physical(
|
||||
unsigned16 segment,
|
||||
void *address
|
||||
);
|
||||
|
||||
void *Physical_to_logical(
|
||||
unsigned16 segment,
|
||||
void *address
|
||||
);
|
||||
|
||||
/* complicated static inline functions */
|
||||
|
||||
#define get_GDTR( _gdtr_address ) \
|
||||
{ \
|
||||
void *_gdtr = (_gdtr_address); \
|
||||
\
|
||||
asm volatile( "sgdt (%0)" : "=r" (_gdtr) : "0" (_gdtr) ); \
|
||||
}
|
||||
|
||||
#define get_GDT_slot( _gdtr_base, _segment, _slot_address ) \
|
||||
{ \
|
||||
register unsigned32 _gdt_slot = (_gdtr_base) + (_segment); \
|
||||
register volatile void *_slot = (_slot_address); \
|
||||
register unsigned32 _temporary = 0; \
|
||||
\
|
||||
asm volatile( "movl %%gs:(%0),%1 ; \
|
||||
movl %1,(%2) ; \
|
||||
movl %%gs:4(%0),%1 ; \
|
||||
movl %1,4(%2)" \
|
||||
: "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \
|
||||
: "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \
|
||||
); \
|
||||
}
|
||||
|
||||
#define set_GDT_slot( _gdtr_base, _segment, _slot_address ) \
|
||||
{ \
|
||||
register unsigned32 _gdt_slot = (_gdtr_base) + (_segment); \
|
||||
register volatile void *_slot = (_slot_address); \
|
||||
register unsigned32 _temporary = 0; \
|
||||
\
|
||||
asm volatile( "movl (%2),%1 ; \
|
||||
movl %1,%%gs:(%0) ; \
|
||||
movl 4(%2),%1 ; \
|
||||
movl %1,%%gs:4(%0) \
|
||||
" \
|
||||
: "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \
|
||||
: "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \
|
||||
); \
|
||||
}
|
||||
|
||||
static inline void set_segment(
|
||||
unsigned16 segment,
|
||||
unsigned32 base,
|
||||
unsigned32 limit
|
||||
)
|
||||
{
|
||||
struct DTR_load_save_format gdtr;
|
||||
volatile struct GDT_slot Gdt_slot;
|
||||
volatile struct GDT_slot *gdt_slot = &Gdt_slot;
|
||||
unsigned16 tmp_segment = 0;
|
||||
unsigned32 limit_adjusted;
|
||||
|
||||
|
||||
/* load physical address of the GDT */
|
||||
|
||||
get_GDTR( &gdtr );
|
||||
|
||||
gdt_slot->type_dt_dpl_p = 0x92; /* present, dpl=0, */
|
||||
/* application=1, */
|
||||
/* type=data read/write */
|
||||
gdt_slot->limit_16_19_granularity = 0x40; /* 32 bit segment */
|
||||
|
||||
limit_adjusted = limit;
|
||||
if ( limit > 4095 ) {
|
||||
gdt_slot->limit_16_19_granularity |= 0x80; /* set granularity bit */
|
||||
limit_adjusted /= 4096;
|
||||
}
|
||||
|
||||
gdt_slot->limit_16_19_granularity |= (limit_adjusted >> 16) & 0xff;
|
||||
gdt_slot->limit_0_15 = limit_adjusted & 0xffff;
|
||||
|
||||
gdt_slot->base_0_15 = base & 0xffff;
|
||||
gdt_slot->base_16_23 = (base >> 16) & 0xff;
|
||||
gdt_slot->base_24_31 = (base >> 24);
|
||||
|
||||
set_GDT_slot( gdtr.physical_address, segment, gdt_slot );
|
||||
|
||||
/* Now, reload all segment registers so the limit takes effect. */
|
||||
|
||||
asm volatile( "movw %%ds,%0 ; movw %0,%%ds\n"
|
||||
"movw %%es,%0 ; movw %0,%%es\n"
|
||||
"movw %%fs,%0 ; movw %0,%%fs\n"
|
||||
"movw %%gs,%0 ; movw %0,%%gs\n"
|
||||
"movw %%ss,%0 ; movw %0,%%ss"
|
||||
: "=r" (tmp_segment)
|
||||
: "0" (tmp_segment)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
@ -1,338 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* entry.s
|
||||
*
|
||||
* This file contains the entry point for the application.
|
||||
* The name of this entry point is compiler dependent.
|
||||
* It jumps to the BSP which is responsible for performing
|
||||
* all initialization.
|
||||
*
|
||||
*/
|
||||
|
||||
.data
|
||||
.global _Do_Load_IDT
|
||||
.global _Do_Load_GDT
|
||||
|
||||
.text
|
||||
.global start # GNU default entry point
|
||||
.global _establish_stack
|
||||
|
||||
.global _bsp_start
|
||||
.global _load_segments
|
||||
.global __exit
|
||||
|
||||
start:
|
||||
nop
|
||||
cli # DISABLE INTERRUPTS!!!
|
||||
#
|
||||
# Load the segment registers
|
||||
#
|
||||
# NOTE: Upon return, gs will contain the segment descriptor for
|
||||
# a segment which maps directly to all of physical memory.
|
||||
#
|
||||
jmp _load_segments # load board dependent segments
|
||||
|
||||
#
|
||||
# Set up the stack
|
||||
#
|
||||
|
||||
_establish_stack:
|
||||
|
||||
movl $stack_end,%esp # set stack pointer
|
||||
movl $stack_end,%ebp # set base pointer
|
||||
|
||||
#
|
||||
# Zero out the BSS segment
|
||||
#
|
||||
zero_bss:
|
||||
cld # make direction flag count up
|
||||
movl $_end,%ecx # find end of .bss
|
||||
movl $_bss_start,%edi # edi = beginning of .bss
|
||||
subl %edi,%ecx # ecx = size of .bss in bytes
|
||||
shrl $2,%ecx # size of .bss in longs
|
||||
xorl %eax,%eax # value to clear out memory
|
||||
repne # while ecx != 0
|
||||
stosl # clear a long in the bss
|
||||
|
||||
#
|
||||
# Set the C heap information for malloc
|
||||
#
|
||||
movl $heap_size,___C_heap_size # set ___C_heap_size
|
||||
movl $heap_memory,___C_heap_start # set ___C_heap_start
|
||||
|
||||
#
|
||||
# Copy the Global Descriptor Table to our space
|
||||
#
|
||||
|
||||
sgdt _Original_GDTR # save original GDT
|
||||
movzwl _Original_GDTR_limit,%ecx # size of GDT in bytes; limit
|
||||
# is 8192 entries * 8 bytes per
|
||||
|
||||
# make ds:esi point to the original GDT
|
||||
|
||||
movl _Original_GDTR_base,%esi
|
||||
push %ds # save ds
|
||||
movw %gs,%ax
|
||||
movw %ax,%ds
|
||||
|
||||
# make es:edi point to the new (our copy) GDT
|
||||
movl $_Global_descriptor_table,%edi
|
||||
|
||||
rep
|
||||
movsb # copy the GDT (ds:esi -> es:edi)
|
||||
|
||||
pop %ds # restore ds
|
||||
|
||||
# Build and load new contents of GDTR
|
||||
movw _Original_GDTR_limit,%ecx # set new limit
|
||||
movw %cx,_New_GDTR_limit
|
||||
|
||||
push $_Global_descriptor_table
|
||||
push %es
|
||||
call _Logical_to_physical
|
||||
addl $6,%esp
|
||||
movl %eax,_New_GDTR_base # set new base
|
||||
|
||||
cmpb $0,_Do_Load_GDT # Should the new GDT be loaded?
|
||||
je no_gdt_load # NO, then branch
|
||||
lgdt _New_GDTR # load the new GDT
|
||||
no_gdt_load:
|
||||
|
||||
#
|
||||
# Copy the Interrupt Descriptor Table to our space
|
||||
#
|
||||
|
||||
sidt _Original_IDTR # save original IDT
|
||||
movzwl _Original_IDTR_limit,%ecx # size of IDT in bytes; limit
|
||||
# is 256 entries * 8 bytes per
|
||||
|
||||
|
||||
# make ds:esi point to the original IDT
|
||||
movl _Original_IDTR_base,%esi
|
||||
|
||||
push %ds # save ds
|
||||
movw %gs,%ax
|
||||
movw %ax,%ds
|
||||
|
||||
# make es:edi point to the new (our copy) IDT
|
||||
movl $_Interrupt_descriptor_table,%edi
|
||||
|
||||
rep
|
||||
movsb # copy the IDT (ds:esi -> es:edi)
|
||||
pop %ds # restore ds
|
||||
|
||||
# Build and load new contents of IDTR
|
||||
movw _Original_IDTR_limit,%ecx # set new limit
|
||||
movw %cx,_New_IDTR_limit
|
||||
|
||||
push $_Interrupt_descriptor_table
|
||||
push %es
|
||||
call _Logical_to_physical
|
||||
addl $6,%esp
|
||||
movl %eax,_New_IDTR_base # set new base
|
||||
|
||||
cmpb $0,_Do_Load_IDT # Should the new IDT be loaded?
|
||||
je no_idt_load # NO, then branch
|
||||
lidt _New_IDTR # load the new IDT
|
||||
no_idt_load:
|
||||
|
||||
#
|
||||
# Initialize the i387.
|
||||
#
|
||||
# Using the NO WAIT form of the instruction insures that if
|
||||
# it is not present the board will not lock up or get an
|
||||
# exception.
|
||||
#
|
||||
|
||||
fninit # MUST USE NO-WAIT FORM
|
||||
|
||||
call __Board_Initialize # initialize the board
|
||||
|
||||
pushl $0 # envp = NULL
|
||||
pushl $0 # argv = NULL
|
||||
pushl $0 # argc = NULL
|
||||
call ___libc_init # initialize the library and
|
||||
# call main
|
||||
addl $12,%esp
|
||||
|
||||
pushl $0 # argc = NULL
|
||||
call __exit # call the Board specific exit
|
||||
addl $4,%esp
|
||||
|
||||
#
|
||||
# Clean up
|
||||
#
|
||||
|
||||
|
||||
.global _Bsp_cleanup
|
||||
|
||||
.global _return_to_monitor
|
||||
|
||||
_Bsp_cleanup:
|
||||
cmpb $0,_Do_Load_IDT # Was the new IDT loaded?
|
||||
je no_idt_restore # NO, then branch
|
||||
lidt _Original_IDTR # restore the new IDT
|
||||
no_idt_restore:
|
||||
|
||||
cmpb $0,_Do_Load_GDT # Was the new GDT loaded?
|
||||
je no_gdt_restore # NO, then branch
|
||||
lgdt _Original_GDTR # restore the new GDT
|
||||
no_gdt_restore:
|
||||
jmp _return_to_monitor
|
||||
|
||||
#
|
||||
# void *Logical_to_physical(
|
||||
# rtems_unsigned16 segment,
|
||||
# void *address
|
||||
# );
|
||||
#
|
||||
# Returns thirty-two bit physical address for segment:address.
|
||||
#
|
||||
|
||||
.global _Logical_to_physical
|
||||
|
||||
.set SEGMENT_ARG, 4
|
||||
.set ADDRESS_ARG, 8
|
||||
|
||||
_Logical_to_physical:
|
||||
|
||||
xorl %eax,%eax # clear eax
|
||||
movzwl SEGMENT_ARG(%esp),%ecx # ecx = segment value
|
||||
movl $_Global_descriptor_table,%edx # edx = address of our GDT
|
||||
addl %ecx,%edx # edx = address of desired entry
|
||||
movb 7(%edx),%ah # ah = base 31:24
|
||||
movb 4(%edx),%al # al = base 23:16
|
||||
shll $16,%eax # move ax into correct bits
|
||||
movw 2(%edx),%ax # ax = base 0:15
|
||||
movl ADDRESS_ARG(%esp),%ecx # ecx = address to convert
|
||||
addl %eax,%ecx # ecx = physical address equivalent
|
||||
movl %ecx,%eax # eax = ecx
|
||||
ret
|
||||
|
||||
#
|
||||
# void *Physical_to_logical(
|
||||
# rtems_unsigned16 segment,
|
||||
# void *address
|
||||
# );
|
||||
#
|
||||
# Returns thirty-two bit physical address for segment:address.
|
||||
#
|
||||
|
||||
.global _Physical_to_logical
|
||||
|
||||
#.set SEGMENT_ARG, 4
|
||||
#.set ADDRESS_ARG, 8 -- use sets from above
|
||||
|
||||
_Physical_to_logical:
|
||||
|
||||
xorl %eax,%eax # clear eax
|
||||
movzwl SEGMENT_ARG(%esp),%ecx # ecx = segment value
|
||||
movl $_Global_descriptor_table,%edx # edx = address of our GDT
|
||||
addl %ecx,%edx # edx = address of desired entry
|
||||
movb 7(%edx),%ah # ah = base 31:24
|
||||
movb 4(%edx),%al # al = base 23:16
|
||||
shll $16,%eax # move ax into correct bits
|
||||
movw 2(%edx),%ax # ax = base 0:15
|
||||
movl ADDRESS_ARG(%esp),%ecx # ecx = address to convert
|
||||
subl %eax,%ecx # ecx = logical address equivalent
|
||||
movl %ecx,%eax # eax = ecx
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* Data Declarations. Start with a macro which helps declare space.
|
||||
*/
|
||||
|
||||
.bss
|
||||
|
||||
#define DECLARE_SPACE(_name,_space,_align) \
|
||||
.globl _name ; \
|
||||
.align _align ; \
|
||||
_name##: .space _space
|
||||
|
||||
#define DECLARE_LABEL(_name) \
|
||||
.globl _name ; \
|
||||
_name##:
|
||||
|
||||
#define DECLARE_PTR(_name) DECLARE_SPACE(_name,4,2)
|
||||
#define DECLARE_U32(_name) DECLARE_SPACE(_name,4,2)
|
||||
#define DECLARE_U16(_name) DECLARE_SPACE(_name,2,1)
|
||||
|
||||
/*
|
||||
* Require environment stuff
|
||||
*/
|
||||
|
||||
DECLARE_LABEL(_environ)
|
||||
DECLARE_PTR(environ)
|
||||
|
||||
DECLARE_LABEL(_errno)
|
||||
DECLARE_U32(errno)
|
||||
|
||||
/*
|
||||
* Miscellaneous Variables used to restore the CPU state.
|
||||
*
|
||||
* Start with a macro to declare the space for the contents of
|
||||
* a Descriptor Table register.
|
||||
*/
|
||||
|
||||
#define DECLARE_DTR_SPACE(_name) \
|
||||
.global _name ; \
|
||||
.align 4 ; \
|
||||
_name##: ; \
|
||||
_name##_limit: .space 2 ; \
|
||||
_name##_base: .space 4
|
||||
|
||||
DECLARE_SPACE(_Interrupt_descriptor_table,256*8,4)
|
||||
DECLARE_SPACE(_Global_descriptor_table,8192*8,4)
|
||||
|
||||
DECLARE_DTR_SPACE(_Original_IDTR)
|
||||
DECLARE_DTR_SPACE(_New_IDTR)
|
||||
DECLARE_DTR_SPACE(_Original_GDTR)
|
||||
DECLARE_DTR_SPACE(_New_GDTR)
|
||||
|
||||
DECLARE_SPACE(_Physical_base_of_ds,4,4)
|
||||
DECLARE_SPACE(_Physical_base_of_cs,4,4)
|
||||
|
||||
/*
|
||||
* Stack Size and Space
|
||||
*/
|
||||
|
||||
.set stack_size, 0x20000
|
||||
|
||||
DECLARE_SPACE(stack_memory,stack_size,4)
|
||||
DECLARE_LABEL(stack_end)
|
@ -1,206 +0,0 @@
|
||||
/* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* i960ca.h
|
||||
*
|
||||
* This file contains macros which are used to access i80960CA
|
||||
* registers which are not addressable by C. The functions
|
||||
* in this file should be useful to the developer of target
|
||||
* specific code.
|
||||
*/
|
||||
|
||||
#ifndef i960ca_h__
|
||||
#define i960ca_h__
|
||||
|
||||
typedef unsigned char unsigned8;
|
||||
typedef unsigned short unsigned16;
|
||||
typedef unsigned int unsigned32;
|
||||
|
||||
/*
|
||||
* Intel i80960CA Processor Control Block
|
||||
*/
|
||||
|
||||
struct i80960ca_prcb {
|
||||
unsigned32 *fault_tbl; /* fault table base address */
|
||||
struct i80960ca_ctltbl
|
||||
*control_tbl; /* control table base address */
|
||||
unsigned32 initial_ac; /* AC register initial value */
|
||||
unsigned32 fault_config; /* fault configuration word */
|
||||
void *intr_tbl; /* interrupt table base address */
|
||||
void *sys_proc_tbl; /* system procedure table */
|
||||
/* base address */
|
||||
unsigned32 reserved; /* reserved */
|
||||
unsigned32 *intr_stack; /* interrupt stack pointer */
|
||||
unsigned32 ins_cache_cfg; /* instruction cache */
|
||||
/* configuration word */
|
||||
unsigned32 reg_cache_cfg; /* register cache */
|
||||
/* configuration word */
|
||||
};
|
||||
|
||||
/*
|
||||
* Intel i80960CA Control Table
|
||||
*/
|
||||
|
||||
struct i80960ca_ctltbl {
|
||||
/* Control Group 0 */
|
||||
unsigned32 ipb0; /* IP breakpoint 0 */
|
||||
unsigned32 ipb1; /* IP breakpoint 1 */
|
||||
unsigned32 dab0; /* data address breakpoint 0 */
|
||||
unsigned32 dab1; /* data address breakpoint 1 */
|
||||
/* Control Group 1 */
|
||||
unsigned32 imap0; /* interrupt map 0 */
|
||||
unsigned32 imap1; /* interrupt map 1 */
|
||||
unsigned32 imap2; /* interrupt map 2 */
|
||||
unsigned32 icon; /* interrupt control */
|
||||
/* Control Group 2 */
|
||||
unsigned32 mcon0; /* memory region 0 configuration */
|
||||
unsigned32 mcon1; /* memory region 1 configuration */
|
||||
unsigned32 mcon2; /* memory region 2 configuration */
|
||||
unsigned32 mcon3; /* memory region 3 configuration */
|
||||
/* Control Group 3 */
|
||||
unsigned32 mcon4; /* memory region 4 configuration */
|
||||
unsigned32 mcon5; /* memory region 5 configuration */
|
||||
unsigned32 mcon6; /* memory region 6 configuration */
|
||||
unsigned32 mcon7; /* memory region 7 configuration */
|
||||
/* Control Group 4 */
|
||||
unsigned32 mcon8; /* memory region 8 configuration */
|
||||
unsigned32 mcon9; /* memory region 9 configuration */
|
||||
unsigned32 mcon10; /* memory region 10 configuration */
|
||||
unsigned32 mcon11; /* memory region 11 configuration */
|
||||
/* Control Group 5 */
|
||||
unsigned32 mcon12; /* memory region 12 configuration */
|
||||
unsigned32 mcon13; /* memory region 13 configuration */
|
||||
unsigned32 mcon14; /* memory region 14 configuration */
|
||||
unsigned32 mcon15; /* memory region 15 configuration */
|
||||
/* Control Group 6 */
|
||||
unsigned32 bpcon; /* breakpoint control */
|
||||
unsigned32 tc; /* trace control */
|
||||
unsigned32 bcon; /* bus configuration control */
|
||||
unsigned32 reserved; /* reserved */
|
||||
};
|
||||
|
||||
#define disable_intr( oldlevel ) \
|
||||
{ (oldlevel) = 0x1f0000; \
|
||||
asm volatile ( "modpc 0,%1,%1" \
|
||||
: "=d" ((oldlevel)) \
|
||||
: "0" ((oldlevel)) ); \
|
||||
}
|
||||
|
||||
#define enable_intr( oldlevel ) \
|
||||
{ unsigned32 _mask = 0x1f0000; \
|
||||
asm volatile ( "modpc 0,%0,%1" \
|
||||
: "=d" (_mask), "=d" ((oldlevel)) \
|
||||
: "0" (_mask), "1" ((oldlevel)) ); \
|
||||
}
|
||||
|
||||
#define flash_intr( oldlevel ) \
|
||||
{ unsigned32 _mask = 0x1f0000; \
|
||||
asm volatile ( "modpc 0,%0,%1 ; \
|
||||
mov %0,%1 ; \
|
||||
modpc 0,%0,%1" \
|
||||
: "=d" (_mask), "=d" ((oldlevel)) \
|
||||
: "0" (_mask), "1" ((oldlevel)) ); \
|
||||
}
|
||||
|
||||
#define atomic_modify( mask, addr, prev ) \
|
||||
{ register unsigned32 _mask = (mask); \
|
||||
register unsigned32 *_addr = (unsigned32 *)(addr); \
|
||||
asm volatile( "atmod %0,%1,%1" \
|
||||
: "=d" (_addr), "=d" (_mask) \
|
||||
: "0" (_addr), "1" (_mask) ); \
|
||||
(prev) = _mask; \
|
||||
}
|
||||
|
||||
#define delay( microseconds ) \
|
||||
{ register unsigned32 _delay=(microseconds); \
|
||||
register unsigned32 _tmp; \
|
||||
asm volatile( "delay0: \
|
||||
remo 3,31,%0 ; \
|
||||
cmpo 0,%0 ; \
|
||||
subo 1,%1,%1 ; \
|
||||
cmpobne.t 0,%1,delay0 " \
|
||||
: "=d" (_tmp), "=d" (_delay) \
|
||||
: "0" (_tmp), "1" (_delay) ); \
|
||||
}
|
||||
|
||||
#define enable_tracing() \
|
||||
{ register unsigned32 _pc = 0x1; \
|
||||
asm volatile( "modpc 0,%0,%0" : "=d" (_pc) : "0" (_pc) ); \
|
||||
}
|
||||
|
||||
#define unmask_intr( xint ) \
|
||||
{ register unsigned32 _mask= (1<<(xint)); \
|
||||
asm volatile( "or sf1,%0,sf1" : "=d" (_mask) : "0" (_mask) ); \
|
||||
}
|
||||
|
||||
#define mask_intr( xint ) \
|
||||
{ register unsigned32 _mask= (1<<(xint)); \
|
||||
asm volatile( "andnot %0,sf1,sf1" : "=d" (_mask) : "0" (_mask) ); \
|
||||
}
|
||||
|
||||
#define clear_intr( xint ) \
|
||||
{ register unsigned32 _xint=(xint); \
|
||||
asm volatile( "loop_til_cleared:" \
|
||||
" clrbit %0,sf0,sf0 ;" \
|
||||
" bbs %0,sf0,loop_til_cleared" \
|
||||
: "=d" (_xint) : "0" (_xint) ); \
|
||||
}
|
||||
|
||||
#define reload_ctl_group( group ) \
|
||||
{ register int _cmd = ((group)|0x400) ; \
|
||||
asm volatile( "sysctl %0,%0,%0" : "=d" (_cmd) : "0" (_cmd) ); \
|
||||
}
|
||||
|
||||
#define cause_intr( intr ) \
|
||||
{ register int _intr = (intr); \
|
||||
asm volatile( "sysctl %0,%0,%0" : "=d" (_intr) : "0" (_intr) ); \
|
||||
}
|
||||
|
||||
#define soft_reset( prcb ) \
|
||||
{ register struct i80960ca_prcb *_prcb = (prcb); \
|
||||
register unsigned32 *_next=0; \
|
||||
register unsigned32 _cmd = 0x30000; \
|
||||
asm volatile( "lda next,%1; \
|
||||
sysctl %0,%1,%2; \
|
||||
next: mov g0,g0" \
|
||||
: "=d" (_cmd), "=d" (_next), "=d" (_prcb) \
|
||||
: "0" (_cmd), "1" (_next), "2" (_prcb) ); \
|
||||
}
|
||||
|
||||
static inline unsigned32 pend_intrs()
|
||||
{ register unsigned32 _intr=0;
|
||||
asm volatile( "mov sf0,%0" : "=d" (_intr) : "0" (_intr) );
|
||||
return ( _intr );
|
||||
}
|
||||
|
||||
static inline unsigned32 mask_intrs()
|
||||
{ register unsigned32 _intr=0;
|
||||
asm volatile( "mov sf1,%0" : "=d" (_intr) : "0" (_intr) );
|
||||
return( _intr );
|
||||
}
|
||||
|
||||
static inline unsigned32 get_fp()
|
||||
{ register unsigned32 _fp=0;
|
||||
asm volatile( "mov fp,%0" : "=d" (_fp) : "0" (_fp) );
|
||||
return ( _fp );
|
||||
}
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
@ -1,24 +0,0 @@
|
||||
# Copyright (C) 1993, 1997 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
# On-Line Applications Research Corporation.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
# The GNU C Library 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
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with the GNU C Library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
# 02111-1307 USA.
|
||||
|
||||
|
||||
# The nindy960 support has only been tested on the following boards:
|
||||
#
|
||||
# + Cyclone CVME961 VMEbus single board computer.
|
@ -1,55 +0,0 @@
|
||||
/* Copyright (C) 1991, 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* The function `_exit' should take a status argument and simply
|
||||
terminate program execution, using the low-order 8 bits of the
|
||||
given integer as status. */
|
||||
|
||||
/* This returns control to Nindy. */
|
||||
/* XXX where is __NORETURN ? */
|
||||
__NORETURN void
|
||||
_exit (status)
|
||||
int status;
|
||||
{
|
||||
/* status is ignored */
|
||||
|
||||
asm volatile( "mov 0,g0; \
|
||||
fmark ; \
|
||||
syncf ; \
|
||||
.word 0xfeedface ; \
|
||||
bx start" : : );
|
||||
/* The constant 0xfeedface is a magic word for break which
|
||||
* is defined by NINDY. The branch extended restarts the
|
||||
* application if the user types "go".
|
||||
*/
|
||||
}
|
||||
weak_alias (_exit, _Exit)
|
||||
|
||||
|
||||
#ifdef HAVE_GNU_LD
|
||||
|
||||
#include <gnu-stabs.h>
|
||||
|
||||
stub_warning(_exit);
|
||||
|
||||
#endif /* GNU stabs. */
|
@ -1,64 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
#include "i960ca.h"
|
||||
|
||||
/* _Board_Initialize()
|
||||
|
||||
This routine initializes the board.
|
||||
|
||||
NOTE: Only tested on a Cyclone CVME961 but should be OK on any i960ca board. */
|
||||
|
||||
void
|
||||
_Board_Initialize ()
|
||||
{
|
||||
struct i80960ca_prcb *prcb; /* ptr to processor control block */
|
||||
struct i80960ca_ctltbl *ctl_tbl; /* ptr to control table */
|
||||
|
||||
static inline struct i80960ca_prcb *get_prcb()
|
||||
{ register struct i80960ca_prcb *_prcb = 0;
|
||||
asm volatile( "calls 5; \
|
||||
mov g0,%0" \
|
||||
: "=d" (_prcb) \
|
||||
: "0" (_prcb) );
|
||||
return ( _prcb );
|
||||
}
|
||||
|
||||
prcb = get_prcb ();
|
||||
ctl_tbl = prcb->control_tbl;
|
||||
|
||||
/* The following configures the data breakpoint (which must be set
|
||||
* before this is executed) to break on writes only.
|
||||
*/
|
||||
|
||||
ctl_tbl->bpcon &= ~0x00cc0000;
|
||||
reload_ctl_group (6);
|
||||
|
||||
/* bit 31 of the Register Cache Control can be set to
|
||||
* enable an alternative caching algorithm. It does
|
||||
* not appear to help our applications.
|
||||
*/
|
||||
|
||||
/* Configure Number of Register Caches */
|
||||
|
||||
prcb->reg_cache_cfg = 8;
|
||||
soft_reset (prcb);
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
#include "i960ca.h"
|
||||
|
||||
/* Console IO routines for a NINDY960 board. */
|
||||
|
||||
/*
|
||||
* NINDY_IO( ... )
|
||||
*
|
||||
* Interface to NINDY.
|
||||
*/
|
||||
|
||||
#define NINDY_INPUT 0
|
||||
#define NINDY_OUTPUT 1
|
||||
|
||||
void ___NINDY_IO_WRAPPER( void ) /* never called */
|
||||
{
|
||||
asm volatile ( " .text" );
|
||||
asm volatile ( " .align 4" );
|
||||
asm volatile ( " .globl _NINDY_IO" );
|
||||
asm volatile ( "_NINDY_IO:" );
|
||||
asm volatile ( " calls 0 /* call console routines */" );
|
||||
asm volatile ( " ret" );
|
||||
}
|
||||
|
||||
/***** !!!! HOW DO I EXFUN NINDY_IO? !!!! *****/
|
||||
|
||||
/* _Console_Putc
|
||||
|
||||
This routine transmits a character using NINDY. */
|
||||
|
||||
int
|
||||
_Console_Putc (ch)
|
||||
char ch;
|
||||
{
|
||||
NINDY_IO( NINDY_OUTPUT, ch );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* _Console_Getc
|
||||
|
||||
This routine reads a character from NINDY and returns it. */
|
||||
|
||||
int
|
||||
_Console_Getc (poll)
|
||||
int poll;
|
||||
{
|
||||
char ch;
|
||||
|
||||
if ( poll ) {
|
||||
/* I don't know how to poll with NINDY */
|
||||
return -1;
|
||||
} else {
|
||||
NINDY_IO( NINDY_INPUT, &ch );
|
||||
return ch;
|
||||
}
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* entry.s
|
||||
*
|
||||
* This file contains the entry point for the application.
|
||||
* The name of this entry point is compiler dependent.
|
||||
* It jumps to the BSP which is responsible for performing
|
||||
* all initialization.
|
||||
*
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl start # GNU960 default entry point
|
||||
|
||||
start:
|
||||
mov 3, r12
|
||||
modpc r12, r12, r12 # enable tracing/trace faults
|
||||
mov g5, g5 # NOP
|
||||
mov 0, g14 # initialize constant for C
|
||||
|
||||
/*
|
||||
* zero out uninitialized data area
|
||||
*/
|
||||
zerobss:
|
||||
lda _end, r4 /* find end of .bss */
|
||||
lda _bss_start, r5 /* find beginning of .bss */
|
||||
ldconst 0, r6
|
||||
|
||||
loop: st r6, (r5) /* to zero out uninitialized */
|
||||
addo 4, r5, r5 /* data area */
|
||||
cmpobl r5, r4, loop /* loop until _end reached */
|
||||
|
||||
|
||||
lda heap_memory, r12 /* tell C lib where heap is */
|
||||
st r12,___C_heap_start
|
||||
lda heap_size, r12 /* tell C lib how big heap is */
|
||||
st r12,___C_heap_size
|
||||
lda stack_memory,r12 /* set up stack pointer: */
|
||||
mov r12, sp
|
||||
mov 0, g14 /* initialize constant for C */
|
||||
|
||||
call init_frames
|
||||
ret /* return to monitor */
|
||||
|
||||
init_frames:
|
||||
ldconst 0x3b001000, g0
|
||||
ldconst 0x00009107, g1
|
||||
modac g1, g0, g0 /* set AC controls */
|
||||
|
||||
/*
|
||||
* Call application mainline.
|
||||
* Someday, real values of argc and argv will be set up.
|
||||
* For now, they are set to 0.
|
||||
*/
|
||||
|
||||
callx __Board_Initialize /* Initialize the board */
|
||||
|
||||
ldconst 0,g0
|
||||
ldconst 0,g1
|
||||
ldconst 0,g2
|
||||
callx ___libc_init /* initialize the library and */
|
||||
/* call main */
|
||||
/*
|
||||
* if we return from main, we have "fallen" off the end
|
||||
* of the program, therefore status is 0
|
||||
* so move 0 to g0 (exit parameter)
|
||||
*/
|
||||
|
||||
mov 0, g0
|
||||
callx __exit
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* Data Declarations. Start with a macro which helps declare space.
|
||||
*/
|
||||
|
||||
#define DECLARE_SPACE(_name,_space,_align) \
|
||||
.globl _name ; \
|
||||
.align _align ; \
|
||||
.comm _name##,_space
|
||||
|
||||
#define DECLARE_LABEL(_name) \
|
||||
.globl _name ; \
|
||||
_name##:
|
||||
|
||||
#define DECLARE_PTR(_name) DECLARE_SPACE(_name,4,2)
|
||||
#define DECLARE_U32(_name) DECLARE_SPACE(_name,4,2)
|
||||
#define DECLARE_U16(_name) DECLARE_SPACE(_name,2,1)
|
||||
|
||||
/*
|
||||
* Require environment stuff
|
||||
*/
|
||||
|
||||
DECLARE_LABEL(_environ)
|
||||
DECLARE_PTR(environ)
|
||||
|
||||
DECLARE_LABEL(_errno)
|
||||
DECLARE_U32(errno)
|
||||
|
||||
/*
|
||||
* Stack Size and Space
|
||||
*/
|
||||
|
||||
.set stack_size, 0x20000
|
||||
|
||||
DECLARE_SPACE(stack_memory,stack_size,4)
|
||||
DECLARE_LABEL(stack_end)
|
||||
|
||||
/*
|
||||
* Heap Size and Space
|
||||
*/
|
||||
|
||||
.set heap_size, 0x20000
|
||||
|
||||
DECLARE_SPACE(heap_memory,heap_size,4)
|
||||
DECLARE_LABEL(heap_end)
|
@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* m68020.h
|
||||
*
|
||||
* This file contains macros which are used to access MC68020
|
||||
* registers which are not addressable by C. These are
|
||||
* useful when developing the board specific support.
|
||||
*/
|
||||
|
||||
#ifndef m68020_h__
|
||||
#define m68020_h__
|
||||
|
||||
typedef void ( *mc68020_isr )( void );
|
||||
|
||||
#define disable_intr( level ) \
|
||||
{ (level) = 0; \
|
||||
asm volatile ( "movew %%sr,%0 ; \
|
||||
orw #0x0700,%%sr" \
|
||||
: "=d" ((level)) : "0" ((level)) ); \
|
||||
}
|
||||
|
||||
#define enable_intr( level ) \
|
||||
{ asm volatile ( "movew %0,%%sr " \
|
||||
: "=d" ((level)) : "0" ((level)) ); \
|
||||
}
|
||||
|
||||
#define flash_intr( level ) \
|
||||
{ asm volatile ( "movew %0,%%sr ; \
|
||||
orw #0x0700,%%sr" \
|
||||
: "=d" ((level)) : "0" ((level)) ); \
|
||||
}
|
||||
|
||||
#define get_vbr( vbr ) \
|
||||
{ (vbr) = 0; \
|
||||
asm volatile ( "movec %%vbr,%0 " \
|
||||
: "=a" (vbr) : "0" (vbr) ); \
|
||||
}
|
||||
|
||||
#define set_vbr( vbr ) \
|
||||
{ register mc68020_isr *_vbr= (mc68020_isr *)(vbr); \
|
||||
asm volatile ( "movec %0,%%vbr " \
|
||||
: "=a" (_vbr) : "0" (_vbr) ); \
|
||||
}
|
||||
|
||||
#define enable_caching() \
|
||||
{ register unsigned int _ctl=0x01; \
|
||||
asm volatile ( "movec %0,%%cacr" \
|
||||
: "=d" (_ctl) : "0" (_ctl) ); \
|
||||
}
|
||||
|
||||
#define delay( microseconds ) \
|
||||
{ register unsigned int _delay=(microseconds); \
|
||||
register unsigned int _tmp=123; \
|
||||
asm volatile( "0: \
|
||||
nbcd %0 ; \
|
||||
nbcd %0 ; \
|
||||
dbf %1,0 " \
|
||||
: "=d" (_tmp), "=d" (_delay) \
|
||||
: "0" (_tmp), "1" (_delay) ); \
|
||||
}
|
||||
|
||||
#define enable_tracing()
|
||||
#define cause_intr( X )
|
||||
#define clear_intr( X )
|
||||
|
||||
extern mc68020_isr M68Kvec[]; /* vector table address */
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
@ -1,2 +0,0 @@
|
||||
# Motorola MVME135 and MVME136 are compatible.
|
||||
standalone/m68k/m68020/mvme136
|
@ -1,23 +0,0 @@
|
||||
# Copyright (C) 1993, 1997 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
# On-Line Applications Research Corporation.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
# The GNU C Library 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
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with the GNU C Library; if not, write to the Free
|
||||
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
# 02111-1307 USA.
|
||||
|
||||
ifeq (bare,$(subdir))
|
||||
install-lib += mvme136.ld
|
||||
endif
|
@ -1,50 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "m68020.h"
|
||||
|
||||
/* Return control to 135Bug */
|
||||
|
||||
void
|
||||
__exit_trap ()
|
||||
{
|
||||
set_vbr( 0 ); /* restore 135Bug vectors */
|
||||
asm volatile( "trap #15" ); /* trap to 135Bug */
|
||||
asm volatile( ".short 0x63" ); /* return to 135Bug (.RETURN) */
|
||||
asm volatile( "jmp main" ); /* restart program */
|
||||
}
|
||||
|
||||
/* The function `_exit' should take a status argument and simply
|
||||
terminate program execution, using the low-order 8 bits of the
|
||||
given integer as status. */
|
||||
|
||||
void
|
||||
__attribute__ ((noreturn))
|
||||
_exit (status)
|
||||
int status;
|
||||
{
|
||||
/* status is ignored */
|
||||
|
||||
M68Kvec[ 45 ] = __exit_trap; /* install exit_trap handler */
|
||||
asm volatile( "trap #13" ); /* insures SUPV mode */
|
||||
}
|
||||
weak_alias (_exit, _Exit)
|
@ -1,51 +0,0 @@
|
||||
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
#include "m68020.h"
|
||||
|
||||
/* _Board_Initialize()
|
||||
|
||||
This routine initializes the Motorola MVME135/MVME136. */
|
||||
|
||||
void
|
||||
_Board_Initialize ()
|
||||
{
|
||||
mc68020_isr *monitors_vector_table;
|
||||
int index;
|
||||
|
||||
monitors_vector_table = (mc68020_isr *)0; /* 135Bug Vectors are at 0 */
|
||||
set_vbr( monitors_vector_table );
|
||||
|
||||
for ( index=2 ; index<=255 ; index++ )
|
||||
M68Kvec[ index ] = monitors_vector_table[ 32 ];
|
||||
|
||||
M68Kvec[ 2 ] = monitors_vector_table[ 2 ]; /* bus error vector */
|
||||
M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */
|
||||
M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */
|
||||
M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */
|
||||
|
||||
set_vbr( &M68Kvec );
|
||||
|
||||
(*(unsigned char *)0xfffb0067) = 0x7f; /* make VME access round-robin */
|
||||
|
||||
enable_caching ();
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/* Copyright (C) 1994, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||
On-Line Applications Research Corporation.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <standalone.h>
|
||||
#include "m68020.h"
|
||||
|
||||
/* Console IO routines for a Motorola MVME135/MVME136 board.
|
||||
|
||||
They currently use the B port. It should be possible to
|
||||
use the A port by filling in the reset of the chip structure,
|
||||
adding an ifdef for PORTA/PORTB, and switching the addresses,
|
||||
and maybe the macros based on the macro. */
|
||||
|
||||
/* M68681 DUART chip register structures and constants */
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned char fill1[ 5 ]; /* channel A regs ( not used ) */
|
||||
volatile unsigned char isr; /* interrupt status reg */
|
||||
volatile unsigned char fill2[ 2 ]; /* counter regs (not used) */
|
||||
volatile unsigned char mr1mr2b; /* MR1B and MR2B regs */
|
||||
volatile unsigned char srb; /* status reg channel B */
|
||||
volatile unsigned char fill3; /* do not access */
|
||||
volatile unsigned char rbb; /* receive buffer channel B */
|
||||
volatile unsigned char ivr; /* interrupt vector register */
|
||||
} r_m681_info;
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned char fill1[ 4 ]; /* channel A regs (not used) */
|
||||
volatile unsigned char acr; /* auxillary control reg */
|
||||
volatile unsigned char imr; /* interrupt mask reg */
|
||||
volatile unsigned char fill2[ 2 ]; /* counter regs (not used) */
|
||||
volatile unsigned char mr1mr2b; /* MR1B and MR2B regs */
|
||||
volatile unsigned char csrb; /* clock select reg */
|
||||
volatile unsigned char crb; /* command reg */
|
||||
volatile unsigned char tbb; /* transmit buffer channel B */
|
||||
volatile unsigned char ivr; /* interrupt vector register */
|
||||
} w_m681_info;
|
||||
|
||||
#define RD_M68681 ((r_m681_info *)0xfffb0040) /* ptr to the M68681 */
|
||||
#define WR_M68681 ((w_m681_info *)0xfffb0040) /* ptr to the M68681 */
|
||||
#define RXRDYB 0x01 /* status reg recv ready mask */
|
||||
#define TXRDYB 0x04 /* status reg trans ready mask */
|
||||
|
||||
/* _Console_Putc
|
||||
|
||||
This routine transmits a character out the M68681. It supports
|
||||
XON/XOFF flow control. */
|
||||
|
||||
#define XON 0x11 /* control-Q */
|
||||
#define XOFF 0x13 /* control-S */
|
||||
|
||||
int
|
||||
_Console_Putc (ch)
|
||||
char ch;
|
||||
{
|
||||
while ( ! (RD_M68681->srb & TXRDYB) ) ;
|
||||
while ( RD_M68681->srb & RXRDYB ) /* must be an XOFF */
|
||||
if ( RD_M68681->rbb == XOFF )
|
||||
do {
|
||||
while ( ! (RD_M68681->srb & RXRDYB) ) ;
|
||||
} while ( RD_M68681->rbb != XON );
|
||||
|
||||
WR_M68681->tbb = ch;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* _Console_Getc
|
||||
|
||||
This routine reads a character from the UART and returns it. */
|
||||
|
||||
int
|
||||
_Console_Getc (poll)
|
||||
int poll;
|
||||
{
|
||||
if ( poll ) {
|
||||
if ( !(RD_M68681->srb & RXRDYB) )
|
||||
return -1;
|
||||
else
|
||||
return RD_M68681->rbb;
|
||||
} else {
|
||||
while ( !(RD_M68681->srb & RXRDYB) );
|
||||
return RD_M68681->rbb;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user