about summary refs log tree commit diff
path: root/sysdeps/sparc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-05-21 02:15:01 +0000
committerUlrich Drepper <drepper@redhat.com>2002-05-21 02:15:01 +0000
commitcf29934141e8e27bd66c9a7fe4f4c217878365a7 (patch)
treeb1c57ba760d4820a1e1d9c76c3e9b48f627d60a3 /sysdeps/sparc
parent509bd8e35ad842944074e43cd2cc22381ee13f5b (diff)
downloadglibc-cf29934141e8e27bd66c9a7fe4f4c217878365a7.tar.gz
glibc-cf29934141e8e27bd66c9a7fe4f4c217878365a7.tar.xz
glibc-cf29934141e8e27bd66c9a7fe4f4c217878365a7.zip
Update.
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.
Diffstat (limited to 'sysdeps/sparc')
-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
3 files changed, 38 insertions, 5 deletions
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 */