about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog28
-rw-r--r--soft-fp/op-1.h1
-rw-r--r--soft-fp/op-2.h1
-rw-r--r--soft-fp/op-4.h1
-rw-r--r--soft-fp/op-common.h21
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h16
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h16
-rw-r--r--sysdeps/sparc/sparc64/strncmp.S11
-rw-r--r--sysdeps/unix/sysv/linux/sparc/fork.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sys/procfs.h69
10 files changed, 149 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 0f6016bdc6..01eb95b231 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2002-05-17  David S. Miller  <davem@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/fork.S: Define _internal aliases.
+
+2002-05-16  David S. Miller  <davem@redhat.com>
+
+	* sysdeps/sparc/sparc32/dl-machine.h (LOAD_PIC_REG): Define.
+	(elf_machine_dynamic): Use it to force PIC register to be loaded.
+	(elf_machine_load_address): Likewise.
+	* sysdeps/sparc/sparc64/dl-machine.h: Mirror sparc32 changes.
+
+	* sysdeps/sparc/sparc64/strncmp.S: When second argument pointer
+	is unaligned, do not forget to fully initialize %g1 magic value.
+
+	* sysdeps/unix/sysv/linux/sparc/sys/procfs.h: Fix 64-bit elf
+	register definitions and provide 32-bit variants of structures
+	during 64-bit builds.
+
+	* soft-fp/op-1.h (_FP_FRAC_CLEAR_OVERP_1): Define.
+	* soft-fp/op-2.h (_FP_FRAC_CLEAR_OVERP_2): Define.
+	* soft-fp/op-4.h (_FP_FRAC_CLEAR_OVERP_4): Define.
+	* soft-fp/op-common.h (_FP_PACK_CANONICAL): After rounding, if
+	_FP_FRAC_OVERP_X is set, use _FP_FRAC_CLEAR_OVERP_X to clear it.
+	(_FP_FROM_INT): Perform right shifts on unsigned integer type.
+	Do not clear implicit one bit here, it must be done post-rounding.
+	Only pad to the left using left shift if value uses less than the
+	available fractional bits.
+
 2002-05-20  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
 
 	* sysdeps/powerpc/Makefile (sysdeps_routines): Use libgcc-compat
diff --git a/soft-fp/op-1.h b/soft-fp/op-1.h
index f732143052..367ff2274b 100644
--- a/soft-fp/op-1.h
+++ b/soft-fp/op-1.h
@@ -55,6 +55,7 @@
 #define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE)X##_f < 0)
 #define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
 #define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_1(fs,X)	(X##_f &= ~_FP_OVERFLOW_##fs)
 #define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
 #define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
 #define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
diff --git a/soft-fp/op-2.h b/soft-fp/op-2.h
index 4a5add55cb..89da27fa4f 100644
--- a/soft-fp/op-2.h
+++ b/soft-fp/op-2.h
@@ -112,6 +112,7 @@
 #define _FP_FRAC_NEGP_2(X)	((_FP_WS_TYPE)X##_f1 < 0)
 #define _FP_FRAC_ZEROP_2(X)	((X##_f1 | X##_f0) == 0)
 #define _FP_FRAC_OVERP_2(fs,X)	(_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_2(fs,X)	(_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
 #define _FP_FRAC_EQ_2(X, Y)	(X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
 #define _FP_FRAC_GT_2(X, Y)	\
   (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 > Y##_f0)
diff --git a/soft-fp/op-4.h b/soft-fp/op-4.h
index 82009000ec..5e3032e44a 100644
--- a/soft-fp/op-4.h
+++ b/soft-fp/op-4.h
@@ -129,6 +129,7 @@
 #define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
 #define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
 #define _FP_FRAC_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
 
 #define _FP_FRAC_EQ_4(X,Y)				\
  (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]		\
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index 012e76f0b7..232604e74a 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -89,11 +89,10 @@ do {								\
 	_FP_ROUND(wc, X);					\
 	if (_FP_FRAC_OVERP_##wc(fs, X))				\
 	  {							\
-	    _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));		\
+	    _FP_FRAC_CLEAR_OVERP_##wc(fs, X);			\
 	    X##_e++;						\
 	  }							\
-	else							\
-	  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
+	_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
 	if (X##_e >= _FP_EXPMAX_##fs)				\
 	  {							\
 	    /* overflow */					\
@@ -682,25 +681,27 @@ do {									\
   do {									\
     if (r)								\
       {									\
+        unsigned rtype ur_;						\
 	X##_c = FP_CLS_NORMAL;						\
 									\
 	if ((X##_s = (r < 0)))						\
 	  r = -r;							\
 									\
+	ur_ = (unsigned rtype) r;					\
 	if (rsize <= _FP_W_TYPE_SIZE)					\
-	  __FP_CLZ(X##_e, r);						\
+	  __FP_CLZ(X##_e, ur_);						\
 	else								\
-	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), 	\
-		     (_FP_W_TYPE)r);					\
+	  __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), 	\
+		     (_FP_W_TYPE)ur_);					\
 	if (rsize < _FP_W_TYPE_SIZE)					\
 		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
 	X##_e = rsize - X##_e - 1;					\
 									\
 	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)	\
-	  __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);	\
-	r &= ~((rtype)1 << X##_e);					\
-	_FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);	\
-	_FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));		\
+	  __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
+	_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			\
+	if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)			\
+	  _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));	\
       }									\
     else								\
       {									\
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 4534464987..6977cdcd26 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -72,6 +72,17 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
     return 0;
 }
 
+/* We have to do this because elf_machine_{dynamic,load_address} can be
+   invoked from functions that have no GOT references, and thus the compiler
+   has no obligation to load the PIC register.  */
+#define LOAD_PIC_REG(PIC_REG)	\
+do {	register Elf32_Addr pc __asm("o7"); \
+	__asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
+	      "call 1f\n\t" \
+	      "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n" \
+	      "1:\tadd %1, %0, %1" \
+	      : "=r" (pc), "=r" (PIC_REG)); \
+} while (0)
 
 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
    first element of the GOT.  This must be inlined in a function which
@@ -80,6 +91,9 @@ static inline Elf32_Addr
 elf_machine_dynamic (void)
 {
   register Elf32_Addr *got asm ("%l7");
+
+  LOAD_PIC_REG (got);
+
   return *got;
 }
 
@@ -89,6 +103,8 @@ elf_machine_load_address (void)
 {
   register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got;
 
+  LOAD_PIC_REG (pic);
+
   /* Utilize the fact that a local .got entry will be partially
      initialized at startup awaiting its RELATIVE fixup.  */
 
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 4ced7deef8..fba323dece 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -39,6 +39,18 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
   return ehdr->e_machine == EM_SPARCV9;
 }
 
+/* We have to do this because elf_machine_{dynamic,load_address} can be
+   invoked from functions that have no GOT references, and thus the compiler
+   has no obligation to load the PIC register.  */
+#define LOAD_PIC_REG(PIC_REG)	\
+do {	Elf64_Addr tmp;		\
+	__asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
+	      "rd %%pc, %0\n\t" \
+	      "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \
+	      "add %0, %1, %0" \
+	      : "=r" (PIC_REG), "=r" (tmp)); \
+} while (0)
+
 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
    first element of the GOT.  This must be inlined in a function which
    uses global data.  */
@@ -47,6 +59,8 @@ elf_machine_dynamic (void)
 {
   register Elf64_Addr *elf_pic_register __asm__("%l7");
 
+  LOAD_PIC_REG (elf_pic_register);
+
   return *elf_pic_register;
 }
 
@@ -56,6 +70,8 @@ elf_machine_load_address (void)
 {
   register Elf64_Addr *elf_pic_register __asm__("%l7");
 
+  LOAD_PIC_REG (elf_pic_register);
+
   /* We used to utilize the fact that a local .got entry will
      be partially initialized at startup awaiting its RELATIVE
      fixup:
diff --git a/sysdeps/sparc/sparc64/strncmp.S b/sysdeps/sparc/sparc64/strncmp.S
index 3bc21d6664..31fcfeee08 100644
--- a/sysdeps/sparc/sparc64/strncmp.S
+++ b/sysdeps/sparc/sparc64/strncmp.S
@@ -290,14 +290,15 @@ ENTRY(strncmp)
 	 ldxa		[%o0] ASI_PNF, %g4		/* Load				*/
 11:	sllx		%g3, 3, %g5			/* IEU0		Group		*/
 	mov		64, %g7				/* IEU1				*/
-	sub		%o1, %g3, %o1			/* IEU0		Group		*/
+	or		%g1, %g2, %g1			/* IEU0		Group		*/
+	sub		%o1, %g3, %o1			/* IEU1				*/
 
-	sub		%g7, %g5, %g7			/* IEU1				*/
+	sub		%g7, %g5, %g7			/* IEU0		Group		*/
 	ldxa		[%o1] ASI_PNF, %o4		/* Load				*/
-	sllx		%g1, 7, %g2			/* IEU0		Group		*/
-	add		%o1, 8, %o1			/* IEU1				*/
+	sllx		%g1, 7, %g2			/* IEU1				*/
+	add		%o1, 8, %o1			/* IEU0		Group		*/
 							/* %g1 = 0101010101010101
-							   %g2 = 8080808080800880
+							   %g2 = 8080808080808080
 							   %g3 = %o1 alignment
 							   %g5 = number of bits to shift left
 							   %g7 = number of bits to shift right */
diff --git a/sysdeps/unix/sysv/linux/sparc/fork.S b/sysdeps/unix/sysv/linux/sparc/fork.S
index 870d9608c1..ad9f3bb475 100644
--- a/sysdeps/unix/sysv/linux/sparc/fork.S
+++ b/sysdeps/unix/sysv/linux/sparc/fork.S
@@ -25,5 +25,6 @@ PSEUDO (__libc_fork, fork, 0)
 	 and	%o0, %o1, %o0
 PSEUDO_END (__libc_fork)
 
+strong_alias (__libc_fork, __fork_internal)
 weak_alias (__libc_fork, __fork)
 weak_alias (__libc_fork, fork)
diff --git a/sysdeps/unix/sysv/linux/sparc/sys/procfs.h b/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
index e5d35f524a..2827b1ec33 100644
--- a/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
+++ b/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
@@ -35,7 +35,7 @@ __BEGIN_DECLS
 
 #if __WORDSIZE == 64
 
-#define ELF_NGREG		20
+#define ELF_NGREG		36
 
 typedef struct
   {
@@ -139,6 +139,73 @@ typedef __pid_t lwpid_t;
 typedef struct elf_prstatus prstatus_t;
 typedef struct elf_prpsinfo prpsinfo_t;
 
+#if __WORDSIZE == 64
+
+/* Provide 32-bit variants so that BFD can read 32-bit
+   core files.  */
+#define ELF_NGREG32		38
+typedef struct
+  {
+    union
+      {
+	unsigned int	pr_regs[32];
+	double		pr_dregs[16];
+      }			pr_fr;
+    unsigned int	__unused;
+    unsigned int	pr_fsr;
+    unsigned char	pr_qcnt;
+    unsigned char	pr_q_entrysize;
+    unsigned char	pr_en;
+    unsigned int	pr_q[64];
+  } elf_fpregset_t32;
+
+typedef unsigned int elf_greg_t32;
+typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG32];
+
+struct elf_prstatus32
+  {
+    struct elf_siginfo pr_info;		/* Info associated with signal.  */
+    short int pr_cursig;		/* Current signal.  */
+    unsigned int pr_sigpend;	/* Set of pending signals.  */
+    unsigned int pr_sighold;	/* Set of held signals.  */
+    __pid_t pr_pid;
+    __pid_t pr_ppid;
+    __pid_t pr_pgrp;
+    __pid_t pr_sid;
+    struct
+      {
+	int tv_sec, tv_usec;
+      } pr_utime,			/* User time.  */
+        pr_stime,			/* System time.  */
+        pr_cutime,			/* Cumulative user time.  */
+        pr_cstime;			/* Cumulative system time.  */
+    elf_gregset_t32 pr_reg;		/* GP registers.  */
+    int pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+struct elf_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned int pr_flag;		/* Flags.  */
+    unsigned short int pr_uid;
+    unsigned short int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+typedef elf_gregset_t32 prgregset32_t;
+typedef elf_fpregset_t32 prfpregset32_t;
+
+typedef struct elf_prstatus32 prstatus32_t;
+typedef struct elf_prpsinfo32 prpsinfo32_t;
+
+#endif  /* sparc64 */
+
 __END_DECLS
 
 #endif	/* sys/procfs.h */