[uClinux-dev] [patch] ARM: -mdisable-got adapted for gcc-3.0.2

Adrian von Bidder avbidder at acter.ch
Fri Nov 9 06:36:34 EST 2001


Heyho!

[this is for information only. discussion of the patch shold take place
on gcc at gcc.gnu.org]

I have rewritten Vladim Lebedev's patch (-mdisable-got) to gcc-2.95.2 to
work with gcc-3.0.2

What it does:
 - makes an arm-uclinux target and adds the -membedded-pic option
 - all labels in the .text segment are addressed pc-relative (especially
long jumps).
 - all labels in the .data segment are addressed relative to the
pic-register.

So there is no GOT. As this seems roughly similar to what -membedded-pic
does on MIPS, I have renamed the option. 

Note that this is not very well tested; it works for my simple hello
world. I will now test it some more (especially on the thumb side), but
I'll be happy to get comments from everybody. I've not hacked gcc before
and I've probably forgotten a zillion of obvious things.

To create arm-uclinux binaries you'll probably have to patch binutils,
too, and link with the armelf_uclinux target - the patch to
binutlils-2.11.2 should go to binutils at sources.redhat.com right after I
sent this msg.

The first hunk of the patch is against config.sub. I have submitted it
to config-patches, and it has been approved; it's included here since I
work with 3.0.2 release.

greets from Zürich
-- vbi
-------------- next part --------------
diff -brudN gcc-3.0.2.orig/config.sub gcc-3.0.2/config.sub
--- gcc-3.0.2.orig/config.sub	Mon Jul 16 12:04:04 2001
+++ gcc-3.0.2/config.sub	Tue Nov  6 12:01:56 2001
@@ -1035,7 +1035,8 @@
 	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -uclinux*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
diff -brudN gcc-3.0.2.orig/gcc/config/arm/arm-protos.h gcc-3.0.2/gcc/config/arm/arm-protos.h
--- gcc-3.0.2.orig/gcc/config/arm/arm-protos.h	Mon Jan 15 20:54:42 2001
+++ gcc-3.0.2/gcc/config/arm/arm-protos.h	Wed Nov  7 17:18:03 2001
@@ -173,8 +173,6 @@
 					PARAMS ((int, rtx *));
 extern void   thumb_expand_movstrqi	PARAMS ((rtx *));
 extern int    thumb_cmp_operand		PARAMS ((rtx, enum machine_mode));
-extern rtx *  thumb_legitimize_pic_address
-					PARAMS ((rtx, enum machine_mode, rtx));
 extern int    thumb_go_if_legitimate_address
 					PARAMS ((enum machine_mode, rtx));
 extern rtx    arm_return_addr		PARAMS ((int, rtx));
diff -brudN gcc-3.0.2.orig/gcc/config/arm/arm.c gcc-3.0.2/gcc/config/arm/arm.c
--- gcc-3.0.2.orig/gcc/config/arm/arm.c	Wed Nov  7 11:58:55 2001
+++ gcc-3.0.2/gcc/config/arm/arm.c	Fri Nov  9 11:28:48 2001
@@ -4,6 +4,8 @@
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter at win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha at arm.com).
+   Modifcations by Adrian von Bidder <avbidder at acter.ch>
+        based on work done by Vlad Lebedev
 
 This file is part of GNU CC.
 
@@ -348,6 +350,12 @@
 {
   unsigned i;
   
+  if (TARGET_EMBEDDED_PIC)
+    {
+      if (! flag_pic) flag_pic = 1;
+      target_flags |= ARM_FLAG_SINGLE_PIC_BASE;
+    }
+
   /* Set up the flags based on the cpu/architecture selected by the user.  */
   for (i = ARRAY_SIZE (arm_select); i--;)
     {
@@ -589,6 +597,9 @@
      which keeps r9 available.  */
   if (flag_pic && !TARGET_APCS_STACK)
     arm_pic_register = 10;
+  /* on thumb we use r6 as pic register, saves one instruction per load */
+  if (flag_pic && TARGET_EMBEDDED_PIC)
+    arm_pic_register = 6;
   
   if (TARGET_APCS_FLOAT)
     warning ("Passing floating point arguments in fp regs not yet supported");
@@ -2145,6 +2156,8 @@
       else
 	address = reg;
 
+      if (!TARGET_EMBEDDED_PIC)
+        {
       if (TARGET_ARM)
 	emit_insn (gen_pic_load_addr_arm (address, orig));
       else
@@ -2155,6 +2168,51 @@
 					   address));
       RTX_UNCHANGING_P (pic_ref) = 1;
       insn = emit_move_insn (reg, pic_ref);
+        } 
+      else if (SYMBOL_REF_FLAG (orig)) 
+        {
+          /* this is a symbol in the .text segment */
+          rtx insn;
+          rtx addr = gen_reg_rtx (Pmode);
+          rtx l1 = gen_label_rtx ();
+          rtx tmp = plus_constant(gen_rtx_LABEL_REF(Pmode, l1), 
+                  TARGET_ARM ? 8 : 4);
+
+          pic_ref = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, tmp));
+          
+          LABEL_PRESERVE_P (l1) = 1;
+          
+          if (TARGET_ARM)
+	    insn = gen_pic_load_addr_arm (addr, pic_ref);
+          else
+	    insn = gen_pic_load_addr_thumb (addr, pic_ref);
+
+          REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, l1,
+                  REG_NOTES (insn));
+          emit_insn (insn);
+
+          if (TARGET_ARM)
+              emit_insn (insn = gen_pic_add_dot_plus_eight (addr, l1));
+          else
+              emit_insn (insn = gen_pic_add_dot_plus_four (addr, l1));
+          REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig, 
+                  REG_NOTES (insn));
+
+          RTX_UNCHANGING_P (pic_ref) = 1;
+          return addr;
+        }
+      else
+        {
+            /* this is a symbol in the .data segment */
+          if (TARGET_ARM)
+	    emit_insn (gen_pic_load_addr_arm (address, orig));
+          else
+	    emit_insn (gen_pic_load_addr_thumb (address, orig));
+
+          pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
+
+          insn = emit_move_insn (reg, pic_ref);
+        }
 #endif
       current_function_uses_pic_offset_table = 1;
       /* Put a REG_EQUAL note on this insn, so that it can be optimized
diff -brudN gcc-3.0.2.orig/gcc/config/arm/arm.h gcc-3.0.2/gcc/config/arm/arm.h
--- gcc-3.0.2.orig/gcc/config/arm/arm.h	Wed Nov  7 11:59:17 2001
+++ gcc-3.0.2/gcc/config/arm/arm.h	Fri Nov  9 11:39:33 2001
@@ -5,6 +5,8 @@
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha at arm.com)
    Minor hacks by Nick Clifton (nickc at cygnus.com)
+   Modifcations by Adrian von Bidder <avbidder at acter.ch>
+        based on work done by Vlad Lebedev
 
 This file is part of GNU CC.
 
@@ -382,6 +384,9 @@
    destination is non-Thumb aware.  */
 #define THUMB_FLAG_CALLER_SUPER_INTERWORKING	(1 << 20)
 
+/* Code shall be pc-relative, data addressed relative to pic-register */
+#define ARM_FLAG_EMBEDDED_PIC                   (1 << 21)
+
 #define TARGET_APCS_FRAME		(target_flags & ARM_FLAG_APCS_FRAME)
 #define TARGET_POKE_FUNCTION_NAME	(target_flags & ARM_FLAG_POKE)
 #define TARGET_FPE			(target_flags & ARM_FLAG_FPE)
@@ -407,6 +412,7 @@
 #define TARGET_BACKTRACE	        (leaf_function_p ()	      			\
 				         ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE)	\
 				         : (target_flags & THUMB_FLAG_BACKTRACE))
+#define TARGET_EMBEDDED_PIC             (target_flags & ARM_FLAG_EMBEDDED_PIC)
 
 /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
    Bit 31 is reserved.  See riscix.h.  */
@@ -486,6 +492,9 @@
    N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
   {"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING,  \
    "" },								   \
+  {"embedded-pic",              ARM_FLAG_EMBEDDED_PIC,                     \
+   N_("Generate code for some embedded targets") },                        \
+  {"no-embedded-pic",          -ARM_FLAG_EMBEDDED_PIC, ""},                \
   SUBTARGET_SWITCHES							   \
   {"",				TARGET_DEFAULT, "" }			   \
 }
@@ -1951,10 +1960,15 @@
    simplification.  */
 /* This doesn't work with AOF syntax, since the string table may be in
    a different AREA.  */
+/* For -membedded-pic, I grab the SYMBOL_REF_FLAG and hope that this
+   does not collide with prior use of it. For other targets, behaviour
+   shouldn't have changed. (avbidder) */
 #ifndef AOF_ASSEMBLER
 #define ENCODE_SECTION_INFO(decl)					\
 {									\
-  if (optimize > 0 && TREE_CONSTANT (decl)				\
+  if (TARGET_EMBEDDED_PIC && (TREE_CODE (decl) == FUNCTION_DECL))       \
+      SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;                  \
+  else if (optimize > 0 && TREE_CONSTANT (decl)	\
       && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))	\
     {									\
       rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'		\
@@ -2857,7 +2871,8 @@
 									\
     /* Mark symbols as position independent.  We only do this in the	\
       .text segment, not in the .data segment. */			\
-    if (NEED_GOT_RELOC && flag_pic && making_const_table &&		\
+    if (NEED_GOT_RELOC && !TARGET_EMBEDDED_PIC &&                       \
+        flag_pic && making_const_table &&		                \
     	(GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF))	\
      {									\
         if (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X))	\
diff -brudN gcc-3.0.2.orig/gcc/config/arm/linux-gas.h gcc-3.0.2/gcc/config/arm/linux-gas.h
--- gcc-3.0.2.orig/gcc/config/arm/linux-gas.h	Tue Jan  2 14:38:41 2001
+++ gcc-3.0.2/gcc/config/arm/linux-gas.h	Wed Nov  7 17:18:03 2001
@@ -74,6 +74,7 @@
 
 /* Clear the instruction cache from `beg' to `end'.  This makes an
    inline system call to SYS_cacheflush.  */
+#ifndef __thumb__
 #define CLEAR_INSN_CACHE(BEG, END)					\
 {									\
   register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
@@ -83,3 +84,25 @@
 		    : "=r" (_beg)					\
 		    : "0" (_beg), "r" (_end), "r" (_flg));		\
 }
+#else
+/* This is a hack. Use the thumb ABI or make it an (interworking)
+   function call */
+#define CLEAR_INSN_CACHE(BEG, END)					\
+{									\
+  register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
+  register unsigned long _end __asm ("a2") = (unsigned long) (END);	\
+  register unsigned long _flg __asm ("a3") = 0;				\
+  unsigned long temp;							\
+  __asm __volatile (							\
+	"adr	%1, 0f\n"						\
+"	bx	%1\n"							\
+"	.align 2\n"							\
+"	.code 32\n"							\
+"0:	swi 0x9f0002		@ sys_cacheflush\n"			\
+"	adr	%1, 0b + 13\n"						\
+"	bx	%1\n"							\
+"	.code 16"							\
+		    : "=r" (_beg), "=r" (temp)				\
+		    : "0" (_beg), "r" (_end), "r" (_flg));		\
+}
+#endif
diff -brudN gcc-3.0.2.orig/gcc/config/arm/t-arm-uclinux gcc-3.0.2/gcc/config/arm/t-arm-uclinux
--- gcc-3.0.2.orig/gcc/config/arm/t-arm-uclinux	Thu Jan  1 01:00:00 1970
+++ gcc-3.0.2/gcc/config/arm/t-arm-uclinux	Fri Nov  9 11:24:27 2001
@@ -0,0 +1,88 @@
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = arm/lib1funcs.asm
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+	echo '#define FLOAT' > fp-bit.c
+	echo '#ifndef __ARMEB__' >> fp-bit.c
+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+	echo '#endif' >> fp-bit.c
+	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+	echo '#ifndef __ARMEB__' > dp-bit.c
+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+	echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
+	echo '#endif' >> dp-bit.c
+	cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+	
+MULTILIB_OPTIONS     = marm/mthumb
+MULTILIB_DIRNAMES    = arm thumb
+MULTILIB_EXCEPTIONS  = 
+
+MULTILIB_OPTIONS    = mno-no-embedded-pic/membedded-pic
+MULTILIB_OPTIONS    = got embedded
+	
+# MULTILIB_OPTIONS     = mlittle-endian/mbig-endian
+# MULTILIB_DIRNAMES    = le be
+# MULTILIB_EXCEPTIONS  = 
+# MULTILIB_MATCHES     = mbig-endian=mbe mlittle-endian=mle
+# 
+# MULTILIB_OPTIONS    += mhard-float/msoft-float
+# MULTILIB_DIRNAMES   += fpu soft
+# 
+# MULTILIB_OPTIONS    += mapcs-32/mapcs-26
+# MULTILIB_DIRNAMES   += 32bit 26bit
+# 
+#MULTILIB_OPTIONS    += mno-thumb-interwork/mthumb-interwork
+#MULTILIB_DIRNAMES   += normal interwork
+#MULTILIB_EXCEPTIONS += *mapcs-26/*mthumb-interwork*
+# 
+# MULTILIB_OPTIONS    += fno-leading-underscore/fleading-underscore
+# MULTILIB_DIRNAMES   += elf under
+# 
+# MULTILIB_OPTIONS    += mcpu=arm7
+# MULTILIB_DIRNAMES   += nofmult
+# MULTILIB_EXCEPTIONS += *mthumb-interwork*/*mcpu=arm7*
+# # We have to match all the arm cpu variants which do not have the
+# # multiply instruction and treat them as if the user had specified
+# # -mcpu=arm7.  Note that in the following the ? is interpreted as
+# # an = for the purposes of matching command line options.
+# # FIXME: There ought to be a better way to do this.
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7d
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7di
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm70
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm700
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm700i
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm710
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm710c
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7100
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7500
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7500fe
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm6
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm60
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm600
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm610
+# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm620
+
+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
+
+# for uclinux:
+MULTILIB_EXTRA_OPTS = frename-registers
+# -frename-registers is to work around what appears to be a bug in gcc's 
+# optimizier - or in my embedded-pic hack (some internal label is left lying
+# around, and then of course produces an unresolved symbol at link time)
+
+# If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS here
+# EXTRA_PARTS = crtbegin.o crtend.o
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc
diff -brudN gcc-3.0.2.orig/gcc/config/arm/uclinux-elf.h gcc-3.0.2/gcc/config/arm/uclinux-elf.h
--- gcc-3.0.2.orig/gcc/config/arm/uclinux-elf.h	Sat Dec 18 14:34:21 1999
+++ gcc-3.0.2/gcc/config/arm/uclinux-elf.h	Fri Nov  9 11:20:58 2001
@@ -29,4 +29,5 @@
 #define TARGET_VERSION fputs (" (ARM/ELF ucLinux)", stderr);
 
 #undef  TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS | ARM_FLAG_SINGLE_PIC_BASE)
+#define TARGET_DEFAULT \
+    (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS | ARM_FLAG_SINGLE_PIC_BASE)
diff -brudN gcc-3.0.2.orig/gcc/config.gcc gcc-3.0.2/gcc/config.gcc
--- gcc-3.0.2.orig/gcc/config.gcc	Wed Oct 10 02:25:25 2001
+++ gcc-3.0.2/gcc/config.gcc	Tue Nov  6 12:01:56 2001
@@ -601,7 +601,7 @@
 	;;
 arm*-*-uclinux*)		# ARM ucLinux
 	tm_file=arm/uclinux-elf.h
-	tmake_file=arm/t-arm-elf
+	tmake_file=arm/t-arm-uclinux
 	;;
 arm*-*-aout)
 	tm_file=arm/aout.h
diff -brudN gcc-3.0.2.orig/gcc/doc/invoke.texi gcc-3.0.2/gcc/doc/invoke.texi
--- gcc-3.0.2.orig/gcc/doc/invoke.texi	Wed Oct 17 11:06:44 2001
+++ gcc-3.0.2/gcc/doc/invoke.texi	Fri Nov  9 11:47:19 2001
@@ -381,6 +381,7 @@
 -mlong-calls  -mno-long-calls @gol
 -msingle-pic-base  -mno-single-pic-base @gol
 -mpic-register=@var{reg} @gol
+-membedded-pic  -mno-embedded-pic @gol
 -mnop-fun-dllimport @gol
 -mpoke-function-name @gol
 -mthumb  -marm @gol
@@ -5954,6 +5955,12 @@
 @opindex mpic-register
 Specify the register to be used for PIC addressing.  The default is R10
 unless stack-checking is enabled, when R9 is used.
+
+@item -membedded-pic
+@opindex membedded-pic
+Causes all code to be pc-relative and all data to be addressed relative
+to the pic register. The default for arm is R10 unless stack-checking is 
+enabled, when R9 is used; for thumb it uses R6 by default.
 
 @item -mpoke-function-name
 @opindex mpoke-function-name


More information about the uClinux-dev mailing list