summaryrefslogtreecommitdiffstats
path: root/meta/packages/gcc/gcc-3.3.4/arm-gotoff.dpatch
blob: 610f9430e0a673ac444cadaaf48fb0a60ffd602e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#! /bin/sh -e

src=gcc
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3"
    src=$3/gcc
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p0 --fuzz 10 < $0
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p0 --fuzz 10 < $0
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

# DP: use GOTOFF not GOT relocs for .LCn and other local symbols;
# DP: don't use gotoff for non-static functions, even if defined locally

--- gcc/config/arm/arm.c	2003-06-14 15:20:53.000000000 +0100
+++ gcc/config/arm/arm.c	2004-03-06 15:15:32.000000000 +0000
@@ -2364,6 +2394,40 @@
   return 1;
 }
 
+/* Return true if OP is a symbolic operand that resolves locally.  */
+
+static int
+local_symbolic_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (op) == CONST
+      && GET_CODE (XEXP (op, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+    op = XEXP (XEXP (op, 0), 0);
+
+  if (GET_CODE (op) == LABEL_REF)
+    return 1;
+
+  if (GET_CODE (op) != SYMBOL_REF)
+    return 0;
+
+  /* These we've been told are local by varasm and encode_section_info
+     respectively.  */
+  if (CONSTANT_POOL_ADDRESS_P (op) || ENCODED_LOCAL_BINDING_ATTR_P (XSTR (op, 0)))
+    return 1;
+
+  /* There is, however, a not insubstantial body of code in the rest of
+     the compiler that assumes it can just stick the results of
+     ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done.  */
+  /* ??? This is a hack.  Should update the body of the compiler to
+     always create a DECL an invoke targetm.encode_section_info.  */
+  if (strncmp (arm_strip_name_encoding (XSTR (op, 0)), ".L", 2) == 0)
+    return 1;
+
+  return 0;
+}
+
 rtx
 legitimize_pic_address (orig, mode, reg)
      rtx orig;
@@ -2404,10 +2468,7 @@
       else
 	emit_insn (gen_pic_load_addr_thumb (address, orig));
 
-      if ((GET_CODE (orig) == LABEL_REF
-	   || (GET_CODE (orig) == SYMBOL_REF && 
-	       ENCODED_SHORT_CALL_ATTR_P (XSTR (orig, 0))))
-	  && NEED_GOT_RELOC)
+      if (local_symbolic_operand (orig, Pmode) && NEED_GOT_RELOC)
 	pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
       else
 	{
@@ -8804,11 +8911,7 @@
       if (NEED_GOT_RELOC && 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)
-		  || ENCODED_SHORT_CALL_ATTR_P (XSTR (x, 0))))
-	    fputs ("(GOTOFF)", asm_out_file);
-	  else if (GET_CODE (x) == LABEL_REF)
+	  if (local_symbolic_operand (x, Pmode))
 	    fputs ("(GOTOFF)", asm_out_file);
 	  else
 	    fputs ("(GOT)", asm_out_file);
@@ -11335,6 +11418,11 @@
       else if (! TREE_PUBLIC (decl))
         arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR);
     }
+
+  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd' 
+      && flag_pic 
+      && (*targetm.binds_local_p) (decl))
+    arm_encode_call_attribute (decl, LOCAL_BINDING_FLAG_CHAR);
 }
 #endif /* !ARM_PE */
 

--- gcc/config/arm/arm.h	Fri Mar  5 18:49:44 2004
+++ gcc/config/arm/arm.h	Fri Mar  5 15:04:31 2004
@@ -1870,6 +1870,7 @@
    Note, '@' and '*' have already been taken.  */
 #define SHORT_CALL_FLAG_CHAR	'^'
 #define LONG_CALL_FLAG_CHAR	'#'
+#define LOCAL_BINDING_FLAG_CHAR '%'
 
 #define ENCODED_SHORT_CALL_ATTR_P(SYMBOL_NAME)	\
   (*(SYMBOL_NAME) == SHORT_CALL_FLAG_CHAR)
@@ -1877,6 +1878,9 @@
 #define ENCODED_LONG_CALL_ATTR_P(SYMBOL_NAME)	\
   (*(SYMBOL_NAME) == LONG_CALL_FLAG_CHAR)
 
+#define ENCODED_LOCAL_BINDING_ATTR_P(SYMBOL_NAME) \
+  (*(SYMBOL_NAME) == LOCAL_BINDING_FLAG_CHAR)
+
 #ifndef SUBTARGET_NAME_ENCODING_LENGTHS
 #define SUBTARGET_NAME_ENCODING_LENGTHS
 #endif
@@ -1888,6 +1892,7 @@
 #define ARM_NAME_ENCODING_LENGTHS		\
   case SHORT_CALL_FLAG_CHAR: return 1;		\
   case LONG_CALL_FLAG_CHAR:  return 1;		\
+  case LOCAL_BINDING_FLAG_CHAR: return 1;	\
   case '*':  return 1;				\
   SUBTARGET_NAME_ENCODING_LENGTHS