about summary refs log tree commit diff
path: root/ports/sysdeps/mips/dl-machine.h
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@codesourcery.com>2013-02-27 23:45:07 +0000
committerMaciej W. Rozycki <macro@codesourcery.com>2013-02-27 23:45:07 +0000
commit43301bd3c281036ba97eef384c9340cc7b6130d3 (patch)
tree263f0cc7e01c33c72e626480a52b2bfc1dce78f0 /ports/sysdeps/mips/dl-machine.h
parent85bd816a603a437aedeb688a60a3e0dba4439c50 (diff)
downloadglibc-43301bd3c281036ba97eef384c9340cc7b6130d3.tar.gz
glibc-43301bd3c281036ba97eef384c9340cc7b6130d3.tar.xz
glibc-43301bd3c281036ba97eef384c9340cc7b6130d3.zip
Add support for building as MIPS16 code.
Diffstat (limited to 'ports/sysdeps/mips/dl-machine.h')
-rw-r--r--ports/sysdeps/mips/dl-machine.h102
1 files changed, 101 insertions, 1 deletions
diff --git a/ports/sysdeps/mips/dl-machine.h b/ports/sysdeps/mips/dl-machine.h
index 91f7a7bb5e..a7c784fec5 100644
--- a/ports/sysdeps/mips/dl-machine.h
+++ b/ports/sysdeps/mips/dl-machine.h
@@ -119,6 +119,7 @@ static inline ElfW(Addr)
 elf_machine_load_address (void)
 {
   ElfW(Addr) addr;
+#ifndef __mips16
   asm ("	.set noreorder\n"
        "	" STRINGXP (PTR_LA) " %0, 0f\n"
        "	bltzal $0, 0f\n"
@@ -128,6 +129,19 @@ elf_machine_load_address (void)
        :	"=r" (addr)
        :	/* No inputs */
        :	"$31");
+#else
+  ElfW(Addr) tmp;
+  asm ("	.set noreorder\n"
+       "	move %1,$gp\n"
+       "	lw %1,%%got(0f)(%1)\n"
+       "0:	.fill 0\n"		/* Clear the ISA bit on 0:.  */
+       "	la %0,0b\n"
+       "	addiu %1,%%lo(0b)\n"
+       "	subu %0,%1\n"
+       "	.set reorder\n"
+       :	"=d" (addr), "=d" (tmp)
+       :	/* No inputs */);
+#endif
   return addr;
 }
 
@@ -210,7 +224,8 @@ do {									\
    2) That under Unix the entry is named __start
       and not just plain _start.  */
 
-#define RTLD_START asm (\
+#ifndef __mips16
+# define RTLD_START asm (\
 	".text\n\
 	" _RTLD_PROLOGUE(ENTRY_POINT) "\
 	" STRINGXV(SETUP_GPX($25)) "\n\
@@ -283,6 +298,91 @@ do {									\
 	".previous"\
 );
 
+#else /* __mips16 */
+/* MIPS16 version.  We currently only support O32 under MIPS16; the proper
+   assembly preprocessor abstractions will need to be added if other ABIs
+   are to be supported.  */
+
+# define RTLD_START asm (\
+	".text\n\
+	.set mips16\n\
+	" _RTLD_PROLOGUE (ENTRY_POINT) "\
+	# Construct GP value in $3.\n\
+	li $3, %hi(_gp_disp)\n\
+	addiu $4, $pc, %lo(_gp_disp)\n\
+	sll $3, 16\n\
+	addu $3, $4\n\
+	move $28, $3\n\
+	lw $4, %got(_DYNAMIC)($3)\n\
+	sw $4, -0x7ff0($3)\n\
+	move $4, $sp\n\
+	addiu $sp, -16\n\
+	# _dl_start() is sufficiently near to use pc-relative\n\
+	# load address.\n\
+	la $3, _dl_start\n\
+	move $25, $3\n\
+	jalr $3\n\
+	addiu $sp, 16\n\
+	" _RTLD_EPILOGUE (ENTRY_POINT) "\
+	\n\
+	\n\
+	" _RTLD_PROLOGUE (_dl_start_user) "\
+	li $16, %hi(_gp_disp)\n\
+	addiu $4, $pc, %lo(_gp_disp)\n\
+	sll $16, 16\n\
+	addu $16, $4\n\
+	move $17, $2\n\
+	move $28, $16\n\
+	lw $4, %got(_dl_skip_args)($16)\n\
+	lw $4, 0($4)\n\
+	beqz $4, 1f\n\
+	# Load the original argument count.\n\
+	lw $5, 0($sp)\n\
+	# Subtract _dl_skip_args from it.\n\
+	subu $5, $4\n\
+	# Adjust the stack pointer to skip _dl_skip_args words.\n\
+	sll $4, " STRINGXP (PTRLOG) "\n\
+	move $6, $sp\n\
+	addu $6, $4\n\
+	move $sp, $6\n\
+	# Save back the modified argument count.\n\
+	sw $5, 0($sp)\n\
+1:	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
+	lw $4, %got(_rtld_local)($16)\n\
+	lw $4, 0($4)\n\
+	lw $5, 0($sp)\n\
+	addiu $6, $sp, " STRINGXP (PTRSIZE) "\n\
+	sll $7, $5, " STRINGXP (PTRLOG) "\n\
+	addu $7, $6\n\
+	addu $7, " STRINGXP (PTRSIZE) "\n\
+	# Make sure the stack pointer is aligned for _dl_init_internal.\n\
+	li $2, 2 * " STRINGXP (SZREG) "\n\
+	neg $2, $2\n\
+	move $3, $sp\n\
+	and $2, $3\n\
+	sw $3, -" STRINGXP (SZREG) "($2)\n\
+	addiu $2, -32\n\
+	move $sp, $2\n\
+	sw $16, 16($sp)\n\
+	# Call the function to run the initializers.\n\
+	lw $2, %call16(_dl_init_internal)($16)\n\
+	move $25, $2\n\
+	jalr $2\n\
+	# Restore the stack pointer for _start.\n\
+	lw $2, 32-" STRINGXP (SZREG) "($sp)\n\
+	move $sp, $2\n\
+	move $28, $16\n\
+	# Pass our finalizer function to the user in $2 as per ELF ABI.\n\
+	lw $2, %call16(_dl_fini)($16)\n\
+	# Jump to the user entry point.\n\
+	move $25, $17\n\
+	jr $17\n\t"\
+	_RTLD_EPILOGUE (_dl_start_user)\
+	".previous"\
+);
+
+#endif /* __mips16 */
+
 /* Names of the architecture-specific auditing callback functions.  */
 # if _MIPS_SIM == _ABIO32
 #  define ARCH_LA_PLTENTER mips_o32_gnu_pltenter