blob: 0c3da95a1f1edb76cc7ac91fdddf8a6ad1d21a50 [file] [log] [blame]
Andrew Geissler84ad7c52020-06-27 00:00:16 -05001From bcd4263219c9756b9c1c1df64c6fef1311057fac Mon Sep 17 00:00:00 2001
Brad Bishop26bdd442019-08-16 17:08:17 -04002From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Sun, 30 Sep 2018 16:31:26 +0530
Andrew Geissler84ad7c52020-06-27 00:00:16 -05004Subject: [PATCH 16/43] MB-X initial commit code cleanup is needed.
Brad Bishop26bdd442019-08-16 17:08:17 -04005
6---
7 bfd/bfd-in2.h | 10 +++
Andrew Geissler84ad7c52020-06-27 00:00:16 -05008 bfd/elf32-microblaze.c | 65 +++++++++++++++-
9 bfd/elf64-microblaze.c | 61 ++++++++++++++-
Brad Bishop26bdd442019-08-16 17:08:17 -040010 bfd/libbfd.h | 2 +
Andrew Geissler84ad7c52020-06-27 00:00:16 -050011 bfd/reloc.c | 12 +++
12 gas/config/tc-microblaze.c | 152 ++++++++++++++++++++++++++++++-------
Brad Bishop26bdd442019-08-16 17:08:17 -040013 include/elf/microblaze.h | 2 +
14 opcodes/microblaze-opc.h | 4 +-
15 opcodes/microblaze-opcm.h | 4 +-
16 9 files changed, 277 insertions(+), 35 deletions(-)
17
18diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -050019index 721531886a..4f777059d8 100644
Brad Bishop26bdd442019-08-16 17:08:17 -040020--- a/bfd/bfd-in2.h
21+++ b/bfd/bfd-in2.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -050022@@ -5876,11 +5876,21 @@ done here - only used for relaxing */
23 * +done here - only used for relaxing */
Brad Bishop26bdd442019-08-16 17:08:17 -040024 BFD_RELOC_MICROBLAZE_64_NONE,
25
Andrew Geissler84ad7c52020-06-27 00:00:16 -050026+/* This is a 64 bit reloc that stores the 32 bit pc relative
Brad Bishop26bdd442019-08-16 17:08:17 -040027+ * +value in two words (with an imml instruction). No relocation is
28+ * +done here - only used for relaxing */
29+ BFD_RELOC_MICROBLAZE_64,
30+
Andrew Geissler84ad7c52020-06-27 00:00:16 -050031 /* This is a 64 bit reloc that stores the 32 bit pc relative
Brad Bishop26bdd442019-08-16 17:08:17 -040032 value in two words (with an imm instruction). The relocation is
33 PC-relative GOT offset */
34 BFD_RELOC_MICROBLAZE_64_GOTPC,
35
Andrew Geissler84ad7c52020-06-27 00:00:16 -050036+/* This is a 64 bit reloc that stores the 32 bit pc relative
Brad Bishop26bdd442019-08-16 17:08:17 -040037+value in two words (with an imml instruction). The relocation is
38+PC-relative GOT offset */
39+ BFD_RELOC_MICROBLAZE_64_GPC,
40+
Andrew Geissler84ad7c52020-06-27 00:00:16 -050041 /* This is a 64 bit reloc that stores the 32 bit pc relative
Brad Bishop26bdd442019-08-16 17:08:17 -040042 value in two words (with an imm instruction). The relocation is
43 GOT offset */
Brad Bishop26bdd442019-08-16 17:08:17 -040044diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -050045index d001437b3f..035e71f311 100644
Brad Bishop26bdd442019-08-16 17:08:17 -040046--- a/bfd/elf32-microblaze.c
47+++ b/bfd/elf32-microblaze.c
48@@ -116,6 +116,20 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
49 0x0000ffff, /* Dest Mask. */
50 TRUE), /* PC relative offset? */
51
52+ HOWTO (R_MICROBLAZE_IMML_64, /* Type. */
53+ 0, /* Rightshift. */
54+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
55+ 16, /* Bitsize. */
56+ TRUE, /* PC_relative. */
57+ 0, /* Bitpos. */
58+ complain_overflow_dont, /* Complain on overflow. */
59+ bfd_elf_generic_reloc,/* Special Function. */
60+ "R_MICROBLAZE_IMML_64", /* Name. */
61+ FALSE, /* Partial Inplace. */
62+ 0, /* Source Mask. */
63+ 0x0000ffff, /* Dest Mask. */
64+ FALSE), /* PC relative offset? */
65+
66 /* A 64 bit relocation. Table entry not really used. */
67 HOWTO (R_MICROBLAZE_64, /* Type. */
68 0, /* Rightshift. */
69@@ -280,6 +294,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
70 0x0000ffff, /* Dest Mask. */
71 TRUE), /* PC relative offset? */
72
73+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
74+ HOWTO (R_MICROBLAZE_GPC_64, /* Type. */
75+ 0, /* Rightshift. */
76+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
77+ 16, /* Bitsize. */
78+ TRUE, /* PC_relative. */
79+ 0, /* Bitpos. */
80+ complain_overflow_dont, /* Complain on overflow. */
81+ bfd_elf_generic_reloc, /* Special Function. */
82+ "R_MICROBLAZE_GPC_64", /* Name. */
83+ FALSE, /* Partial Inplace. */
84+ 0, /* Source Mask. */
85+ 0x0000ffff, /* Dest Mask. */
86+ TRUE), /* PC relative offset? */
87+
88 /* A 64 bit GOT relocation. Table-entry not really used. */
89 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
90 0, /* Rightshift. */
91@@ -619,9 +648,15 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
92 case BFD_RELOC_VTABLE_ENTRY:
93 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
94 break;
95+ case BFD_RELOC_MICROBLAZE_64:
96+ microblaze_reloc = R_MICROBLAZE_IMML_64;
97+ break;
98 case BFD_RELOC_MICROBLAZE_64_GOTPC:
99 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
100 break;
101+ case BFD_RELOC_MICROBLAZE_64_GPC:
102+ microblaze_reloc = R_MICROBLAZE_GPC_64;
103+ break;
104 case BFD_RELOC_MICROBLAZE_64_GOT:
105 microblaze_reloc = R_MICROBLAZE_GOT_64;
106 break;
107@@ -1467,7 +1502,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
108 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
109 {
110 relocation += addend;
111- if (r_type == R_MICROBLAZE_32)
112+ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
113 bfd_put_32 (input_bfd, relocation, contents + offset);
114 else
115 {
116@@ -1933,6 +1968,28 @@ microblaze_elf_relax_section (bfd *abfd,
117 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
118 }
119 break;
120+ case R_MICROBLAZE_IMML_64:
121+ {
122+ /* This was a PC-relative instruction that was
123+ completely resolved. */
124+ int sfix, efix;
125+ unsigned int val;
126+ bfd_vma target_address;
127+ target_address = irel->r_addend + irel->r_offset;
128+ sfix = calc_fixup (irel->r_offset, 0, sec);
129+ efix = calc_fixup (target_address, 0, sec);
130+
131+ /* Validate the in-band val. */
132+ val = bfd_get_32 (abfd, contents + irel->r_offset);
133+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
134+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
135+ }
136+ irel->r_addend -= (efix - sfix);
137+ /* Should use HOWTO. */
138+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
139+ irel->r_addend);
140+ }
141+ break;
142 case R_MICROBLAZE_NONE:
143 case R_MICROBLAZE_32_NONE:
144 {
145@@ -2037,9 +2094,9 @@ microblaze_elf_relax_section (bfd *abfd,
146 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
147 irelscan->r_addend);
148 }
149- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
150- {
151- isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
152+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)// || ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
153+ {
154+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
155
156 /* Look at the reloc only if the value has been resolved. */
157 if (isym->st_shndx == shndx
158diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500159index 0f43ae6ea8..56a45f2a05 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400160--- a/bfd/elf64-microblaze.c
161+++ b/bfd/elf64-microblaze.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500162@@ -116,6 +116,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
163 0x0000ffff, /* Dest Mask. */
Brad Bishop26bdd442019-08-16 17:08:17 -0400164 TRUE), /* PC relative offset? */
165
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500166+ /* A 64 bit relocation. Table entry not really used. */
Brad Bishop26bdd442019-08-16 17:08:17 -0400167+ HOWTO (R_MICROBLAZE_IMML_64, /* Type. */
168+ 0, /* Rightshift. */
169+ 4, /* Size (0 = byte, 1 = short, 2 = long). */
170+ 64, /* Bitsize. */
171+ TRUE, /* PC_relative. */
172+ 0, /* Bitpos. */
173+ complain_overflow_dont, /* Complain on overflow. */
174+ bfd_elf_generic_reloc,/* Special Function. */
175+ "R_MICROBLAZE_IMML_64", /* Name. */
176+ FALSE, /* Partial Inplace. */
177+ 0, /* Source Mask. */
178+ 0x0000ffff, /* Dest Mask. */
179+ TRUE), /* PC relative offset? */
180+
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500181 /* A 64 bit relocation. Table entry not really used. */
Brad Bishop26bdd442019-08-16 17:08:17 -0400182 HOWTO (R_MICROBLAZE_64, /* Type. */
183 0, /* Rightshift. */
Brad Bishop26bdd442019-08-16 17:08:17 -0400184@@ -265,6 +280,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
185 0x0000ffff, /* Dest Mask. */
186 TRUE), /* PC relative offset? */
187
188+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
189+ HOWTO (R_MICROBLAZE_GPC_64, /* Type. */
190+ 0, /* Rightshift. */
191+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
192+ 16, /* Bitsize. */
193+ TRUE, /* PC_relative. */
194+ 0, /* Bitpos. */
195+ complain_overflow_dont, /* Complain on overflow. */
196+ bfd_elf_generic_reloc, /* Special Function. */
197+ "R_MICROBLAZE_GPC_64", /* Name. */
198+ FALSE, /* Partial Inplace. */
199+ 0, /* Source Mask. */
200+ 0x0000ffff, /* Dest Mask. */
201+ TRUE), /* PC relative offset? */
202+
203 /* A 64 bit GOT relocation. Table-entry not really used. */
204 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
205 0, /* Rightshift. */
206@@ -589,9 +619,15 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
207 case BFD_RELOC_VTABLE_ENTRY:
208 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
209 break;
210+ case BFD_RELOC_MICROBLAZE_64:
211+ microblaze_reloc = R_MICROBLAZE_IMML_64;
212+ break;
213 case BFD_RELOC_MICROBLAZE_64_GOTPC:
214 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
215 break;
216+ case BFD_RELOC_MICROBLAZE_64_GPC:
217+ microblaze_reloc = R_MICROBLAZE_GPC_64;
218+ break;
219 case BFD_RELOC_MICROBLAZE_64_GOT:
220 microblaze_reloc = R_MICROBLAZE_GOT_64;
221 break;
222@@ -1161,6 +1197,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
223 break; /* Do nothing. */
224
225 case (int) R_MICROBLAZE_GOTPC_64:
226+ case (int) R_MICROBLAZE_GPC_64:
227 relocation = htab->sgotplt->output_section->vma
228 + htab->sgotplt->output_offset;
229 relocation -= (input_section->output_section->vma
230@@ -1431,7 +1468,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
231 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
232 {
233 relocation += addend;
234- if (r_type == R_MICROBLAZE_32)
235+ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
236 bfd_put_32 (input_bfd, relocation, contents + offset);
237 else
238 {
239@@ -1876,6 +1913,28 @@ microblaze_elf_relax_section (bfd *abfd,
240 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
241 }
242 break;
243+ case R_MICROBLAZE_IMML_64:
244+ {
245+ /* This was a PC-relative instruction that was
246+ completely resolved. */
247+ int sfix, efix;
248+ unsigned int val;
249+ bfd_vma target_address;
250+ target_address = irel->r_addend + irel->r_offset;
251+ sfix = calc_fixup (irel->r_offset, 0, sec);
252+ efix = calc_fixup (target_address, 0, sec);
253+
254+ /* Validate the in-band val. */
255+ val = bfd_get_32 (abfd, contents + irel->r_offset);
256+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
257+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
258+ }
259+ irel->r_addend -= (efix - sfix);
260+ /* Should use HOWTO. */
261+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
262+ irel->r_addend);
263+ }
264+ break;
265 case R_MICROBLAZE_NONE:
266 case R_MICROBLAZE_32_NONE:
267 {
268diff --git a/bfd/libbfd.h b/bfd/libbfd.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500269index feb9fada1e..450653f2d8 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400270--- a/bfd/libbfd.h
271+++ b/bfd/libbfd.h
272@@ -2903,7 +2903,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
273 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
274 "BFD_RELOC_MICROBLAZE_32_NONE",
275 "BFD_RELOC_MICROBLAZE_64_NONE",
276+ "BFD_RELOC_MICROBLAZE_64",
277 "BFD_RELOC_MICROBLAZE_64_GOTPC",
278+ "BFD_RELOC_MICROBLAZE_64_GPC",
279 "BFD_RELOC_MICROBLAZE_64_GOT",
280 "BFD_RELOC_MICROBLAZE_64_PLT",
281 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
282diff --git a/bfd/reloc.c b/bfd/reloc.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500283index 87753ae4f0..ccf29f54cf 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400284--- a/bfd/reloc.c
285+++ b/bfd/reloc.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500286@@ -6803,12 +6803,24 @@ ENUMDOC
287 done here - only used for relaxing
Brad Bishop26bdd442019-08-16 17:08:17 -0400288 ENUM
289 BFD_RELOC_MICROBLAZE_64_NONE
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500290+ENUMDOC
Brad Bishop26bdd442019-08-16 17:08:17 -0400291+ This is a 32 bit reloc that stores the 32 bit pc relative
292+ value in two words (with an imml instruction). No relocation is
293+ done here - only used for relaxing
294+ENUM
295+ BFD_RELOC_MICROBLAZE_64
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500296 ENUMDOC
Brad Bishop26bdd442019-08-16 17:08:17 -0400297 This is a 64 bit reloc that stores the 32 bit pc relative
298 value in two words (with an imm instruction). No relocation is
299 done here - only used for relaxing
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500300 ENUM
Brad Bishop26bdd442019-08-16 17:08:17 -0400301 BFD_RELOC_MICROBLAZE_64_GOTPC
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500302+ENUMDOC
303+ This is a 64 bit reloc that stores the 32 bit pc relative
Brad Bishop26bdd442019-08-16 17:08:17 -0400304+ value in two words (with an imml instruction). No relocation is
305+ done here - only used for relaxing
306+ENUM
307+ BFD_RELOC_MICROBLAZE_64_GPC
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500308 ENUMDOC
309 This is a 64 bit reloc that stores the 32 bit pc relative
Brad Bishop26bdd442019-08-16 17:08:17 -0400310 value in two words (with an imm instruction). The relocation is
Brad Bishop26bdd442019-08-16 17:08:17 -0400311diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500312index c79434785a..3f90b7c892 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400313--- a/gas/config/tc-microblaze.c
314+++ b/gas/config/tc-microblaze.c
315@@ -94,6 +94,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
316 #define TLSTPREL_OFFSET 16
317 #define TEXT_OFFSET 17
318 #define TEXT_PC_OFFSET 18
319+#define DEFINED_64_OFFSET 19
320
321 /* Initialize the relax table. */
322 const relax_typeS md_relax_table[] =
323@@ -117,6 +118,8 @@ const relax_typeS md_relax_table[] =
324 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
325 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
326 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
327+// { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
328+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 17: DEFINED_64_OFFSET. */
329 };
330
331 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
332@@ -396,7 +399,8 @@ const pseudo_typeS md_pseudo_table[] =
333 {"data32", cons, 4}, /* Same as word. */
334 {"ent", s_func, 0}, /* Treat ent as function entry point. */
335 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
336- {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
337+ {"gpword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
338+ {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
339 {"weakext", microblaze_s_weakext, 0},
340 {"rodata", microblaze_s_rdata, 0},
341 {"sdata2", microblaze_s_rdata, 1},
342@@ -405,6 +409,7 @@ const pseudo_typeS md_pseudo_table[] =
343 {"sbss", microblaze_s_bss, 1},
344 {"text", microblaze_s_text, 0},
345 {"word", cons, 4},
346+ {"dword", cons, 8},
347 {"frame", s_ignore, 0},
348 {"mask", s_ignore, 0}, /* Emitted by gcc. */
349 {NULL, NULL, 0}
350@@ -898,7 +903,7 @@ check_got (int * got_type, int * got_len)
351 extern bfd_reloc_code_real_type
352 parse_cons_expression_microblaze (expressionS *exp, int size)
353 {
354- if (size == 4)
355+ if (size == 4 || (microblaze_arch_size == 64 && size == 8))
356 {
357 /* Handle @GOTOFF et.al. */
358 char *save, *gotfree_copy;
359@@ -930,6 +935,7 @@ parse_cons_expression_microblaze (expressionS *exp, int size)
360
361 static const char * str_microblaze_ro_anchor = "RO";
362 static const char * str_microblaze_rw_anchor = "RW";
363+static const char * str_microblaze_64 = "64";
364
365 static bfd_boolean
366 check_spl_reg (unsigned * reg)
367@@ -1174,6 +1180,33 @@ md_assemble (char * str)
368 inst |= (immed << IMM_LOW) & IMM_MASK;
369 }
370 }
371+#if 0 //revisit
372+ else if (streq (name, "lli") || streq (name, "sli"))
373+ {
374+ temp = immed & 0xFFFFFFFFFFFF8000;
375+ if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
376+ {
377+ /* Needs an immediate inst. */
378+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
379+ if (opcode1 == NULL)
380+ {
381+ as_bad (_("unknown opcode \"%s\""), "imml");
382+ return;
383+ }
384+
385+ inst1 = opcode1->bit_sequence;
386+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
387+ output[0] = INST_BYTE0 (inst1);
388+ output[1] = INST_BYTE1 (inst1);
389+ output[2] = INST_BYTE2 (inst1);
390+ output[3] = INST_BYTE3 (inst1);
391+ output = frag_more (isize);
392+ }
393+ inst |= (reg1 << RD_LOW) & RD_MASK;
394+ inst |= (reg2 << RA_LOW) & RA_MASK;
395+ inst |= (immed << IMM_LOW) & IMM_MASK;
396+ }
397+#endif
398 else
399 {
400 temp = immed & 0xFFFF8000;
401@@ -1926,6 +1959,7 @@ md_assemble (char * str)
402 if (exp.X_op != O_constant)
403 {
404 char *opc = NULL;
405+ //char *opc = str_microblaze_64;
406 relax_substateT subtype;
407
408 if (exp.X_md != 0)
409@@ -1939,7 +1973,7 @@ md_assemble (char * str)
410 subtype, /* PC-relative or not. */
411 exp.X_add_symbol,
412 exp.X_add_number,
413- opc);
414+ (char *) opc);
415 immedl = 0L;
416 }
417 else
418@@ -1977,7 +2011,7 @@ md_assemble (char * str)
419 reg1 = 0;
420 }
421 if (strcmp (op_end, ""))
422- op_end = parse_imml (op_end + 1, & exp, MIN_IMM, MAX_IMM);
423+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
424 else
425 as_fatal (_("Error in statement syntax"));
426
427@@ -1987,7 +2021,8 @@ md_assemble (char * str)
428
429 if (exp.X_op != O_constant)
430 {
431- char *opc = NULL;
432+ //char *opc = NULL;
433+ char *opc = str_microblaze_64;
434 relax_substateT subtype;
435
436 if (exp.X_md != 0)
437@@ -2001,14 +2036,13 @@ md_assemble (char * str)
438 subtype, /* PC-relative or not. */
439 exp.X_add_symbol,
440 exp.X_add_number,
441- opc);
442+ (char *) opc);
443 immedl = 0L;
444 }
445 else
446 {
447 output = frag_more (isize);
448 immedl = exp.X_add_number;
449-
450 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
451 if (opcode1 == NULL)
452 {
453@@ -2187,13 +2221,23 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
454 fragP->fr_fix += INST_WORD_SIZE * 2;
455 fragP->fr_var = 0;
456 break;
457+ case DEFINED_64_OFFSET:
458+ if (fragP->fr_symbol == GOT_symbol)
459+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
460+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GPC);
461+ else
462+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
463+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64);
464+ fragP->fr_fix += INST_WORD_SIZE * 2;
465+ fragP->fr_var = 0;
466+ break;
467 case DEFINED_ABS_SEGMENT:
468 if (fragP->fr_symbol == GOT_symbol)
469 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
470 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
471 else
472 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
473- fragP->fr_offset, FALSE, BFD_RELOC_64);
474+ fragP->fr_offset, TRUE, BFD_RELOC_64);
475 fragP->fr_fix += INST_WORD_SIZE * 2;
476 fragP->fr_var = 0;
477 break;
478@@ -2416,22 +2460,38 @@ md_apply_fix (fixS * fixP,
479 case BFD_RELOC_64_PCREL:
480 case BFD_RELOC_64:
481 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
482+ case BFD_RELOC_MICROBLAZE_64:
483 /* Add an imm instruction. First save the current instruction. */
484 for (i = 0; i < INST_WORD_SIZE; i++)
485 buf[i + INST_WORD_SIZE] = buf[i];
486+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
487+ {
488+ /* Generate the imm instruction. */
489+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
490+ if (opcode1 == NULL)
491+ {
492+ as_bad (_("unknown opcode \"%s\""), "imml");
493+ return;
494+ }
495
496- /* Generate the imm instruction. */
497- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
498- if (opcode1 == NULL)
499- {
500- as_bad (_("unknown opcode \"%s\""), "imm");
501- return;
502- }
503-
504- inst1 = opcode1->bit_sequence;
505- if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
506- inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
507-
508+ inst1 = opcode1->bit_sequence;
509+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
510+ inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
511+ }
512+ else
513+ {
514+ /* Generate the imm instruction. */
515+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
516+ if (opcode1 == NULL)
517+ {
518+ as_bad (_("unknown opcode \"%s\""), "imm");
519+ return;
520+ }
521+
522+ inst1 = opcode1->bit_sequence;
523+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
524+ inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
525+ }
526 buf[0] = INST_BYTE0 (inst1);
527 buf[1] = INST_BYTE1 (inst1);
528 buf[2] = INST_BYTE2 (inst1);
529@@ -2460,6 +2520,7 @@ md_apply_fix (fixS * fixP,
530 /* Fall through. */
531
532 case BFD_RELOC_MICROBLAZE_64_GOTPC:
533+ case BFD_RELOC_MICROBLAZE_64_GPC:
534 case BFD_RELOC_MICROBLAZE_64_GOT:
535 case BFD_RELOC_MICROBLAZE_64_PLT:
536 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
537@@ -2467,12 +2528,16 @@ md_apply_fix (fixS * fixP,
538 /* Add an imm instruction. First save the current instruction. */
539 for (i = 0; i < INST_WORD_SIZE; i++)
540 buf[i + INST_WORD_SIZE] = buf[i];
541-
542- /* Generate the imm instruction. */
543- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
544+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
545+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
546+ else
547+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
548 if (opcode1 == NULL)
549 {
550- as_bad (_("unknown opcode \"%s\""), "imm");
551+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
552+ as_bad (_("unknown opcode \"%s\""), "imml");
553+ else
554+ as_bad (_("unknown opcode \"%s\""), "imm");
555 return;
556 }
557
558@@ -2496,6 +2561,8 @@ md_apply_fix (fixS * fixP,
559 moves code around due to relaxing. */
560 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
561 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
562+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
563+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
564 else if (fixP->fx_r_type == BFD_RELOC_32)
565 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
566 else
567@@ -2539,6 +2606,32 @@ md_estimate_size_before_relax (fragS * fragP,
568 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
569 abort ();
570 }
571+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type
572+ && !S_IS_WEAK (fragP->fr_symbol))
573+ {
574+ if (fragP->fr_opcode != NULL) {
575+ if(streq (fragP->fr_opcode, str_microblaze_64))
576+ {
577+ /* Used as an absolute value. */
578+ fragP->fr_subtype = DEFINED_64_OFFSET;
579+ /* Variable part does not change. */
580+ fragP->fr_var = INST_WORD_SIZE;
581+ }
582+ else
583+ {
584+ fragP->fr_subtype = DEFINED_PC_OFFSET;
585+ /* Don't know now whether we need an imm instruction. */
586+ fragP->fr_var = INST_WORD_SIZE;
587+ }
588+ }
589+ else
590+ {
591+ fragP->fr_subtype = DEFINED_PC_OFFSET;
592+ /* Don't know now whether we need an imm instruction. */
593+ fragP->fr_var = INST_WORD_SIZE;
594+ }
595+ }
596+ #if 0
597 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
598 !S_IS_WEAK (fragP->fr_symbol))
599 {
600@@ -2546,6 +2639,7 @@ md_estimate_size_before_relax (fragS * fragP,
601 /* Don't know now whether we need an imm instruction. */
602 fragP->fr_var = INST_WORD_SIZE;
603 }
604+#endif
605 else if (S_IS_DEFINED (fragP->fr_symbol)
606 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
607 {
608@@ -2648,6 +2742,7 @@ md_estimate_size_before_relax (fragS * fragP,
609 case TLSLD_OFFSET:
610 case TLSTPREL_OFFSET:
611 case TLSDTPREL_OFFSET:
612+ case DEFINED_64_OFFSET:
613 fragP->fr_var = INST_WORD_SIZE*2;
614 break;
615 case DEFINED_RO_SEGMENT:
616@@ -2701,7 +2796,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
617 else
618 {
619 /* The case where we are going to resolve things... */
620- if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
621+ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
622 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
623 else
624 return fixp->fx_where + fixp->fx_frag->fr_address;
625@@ -2734,6 +2829,8 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
626 case BFD_RELOC_MICROBLAZE_32_RWSDA:
627 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
628 case BFD_RELOC_MICROBLAZE_64_GOTPC:
629+ case BFD_RELOC_MICROBLAZE_64_GPC:
630+ case BFD_RELOC_MICROBLAZE_64:
631 case BFD_RELOC_MICROBLAZE_64_GOT:
632 case BFD_RELOC_MICROBLAZE_64_PLT:
633 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
634@@ -2876,7 +2973,10 @@ cons_fix_new_microblaze (fragS * frag,
635 r = BFD_RELOC_32;
636 break;
637 case 8:
638- r = BFD_RELOC_64;
639+ if (microblaze_arch_size == 64)
640+ r = BFD_RELOC_32;
641+ else
642+ r = BFD_RELOC_64;
643 break;
644 default:
645 as_bad (_("unsupported BFD relocation size %u"), size);
646diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500647index 6ee0966444..16b2736577 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400648--- a/include/elf/microblaze.h
649+++ b/include/elf/microblaze.h
650@@ -62,6 +62,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
651 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
652 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
653 RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
654+ RELOC_NUMBER (R_MICROBLAZE_IMML_64, 34)
655+ RELOC_NUMBER (R_MICROBLAZE_GPC_64, 35) /* GOT entry offset. */
656
657 END_RELOC_NUMBERS (R_MICROBLAZE_max)
658
659diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500660index 985834b8df..9b6264b61c 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400661--- a/opcodes/microblaze-opc.h
662+++ b/opcodes/microblaze-opc.h
663@@ -538,8 +538,8 @@ struct op_code_struct
664 {"llr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000300, OPCODE_MASK_H4, llr, memory_load_inst },
665 {"sl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000100, OPCODE_MASK_H4, sl, memory_store_inst },
666 {"slr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000300, OPCODE_MASK_H4, slr, memory_store_inst },
667- {"lli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst }, /* Identical to 32-bit */
668- {"sli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst }, /* Identical to 32-bit */
669+ {"lli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xEC000000, OPCODE_MASK_H, invalid_inst, memory_load_inst }, /* Identical to 32-bit */
670+ {"sli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xFC000000, OPCODE_MASK_H, invalid_inst, memory_store_inst }, /* Identical to 32-bit */
671 {"lla", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* lla translates to addlik */
672 {"dadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000400, OPCODE_MASK_H4, dadd, arithmetic_inst },
673 {"drsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000480, OPCODE_MASK_H4, drsub, arithmetic_inst },
674diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500675index 076dbcd0b3..5f2e190d23 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400676--- a/opcodes/microblaze-opcm.h
677+++ b/opcodes/microblaze-opcm.h
678@@ -40,8 +40,8 @@ enum microblaze_instr
679 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
680 brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
681 bgtid, bgei, bgeid, lbu, lbuea, lbur, lhu, lhuea, lhur, lw, lwea, lwr, lwx,
682- sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi,
683- sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv,
684+ sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi, lli,
685+ sbi, shi, sli, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv,
686 fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, flt,
687 fint, fsqrt,
688 tget, tcget, tnget, tncget, tput, tcput, tnput, tncput,
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500689--
6902.17.1
691