blob: b98db228d1dc743433a4d938eed4dd6d4dc50152 [file] [log] [blame]
Brad Bishop26bdd442019-08-16 17:08:17 -04001From 6b6c4a67212ced3fe1593fb173cfc4bce8d7f922 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Tue, 11 Sep 2018 17:30:17 +0530
4Subject: [PATCH] Added relocations for MB-X
5
6Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
7Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
8
9---
10 bfd/bfd-in2.h | 11 ++++--
11 bfd/libbfd.h | 4 +--
12 bfd/reloc.c | 26 +++++++-------
13 gas/config/tc-microblaze.c | 90 ++++++++++++++++++++--------------------------
14 4 files changed, 62 insertions(+), 69 deletions(-)
15
16diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
17index 90645d1..f74aac1 100644
18--- a/bfd/bfd-in2.h
19+++ b/bfd/bfd-in2.h
20@@ -5873,16 +5873,21 @@ done here - only used for relaxing */
21 BFD_RELOC_MICROBLAZE_32_NONE,
22
23 /* This is a 64 bit reloc that stores the 32 bit pc relative
24- * +value in two words (with an imm instruction). No relocation is
25+ * +value in two words (with an imml instruction). No relocation is
26 * +done here - only used for relaxing */
27- BFD_RELOC_MICROBLAZE_64_NONE,
28+ BFD_RELOC_MICROBLAZE_64_PCREL,
29
30-/* This is a 64 bit reloc that stores the 32 bit pc relative
31+/* This is a 64 bit reloc that stores the 32 bit relative
32 * +value in two words (with an imml instruction). No relocation is
33 * +done here - only used for relaxing */
34 BFD_RELOC_MICROBLAZE_64,
35
36 /* This is a 64 bit reloc that stores the 32 bit pc relative
37+ * +value in two words (with an imm instruction). No relocation is
38+ * +done here - only used for relaxing */
39+ BFD_RELOC_MICROBLAZE_64_NONE,
40+
41+/* This is a 64 bit reloc that stores the 32 bit pc relative
42 value in two words (with an imm instruction). The relocation is
43 PC-relative GOT offset */
44 BFD_RELOC_MICROBLAZE_64_GOTPC,
45diff --git a/bfd/libbfd.h b/bfd/libbfd.h
46index 450653f..d87a183 100644
47--- a/bfd/libbfd.h
48+++ b/bfd/libbfd.h
49@@ -2903,14 +2903,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
50 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
51 "BFD_RELOC_MICROBLAZE_32_NONE",
52 "BFD_RELOC_MICROBLAZE_64_NONE",
53- "BFD_RELOC_MICROBLAZE_64",
54 "BFD_RELOC_MICROBLAZE_64_GOTPC",
55- "BFD_RELOC_MICROBLAZE_64_GPC",
56 "BFD_RELOC_MICROBLAZE_64_GOT",
57 "BFD_RELOC_MICROBLAZE_64_PLT",
58 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
59 "BFD_RELOC_MICROBLAZE_32_GOTOFF",
60 "BFD_RELOC_MICROBLAZE_COPY",
61+ "BFD_RELOC_MICROBLAZE_64",
62+ "BFD_RELOC_MICROBLAZE_64_PCREL",
63 "BFD_RELOC_MICROBLAZE_64_TLS",
64 "BFD_RELOC_MICROBLAZE_64_TLSGD",
65 "BFD_RELOC_MICROBLAZE_64_TLSLD",
66diff --git a/bfd/reloc.c b/bfd/reloc.c
67index ccf29f5..861f2d4 100644
68--- a/bfd/reloc.c
69+++ b/bfd/reloc.c
70@@ -6804,12 +6804,6 @@ ENUMDOC
71 ENUM
72 BFD_RELOC_MICROBLAZE_64_NONE
73 ENUMDOC
74- This is a 32 bit reloc that stores the 32 bit pc relative
75- value in two words (with an imml instruction). No relocation is
76- done here - only used for relaxing
77-ENUM
78- BFD_RELOC_MICROBLAZE_64
79-ENUMDOC
80 This is a 64 bit reloc that stores the 32 bit pc relative
81 value in two words (with an imm instruction). No relocation is
82 done here - only used for relaxing
83@@ -6817,12 +6811,6 @@ ENUM
84 BFD_RELOC_MICROBLAZE_64_GOTPC
85 ENUMDOC
86 This is a 64 bit reloc that stores the 32 bit pc relative
87- value in two words (with an imml instruction). No relocation is
88- done here - only used for relaxing
89-ENUM
90- BFD_RELOC_MICROBLAZE_64_GPC
91-ENUMDOC
92- This is a 64 bit reloc that stores the 32 bit pc relative
93 value in two words (with an imm instruction). The relocation is
94 PC-relative GOT offset
95 ENUM
96@@ -6906,6 +6894,20 @@ ENUMDOC
97 value in two words (with an imm instruction). The relocation is
98 relative offset from start of TEXT.
99
100+ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
101+ to two words (uses imml instruction).
102+ENUM
103+BFD_RELOC_MICROBLAZE_64,
104+ENUMDOC
105+ This is a 64 bit reloc that stores the 64 bit pc relative
106+ value in two words (with an imml instruction). No relocation is
107+ done here - only used for relaxing
108+ENUM
109+BFD_RELOC_MICROBLAZE_64_PCREL,
110+ENUMDOC
111+ This is a 32 bit reloc that stores the 32 bit pc relative
112+ value in two words (with an imml instruction). No relocation is
113+ done here - only used for relaxing
114 ENUM
115 BFD_RELOC_AARCH64_RELOC_START
116 ENUMDOC
117diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
118index 3f90b7c..587a4d5 100644
119--- a/gas/config/tc-microblaze.c
120+++ b/gas/config/tc-microblaze.c
121@@ -95,6 +95,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
122 #define TEXT_OFFSET 17
123 #define TEXT_PC_OFFSET 18
124 #define DEFINED_64_OFFSET 19
125+#define DEFINED_64_PC_OFFSET 20
126
127 /* Initialize the relax table. */
128 const relax_typeS md_relax_table[] =
129@@ -119,7 +120,8 @@ const relax_typeS md_relax_table[] =
130 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
131 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
132 // { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
133- { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 17: DEFINED_64_OFFSET. */
134+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 19: DEFINED_64_OFFSET. */
135+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
136 };
137
138 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
139@@ -1180,33 +1182,6 @@ md_assemble (char * str)
140 inst |= (immed << IMM_LOW) & IMM_MASK;
141 }
142 }
143-#if 0 //revisit
144- else if (streq (name, "lli") || streq (name, "sli"))
145- {
146- temp = immed & 0xFFFFFFFFFFFF8000;
147- if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
148- {
149- /* Needs an immediate inst. */
150- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
151- if (opcode1 == NULL)
152- {
153- as_bad (_("unknown opcode \"%s\""), "imml");
154- return;
155- }
156-
157- inst1 = opcode1->bit_sequence;
158- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
159- output[0] = INST_BYTE0 (inst1);
160- output[1] = INST_BYTE1 (inst1);
161- output[2] = INST_BYTE2 (inst1);
162- output[3] = INST_BYTE3 (inst1);
163- output = frag_more (isize);
164- }
165- inst |= (reg1 << RD_LOW) & RD_MASK;
166- inst |= (reg2 << RA_LOW) & RA_MASK;
167- inst |= (immed << IMM_LOW) & IMM_MASK;
168- }
169-#endif
170 else
171 {
172 temp = immed & 0xFFFF8000;
173@@ -1958,8 +1933,8 @@ md_assemble (char * str)
174
175 if (exp.X_op != O_constant)
176 {
177- char *opc = NULL;
178- //char *opc = str_microblaze_64;
179+ //char *opc = NULL;
180+ char *opc = str_microblaze_64;
181 relax_substateT subtype;
182
183 if (exp.X_md != 0)
184@@ -2221,13 +2196,19 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
185 fragP->fr_fix += INST_WORD_SIZE * 2;
186 fragP->fr_var = 0;
187 break;
188+ case DEFINED_64_PC_OFFSET:
189+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
190+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PCREL);
191+ fragP->fr_fix += INST_WORD_SIZE * 2;
192+ fragP->fr_var = 0;
193+ break;
194 case DEFINED_64_OFFSET:
195 if (fragP->fr_symbol == GOT_symbol)
196 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
197- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GPC);
198+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GPC);
199 else
200 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
201- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64);
202+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64);
203 fragP->fr_fix += INST_WORD_SIZE * 2;
204 fragP->fr_var = 0;
205 break;
206@@ -2237,7 +2218,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
207 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
208 else
209 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
210- fragP->fr_offset, TRUE, BFD_RELOC_64);
211+ fragP->fr_offset, FALSE, BFD_RELOC_64);
212 fragP->fr_fix += INST_WORD_SIZE * 2;
213 fragP->fr_var = 0;
214 break;
215@@ -2457,14 +2438,17 @@ md_apply_fix (fixS * fixP,
216 }
217 }
218 break;
219+
220 case BFD_RELOC_64_PCREL:
221 case BFD_RELOC_64:
222 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
223 case BFD_RELOC_MICROBLAZE_64:
224+ case BFD_RELOC_MICROBLAZE_64_PCREL:
225 /* Add an imm instruction. First save the current instruction. */
226 for (i = 0; i < INST_WORD_SIZE; i++)
227 buf[i + INST_WORD_SIZE] = buf[i];
228- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
229+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
230+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
231 {
232 /* Generate the imm instruction. */
233 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
234@@ -2477,6 +2461,10 @@ md_apply_fix (fixS * fixP,
235 inst1 = opcode1->bit_sequence;
236 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
237 inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
238+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
239+ fixP->fx_r_type = BFD_RELOC_64;
240+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
241+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
242 }
243 else
244 {
245@@ -2487,7 +2475,7 @@ md_apply_fix (fixS * fixP,
246 as_bad (_("unknown opcode \"%s\""), "imm");
247 return;
248 }
249-
250+
251 inst1 = opcode1->bit_sequence;
252 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
253 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
254@@ -2534,7 +2522,7 @@ md_apply_fix (fixS * fixP,
255 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
256 if (opcode1 == NULL)
257 {
258- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
259+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
260 as_bad (_("unknown opcode \"%s\""), "imml");
261 else
262 as_bad (_("unknown opcode \"%s\""), "imm");
263@@ -2561,8 +2549,6 @@ md_apply_fix (fixS * fixP,
264 moves code around due to relaxing. */
265 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
266 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
267- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
268- fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
269 else if (fixP->fx_r_type == BFD_RELOC_32)
270 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
271 else
272@@ -2613,33 +2599,24 @@ md_estimate_size_before_relax (fragS * fragP,
273 if(streq (fragP->fr_opcode, str_microblaze_64))
274 {
275 /* Used as an absolute value. */
276- fragP->fr_subtype = DEFINED_64_OFFSET;
277+ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
278 /* Variable part does not change. */
279- fragP->fr_var = INST_WORD_SIZE;
280+ fragP->fr_var = INST_WORD_SIZE*2;
281 }
282 else
283 {
284 fragP->fr_subtype = DEFINED_PC_OFFSET;
285- /* Don't know now whether we need an imm instruction. */
286+ /* Don't know now whether we need an imm instruction. */
287 fragP->fr_var = INST_WORD_SIZE;
288 }
289 }
290 else
291 {
292 fragP->fr_subtype = DEFINED_PC_OFFSET;
293- /* Don't know now whether we need an imm instruction. */
294+ /* Don't know now whether we need an imm instruction. */
295 fragP->fr_var = INST_WORD_SIZE;
296 }
297 }
298- #if 0
299- else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
300- !S_IS_WEAK (fragP->fr_symbol))
301- {
302- fragP->fr_subtype = DEFINED_PC_OFFSET;
303- /* Don't know now whether we need an imm instruction. */
304- fragP->fr_var = INST_WORD_SIZE;
305- }
306-#endif
307 else if (S_IS_DEFINED (fragP->fr_symbol)
308 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
309 {
310@@ -2669,6 +2646,13 @@ md_estimate_size_before_relax (fragS * fragP,
311 /* Variable part does not change. */
312 fragP->fr_var = INST_WORD_SIZE*2;
313 }
314+ else if (streq (fragP->fr_opcode, str_microblaze_64))
315+ {
316+ /* Used as an absolute value. */
317+ fragP->fr_subtype = DEFINED_64_OFFSET;
318+ /* Variable part does not change. */
319+ fragP->fr_var = INST_WORD_SIZE;
320+ }
321 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
322 {
323 /* It is accessed using the small data read only anchor. */
324@@ -2743,6 +2727,7 @@ md_estimate_size_before_relax (fragS * fragP,
325 case TLSTPREL_OFFSET:
326 case TLSDTPREL_OFFSET:
327 case DEFINED_64_OFFSET:
328+ case DEFINED_64_PC_OFFSET:
329 fragP->fr_var = INST_WORD_SIZE*2;
330 break;
331 case DEFINED_RO_SEGMENT:
332@@ -2796,7 +2781,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
333 else
334 {
335 /* The case where we are going to resolve things... */
336- if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
337+ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
338 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
339 else
340 return fixp->fx_where + fixp->fx_frag->fr_address;
341@@ -2831,6 +2816,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
342 case BFD_RELOC_MICROBLAZE_64_GOTPC:
343 case BFD_RELOC_MICROBLAZE_64_GPC:
344 case BFD_RELOC_MICROBLAZE_64:
345+ case BFD_RELOC_MICROBLAZE_64_PCREL:
346 case BFD_RELOC_MICROBLAZE_64_GOT:
347 case BFD_RELOC_MICROBLAZE_64_PLT:
348 case BFD_RELOC_MICROBLAZE_64_GOTOFF: