summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/binutils
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@kernel.crashing.org>2020-07-21 10:53:19 -0500
committerMark Hatle <mark.hatle@kernel.crashing.org>2020-08-14 11:56:33 -0500
commit8138cf33a5d2900bbd44259af9776b78f23763a7 (patch)
tree04792e71c54f4052e51c7939d16750bd2317abd3 /meta-microblaze/recipes-devtools/binutils
parent557ab11ff5be82548b5fd97e9c75b3e9b7524414 (diff)
downloadmeta-xilinx-8138cf33a5d2900bbd44259af9776b78f23763a7.tar.gz
meta-microblaze: Rename recipes-microblaze to match oe-core
Signed-off-by: Mark Hatle <mark.hatle@kernel.crashing.org>
Diffstat (limited to 'meta-microblaze/recipes-devtools/binutils')
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils-cross-canadian_%.bbappend4
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils-cross_%.bbappend4
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc54
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch65
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-mlittle-endian-and-mbig-endian-flags.patch64
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0003-Disable-the-warning-message-for-eh_frame_hdr.patch31
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-relaxation-of-assembler-resolved-references.patch74
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch247
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch39
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0007-Fix-bug-in-TLSTPREL-Relocation.patch33
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-Address-extension-instructions.patch98
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0009-fixing-the-MAX_OPCODES-to-correct-value.patch25
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0010-Add-new-bit-field-instructions.patch230
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0011-fixing-the-imm-bug.patch27
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch33
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0013-fixing-the-constant-range-check-issue.patch26
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch36
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0015-intial-commit-of-MB-64-bit.patch4738
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0016-MB-X-initial-commit.patch691
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch36
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0018-Added-relocations-for-MB-X.patch346
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0019-Fixed-MB-x-relocation-issues.patch373
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0020-Fixing-the-branch-related-issues.patch25
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0021-Fixed-address-computation-issues-with-64bit-address.patch220
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0022-Adding-new-relocation-to-support-64bit-rodata.patch166
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0023-fixing-the-.bss-relocation-issue.patch76
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch44
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch68
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch31
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state.patch76
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-Microblaze-Binutils-security-check-is-causing-.patch33
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0029-fixing-the-long-long-long-mingw-toolchain-issue.patch57
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch359
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0031-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch551
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0032-Add-initial-port-of-linux-gdbserver.patch435
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0033-Initial-port-of-core-reading-support.patch388
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0034-Fix-debug-message-when-register-is-unavailable.patch40
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0035-revert-master-rebase-changes-to-gdbserver.patch31
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0036-revert-master-rebase-changes-to-gdbserver-previous-c.patch33
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0037-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch32
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0038-Initial-support-for-native-gdb.patch511
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0039-Fixing-the-issues-related-to-GDB-7.12.patch309
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-microblaze-Adding-64-bit-MB-support.patch1168
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0041-patch-MicroBlaze-porting-GDB-for-linux.patch155
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0042-Correcting-the-register-names-from-slr-shr-to-rslr-r.patch146
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0043-Removing-the-header-gdb_assert.h-from-MB-target-file.patch24
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch364
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch86
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0046-Patch-MicroBlaze-m64-This-patch-will-remove-imml-0-a.patch38
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0047-Patch-MicroBlaze-commit-for-triggering-build-to-remo.patch25
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0048-Patch-MicroBlaze-Adding-more-description-to-the-imml.patch27
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0049-Patch-MicroBlaze-improper-address-mapping-of-PROVIDE.patch39
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0050-Fix-i386-md_pseudo_table.patch28
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils_%.bbappend4
54 files changed, 12863 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils-cross-canadian_%.bbappend b/meta-microblaze/recipes-devtools/binutils/binutils-cross-canadian_%.bbappend
new file mode 100644
index 00000000..e439cae7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils-cross-canadian_%.bbappend
@@ -0,0 +1,4 @@
1MICROBLAZEPATCHES = ""
2MICROBLAZEPATCHES_microblaze = "binutils-microblaze.inc"
3
4require ${MICROBLAZEPATCHES}
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils-cross_%.bbappend b/meta-microblaze/recipes-devtools/binutils/binutils-cross_%.bbappend
new file mode 100644
index 00000000..e439cae7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils-cross_%.bbappend
@@ -0,0 +1,4 @@
1MICROBLAZEPATCHES = ""
2MICROBLAZEPATCHES_microblaze = "binutils-microblaze.inc"
3
4require ${MICROBLAZEPATCHES}
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc b/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
new file mode 100644
index 00000000..ed6e75b2
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
@@ -0,0 +1,54 @@
1FILESEXTRAPATHS_append := ":${THISDIR}/binutils"
2
3SRC_URI_append = " \
4 file://0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch \
5 file://0002-Add-mlittle-endian-and-mbig-endian-flags.patch \
6 file://0003-Disable-the-warning-message-for-eh_frame_hdr.patch \
7 file://0004-Fix-relaxation-of-assembler-resolved-references.patch \
8 file://0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch \
9 file://0006-upstream-change-to-garbage-collection-sweep-causes-m.patch \
10 file://0007-Fix-bug-in-TLSTPREL-Relocation.patch \
11 file://0008-Added-Address-extension-instructions.patch \
12 file://0009-fixing-the-MAX_OPCODES-to-correct-value.patch \
13 file://0010-Add-new-bit-field-instructions.patch \
14 file://0011-fixing-the-imm-bug.patch \
15 file://0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch \
16 file://0013-fixing-the-constant-range-check-issue.patch \
17 file://0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch \
18 file://0015-intial-commit-of-MB-64-bit.patch \
19 file://0016-MB-X-initial-commit.patch \
20 file://0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch \
21 file://0018-Added-relocations-for-MB-X.patch \
22 file://0019-Fixed-MB-x-relocation-issues.patch \
23 file://0020-Fixing-the-branch-related-issues.patch \
24 file://0021-Fixed-address-computation-issues-with-64bit-address.patch \
25 file://0022-Adding-new-relocation-to-support-64bit-rodata.patch \
26 file://0023-fixing-the-.bss-relocation-issue.patch \
27 file://0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch \
28 file://0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch \
29 file://0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch \
30 file://0027-Revert-ld-Remove-unused-expression-state.patch \
31 file://0028-Patch-Microblaze-Binutils-security-check-is-causing-.patch \
32 file://0029-fixing-the-long-long-long-mingw-toolchain-issue.patch \
33 file://0030-Added-support-to-new-arithmetic-single-register-inst.patch \
34 file://0031-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch \
35 file://0032-Add-initial-port-of-linux-gdbserver.patch \
36 file://0033-Initial-port-of-core-reading-support.patch \
37 file://0034-Fix-debug-message-when-register-is-unavailable.patch \
38 file://0035-revert-master-rebase-changes-to-gdbserver.patch \
39 file://0036-revert-master-rebase-changes-to-gdbserver-previous-c.patch \
40 file://0037-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch \
41 file://0038-Initial-support-for-native-gdb.patch \
42 file://0039-Fixing-the-issues-related-to-GDB-7.12.patch \
43 file://0040-Patch-microblaze-Adding-64-bit-MB-support.patch \
44 file://0041-patch-MicroBlaze-porting-GDB-for-linux.patch \
45 file://0042-Correcting-the-register-names-from-slr-shr-to-rslr-r.patch \
46 file://0043-Removing-the-header-gdb_assert.h-from-MB-target-file.patch \
47 file://0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch \
48 file://0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch \
49 file://0046-Patch-MicroBlaze-m64-This-patch-will-remove-imml-0-a.patch \
50 file://0047-Patch-MicroBlaze-commit-for-triggering-build-to-remo.patch \
51 file://0048-Patch-MicroBlaze-Adding-more-description-to-the-imml.patch \
52 file://0049-Patch-MicroBlaze-improper-address-mapping-of-PROVIDE.patch \
53 file://0050-Fix-i386-md_pseudo_table.patch \
54 "
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch
new file mode 100644
index 00000000..e0de79fd
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch
@@ -0,0 +1,65 @@
1From 247ead894f7079a4ededf2b48a65ffa6e78e2222 Mon Sep 17 00:00:00 2001
2From: David Holsgrove <david.holsgrove@xilinx.com>
3Date: Wed, 8 May 2013 11:03:36 +1000
4Subject: [PATCH 01/43] Add wdc.ext.clear and wdc.ext.flush insns
5
6Added two new instructions, wdc.ext.clear and wdc.ext.flush,
7to enable MicroBlaze to flush an external cache, which is
8used with the new coherency support for multiprocessing.
9
10Signed-off-by:nagaraju <nmekala@xilix.com>
11Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
12---
13 opcodes/microblaze-opc.h | 5 ++++-
14 opcodes/microblaze-opcm.h | 4 ++--
15 2 files changed, 6 insertions(+), 3 deletions(-)
16
17diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
18index 62ee3c9a4d..865151f95b 100644
19--- a/opcodes/microblaze-opc.h
20+++ b/opcodes/microblaze-opc.h
21@@ -91,6 +91,7 @@
22 #define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */
23 #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */
24 #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */
25+#define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */
26 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
27
28 /* New Mask for msrset, msrclr insns. */
29@@ -101,7 +102,7 @@
30 #define DELAY_SLOT 1
31 #define NO_DELAY_SLOT 0
32
33-#define MAX_OPCODES 289
34+#define MAX_OPCODES 291
35
36 struct op_code_struct
37 {
38@@ -174,7 +175,9 @@ struct op_code_struct
39 {"wic", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
40 {"wdc", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
41 {"wdc.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst },
42+ {"wdc.ext.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000466, OPCODE_MASK_H35B, wdcextclear, special_inst },
43 {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst },
44+ {"wdc.ext.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000476, OPCODE_MASK_H35B, wdcextflush, special_inst },
45 {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
46 {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
47 {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
48diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
49index 5a2d3b0c8b..42f3dd3be5 100644
50--- a/opcodes/microblaze-opcm.h
51+++ b/opcodes/microblaze-opcm.h
52@@ -33,8 +33,8 @@ enum microblaze_instr
53 /* 'or/and/xor' are C++ keywords. */
54 microblaze_or, microblaze_and, microblaze_xor,
55 andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16,
56- wic, wdc, wdcclear, wdcflush, mts, mfs, mbar, br, brd,
57- brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
58+ wic, wdc, wdcclear, wdcextclear, wdcflush, wdcextflush, mts, mfs, mbar, br,
59+ brd, brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
60 bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
61 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
62 brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
63--
642.17.1
65
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-mlittle-endian-and-mbig-endian-flags.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-mlittle-endian-and-mbig-endian-flags.patch
new file mode 100644
index 00000000..98e40c0e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-mlittle-endian-and-mbig-endian-flags.patch
@@ -0,0 +1,64 @@
1From 7163824e07ade3ad2dc24e888265d27e0bc87869 Mon Sep 17 00:00:00 2001
2From: nagaraju <nmekala@xilix.com>
3Date: Tue, 19 Mar 2013 17:18:23 +0530
4Subject: [PATCH 02/43] Add mlittle-endian and mbig-endian flags
5
6Added support in gas for mlittle-endian and mbig-endian flags
7as options.
8
9Updated show usage for MicroBlaze specific assembler options
10to include new entries.
11
12Signed-off-by:nagaraju <nmekala@xilix.com>
13Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
14---
15 gas/config/tc-microblaze.c | 9 +++++++++
16 1 file changed, 9 insertions(+)
17
18diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
19index ab90c6b20f..c92e9ce563 100644
20--- a/gas/config/tc-microblaze.c
21+++ b/gas/config/tc-microblaze.c
22@@ -37,6 +37,8 @@
23
24 #define OPTION_EB (OPTION_MD_BASE + 0)
25 #define OPTION_EL (OPTION_MD_BASE + 1)
26+#define OPTION_LITTLE (OPTION_MD_BASE + 2)
27+#define OPTION_BIG (OPTION_MD_BASE + 3)
28
29 void microblaze_generate_symbol (char *sym);
30 static bfd_boolean check_spl_reg (unsigned *);
31@@ -1845,6 +1847,8 @@ struct option md_longopts[] =
32 {
33 {"EB", no_argument, NULL, OPTION_EB},
34 {"EL", no_argument, NULL, OPTION_EL},
35+ {"mlittle-endian", no_argument, NULL, OPTION_LITTLE},
36+ {"mbig-endian", no_argument, NULL, OPTION_BIG},
37 { NULL, no_argument, NULL, 0}
38 };
39
40@@ -2498,9 +2502,11 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
41 switch (c)
42 {
43 case OPTION_EB:
44+ case OPTION_BIG:
45 target_big_endian = 1;
46 break;
47 case OPTION_EL:
48+ case OPTION_LITTLE:
49 target_big_endian = 0;
50 break;
51 default:
52@@ -2515,6 +2521,9 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
53 /* fprintf(stream, _("\
54 MicroBlaze options:\n\
55 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
56+ fprintf (stream, _(" MicroBlaze specific assembler options:\n"));
57+ fprintf (stream, " -%-23s%s\n", "mbig-endian", N_("assemble for a big endian cpu"));
58+ fprintf (stream, " -%-23s%s\n", "mlittle-endian", N_("assemble for a little endian cpu"));
59 }
60
61
62--
632.17.1
64
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0003-Disable-the-warning-message-for-eh_frame_hdr.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0003-Disable-the-warning-message-for-eh_frame_hdr.patch
new file mode 100644
index 00000000..445f5dd8
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0003-Disable-the-warning-message-for-eh_frame_hdr.patch
@@ -0,0 +1,31 @@
1From 2b9eec7fdfae66c5500baef444559976d1b20e0b Mon Sep 17 00:00:00 2001
2From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
3Date: Fri, 22 Jun 2012 01:20:20 +0200
4Subject: [PATCH 03/43] Disable the warning message for eh_frame_hdr
5
6Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
7---
8 bfd/elf-eh-frame.c | 3 +++
9 1 file changed, 3 insertions(+)
10
11diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
12index a13e81ebb8..1824ba6e5b 100644
13--- a/bfd/elf-eh-frame.c
14+++ b/bfd/elf-eh-frame.c
15@@ -1044,10 +1044,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
16 goto success;
17
18 free_no_table:
19+/* FIXME: Remove the microblaze specifics when relaxing gets fixed. */
20+if (bfd_get_arch(abfd) != bfd_arch_microblaze) {
21 _bfd_error_handler
22 /* xgettext:c-format */
23 (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
24 abfd, sec);
25+}
26 hdr_info->u.dwarf.table = FALSE;
27 if (sec_info)
28 free (sec_info);
29--
302.17.1
31
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-relaxation-of-assembler-resolved-references.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-relaxation-of-assembler-resolved-references.patch
new file mode 100644
index 00000000..d1b754c3
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-relaxation-of-assembler-resolved-references.patch
@@ -0,0 +1,74 @@
1From ababe1df64146c616455eb1af4cf8fd21eb6f42c Mon Sep 17 00:00:00 2001
2From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
3Date: Tue, 14 Feb 2012 01:00:22 +0100
4Subject: [PATCH 04/43] Fix relaxation of assembler resolved references
5
6---
7 bfd/elf32-microblaze.c | 38 ++++++++++++++++++++++++++++++++++++++
8 gas/config/tc-microblaze.c | 1 +
9 2 files changed, 39 insertions(+)
10
11diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
12index e3c8027248..359484dd5e 100644
13--- a/bfd/elf32-microblaze.c
14+++ b/bfd/elf32-microblaze.c
15@@ -1973,6 +1973,44 @@ microblaze_elf_relax_section (bfd *abfd,
16 irelscanend = irelocs + o->reloc_count;
17 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
18 {
19+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE)
20+ {
21+ unsigned int val;
22+
23+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
24+
25+ /* This was a PC-relative instruction that was completely resolved. */
26+ if (ocontents == NULL)
27+ {
28+ if (elf_section_data (o)->this_hdr.contents != NULL)
29+ ocontents = elf_section_data (o)->this_hdr.contents;
30+ else
31+ {
32+ /* We always cache the section contents.
33+ Perhaps, if info->keep_memory is FALSE, we
34+ should free them, if we are permitted to. */
35+
36+ if (o->rawsize == 0)
37+ o->rawsize = o->size;
38+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
39+ if (ocontents == NULL)
40+ goto error_return;
41+ if (!bfd_get_section_contents (abfd, o, ocontents,
42+ (file_ptr) 0,
43+ o->rawsize))
44+ goto error_return;
45+ elf_section_data (o)->this_hdr.contents = ocontents;
46+ }
47+ }
48+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
49+ + isym->st_value, sec);
50+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
51+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
52+ irelscan->r_addend);
53+ }
54+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_NONE) {
55+ fprintf(stderr, "Unhandled NONE 64\n");
56+ }
57 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
58 {
59 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
60diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
61index c92e9ce563..3e728400b7 100644
62--- a/gas/config/tc-microblaze.c
63+++ b/gas/config/tc-microblaze.c
64@@ -2205,6 +2205,7 @@ md_apply_fix (fixS * fixP,
65 else
66 fixP->fx_r_type = BFD_RELOC_NONE;
67 fixP->fx_addsy = section_symbol (absolute_section);
68+ fixP->fx_done = 0;
69 }
70 return;
71 }
72--
732.17.1
74
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch
new file mode 100644
index 00000000..ac13e6e3
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch
@@ -0,0 +1,247 @@
1From e9837b5aec42b084c93868095b409f9a6a81b570 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 6 Feb 2017 15:53:08 +0530
4Subject: [PATCH 05/43] [LOCAL]: Fixup debug_loc sections after linker
5 relaxation Adds a new reloctype R_MICROBLAZE_32_NONE, used for passing reloc
6 info from the assembler to the linker when the linker manages to fully
7 resolve a local symbol reference.
8
9This is a workaround for design flaws in the assembler to
10linker interface with regards to linker relaxation.
11
12Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
13Signed-off-by: Nagaraju Mekala <nmekala@xilinx.com>
14---
15 bfd/bfd-in2.h | 9 +++++--
16 bfd/elf32-microblaze.c | 53 ++++++++++++++++++++++++++++----------
17 bfd/libbfd.h | 1 +
18 bfd/reloc.c | 6 +++++
19 binutils/readelf.c | 4 +++
20 gas/config/tc-microblaze.c | 5 +++-
21 include/elf/microblaze.h | 2 ++
22 7 files changed, 64 insertions(+), 16 deletions(-)
23
24diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
25index e25da50aaf..721531886a 100644
26--- a/bfd/bfd-in2.h
27+++ b/bfd/bfd-in2.h
28@@ -5866,10 +5866,15 @@ value relative to the read-write small data area anchor */
29 expressions of the form "Symbol Op Symbol" */
30 BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
31
32-/* This is a 64 bit reloc that stores the 32 bit pc relative
33+/* This is a 32 bit reloc that stores the 32 bit pc relative
34 value in two words (with an imm instruction). No relocation is
35 done here - only used for relaxing */
36- BFD_RELOC_MICROBLAZE_64_NONE,
37+ BFD_RELOC_MICROBLAZE_32_NONE,
38+
39+/* This is a 64 bit reloc that stores the 32 bit pc relative
40+ * +value in two words (with an imm instruction). No relocation is
41+ * +done here - only used for relaxing */
42+ BFD_RELOC_MICROBLAZE_64_NONE,
43
44 /* This is a 64 bit reloc that stores the 32 bit pc relative
45 value in two words (with an imm instruction). The relocation is
46diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
47index 359484dd5e..1c69c269c7 100644
48--- a/bfd/elf32-microblaze.c
49+++ b/bfd/elf32-microblaze.c
50@@ -176,7 +176,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
51 0x0000ffff, /* Dest Mask. */
52 FALSE), /* PC relative offset? */
53
54- /* This reloc does nothing. Used for relaxation. */
55+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
56+ 0, /* Rightshift. */
57+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
58+ 32, /* Bitsize. */
59+ TRUE, /* PC_relative. */
60+ 0, /* Bitpos. */
61+ complain_overflow_bitfield, /* Complain on overflow. */
62+ NULL, /* Special Function. */
63+ "R_MICROBLAZE_32_NONE",/* Name. */
64+ FALSE, /* Partial Inplace. */
65+ 0, /* Source Mask. */
66+ 0, /* Dest Mask. */
67+ FALSE), /* PC relative offset? */
68+
69+ /* This reloc does nothing. Used for relaxation. */
70 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
71 0, /* Rightshift. */
72 3, /* Size (0 = byte, 1 = short, 2 = long). */
73@@ -562,6 +576,9 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
74 case BFD_RELOC_NONE:
75 microblaze_reloc = R_MICROBLAZE_NONE;
76 break;
77+ case BFD_RELOC_MICROBLAZE_32_NONE:
78+ microblaze_reloc = R_MICROBLAZE_32_NONE;
79+ break;
80 case BFD_RELOC_MICROBLAZE_64_NONE:
81 microblaze_reloc = R_MICROBLAZE_64_NONE;
82 break;
83@@ -1918,6 +1935,7 @@ microblaze_elf_relax_section (bfd *abfd,
84 }
85 break;
86 case R_MICROBLAZE_NONE:
87+ case R_MICROBLAZE_32_NONE:
88 {
89 /* This was a PC-relative instruction that was
90 completely resolved. */
91@@ -1926,12 +1944,18 @@ microblaze_elf_relax_section (bfd *abfd,
92 target_address = irel->r_addend + irel->r_offset;
93 sfix = calc_fixup (irel->r_offset, 0, sec);
94 efix = calc_fixup (target_address, 0, sec);
95+
96+ /* Validate the in-band val. */
97+ val = bfd_get_32 (abfd, contents + irel->r_offset);
98+ if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
99+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
100+ }
101 irel->r_addend -= (efix - sfix);
102 /* Should use HOWTO. */
103 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
104 irel->r_addend);
105- }
106- break;
107+ }
108+ break;
109 case R_MICROBLAZE_64_NONE:
110 {
111 /* This was a PC-relative 64-bit instruction that was
112@@ -1973,12 +1997,16 @@ microblaze_elf_relax_section (bfd *abfd,
113 irelscanend = irelocs + o->reloc_count;
114 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
115 {
116- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE)
117+ if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
118 {
119 unsigned int val;
120
121 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
122
123+ /* hax: We only do the following fixup for debug location lists. */
124+ if (strcmp(".debug_loc", o->name))
125+ continue;
126+
127 /* This was a PC-relative instruction that was completely resolved. */
128 if (ocontents == NULL)
129 {
130@@ -1999,18 +2027,17 @@ microblaze_elf_relax_section (bfd *abfd,
131 (file_ptr) 0,
132 o->rawsize))
133 goto error_return;
134- elf_section_data (o)->this_hdr.contents = ocontents;
135- }
136- }
137- irelscan->r_addend -= calc_fixup (irelscan->r_addend
138- + isym->st_value, sec);
139+ elf_section_data (o)->this_hdr.contents = ocontents;
140+ }
141+ }
142 val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
143+ if (val != irelscan->r_addend) {
144+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
145+ }
146+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
147 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
148 irelscan->r_addend);
149 }
150- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_NONE) {
151- fprintf(stderr, "Unhandled NONE 64\n");
152- }
153 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
154 {
155 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
156@@ -2070,7 +2097,7 @@ microblaze_elf_relax_section (bfd *abfd,
157 elf_section_data (o)->this_hdr.contents = ocontents;
158 }
159 }
160- irelscan->r_addend -= calc_fixup (irel->r_addend
161+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
162 + isym->st_value,
163 0,
164 sec);
165diff --git a/bfd/libbfd.h b/bfd/libbfd.h
166index 36284d71a9..feb9fada1e 100644
167--- a/bfd/libbfd.h
168+++ b/bfd/libbfd.h
169@@ -2901,6 +2901,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
170 "BFD_RELOC_MICROBLAZE_32_ROSDA",
171 "BFD_RELOC_MICROBLAZE_32_RWSDA",
172 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
173+ "BFD_RELOC_MICROBLAZE_32_NONE",
174 "BFD_RELOC_MICROBLAZE_64_NONE",
175 "BFD_RELOC_MICROBLAZE_64_GOTPC",
176 "BFD_RELOC_MICROBLAZE_64_GOT",
177diff --git a/bfd/reloc.c b/bfd/reloc.c
178index e6446a7809..87753ae4f0 100644
179--- a/bfd/reloc.c
180+++ b/bfd/reloc.c
181@@ -6795,6 +6795,12 @@ ENUM
182 ENUMDOC
183 This is a 32 bit reloc for the microblaze to handle
184 expressions of the form "Symbol Op Symbol"
185+ENUM
186+ BFD_RELOC_MICROBLAZE_32_NONE
187+ENUMDOC
188+ This is a 32 bit reloc that stores the 32 bit pc relative
189+ value in two words (with an imm instruction). No relocation is
190+ done here - only used for relaxing
191 ENUM
192 BFD_RELOC_MICROBLAZE_64_NONE
193 ENUMDOC
194diff --git a/binutils/readelf.c b/binutils/readelf.c
195index b13eb6a43b..da6252c128 100644
196--- a/binutils/readelf.c
197+++ b/binutils/readelf.c
198@@ -13019,6 +13019,10 @@ is_none_reloc (Filedata * filedata, unsigned int reloc_type)
199 || reloc_type == 32 /* R_AVR_DIFF32. */);
200 case EM_METAG:
201 return reloc_type == 3; /* R_METAG_NONE. */
202+ case EM_MICROBLAZE:
203+ return reloc_type == 30 /* R_MICROBLAZE_32_NONE. */
204+ || reloc_type == 0 /* R_MICROBLAZE_NONE. */
205+ || reloc_type == 9; /* R_MICROBLAZE_64_NONE. */
206 case EM_NDS32:
207 return (reloc_type == 0 /* R_XTENSA_NONE. */
208 || reloc_type == 204 /* R_NDS32_DIFF8. */
209diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
210index 3e728400b7..fa665b4e25 100644
211--- a/gas/config/tc-microblaze.c
212+++ b/gas/config/tc-microblaze.c
213@@ -2201,7 +2201,9 @@ md_apply_fix (fixS * fixP,
214 /* This fixup has been resolved. Create a reloc in case the linker
215 moves code around due to relaxing. */
216 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
217- fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
218+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
219+ else if (fixP->fx_r_type == BFD_RELOC_32)
220+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
221 else
222 fixP->fx_r_type = BFD_RELOC_NONE;
223 fixP->fx_addsy = section_symbol (absolute_section);
224@@ -2426,6 +2428,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
225 switch (fixp->fx_r_type)
226 {
227 case BFD_RELOC_NONE:
228+ case BFD_RELOC_MICROBLAZE_32_NONE:
229 case BFD_RELOC_MICROBLAZE_64_NONE:
230 case BFD_RELOC_32:
231 case BFD_RELOC_MICROBLAZE_32_LO:
232diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
233index 830b5ad446..6ee0966444 100644
234--- a/include/elf/microblaze.h
235+++ b/include/elf/microblaze.h
236@@ -61,6 +61,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
237 RELOC_NUMBER (R_MICROBLAZE_TEXTPCREL_64, 30) /* PC-relative TEXT offset. */
238 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
239 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
240+ RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
241+
242 END_RELOC_NUMBERS (R_MICROBLAZE_max)
243
244 /* Global base address names. */
245--
2462.17.1
247
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch
new file mode 100644
index 00000000..97d692c7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch
@@ -0,0 +1,39 @@
1From 403d6e82742452be4e3f3010c8d9989f0a490c0b Mon Sep 17 00:00:00 2001
2From: David Holsgrove <david.holsgrove@xilinx.com>
3Date: Wed, 27 Feb 2013 13:56:11 +1000
4Subject: [PATCH 06/43] upstream change to garbage collection sweep causes mb
5 regression
6
7Upstream change for PR13177 now clears the def_regular during gc_sweep of a
8section. (All other archs in binutils/bfd/elf32-*.c received an update
9to a warning about unresolvable relocations - this warning is not present
10in binutils/bfd/elf32-microblaze.c, but this warning check would not
11prevent the error being seen)
12
13The visible issue with this change is when running a c++ application
14in Petalinux which links libstdc++.so for exception handling it segfaults
15on execution.
16
17This does not occur if static linking libstdc++.a, so its during the
18relocations for a shared lib with garbage collection this occurs
19
20Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
21---
22 bfd/elflink.c | 1 -
23 1 file changed, 1 deletion(-)
24
25diff --git a/bfd/elflink.c b/bfd/elflink.c
26index e50c0e4b38..09d43e3ca5 100644
27--- a/bfd/elflink.c
28+++ b/bfd/elflink.c
29@@ -6187,7 +6187,6 @@ elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
30
31 inf = (struct elf_gc_sweep_symbol_info *) data;
32 (*inf->hide_symbol) (inf->info, h, TRUE);
33- h->def_regular = 0;
34 h->ref_regular = 0;
35 h->ref_regular_nonweak = 0;
36 }
37--
382.17.1
39
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0007-Fix-bug-in-TLSTPREL-Relocation.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0007-Fix-bug-in-TLSTPREL-Relocation.patch
new file mode 100644
index 00000000..49534b4e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0007-Fix-bug-in-TLSTPREL-Relocation.patch
@@ -0,0 +1,33 @@
1From 072a8968c50b2ebd93e225a6b959916f9d60b493 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 15 Jun 2015 16:50:30 +0530
4Subject: [PATCH 07/43] Fix bug in TLSTPREL Relocation
5
6Fixed the problem related to the fixup/relocations TLSTPREL.
7When the fixup is applied the addend is not added at the correct offset
8of the instruction. The offset is hard coded considering its big endian
9and it fails for Little endian. This patch allows support for both
10big & little-endian compilers
11---
12 bfd/elf32-microblaze.c | 4 ++--
13 1 file changed, 2 insertions(+), 2 deletions(-)
14
15diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
16index 1c69c269c7..d19a6dca84 100644
17--- a/bfd/elf32-microblaze.c
18+++ b/bfd/elf32-microblaze.c
19@@ -1451,9 +1451,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
20 relocation += addend;
21 relocation -= dtprel_base(info);
22 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
23- contents + offset + 2);
24+ contents + offset + endian);
25 bfd_put_16 (input_bfd, relocation & 0xffff,
26- contents + offset + 2 + INST_WORD_SIZE);
27+ contents + offset + endian + INST_WORD_SIZE);
28 break;
29 case (int) R_MICROBLAZE_TEXTREL_64:
30 case (int) R_MICROBLAZE_TEXTREL_32_LO:
31--
322.17.1
33
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-Address-extension-instructions.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-Address-extension-instructions.patch
new file mode 100644
index 00000000..51fcee90
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-Address-extension-instructions.patch
@@ -0,0 +1,98 @@
1From 4674056da6bafa8168c0a680498b958f3a39be94 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 18 Jan 2016 12:28:21 +0530
4Subject: [PATCH 08/43] Added Address extension instructions
5
6This patch adds the support of new instructions which are required
7for supporting Address extension feature.
8
9Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
10
11ChangeLog:
12 2016-01-18 Nagaraju Mekala <nmekala@xilix.com>
13
14 *microblaze-opc.h (op_code_struct): Update
15 Added new instructions
16 *microblaze-opcm.h (microblaze_instr): Update
17 Added new instructions
18---
19 opcodes/microblaze-opc.h | 11 +++++++++++
20 opcodes/microblaze-opcm.h | 10 +++++-----
21 2 files changed, 16 insertions(+), 5 deletions(-)
22
23diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
24index 865151f95b..330f1040e7 100644
25--- a/opcodes/microblaze-opc.h
26+++ b/opcodes/microblaze-opc.h
27@@ -178,8 +178,11 @@ struct op_code_struct
28 {"wdc.ext.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000466, OPCODE_MASK_H35B, wdcextclear, special_inst },
29 {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst },
30 {"wdc.ext.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000476, OPCODE_MASK_H35B, wdcextflush, special_inst },
31+ {"wdc.clear.ea", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E6, OPCODE_MASK_H34B, wdcclearea, special_inst },
32 {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
33+ {"mtse", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9500C000, OPCODE_MASK_H13S, mtse,special_inst },
34 {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
35+ {"mfse", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94088000, OPCODE_MASK_H23S, mfse, special_inst },
36 {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
37 {"brd", INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98100000, OPCODE_MASK_H124, brd, branch_inst },
38 {"brld", INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98140000, OPCODE_MASK_H24, brld, branch_inst },
39@@ -229,18 +232,24 @@ struct op_code_struct
40 {"bgeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBEA00000, OPCODE_MASK_H1, bgeid, branch_inst },
41 {"lbu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000000, OPCODE_MASK_H4, lbu, memory_load_inst },
42 {"lbur", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000200, OPCODE_MASK_H4, lbur, memory_load_inst },
43+ {"lbuea", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000080, OPCODE_MASK_H4, lbuea, memory_load_inst },
44 {"lhu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000000, OPCODE_MASK_H4, lhu, memory_load_inst },
45 {"lhur", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000200, OPCODE_MASK_H4, lhur, memory_load_inst },
46+ {"lhuea", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000080, OPCODE_MASK_H4, lhuea, memory_load_inst },
47 {"lw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000000, OPCODE_MASK_H4, lw, memory_load_inst },
48 {"lwr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000200, OPCODE_MASK_H4, lwr, memory_load_inst },
49 {"lwx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000400, OPCODE_MASK_H4, lwx, memory_load_inst },
50+ {"lwea", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000080, OPCODE_MASK_H4, lwea, memory_load_inst },
51 {"sb", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000000, OPCODE_MASK_H4, sb, memory_store_inst },
52 {"sbr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000200, OPCODE_MASK_H4, sbr, memory_store_inst },
53+ {"sbea", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000080, OPCODE_MASK_H4, sbea, memory_store_inst },
54 {"sh", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000000, OPCODE_MASK_H4, sh, memory_store_inst },
55 {"shr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000200, OPCODE_MASK_H4, shr, memory_store_inst },
56+ {"shea", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000080, OPCODE_MASK_H4, shea, memory_store_inst },
57 {"sw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000000, OPCODE_MASK_H4, sw, memory_store_inst },
58 {"swr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000200, OPCODE_MASK_H4, swr, memory_store_inst },
59 {"swx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000400, OPCODE_MASK_H4, swx, memory_store_inst },
60+ {"swea", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000080, OPCODE_MASK_H4, swea, memory_store_inst },
61 {"lbui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst },
62 {"lhui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst },
63 {"lwi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, lwi, memory_load_inst },
64@@ -405,6 +414,8 @@ struct op_code_struct
65 {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst },
66 {"mbar", INST_TYPE_IMM5, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8020004, OPCODE_MASK_HN, mbar, special_inst },
67 {"sleep", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBA020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 16. */
68+ {"hibernate", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB9020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 8. */
69+ {"suspend", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBB020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 24. */
70 {"swapb", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E0, OPCODE_MASK_H4, swapb, arithmetic_inst },
71 {"swaph", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E2, OPCODE_MASK_H4, swaph, arithmetic_inst },
72 {"", 0, 0, 0, 0, 0, 0, 0, 0},
73diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
74index 42f3dd3be5..1c39dbf50b 100644
75--- a/opcodes/microblaze-opcm.h
76+++ b/opcodes/microblaze-opcm.h
77@@ -33,13 +33,13 @@ enum microblaze_instr
78 /* 'or/and/xor' are C++ keywords. */
79 microblaze_or, microblaze_and, microblaze_xor,
80 andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16,
81- wic, wdc, wdcclear, wdcextclear, wdcflush, wdcextflush, mts, mfs, mbar, br,
82- brd, brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
83- bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
84+ wic, wdc, wdcclear, wdcextclear, wdcflush, wdcextflush, wdcclearea, mts, mtse,
85+ mfs, mfse, mbar, br, brd, brld, bra, brad, brald, microblaze_brk, beq, beqd,
86+ bne, bned, blt, bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
87 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
88 brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
89- bgtid, bgei, bgeid, lbu, lbur, lhu, lhur, lw, lwr, lwx, sb, sbr, sh,
90- shr, sw, swr, swx, lbui, lhui, lwi,
91+ bgtid, bgei, bgeid, lbu, lbuea, lbur, lhu, lhuea, lhur, lw, lwea, lwr, lwx,
92+ sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi,
93 sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv,
94 fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, flt,
95 fint, fsqrt,
96--
972.17.1
98
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0009-fixing-the-MAX_OPCODES-to-correct-value.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0009-fixing-the-MAX_OPCODES-to-correct-value.patch
new file mode 100644
index 00000000..d93ccd20
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0009-fixing-the-MAX_OPCODES-to-correct-value.patch
@@ -0,0 +1,25 @@
1From 7651a2f7ab486e26981cb5e032bf578d0951ff4a Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Thu, 28 Jan 2016 14:07:34 +0530
4Subject: [PATCH 09/43] fixing the MAX_OPCODES to correct value
5
6---
7 opcodes/microblaze-opc.h | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
11index 330f1040e7..2a6b841232 100644
12--- a/opcodes/microblaze-opc.h
13+++ b/opcodes/microblaze-opc.h
14@@ -102,7 +102,7 @@
15 #define DELAY_SLOT 1
16 #define NO_DELAY_SLOT 0
17
18-#define MAX_OPCODES 291
19+#define MAX_OPCODES 299
20
21 struct op_code_struct
22 {
23--
242.17.1
25
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0010-Add-new-bit-field-instructions.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0010-Add-new-bit-field-instructions.patch
new file mode 100644
index 00000000..901c53e6
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0010-Add-new-bit-field-instructions.patch
@@ -0,0 +1,230 @@
1From 7e9e123337f2d441b213ea9d0be07e9049241f64 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 18 Jul 2016 12:24:28 +0530
4Subject: [PATCH 10/43] Add new bit-field instructions
5
6This patches adds new bsefi and bsifi instructions.
7BSEFI- The instruction shall extract a bit field from a
8register and place it right-adjusted in the destination register.
9The other bits in the destination register shall be set to zero
10BSIFI- The instruction shall insert a right-adjusted bit field
11from a register at another position in the destination register.
12The rest of the bits in the destination register shall be unchanged
13
14Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
15---
16 gas/config/tc-microblaze.c | 71 +++++++++++++++++++++++++++++++++++++-
17 opcodes/microblaze-dis.c | 16 +++++++++
18 opcodes/microblaze-opc.h | 12 ++++++-
19 opcodes/microblaze-opcm.h | 6 +++-
20 4 files changed, 102 insertions(+), 3 deletions(-)
21
22diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
23index fa665b4e25..71bb888ab8 100644
24--- a/gas/config/tc-microblaze.c
25+++ b/gas/config/tc-microblaze.c
26@@ -917,7 +917,7 @@ md_assemble (char * str)
27 unsigned reg2;
28 unsigned reg3;
29 unsigned isize;
30- unsigned int immed, temp;
31+ unsigned int immed, immed2, temp;
32 expressionS exp;
33 char name[20];
34
35@@ -1172,7 +1172,76 @@ md_assemble (char * str)
36 inst |= (reg2 << RA_LOW) & RA_MASK;
37 inst |= (immed << IMM_LOW) & IMM5_MASK;
38 break;
39+ case INST_TYPE_RD_R1_IMM5_IMM5:
40+ if (strcmp (op_end, ""))
41+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
42+ else
43+ {
44+ as_fatal (_("Error in statement syntax"));
45+ reg1 = 0;
46+ }
47+ if (strcmp (op_end, ""))
48+ op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
49+ else
50+ {
51+ as_fatal (_("Error in statement syntax"));
52+ reg2 = 0;
53+ }
54+
55+ /* Check for spl registers. */
56+ if (check_spl_reg (&reg1))
57+ as_fatal (_("Cannot use special register with this instruction"));
58+ if (check_spl_reg (&reg2))
59+ as_fatal (_("Cannot use special register with this instruction"));
60
61+ /* Width immediate value. */
62+ if (strcmp (op_end, ""))
63+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH);
64+ else
65+ as_fatal (_("Error in statement syntax"));
66+ if (exp.X_op != O_constant)
67+ {
68+ as_warn (_("Symbol used as immediate width value for bit field instruction"));
69+ immed = 1;
70+ }
71+ else
72+ immed = exp.X_add_number;
73+ if (opcode->instr == bsefi && immed > 31)
74+ as_fatal (_("Width value must be less than 32"));
75+
76+ /* Shift immediate value. */
77+ if (strcmp (op_end, ""))
78+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM);
79+ else
80+ as_fatal (_("Error in statement syntax"));
81+ if (exp.X_op != O_constant)
82+ {
83+ as_warn (_("Symbol used as immediate shift value for bit field instruction"));
84+ immed2 = 0;
85+ }
86+ else
87+ {
88+ output = frag_more (isize);
89+ immed2 = exp.X_add_number;
90+ }
91+ if (immed2 != (immed2 % 32))
92+ {
93+ as_warn (_("Shift value greater than 32. using <value %% 32>"));
94+ immed2 = immed2 % 32;
95+ }
96+
97+ /* Check combined value. */
98+ if (immed + immed2 > 32)
99+ as_fatal (_("Width value + shift value must not be greater than 32"));
100+
101+ inst |= (reg1 << RD_LOW) & RD_MASK;
102+ inst |= (reg2 << RA_LOW) & RA_MASK;
103+ if (opcode->instr == bsefi)
104+ inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */
105+ else
106+ inst |= ((immed + immed2 - 1) & IMM5_MASK) << IMM_WIDTH_LOW; /* bsifi */
107+ inst |= (immed2 << IMM_LOW) & IMM5_MASK;
108+ break;
109 case INST_TYPE_R1_R2:
110 if (strcmp (op_end, ""))
111 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
112diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
113index f691740dfd..f8aaf27873 100644
114--- a/opcodes/microblaze-dis.c
115+++ b/opcodes/microblaze-dis.c
116@@ -73,6 +73,18 @@ get_field_imm5_mbar (long instr)
117 return(strdup(tmpstr));
118 }
119
120+static char *
121+get_field_imm5width (long instr)
122+{
123+ char tmpstr[25];
124+
125+ if (instr & 0x00004000)
126+ sprintf (tmpstr, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
127+ else
128+ sprintf (tmpstr, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >> IMM_LOW) + 1)); /* bsifi */
129+ return (strdup (tmpstr));
130+}
131+
132 static char *
133 get_field_rfsl (long instr)
134 {
135@@ -396,6 +408,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
136 /* For mbar 16 or sleep insn. */
137 case INST_TYPE_NONE:
138 break;
139+ /* For bit field insns. */
140+ case INST_TYPE_RD_R1_IMM5_IMM5:
141+ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (inst),get_field_r1(inst),get_field_imm5width (inst), get_field_imm5 (inst));
142+ break;
143 /* For tuqula instruction */
144 case INST_TYPE_RD:
145 print_func (stream, "\t%s", get_field_rd (inst));
146diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
147index 2a6b841232..ce8ac351b5 100644
148--- a/opcodes/microblaze-opc.h
149+++ b/opcodes/microblaze-opc.h
150@@ -59,6 +59,9 @@
151 /* For mbar. */
152 #define INST_TYPE_IMM5 20
153
154+/* For bsefi and bsifi */
155+#define INST_TYPE_RD_R1_IMM5_IMM5 21
156+
157 #define INST_TYPE_NONE 25
158
159
160@@ -89,7 +92,9 @@
161 #define OPCODE_MASK_H124 0xFFFF07FF /* High 16, and low 11 bits. */
162 #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits. */
163 #define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */
164+#define OPCODE_MASK_H3B 0xFC00C600 /* High 6 bits and bits 16, 17, 21, 22. */
165 #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */
166+#define OPCODE_MASK_H32B 0xFC00C000 /* High 6 bits and bit 16, 17. */
167 #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */
168 #define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */
169 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
170@@ -102,7 +107,7 @@
171 #define DELAY_SLOT 1
172 #define NO_DELAY_SLOT 0
173
174-#define MAX_OPCODES 299
175+#define MAX_OPCODES 301
176
177 struct op_code_struct
178 {
179@@ -159,6 +164,8 @@ struct op_code_struct
180 {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst },
181 {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst },
182 {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst },
183+ {"bsefi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst },
184+ {"bsifi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst },
185 {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, microblaze_or, logical_inst },
186 {"and", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000000, OPCODE_MASK_H4, microblaze_and, logical_inst },
187 {"xor", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000000, OPCODE_MASK_H4, microblaze_xor, logical_inst },
188@@ -438,5 +445,8 @@ char pvr_register_prefix[] = "rpvr";
189 #define MIN_IMM5 ((int) 0x00000000)
190 #define MAX_IMM5 ((int) 0x0000001f)
191
192+#define MIN_IMM_WIDTH ((int) 0x00000001)
193+#define MAX_IMM_WIDTH ((int) 0x00000020)
194+
195 #endif /* MICROBLAZE_OPC */
196
197diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
198index 1c39dbf50b..28662694cd 100644
199--- a/opcodes/microblaze-opcm.h
200+++ b/opcodes/microblaze-opcm.h
201@@ -29,7 +29,7 @@ enum microblaze_instr
202 addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
203 mulh, mulhu, mulhsu,swapb,swaph,
204 idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
205- ncget, ncput, muli, bslli, bsrai, bsrli, mului,
206+ ncget, ncput, muli, bslli, bsrai, bsrli, bsefi, bsifi, mului,
207 /* 'or/and/xor' are C++ keywords. */
208 microblaze_or, microblaze_and, microblaze_xor,
209 andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16,
210@@ -129,6 +129,7 @@ enum microblaze_instr_type
211 #define RB_LOW 11 /* Low bit for RB. */
212 #define IMM_LOW 0 /* Low bit for immediate. */
213 #define IMM_MBAR 21 /* low bit for mbar instruction. */
214+#define IMM_WIDTH_LOW 6 /* Low bit for immediate width */
215
216 #define RD_MASK 0x03E00000
217 #define RA_MASK 0x001F0000
218@@ -141,6 +142,9 @@ enum microblaze_instr_type
219 /* Imm mask for mbar. */
220 #define IMM5_MBAR_MASK 0x03E00000
221
222+/* Imm mask for extract/insert width. */
223+#define IMM5_WIDTH_MASK 0x000007C0
224+
225 /* FSL imm mask for get, put instructions. */
226 #define RFSL_MASK 0x000000F
227
228--
2292.17.1
230
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0011-fixing-the-imm-bug.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0011-fixing-the-imm-bug.patch
new file mode 100644
index 00000000..4c1b0c25
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0011-fixing-the-imm-bug.patch
@@ -0,0 +1,27 @@
1From 8b2e8fe916066bb1caa99abc67f8cde3ebd41c70 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 10 Jul 2017 16:07:28 +0530
4Subject: [PATCH 11/43] fixing the imm bug. with relax option imm -1 is also
5 getting removed this is corrected now.
6
7---
8 bfd/elf32-microblaze.c | 3 +--
9 1 file changed, 1 insertion(+), 2 deletions(-)
10
11diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
12index d19a6dca84..d001437b3f 100644
13--- a/bfd/elf32-microblaze.c
14+++ b/bfd/elf32-microblaze.c
15@@ -1869,8 +1869,7 @@ microblaze_elf_relax_section (bfd *abfd,
16 else
17 symval += irel->r_addend;
18
19- if ((symval & 0xffff8000) == 0
20- || (symval & 0xffff8000) == 0xffff8000)
21+ if ((symval & 0xffff8000) == 0)
22 {
23 /* We can delete this instruction. */
24 sec->relax[sec->relax_count].addr = irel->r_offset;
25--
262.17.1
27
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch
new file mode 100644
index 00000000..ad4db430
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch
@@ -0,0 +1,33 @@
1From 2a7b66bbc0473c6cbe6653a48818962b5b411ef2 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Fri, 29 Sep 2017 18:00:23 +0530
4Subject: [PATCH 12/43] [Patch,Microblaze]: fixed bug in GCC so that It will
5 support .long 0U and .long 0u
6
7---
8 gas/expr.c | 9 +++++++++
9 1 file changed, 9 insertions(+)
10
11diff --git a/gas/expr.c b/gas/expr.c
12index ee85bda1cc..b502418b71 100644
13--- a/gas/expr.c
14+++ b/gas/expr.c
15@@ -810,6 +810,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
16 break;
17 }
18 }
19+ if ((*input_line_pointer == 'U') || (*input_line_pointer == 'u'))
20+ {
21+ input_line_pointer--;
22+
23+ integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
24+ ? 0 : 10,
25+ expressionP);
26+ break;
27+ }
28 c = *input_line_pointer;
29 switch (c)
30 {
31--
322.17.1
33
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0013-fixing-the-constant-range-check-issue.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0013-fixing-the-constant-range-check-issue.patch
new file mode 100644
index 00000000..323b7bde
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0013-fixing-the-constant-range-check-issue.patch
@@ -0,0 +1,26 @@
1From 59a9a1a913b7dfa424792c907001413c1ddd320c Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 16 Oct 2017 15:44:23 +0530
4Subject: [PATCH 13/43] fixing the constant range check issue sample error: not
5 in range ffffffff80000000..7fffffff, not ffffffff70000000
6
7---
8 gas/config/tc-microblaze.c | 2 +-
9 1 file changed, 1 insertion(+), 1 deletion(-)
10
11diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
12index 71bb888ab8..16b10d00a9 100644
13--- a/gas/config/tc-microblaze.c
14+++ b/gas/config/tc-microblaze.c
15@@ -757,7 +757,7 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
16 if ((e->X_add_number >> 31) == 1)
17 e->X_add_number |= -((addressT) (1U << 31));
18
19- if (e->X_add_number < min || e->X_add_number > max)
20+ if ((int)e->X_add_number < min || (int)e->X_add_number > max)
21 {
22 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
23 (long) min, (long) max, (long) e->X_add_number);
24--
252.17.1
26
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch
new file mode 100644
index 00000000..1a3e0130
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch
@@ -0,0 +1,36 @@
1From 00b7561a868b08dab952b9b9f4a01118195aeb29 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 21 Feb 2018 12:32:02 +0530
4Subject: [PATCH 14/43] [Patch,Microblaze]: Compiler will give error messages
5 in more detail for mxl-gp-opt flag..
6
7---
8 ld/ldmain.c | 12 ++++++++++++
9 1 file changed, 12 insertions(+)
10
11diff --git a/ld/ldmain.c b/ld/ldmain.c
12index 77cdbd0dd2..517d85baef 100644
13--- a/ld/ldmain.c
14+++ b/ld/ldmain.c
15@@ -1446,6 +1446,18 @@ reloc_overflow (struct bfd_link_info *info,
16 break;
17 case bfd_link_hash_defined:
18 case bfd_link_hash_defweak:
19+
20+ if((strcmp(reloc_name,"R_MICROBLAZE_SRW32") == 0) && entry->type == bfd_link_hash_defined)
21+ {
22+ einfo (_(" relocation truncated to fit: don't enable small data pointer optimizations[mxl-gp-opt] if extern or multiple declarations used: "
23+ "%s against symbol `%T' defined in %A section in %B"),
24+ reloc_name, entry->root.string,
25+ entry->u.def.section,
26+ entry->u.def.section == bfd_abs_section_ptr
27+ ? info->output_bfd : entry->u.def.section->owner);
28+ break;
29+ }
30+
31 einfo (_(" relocation truncated to fit: "
32 "%s against symbol `%pT' defined in %pA section in %pB"),
33 reloc_name, entry->root.string,
34--
352.17.1
36
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0015-intial-commit-of-MB-64-bit.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0015-intial-commit-of-MB-64-bit.patch
new file mode 100644
index 00000000..d0f96eca
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0015-intial-commit-of-MB-64-bit.patch
@@ -0,0 +1,4738 @@
1From 9aeae734291f8aaeb449c1403561b71de1ea3bea Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Sun, 30 Sep 2018 16:28:28 +0530
4Subject: [PATCH 15/43] intial commit of MB 64-bit
5
6---
7 bfd/Makefile.am | 2 +
8 bfd/Makefile.in | 3 +
9 bfd/config.bfd | 4 +
10 bfd/configure | 2 +
11 bfd/configure.ac | 2 +
12 bfd/cpu-microblaze.c | 52 +-
13 bfd/elf64-microblaze.c | 3584 ++++++++++++++++++++++++++++
14 bfd/targets.c | 6 +
15 gas/config/tc-microblaze.c | 274 ++-
16 gas/config/tc-microblaze.h | 4 +-
17 include/elf/common.h | 1 +
18 ld/Makefile.am | 8 +
19 ld/Makefile.in | 10 +
20 ld/configure.tgt | 3 +
21 ld/emulparams/elf64microblaze.sh | 23 +
22 ld/emulparams/elf64microblazeel.sh | 23 +
23 opcodes/microblaze-dis.c | 39 +-
24 opcodes/microblaze-opc.h | 162 +-
25 opcodes/microblaze-opcm.h | 20 +-
26 19 files changed, 4181 insertions(+), 41 deletions(-)
27 create mode 100644 bfd/elf64-microblaze.c
28 create mode 100644 ld/emulparams/elf64microblaze.sh
29 create mode 100644 ld/emulparams/elf64microblazeel.sh
30
31diff --git a/bfd/Makefile.am b/bfd/Makefile.am
32index a9191555ad..c5fd250812 100644
33--- a/bfd/Makefile.am
34+++ b/bfd/Makefile.am
35@@ -570,6 +570,7 @@ BFD64_BACKENDS = \
36 elf64-riscv.lo \
37 elfxx-riscv.lo \
38 elf64-s390.lo \
39+ elf64-microblaze.lo \
40 elf64-sparc.lo \
41 elf64-tilegx.lo \
42 elf64-x86-64.lo \
43@@ -603,6 +604,7 @@ BFD64_BACKENDS_CFILES = \
44 elf64-nfp.c \
45 elf64-ppc.c \
46 elf64-s390.c \
47+ elf64-microblaze.c \
48 elf64-sparc.c \
49 elf64-tilegx.c \
50 elf64-x86-64.c \
51diff --git a/bfd/Makefile.in b/bfd/Makefile.in
52index 896df52042..fd457cba1e 100644
53--- a/bfd/Makefile.in
54+++ b/bfd/Makefile.in
55@@ -995,6 +995,7 @@ BFD64_BACKENDS = \
56 elf64-riscv.lo \
57 elfxx-riscv.lo \
58 elf64-s390.lo \
59+ elf64-microblaze.lo \
60 elf64-sparc.lo \
61 elf64-tilegx.lo \
62 elf64-x86-64.lo \
63@@ -1028,6 +1029,7 @@ BFD64_BACKENDS_CFILES = \
64 elf64-nfp.c \
65 elf64-ppc.c \
66 elf64-s390.c \
67+ elf64-microblaze.c \
68 elf64-sparc.c \
69 elf64-tilegx.c \
70 elf64-x86-64.c \
71@@ -1494,6 +1496,7 @@ distclean-compile:
72 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ppc.Plo@am__quote@
73 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-riscv.Plo@am__quote@
74 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-s390.Plo@am__quote@
75+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-microblaze.Plo@am__quote@
76 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sparc.Plo@am__quote@
77 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-tilegx.Plo@am__quote@
78 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-x86-64.Plo@am__quote@
79diff --git a/bfd/config.bfd b/bfd/config.bfd
80index 0e1ddb659c..93d210643d 100644
81--- a/bfd/config.bfd
82+++ b/bfd/config.bfd
83@@ -850,11 +850,15 @@ case "${targ}" in
84 microblazeel*-*)
85 targ_defvec=microblaze_elf32_le_vec
86 targ_selvecs=microblaze_elf32_vec
87+ targ64_selvecs=microblaze_elf64_vec
88+ targ64_selvecs=microblaze_elf64_le_vec
89 ;;
90
91 microblaze*-*)
92 targ_defvec=microblaze_elf32_vec
93 targ_selvecs=microblaze_elf32_le_vec
94+ targ64_selvecs=microblaze_elf64_vec
95+ targ64_selvecs=microblaze_elf64_le_vec
96 ;;
97
98 #ifdef BFD64
99diff --git a/bfd/configure b/bfd/configure
100index 04786696dc..d455abe7c5 100755
101--- a/bfd/configure
102+++ b/bfd/configure
103@@ -14847,6 +14847,8 @@ do
104 rx_elf32_linux_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
105 s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
106 s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
107+ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
108+ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
109 score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
110 score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
111 sh_coff_vec) tb="$tb coff-sh.lo $coff" ;;
112diff --git a/bfd/configure.ac b/bfd/configure.ac
113index eda38ea086..f01c3362fe 100644
114--- a/bfd/configure.ac
115+++ b/bfd/configure.ac
116@@ -615,6 +615,8 @@ do
117 rx_elf32_linux_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
118 s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
119 s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
120+ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
121+ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
122 score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
123 score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
124 sh_coff_vec) tb="$tb coff-sh.lo $coff" ;;
125diff --git a/bfd/cpu-microblaze.c b/bfd/cpu-microblaze.c
126index 9bc2eb3de9..c91ba46f75 100644
127--- a/bfd/cpu-microblaze.c
128+++ b/bfd/cpu-microblaze.c
129@@ -23,7 +23,24 @@
130 #include "bfd.h"
131 #include "libbfd.h"
132
133-const bfd_arch_info_type bfd_microblaze_arch =
134+const bfd_arch_info_type bfd_microblaze_arch[] =
135+{
136+#if BFD_DEFAULT_TARGET_SIZE == 64
137+{
138+ 64, /* 32 bits in a word. */
139+ 64, /* 32 bits in an address. */
140+ 8, /* 8 bits in a byte. */
141+ bfd_arch_microblaze, /* Architecture. */
142+ 0, /* Machine number - 0 for now. */
143+ "microblaze", /* Architecture name. */
144+ "MicroBlaze", /* Printable name. */
145+ 3, /* Section align power. */
146+ FALSE, /* Is this the default architecture ? */
147+ bfd_default_compatible, /* Architecture comparison function. */
148+ bfd_default_scan, /* String to architecture conversion. */
149+ bfd_arch_default_fill, /* Default fill. */
150+ &bfd_microblaze_arch[1] /* Next in list. */
151+},
152 {
153 32, /* 32 bits in a word. */
154 32, /* 32 bits in an address. */
155@@ -38,4 +55,37 @@ const bfd_arch_info_type bfd_microblaze_arch =
156 bfd_default_scan, /* String to architecture conversion. */
157 bfd_arch_default_fill, /* Default fill. */
158 NULL /* Next in list. */
159+}
160+#else
161+{
162+ 32, /* 32 bits in a word. */
163+ 32, /* 32 bits in an address. */
164+ 8, /* 8 bits in a byte. */
165+ bfd_arch_microblaze, /* Architecture. */
166+ 0, /* Machine number - 0 for now. */
167+ "microblaze", /* Architecture name. */
168+ "MicroBlaze", /* Printable name. */
169+ 3, /* Section align power. */
170+ TRUE, /* Is this the default architecture ? */
171+ bfd_default_compatible, /* Architecture comparison function. */
172+ bfd_default_scan, /* String to architecture conversion. */
173+ bfd_arch_default_fill, /* Default fill. */
174+ &bfd_microblaze_arch[1] /* Next in list. */
175+},
176+{
177+ 64, /* 32 bits in a word. */
178+ 64, /* 32 bits in an address. */
179+ 8, /* 8 bits in a byte. */
180+ bfd_arch_microblaze, /* Architecture. */
181+ 0, /* Machine number - 0 for now. */
182+ "microblaze", /* Architecture name. */
183+ "MicroBlaze", /* Printable name. */
184+ 3, /* Section align power. */
185+ FALSE, /* Is this the default architecture ? */
186+ bfd_default_compatible, /* Architecture comparison function. */
187+ bfd_default_scan, /* String to architecture conversion. */
188+ bfd_arch_default_fill, /* Default fill. */
189+ NULL /* Next in list. */
190+}
191+#endif
192 };
193diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
194new file mode 100644
195index 0000000000..0f43ae6ea8
196--- /dev/null
197+++ b/bfd/elf64-microblaze.c
198@@ -0,0 +1,3584 @@
199+/* Xilinx MicroBlaze-specific support for 32-bit ELF
200+
201+ Copyright (C) 2009-2016 Free Software Foundation, Inc.
202+
203+ This file is part of BFD, the Binary File Descriptor library.
204+
205+ This program is free software; you can redistribute it and/or modify
206+ it under the terms of the GNU General Public License as published by
207+ the Free Software Foundation; either version 3 of the License, or
208+ (at your option) any later version.
209+
210+ This program is distributed in the hope that it will be useful,
211+ but WITHOUT ANY WARRANTY; without even the implied warranty of
212+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
213+ GNU General Public License for more details.
214+
215+ You should have received a copy of the GNU General Public License
216+ along with this program; if not, write to the
217+ Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
218+ Boston, MA 02110-1301, USA. */
219+
220+
221+int dbg1 = 0;
222+
223+#include "sysdep.h"
224+#include "bfd.h"
225+#include "bfdlink.h"
226+#include "libbfd.h"
227+#include "elf-bfd.h"
228+#include "elf/microblaze.h"
229+#include <assert.h>
230+
231+#define USE_RELA /* Only USE_REL is actually significant, but this is
232+ here are a reminder... */
233+#define INST_WORD_SIZE 4
234+
235+static int ro_small_data_pointer = 0;
236+static int rw_small_data_pointer = 0;
237+
238+static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
239+
240+static reloc_howto_type microblaze_elf_howto_raw[] =
241+{
242+ /* This reloc does nothing. */
243+ HOWTO (R_MICROBLAZE_NONE, /* Type. */
244+ 0, /* Rightshift. */
245+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
246+ 0, /* Bitsize. */
247+ FALSE, /* PC_relative. */
248+ 0, /* Bitpos. */
249+ complain_overflow_dont, /* Complain on overflow. */
250+ NULL, /* Special Function. */
251+ "R_MICROBLAZE_NONE", /* Name. */
252+ FALSE, /* Partial Inplace. */
253+ 0, /* Source Mask. */
254+ 0, /* Dest Mask. */
255+ FALSE), /* PC relative offset? */
256+
257+ /* A standard 32 bit relocation. */
258+ HOWTO (R_MICROBLAZE_32, /* Type. */
259+ 0, /* Rightshift. */
260+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
261+ 32, /* Bitsize. */
262+ FALSE, /* PC_relative. */
263+ 0, /* Bitpos. */
264+ complain_overflow_bitfield, /* Complain on overflow. */
265+ bfd_elf_generic_reloc,/* Special Function. */
266+ "R_MICROBLAZE_32", /* Name. */
267+ FALSE, /* Partial Inplace. */
268+ 0, /* Source Mask. */
269+ 0xffffffff, /* Dest Mask. */
270+ FALSE), /* PC relative offset? */
271+
272+ /* A standard PCREL 32 bit relocation. */
273+ HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
274+ 0, /* Rightshift. */
275+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
276+ 32, /* Bitsize. */
277+ TRUE, /* PC_relative. */
278+ 0, /* Bitpos. */
279+ complain_overflow_bitfield, /* Complain on overflow. */
280+ bfd_elf_generic_reloc,/* Special Function. */
281+ "R_MICROBLAZE_32_PCREL", /* Name. */
282+ TRUE, /* Partial Inplace. */
283+ 0, /* Source Mask. */
284+ 0xffffffff, /* Dest Mask. */
285+ TRUE), /* PC relative offset? */
286+
287+ /* A 64 bit PCREL relocation. Table-entry not really used. */
288+ HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
289+ 0, /* Rightshift. */
290+ 4, /* Size (0 = byte, 1 = short, 2 = long). */
291+ 64, /* Bitsize. */
292+ TRUE, /* PC_relative. */
293+ 0, /* Bitpos. */
294+ complain_overflow_dont, /* Complain on overflow. */
295+ bfd_elf_generic_reloc,/* Special Function. */
296+ "R_MICROBLAZE_64_PCREL", /* Name. */
297+ FALSE, /* Partial Inplace. */
298+ 0, /* Source Mask. */
299+ 0x0000ffff, /* Dest Mask. */
300+ TRUE), /* PC relative offset? */
301+
302+ /* The low half of a PCREL 32 bit relocation. */
303+ HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
304+ 0, /* Rightshift. */
305+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
306+ 16, /* Bitsize. */
307+ TRUE, /* PC_relative. */
308+ 0, /* Bitpos. */
309+ complain_overflow_signed, /* Complain on overflow. */
310+ bfd_elf_generic_reloc, /* Special Function. */
311+ "R_MICROBLAZE_32_PCREL_LO", /* Name. */
312+ FALSE, /* Partial Inplace. */
313+ 0, /* Source Mask. */
314+ 0x0000ffff, /* Dest Mask. */
315+ TRUE), /* PC relative offset? */
316+
317+ /* A 64 bit relocation. Table entry not really used. */
318+ HOWTO (R_MICROBLAZE_64, /* Type. */
319+ 0, /* Rightshift. */
320+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
321+ 16, /* Bitsize. */
322+ FALSE, /* PC_relative. */
323+ 0, /* Bitpos. */
324+ complain_overflow_dont, /* Complain on overflow. */
325+ bfd_elf_generic_reloc,/* Special Function. */
326+ "R_MICROBLAZE_64", /* Name. */
327+ FALSE, /* Partial Inplace. */
328+ 0, /* Source Mask. */
329+ 0x0000ffff, /* Dest Mask. */
330+ FALSE), /* PC relative offset? */
331+
332+ /* The low half of a 32 bit relocation. */
333+ HOWTO (R_MICROBLAZE_32_LO, /* Type. */
334+ 0, /* Rightshift. */
335+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
336+ 16, /* Bitsize. */
337+ FALSE, /* PC_relative. */
338+ 0, /* Bitpos. */
339+ complain_overflow_signed, /* Complain on overflow. */
340+ bfd_elf_generic_reloc,/* Special Function. */
341+ "R_MICROBLAZE_32_LO", /* Name. */
342+ FALSE, /* Partial Inplace. */
343+ 0, /* Source Mask. */
344+ 0x0000ffff, /* Dest Mask. */
345+ FALSE), /* PC relative offset? */
346+
347+ /* Read-only small data section relocation. */
348+ HOWTO (R_MICROBLAZE_SRO32, /* Type. */
349+ 0, /* Rightshift. */
350+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
351+ 16, /* Bitsize. */
352+ FALSE, /* PC_relative. */
353+ 0, /* Bitpos. */
354+ complain_overflow_bitfield, /* Complain on overflow. */
355+ bfd_elf_generic_reloc,/* Special Function. */
356+ "R_MICROBLAZE_SRO32", /* Name. */
357+ FALSE, /* Partial Inplace. */
358+ 0, /* Source Mask. */
359+ 0x0000ffff, /* Dest Mask. */
360+ FALSE), /* PC relative offset? */
361+
362+ /* Read-write small data area relocation. */
363+ HOWTO (R_MICROBLAZE_SRW32, /* Type. */
364+ 0, /* Rightshift. */
365+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
366+ 16, /* Bitsize. */
367+ FALSE, /* PC_relative. */
368+ 0, /* Bitpos. */
369+ complain_overflow_bitfield, /* Complain on overflow. */
370+ bfd_elf_generic_reloc,/* Special Function. */
371+ "R_MICROBLAZE_SRW32", /* Name. */
372+ FALSE, /* Partial Inplace. */
373+ 0, /* Source Mask. */
374+ 0x0000ffff, /* Dest Mask. */
375+ FALSE), /* PC relative offset? */
376+
377+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
378+ 0, /* Rightshift. */
379+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
380+ 32, /* Bitsize. */
381+ TRUE, /* PC_relative. */
382+ 0, /* Bitpos. */
383+ complain_overflow_bitfield, /* Complain on overflow. */
384+ NULL, /* Special Function. */
385+ "R_MICROBLAZE_32_NONE",/* Name. */
386+ FALSE, /* Partial Inplace. */
387+ 0, /* Source Mask. */
388+ 0, /* Dest Mask. */
389+ FALSE), /* PC relative offset? */
390+
391+ /* This reloc does nothing. Used for relaxation. */
392+ HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
393+ 0, /* Rightshift. */
394+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
395+ 0, /* Bitsize. */
396+ TRUE, /* PC_relative. */
397+ 0, /* Bitpos. */
398+ complain_overflow_dont, /* Complain on overflow. */
399+ NULL, /* Special Function. */
400+ "R_MICROBLAZE_64_NONE",/* Name. */
401+ FALSE, /* Partial Inplace. */
402+ 0, /* Source Mask. */
403+ 0, /* Dest Mask. */
404+ FALSE), /* PC relative offset? */
405+
406+ /* Symbol Op Symbol relocation. */
407+ HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
408+ 0, /* Rightshift. */
409+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
410+ 32, /* Bitsize. */
411+ FALSE, /* PC_relative. */
412+ 0, /* Bitpos. */
413+ complain_overflow_bitfield, /* Complain on overflow. */
414+ bfd_elf_generic_reloc,/* Special Function. */
415+ "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
416+ FALSE, /* Partial Inplace. */
417+ 0, /* Source Mask. */
418+ 0xffffffff, /* Dest Mask. */
419+ FALSE), /* PC relative offset? */
420+
421+ /* GNU extension to record C++ vtable hierarchy. */
422+ HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
423+ 0, /* Rightshift. */
424+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
425+ 0, /* Bitsize. */
426+ FALSE, /* PC_relative. */
427+ 0, /* Bitpos. */
428+ complain_overflow_dont,/* Complain on overflow. */
429+ NULL, /* Special Function. */
430+ "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
431+ FALSE, /* Partial Inplace. */
432+ 0, /* Source Mask. */
433+ 0, /* Dest Mask. */
434+ FALSE), /* PC relative offset? */
435+
436+ /* GNU extension to record C++ vtable member usage. */
437+ HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
438+ 0, /* Rightshift. */
439+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
440+ 0, /* Bitsize. */
441+ FALSE, /* PC_relative. */
442+ 0, /* Bitpos. */
443+ complain_overflow_dont,/* Complain on overflow. */
444+ _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
445+ "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
446+ FALSE, /* Partial Inplace. */
447+ 0, /* Source Mask. */
448+ 0, /* Dest Mask. */
449+ FALSE), /* PC relative offset? */
450+
451+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
452+ HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
453+ 0, /* Rightshift. */
454+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
455+ 16, /* Bitsize. */
456+ TRUE, /* PC_relative. */
457+ 0, /* Bitpos. */
458+ complain_overflow_dont, /* Complain on overflow. */
459+ bfd_elf_generic_reloc, /* Special Function. */
460+ "R_MICROBLAZE_GOTPC_64", /* Name. */
461+ FALSE, /* Partial Inplace. */
462+ 0, /* Source Mask. */
463+ 0x0000ffff, /* Dest Mask. */
464+ TRUE), /* PC relative offset? */
465+
466+ /* A 64 bit GOT relocation. Table-entry not really used. */
467+ HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
468+ 0, /* Rightshift. */
469+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
470+ 16, /* Bitsize. */
471+ FALSE, /* PC_relative. */
472+ 0, /* Bitpos. */
473+ complain_overflow_dont, /* Complain on overflow. */
474+ bfd_elf_generic_reloc,/* Special Function. */
475+ "R_MICROBLAZE_GOT_64",/* Name. */
476+ FALSE, /* Partial Inplace. */
477+ 0, /* Source Mask. */
478+ 0x0000ffff, /* Dest Mask. */
479+ FALSE), /* PC relative offset? */
480+
481+ /* A 64 bit PLT relocation. Table-entry not really used. */
482+ HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
483+ 0, /* Rightshift. */
484+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
485+ 16, /* Bitsize. */
486+ TRUE, /* PC_relative. */
487+ 0, /* Bitpos. */
488+ complain_overflow_dont, /* Complain on overflow. */
489+ bfd_elf_generic_reloc,/* Special Function. */
490+ "R_MICROBLAZE_PLT_64",/* Name. */
491+ FALSE, /* Partial Inplace. */
492+ 0, /* Source Mask. */
493+ 0x0000ffff, /* Dest Mask. */
494+ TRUE), /* PC relative offset? */
495+
496+ /* Table-entry not really used. */
497+ HOWTO (R_MICROBLAZE_REL, /* Type. */
498+ 0, /* Rightshift. */
499+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
500+ 16, /* Bitsize. */
501+ TRUE, /* PC_relative. */
502+ 0, /* Bitpos. */
503+ complain_overflow_dont, /* Complain on overflow. */
504+ bfd_elf_generic_reloc,/* Special Function. */
505+ "R_MICROBLAZE_REL", /* Name. */
506+ FALSE, /* Partial Inplace. */
507+ 0, /* Source Mask. */
508+ 0x0000ffff, /* Dest Mask. */
509+ TRUE), /* PC relative offset? */
510+
511+ /* Table-entry not really used. */
512+ HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
513+ 0, /* Rightshift. */
514+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
515+ 16, /* Bitsize. */
516+ TRUE, /* PC_relative. */
517+ 0, /* Bitpos. */
518+ complain_overflow_dont, /* Complain on overflow. */
519+ bfd_elf_generic_reloc,/* Special Function. */
520+ "R_MICROBLAZE_JUMP_SLOT", /* Name. */
521+ FALSE, /* Partial Inplace. */
522+ 0, /* Source Mask. */
523+ 0x0000ffff, /* Dest Mask. */
524+ TRUE), /* PC relative offset? */
525+
526+ /* Table-entry not really used. */
527+ HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
528+ 0, /* Rightshift. */
529+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
530+ 16, /* Bitsize. */
531+ TRUE, /* PC_relative. */
532+ 0, /* Bitpos. */
533+ complain_overflow_dont, /* Complain on overflow. */
534+ bfd_elf_generic_reloc,/* Special Function. */
535+ "R_MICROBLAZE_GLOB_DAT", /* Name. */
536+ FALSE, /* Partial Inplace. */
537+ 0, /* Source Mask. */
538+ 0x0000ffff, /* Dest Mask. */
539+ TRUE), /* PC relative offset? */
540+
541+ /* A 64 bit GOT relative relocation. Table-entry not really used. */
542+ HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
543+ 0, /* Rightshift. */
544+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
545+ 16, /* Bitsize. */
546+ FALSE, /* PC_relative. */
547+ 0, /* Bitpos. */
548+ complain_overflow_dont, /* Complain on overflow. */
549+ bfd_elf_generic_reloc,/* Special Function. */
550+ "R_MICROBLAZE_GOTOFF_64", /* Name. */
551+ FALSE, /* Partial Inplace. */
552+ 0, /* Source Mask. */
553+ 0x0000ffff, /* Dest Mask. */
554+ FALSE), /* PC relative offset? */
555+
556+ /* A 32 bit GOT relative relocation. Table-entry not really used. */
557+ HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
558+ 0, /* Rightshift. */
559+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
560+ 16, /* Bitsize. */
561+ FALSE, /* PC_relative. */
562+ 0, /* Bitpos. */
563+ complain_overflow_dont, /* Complain on overflow. */
564+ bfd_elf_generic_reloc, /* Special Function. */
565+ "R_MICROBLAZE_GOTOFF_32", /* Name. */
566+ FALSE, /* Partial Inplace. */
567+ 0, /* Source Mask. */
568+ 0x0000ffff, /* Dest Mask. */
569+ FALSE), /* PC relative offset? */
570+
571+ /* COPY relocation. Table-entry not really used. */
572+ HOWTO (R_MICROBLAZE_COPY, /* Type. */
573+ 0, /* Rightshift. */
574+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
575+ 16, /* Bitsize. */
576+ FALSE, /* PC_relative. */
577+ 0, /* Bitpos. */
578+ complain_overflow_dont, /* Complain on overflow. */
579+ bfd_elf_generic_reloc,/* Special Function. */
580+ "R_MICROBLAZE_COPY", /* Name. */
581+ FALSE, /* Partial Inplace. */
582+ 0, /* Source Mask. */
583+ 0x0000ffff, /* Dest Mask. */
584+ FALSE), /* PC relative offset? */
585+
586+ /* Marker relocs for TLS. */
587+ HOWTO (R_MICROBLAZE_TLS,
588+ 0, /* rightshift */
589+ 2, /* size (0 = byte, 1 = short, 2 = long) */
590+ 32, /* bitsize */
591+ FALSE, /* pc_relative */
592+ 0, /* bitpos */
593+ complain_overflow_dont, /* complain_on_overflow */
594+ bfd_elf_generic_reloc, /* special_function */
595+ "R_MICROBLAZE_TLS", /* name */
596+ FALSE, /* partial_inplace */
597+ 0, /* src_mask */
598+ 0x0000ffff, /* dst_mask */
599+ FALSE), /* pcrel_offset */
600+
601+ HOWTO (R_MICROBLAZE_TLSGD,
602+ 0, /* rightshift */
603+ 2, /* size (0 = byte, 1 = short, 2 = long) */
604+ 32, /* bitsize */
605+ FALSE, /* pc_relative */
606+ 0, /* bitpos */
607+ complain_overflow_dont, /* complain_on_overflow */
608+ bfd_elf_generic_reloc, /* special_function */
609+ "R_MICROBLAZE_TLSGD", /* name */
610+ FALSE, /* partial_inplace */
611+ 0, /* src_mask */
612+ 0x0000ffff, /* dst_mask */
613+ FALSE), /* pcrel_offset */
614+
615+ HOWTO (R_MICROBLAZE_TLSLD,
616+ 0, /* rightshift */
617+ 2, /* size (0 = byte, 1 = short, 2 = long) */
618+ 32, /* bitsize */
619+ FALSE, /* pc_relative */
620+ 0, /* bitpos */
621+ complain_overflow_dont, /* complain_on_overflow */
622+ bfd_elf_generic_reloc, /* special_function */
623+ "R_MICROBLAZE_TLSLD", /* name */
624+ FALSE, /* partial_inplace */
625+ 0, /* src_mask */
626+ 0x0000ffff, /* dst_mask */
627+ FALSE), /* pcrel_offset */
628+
629+ /* Computes the load module index of the load module that contains the
630+ definition of its TLS sym. */
631+ HOWTO (R_MICROBLAZE_TLSDTPMOD32,
632+ 0, /* rightshift */
633+ 2, /* size (0 = byte, 1 = short, 2 = long) */
634+ 32, /* bitsize */
635+ FALSE, /* pc_relative */
636+ 0, /* bitpos */
637+ complain_overflow_dont, /* complain_on_overflow */
638+ bfd_elf_generic_reloc, /* special_function */
639+ "R_MICROBLAZE_TLSDTPMOD32", /* name */
640+ FALSE, /* partial_inplace */
641+ 0, /* src_mask */
642+ 0x0000ffff, /* dst_mask */
643+ FALSE), /* pcrel_offset */
644+
645+ /* Computes a dtv-relative displacement, the difference between the value
646+ of sym+add and the base address of the thread-local storage block that
647+ contains the definition of sym, minus 0x8000. Used for initializing GOT */
648+ HOWTO (R_MICROBLAZE_TLSDTPREL32,
649+ 0, /* rightshift */
650+ 2, /* size (0 = byte, 1 = short, 2 = long) */
651+ 32, /* bitsize */
652+ FALSE, /* pc_relative */
653+ 0, /* bitpos */
654+ complain_overflow_dont, /* complain_on_overflow */
655+ bfd_elf_generic_reloc, /* special_function */
656+ "R_MICROBLAZE_TLSDTPREL32", /* name */
657+ FALSE, /* partial_inplace */
658+ 0, /* src_mask */
659+ 0x0000ffff, /* dst_mask */
660+ FALSE), /* pcrel_offset */
661+
662+ /* Computes a dtv-relative displacement, the difference between the value
663+ of sym+add and the base address of the thread-local storage block that
664+ contains the definition of sym, minus 0x8000. */
665+ HOWTO (R_MICROBLAZE_TLSDTPREL64,
666+ 0, /* rightshift */
667+ 2, /* size (0 = byte, 1 = short, 2 = long) */
668+ 32, /* bitsize */
669+ FALSE, /* pc_relative */
670+ 0, /* bitpos */
671+ complain_overflow_dont, /* complain_on_overflow */
672+ bfd_elf_generic_reloc, /* special_function */
673+ "R_MICROBLAZE_TLSDTPREL64", /* name */
674+ FALSE, /* partial_inplace */
675+ 0, /* src_mask */
676+ 0x0000ffff, /* dst_mask */
677+ FALSE), /* pcrel_offset */
678+
679+ /* Computes a tp-relative displacement, the difference between the value of
680+ sym+add and the value of the thread pointer (r13). */
681+ HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
682+ 0, /* rightshift */
683+ 2, /* size (0 = byte, 1 = short, 2 = long) */
684+ 32, /* bitsize */
685+ FALSE, /* pc_relative */
686+ 0, /* bitpos */
687+ complain_overflow_dont, /* complain_on_overflow */
688+ bfd_elf_generic_reloc, /* special_function */
689+ "R_MICROBLAZE_TLSGOTTPREL32", /* name */
690+ FALSE, /* partial_inplace */
691+ 0, /* src_mask */
692+ 0x0000ffff, /* dst_mask */
693+ FALSE), /* pcrel_offset */
694+
695+ /* Computes a tp-relative displacement, the difference between the value of
696+ sym+add and the value of the thread pointer (r13). */
697+ HOWTO (R_MICROBLAZE_TLSTPREL32,
698+ 0, /* rightshift */
699+ 2, /* size (0 = byte, 1 = short, 2 = long) */
700+ 32, /* bitsize */
701+ FALSE, /* pc_relative */
702+ 0, /* bitpos */
703+ complain_overflow_dont, /* complain_on_overflow */
704+ bfd_elf_generic_reloc, /* special_function */
705+ "R_MICROBLAZE_TLSTPREL32", /* name */
706+ FALSE, /* partial_inplace */
707+ 0, /* src_mask */
708+ 0x0000ffff, /* dst_mask */
709+ FALSE), /* pcrel_offset */
710+
711+};
712+
713+#ifndef NUM_ELEM
714+#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
715+#endif
716+
717+/* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
718+
719+static void
720+microblaze_elf_howto_init (void)
721+{
722+ unsigned int i;
723+
724+ for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
725+ {
726+ unsigned int type;
727+
728+ type = microblaze_elf_howto_raw[i].type;
729+
730+ BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
731+
732+ microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
733+ }
734+}
735+
736+static reloc_howto_type *
737+microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
738+ bfd_reloc_code_real_type code)
739+{
740+ enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
741+
742+ switch (code)
743+ {
744+ case BFD_RELOC_NONE:
745+ microblaze_reloc = R_MICROBLAZE_NONE;
746+ break;
747+ case BFD_RELOC_MICROBLAZE_32_NONE:
748+ microblaze_reloc = R_MICROBLAZE_32_NONE;
749+ break;
750+ case BFD_RELOC_MICROBLAZE_64_NONE:
751+ microblaze_reloc = R_MICROBLAZE_64_NONE;
752+ break;
753+ case BFD_RELOC_32:
754+ microblaze_reloc = R_MICROBLAZE_32;
755+ break;
756+ /* RVA is treated the same as 32 */
757+ case BFD_RELOC_RVA:
758+ microblaze_reloc = R_MICROBLAZE_32;
759+ break;
760+ case BFD_RELOC_32_PCREL:
761+ microblaze_reloc = R_MICROBLAZE_32_PCREL;
762+ break;
763+ case BFD_RELOC_64_PCREL:
764+ microblaze_reloc = R_MICROBLAZE_64_PCREL;
765+ break;
766+ case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
767+ microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
768+ break;
769+ case BFD_RELOC_64:
770+ microblaze_reloc = R_MICROBLAZE_64;
771+ break;
772+ case BFD_RELOC_MICROBLAZE_32_LO:
773+ microblaze_reloc = R_MICROBLAZE_32_LO;
774+ break;
775+ case BFD_RELOC_MICROBLAZE_32_ROSDA:
776+ microblaze_reloc = R_MICROBLAZE_SRO32;
777+ break;
778+ case BFD_RELOC_MICROBLAZE_32_RWSDA:
779+ microblaze_reloc = R_MICROBLAZE_SRW32;
780+ break;
781+ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
782+ microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
783+ break;
784+ case BFD_RELOC_VTABLE_INHERIT:
785+ microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
786+ break;
787+ case BFD_RELOC_VTABLE_ENTRY:
788+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
789+ break;
790+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
791+ microblaze_reloc = R_MICROBLAZE_GOTPC_64;
792+ break;
793+ case BFD_RELOC_MICROBLAZE_64_GOT:
794+ microblaze_reloc = R_MICROBLAZE_GOT_64;
795+ break;
796+ case BFD_RELOC_MICROBLAZE_64_PLT:
797+ microblaze_reloc = R_MICROBLAZE_PLT_64;
798+ break;
799+ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
800+ microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
801+ break;
802+ case BFD_RELOC_MICROBLAZE_32_GOTOFF:
803+ microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
804+ break;
805+ case BFD_RELOC_MICROBLAZE_64_TLSGD:
806+ microblaze_reloc = R_MICROBLAZE_TLSGD;
807+ break;
808+ case BFD_RELOC_MICROBLAZE_64_TLSLD:
809+ microblaze_reloc = R_MICROBLAZE_TLSLD;
810+ break;
811+ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
812+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
813+ break;
814+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
815+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
816+ break;
817+ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
818+ microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
819+ break;
820+ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
821+ microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
822+ break;
823+ case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
824+ microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
825+ break;
826+ case BFD_RELOC_MICROBLAZE_COPY:
827+ microblaze_reloc = R_MICROBLAZE_COPY;
828+ break;
829+ default:
830+ return (reloc_howto_type *) NULL;
831+ }
832+
833+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
834+ /* Initialize howto table if needed. */
835+ microblaze_elf_howto_init ();
836+
837+ return microblaze_elf_howto_table [(int) microblaze_reloc];
838+};
839+
840+static reloc_howto_type *
841+microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
842+ const char *r_name)
843+{
844+ unsigned int i;
845+
846+ for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
847+ if (microblaze_elf_howto_raw[i].name != NULL
848+ && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
849+ return &microblaze_elf_howto_raw[i];
850+
851+ return NULL;
852+}
853+
854+/* Set the howto pointer for a RCE ELF reloc. */
855+
856+static void
857+microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
858+ arelent * cache_ptr,
859+ Elf_Internal_Rela * dst)
860+{
861+ unsigned int r_type;
862+
863+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
864+ /* Initialize howto table if needed. */
865+ microblaze_elf_howto_init ();
866+
867+ r_type = ELF64_R_TYPE (dst->r_info);
868+ if (r_type >= R_MICROBLAZE_max)
869+ {
870+ (*_bfd_error_handler) (_("%B: unrecognised MicroBlaze reloc number: %d"),
871+ abfd, r_type);
872+ bfd_set_error (bfd_error_bad_value);
873+ r_type = R_MICROBLAZE_NONE;
874+ }
875+
876+ cache_ptr->howto = microblaze_elf_howto_table [r_type];
877+}
878+
879+/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
880+
881+static bfd_boolean
882+microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
883+{
884+ if (name[0] == 'L' && name[1] == '.')
885+ return TRUE;
886+
887+ if (name[0] == '$' && name[1] == 'L')
888+ return TRUE;
889+
890+ /* With gcc, the labels go back to starting with '.', so we accept
891+ the generic ELF local label syntax as well. */
892+ return _bfd_elf_is_local_label_name (abfd, name);
893+}
894+
895+/* The microblaze linker (like many others) needs to keep track of
896+ the number of relocs that it decides to copy as dynamic relocs in
897+ check_relocs for each symbol. This is so that it can later discard
898+ them if they are found to be unnecessary. We store the information
899+ in a field extending the regular ELF linker hash table. */
900+
901+struct elf64_mb_dyn_relocs
902+{
903+ struct elf64_mb_dyn_relocs *next;
904+
905+ /* The input section of the reloc. */
906+ asection *sec;
907+
908+ /* Total number of relocs copied for the input section. */
909+ bfd_size_type count;
910+
911+ /* Number of pc-relative relocs copied for the input section. */
912+ bfd_size_type pc_count;
913+};
914+
915+/* ELF linker hash entry. */
916+
917+struct elf64_mb_link_hash_entry
918+{
919+ struct elf_link_hash_entry elf;
920+
921+ /* Track dynamic relocs copied for this symbol. */
922+ struct elf64_mb_dyn_relocs *dyn_relocs;
923+
924+ /* TLS Reference Types for the symbol; Updated by check_relocs */
925+#define TLS_GD 1 /* GD reloc. */
926+#define TLS_LD 2 /* LD reloc. */
927+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
928+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
929+#define TLS_TLS 16 /* Any TLS reloc. */
930+ unsigned char tls_mask;
931+
932+};
933+
934+#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
935+#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
936+#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
937+#define IS_TLS_NONE(x) (x == 0)
938+
939+#define elf64_mb_hash_entry(ent) ((struct elf64_mb_link_hash_entry *)(ent))
940+
941+/* ELF linker hash table. */
942+
943+struct elf64_mb_link_hash_table
944+{
945+ struct elf_link_hash_table elf;
946+
947+ /* Short-cuts to get to dynamic linker sections. */
948+ asection *sgot;
949+ asection *sgotplt;
950+ asection *srelgot;
951+ asection *splt;
952+ asection *srelplt;
953+ asection *sdynbss;
954+ asection *srelbss;
955+
956+ /* Small local sym to section mapping cache. */
957+ struct sym_cache sym_sec;
958+
959+ /* TLS Local Dynamic GOT Entry */
960+ union {
961+ bfd_signed_vma refcount;
962+ bfd_vma offset;
963+ } tlsld_got;
964+};
965+
966+/* Nonzero if this section has TLS related relocations. */
967+#define has_tls_reloc sec_flg0
968+
969+/* Get the ELF linker hash table from a link_info structure. */
970+
971+#define elf64_mb_hash_table(p) \
972+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
973+ == MICROBLAZE_ELF_DATA ? ((struct elf64_mb_link_hash_table *) ((p)->hash)) : NULL)
974+
975+/* Create an entry in a microblaze ELF linker hash table. */
976+
977+static struct bfd_hash_entry *
978+link_hash_newfunc (struct bfd_hash_entry *entry,
979+ struct bfd_hash_table *table,
980+ const char *string)
981+{
982+ /* Allocate the structure if it has not already been allocated by a
983+ subclass. */
984+ if (entry == NULL)
985+ {
986+ entry = bfd_hash_allocate (table,
987+ sizeof (struct elf64_mb_link_hash_entry));
988+ if (entry == NULL)
989+ return entry;
990+ }
991+
992+ /* Call the allocation method of the superclass. */
993+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
994+ if (entry != NULL)
995+ {
996+ struct elf64_mb_link_hash_entry *eh;
997+
998+ eh = (struct elf64_mb_link_hash_entry *) entry;
999+ eh->dyn_relocs = NULL;
1000+ eh->tls_mask = 0;
1001+ }
1002+
1003+ return entry;
1004+}
1005+
1006+/* Create a mb ELF linker hash table. */
1007+
1008+static struct bfd_link_hash_table *
1009+microblaze_elf_link_hash_table_create (bfd *abfd)
1010+{
1011+ struct elf64_mb_link_hash_table *ret;
1012+ bfd_size_type amt = sizeof (struct elf64_mb_link_hash_table);
1013+
1014+ ret = (struct elf64_mb_link_hash_table *) bfd_zmalloc (amt);
1015+ if (ret == NULL)
1016+ return NULL;
1017+
1018+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
1019+ sizeof (struct elf64_mb_link_hash_entry),
1020+ MICROBLAZE_ELF_DATA))
1021+ {
1022+ free (ret);
1023+ return NULL;
1024+ }
1025+
1026+ return &ret->elf.root;
1027+}
1028+
1029+/* Set the values of the small data pointers. */
1030+
1031+static void
1032+microblaze_elf_final_sdp (struct bfd_link_info *info)
1033+{
1034+ struct bfd_link_hash_entry *h;
1035+
1036+ h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
1037+ if (h != (struct bfd_link_hash_entry *) NULL
1038+ && h->type == bfd_link_hash_defined)
1039+ ro_small_data_pointer = (h->u.def.value
1040+ + h->u.def.section->output_section->vma
1041+ + h->u.def.section->output_offset);
1042+
1043+ h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
1044+ if (h != (struct bfd_link_hash_entry *) NULL
1045+ && h->type == bfd_link_hash_defined)
1046+ rw_small_data_pointer = (h->u.def.value
1047+ + h->u.def.section->output_section->vma
1048+ + h->u.def.section->output_offset);
1049+}
1050+
1051+static bfd_vma
1052+dtprel_base (struct bfd_link_info *info)
1053+{
1054+ /* If tls_sec is NULL, we should have signalled an error already. */
1055+ if (elf_hash_table (info)->tls_sec == NULL)
1056+ return 0;
1057+ return elf_hash_table (info)->tls_sec->vma;
1058+}
1059+
1060+/* The size of the thread control block. */
1061+#define TCB_SIZE 8
1062+
1063+/* Output a simple dynamic relocation into SRELOC. */
1064+
1065+static void
1066+microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
1067+ asection *sreloc,
1068+ unsigned long reloc_index,
1069+ unsigned long indx,
1070+ int r_type,
1071+ bfd_vma offset,
1072+ bfd_vma addend)
1073+{
1074+
1075+ Elf_Internal_Rela rel;
1076+
1077+ rel.r_info = ELF64_R_INFO (indx, r_type);
1078+ rel.r_offset = offset;
1079+ rel.r_addend = addend;
1080+
1081+ bfd_elf64_swap_reloca_out (output_bfd, &rel,
1082+ (sreloc->contents + reloc_index * sizeof (Elf64_External_Rela)));
1083+}
1084+
1085+/* This code is taken from elf64-m32r.c
1086+ There is some attempt to make this function usable for many architectures,
1087+ both USE_REL and USE_RELA ['twould be nice if such a critter existed],
1088+ if only to serve as a learning tool.
1089+
1090+ The RELOCATE_SECTION function is called by the new ELF backend linker
1091+ to handle the relocations for a section.
1092+
1093+ The relocs are always passed as Rela structures; if the section
1094+ actually uses Rel structures, the r_addend field will always be
1095+ zero.
1096+
1097+ This function is responsible for adjust the section contents as
1098+ necessary, and (if using Rela relocs and generating a
1099+ relocatable output file) adjusting the reloc addend as
1100+ necessary.
1101+
1102+ This function does not have to worry about setting the reloc
1103+ address or the reloc symbol index.
1104+
1105+ LOCAL_SYMS is a pointer to the swapped in local symbols.
1106+
1107+ LOCAL_SECTIONS is an array giving the section in the input file
1108+ corresponding to the st_shndx field of each local symbol.
1109+
1110+ The global hash table entry for the global symbols can be found
1111+ via elf_sym_hashes (input_bfd).
1112+
1113+ When generating relocatable output, this function must handle
1114+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
1115+ going to be the section symbol corresponding to the output
1116+ section, which means that the addend must be adjusted
1117+ accordingly. */
1118+
1119+static bfd_boolean
1120+microblaze_elf_relocate_section (bfd *output_bfd,
1121+ struct bfd_link_info *info,
1122+ bfd *input_bfd,
1123+ asection *input_section,
1124+ bfd_byte *contents,
1125+ Elf_Internal_Rela *relocs,
1126+ Elf_Internal_Sym *local_syms,
1127+ asection **local_sections)
1128+{
1129+ struct elf64_mb_link_hash_table *htab;
1130+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1131+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
1132+ Elf_Internal_Rela *rel, *relend;
1133+ int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
1134+ /* Assume success. */
1135+ bfd_boolean ret = TRUE;
1136+ asection *sreloc;
1137+ bfd_vma *local_got_offsets;
1138+ unsigned int tls_type;
1139+
1140+ if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
1141+ microblaze_elf_howto_init ();
1142+
1143+ htab = elf64_mb_hash_table (info);
1144+ if (htab == NULL)
1145+ return FALSE;
1146+
1147+ local_got_offsets = elf_local_got_offsets (input_bfd);
1148+
1149+ sreloc = elf_section_data (input_section)->sreloc;
1150+
1151+ rel = relocs;
1152+ relend = relocs + input_section->reloc_count;
1153+ for (; rel < relend; rel++)
1154+ {
1155+ int r_type;
1156+ reloc_howto_type *howto;
1157+ unsigned long r_symndx;
1158+ bfd_vma addend = rel->r_addend;
1159+ bfd_vma offset = rel->r_offset;
1160+ struct elf_link_hash_entry *h;
1161+ Elf_Internal_Sym *sym;
1162+ asection *sec;
1163+ const char *sym_name;
1164+ bfd_reloc_status_type r = bfd_reloc_ok;
1165+ const char *errmsg = NULL;
1166+ bfd_boolean unresolved_reloc = FALSE;
1167+
1168+ h = NULL;
1169+ r_type = ELF64_R_TYPE (rel->r_info);
1170+ tls_type = 0;
1171+
1172+ if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
1173+ {
1174+ (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
1175+ bfd_get_filename (input_bfd), (int) r_type);
1176+ bfd_set_error (bfd_error_bad_value);
1177+ ret = FALSE;
1178+ continue;
1179+ }
1180+
1181+ howto = microblaze_elf_howto_table[r_type];
1182+ r_symndx = ELF64_R_SYM (rel->r_info);
1183+
1184+ if (bfd_link_relocatable (info))
1185+ {
1186+ /* This is a relocatable link. We don't have to change
1187+ anything, unless the reloc is against a section symbol,
1188+ in which case we have to adjust according to where the
1189+ section symbol winds up in the output section. */
1190+ sec = NULL;
1191+ if (r_symndx >= symtab_hdr->sh_info)
1192+ /* External symbol. */
1193+ continue;
1194+
1195+ /* Local symbol. */
1196+ sym = local_syms + r_symndx;
1197+ sym_name = "<local symbol>";
1198+ /* STT_SECTION: symbol is associated with a section. */
1199+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1200+ /* Symbol isn't associated with a section. Nothing to do. */
1201+ continue;
1202+
1203+ sec = local_sections[r_symndx];
1204+ addend += sec->output_offset + sym->st_value;
1205+#ifndef USE_REL
1206+ /* This can't be done for USE_REL because it doesn't mean anything
1207+ and elf_link_input_bfd asserts this stays zero. */
1208+ /* rel->r_addend = addend; */
1209+#endif
1210+
1211+#ifndef USE_REL
1212+ /* Addends are stored with relocs. We're done. */
1213+ continue;
1214+#else /* USE_REL */
1215+ /* If partial_inplace, we need to store any additional addend
1216+ back in the section. */
1217+ if (!howto->partial_inplace)
1218+ continue;
1219+ /* ??? Here is a nice place to call a special_function like handler. */
1220+ r = _bfd_relocate_contents (howto, input_bfd, addend,
1221+ contents + offset);
1222+#endif /* USE_REL */
1223+ }
1224+ else
1225+ {
1226+ bfd_vma relocation;
1227+
1228+ /* This is a final link. */
1229+ sym = NULL;
1230+ sec = NULL;
1231+ unresolved_reloc = FALSE;
1232+
1233+ if (r_symndx < symtab_hdr->sh_info)
1234+ {
1235+ /* Local symbol. */
1236+ sym = local_syms + r_symndx;
1237+ sec = local_sections[r_symndx];
1238+ if (sec == 0)
1239+ continue;
1240+ sym_name = "<local symbol>";
1241+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1242+ /* r_addend may have changed if the reference section was
1243+ a merge section. */
1244+ addend = rel->r_addend;
1245+ }
1246+ else
1247+ {
1248+ /* External symbol. */
1249+ bfd_boolean warned ATTRIBUTE_UNUSED;
1250+ bfd_boolean ignored ATTRIBUTE_UNUSED;
1251+
1252+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1253+ r_symndx, symtab_hdr, sym_hashes,
1254+ h, sec, relocation,
1255+ unresolved_reloc, warned, ignored);
1256+ sym_name = h->root.root.string;
1257+ }
1258+
1259+ /* Sanity check the address. */
1260+ if (offset > bfd_get_section_limit (input_bfd, input_section))
1261+ {
1262+ r = bfd_reloc_outofrange;
1263+ goto check_reloc;
1264+ }
1265+
1266+ switch ((int) r_type)
1267+ {
1268+ case (int) R_MICROBLAZE_SRO32 :
1269+ {
1270+ const char *name;
1271+
1272+ /* Only relocate if the symbol is defined. */
1273+ if (sec)
1274+ {
1275+ name = bfd_get_section_name (sec->owner, sec);
1276+
1277+ if (strcmp (name, ".sdata2") == 0
1278+ || strcmp (name, ".sbss2") == 0)
1279+ {
1280+ if (ro_small_data_pointer == 0)
1281+ microblaze_elf_final_sdp (info);
1282+ if (ro_small_data_pointer == 0)
1283+ {
1284+ ret = FALSE;
1285+ r = bfd_reloc_undefined;
1286+ goto check_reloc;
1287+ }
1288+
1289+ /* At this point `relocation' contains the object's
1290+ address. */
1291+ relocation -= ro_small_data_pointer;
1292+ /* Now it contains the offset from _SDA2_BASE_. */
1293+ r = _bfd_final_link_relocate (howto, input_bfd,
1294+ input_section,
1295+ contents, offset,
1296+ relocation, addend);
1297+ }
1298+ else
1299+ {
1300+ (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
1301+ bfd_get_filename (input_bfd),
1302+ sym_name,
1303+ microblaze_elf_howto_table[(int) r_type]->name,
1304+ bfd_get_section_name (sec->owner, sec));
1305+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
1306+ ret = FALSE;
1307+ continue;
1308+ }
1309+ }
1310+ }
1311+ break;
1312+
1313+ case (int) R_MICROBLAZE_SRW32 :
1314+ {
1315+ const char *name;
1316+
1317+ /* Only relocate if the symbol is defined. */
1318+ if (sec)
1319+ {
1320+ name = bfd_get_section_name (sec->owner, sec);
1321+
1322+ if (strcmp (name, ".sdata") == 0
1323+ || strcmp (name, ".sbss") == 0)
1324+ {
1325+ if (rw_small_data_pointer == 0)
1326+ microblaze_elf_final_sdp (info);
1327+ if (rw_small_data_pointer == 0)
1328+ {
1329+ ret = FALSE;
1330+ r = bfd_reloc_undefined;
1331+ goto check_reloc;
1332+ }
1333+
1334+ /* At this point `relocation' contains the object's
1335+ address. */
1336+ relocation -= rw_small_data_pointer;
1337+ /* Now it contains the offset from _SDA_BASE_. */
1338+ r = _bfd_final_link_relocate (howto, input_bfd,
1339+ input_section,
1340+ contents, offset,
1341+ relocation, addend);
1342+ }
1343+ else
1344+ {
1345+ (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
1346+ bfd_get_filename (input_bfd),
1347+ sym_name,
1348+ microblaze_elf_howto_table[(int) r_type]->name,
1349+ bfd_get_section_name (sec->owner, sec));
1350+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
1351+ ret = FALSE;
1352+ continue;
1353+ }
1354+ }
1355+ }
1356+ break;
1357+
1358+ case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1359+ break; /* Do nothing. */
1360+
1361+ case (int) R_MICROBLAZE_GOTPC_64:
1362+ relocation = htab->sgotplt->output_section->vma
1363+ + htab->sgotplt->output_offset;
1364+ relocation -= (input_section->output_section->vma
1365+ + input_section->output_offset
1366+ + offset + INST_WORD_SIZE);
1367+ relocation += addend;
1368+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1369+ contents + offset + endian);
1370+ bfd_put_16 (input_bfd, relocation & 0xffff,
1371+ contents + offset + endian + INST_WORD_SIZE);
1372+ break;
1373+
1374+ case (int) R_MICROBLAZE_PLT_64:
1375+ {
1376+ bfd_vma immediate;
1377+ if (htab->splt != NULL && h != NULL
1378+ && h->plt.offset != (bfd_vma) -1)
1379+ {
1380+ relocation = (htab->splt->output_section->vma
1381+ + htab->splt->output_offset
1382+ + h->plt.offset);
1383+ unresolved_reloc = FALSE;
1384+ immediate = relocation - (input_section->output_section->vma
1385+ + input_section->output_offset
1386+ + offset + INST_WORD_SIZE);
1387+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1388+ contents + offset + endian);
1389+ bfd_put_16 (input_bfd, immediate & 0xffff,
1390+ contents + offset + endian + INST_WORD_SIZE);
1391+ }
1392+ else
1393+ {
1394+ relocation -= (input_section->output_section->vma
1395+ + input_section->output_offset
1396+ + offset + INST_WORD_SIZE);
1397+ immediate = relocation;
1398+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1399+ contents + offset + endian);
1400+ bfd_put_16 (input_bfd, immediate & 0xffff,
1401+ contents + offset + endian + INST_WORD_SIZE);
1402+ }
1403+ break;
1404+ }
1405+
1406+ case (int) R_MICROBLAZE_TLSGD:
1407+ tls_type = (TLS_TLS | TLS_GD);
1408+ goto dogot;
1409+ case (int) R_MICROBLAZE_TLSLD:
1410+ tls_type = (TLS_TLS | TLS_LD);
1411+ dogot:
1412+ case (int) R_MICROBLAZE_GOT_64:
1413+ {
1414+ bfd_vma *offp;
1415+ bfd_vma off, off2;
1416+ unsigned long indx;
1417+ bfd_vma static_value;
1418+
1419+ bfd_boolean need_relocs = FALSE;
1420+ if (htab->sgot == NULL)
1421+ abort ();
1422+
1423+ indx = 0;
1424+ offp = NULL;
1425+
1426+ /* 1. Identify GOT Offset;
1427+ 2. Compute Static Values
1428+ 3. Process Module Id, Process Offset
1429+ 4. Fixup Relocation with GOT offset value. */
1430+
1431+ /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1432+ if (IS_TLS_LD (tls_type))
1433+ offp = &htab->tlsld_got.offset;
1434+ else if (h != NULL)
1435+ {
1436+ if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
1437+ offp = &h->got.offset;
1438+ else
1439+ abort ();
1440+ }
1441+ else
1442+ {
1443+ if (local_got_offsets == NULL)
1444+ abort ();
1445+ offp = &local_got_offsets[r_symndx];
1446+ }
1447+
1448+ if (!offp)
1449+ abort ();
1450+
1451+ off = (*offp) & ~1;
1452+ off2 = off;
1453+
1454+ if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1455+ off2 = off + 4;
1456+
1457+ /* Symbol index to use for relocs */
1458+ if (h != NULL)
1459+ {
1460+ bfd_boolean dyn =
1461+ elf_hash_table (info)->dynamic_sections_created;
1462+
1463+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1464+ bfd_link_pic (info),
1465+ h)
1466+ && (!bfd_link_pic (info)
1467+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
1468+ indx = h->dynindx;
1469+ }
1470+
1471+ /* Need to generate relocs ? */
1472+ if ((bfd_link_pic (info) || indx != 0)
1473+ && (h == NULL
1474+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1475+ || h->root.type != bfd_link_hash_undefweak))
1476+ need_relocs = TRUE;
1477+
1478+ /* 2. Compute/Emit Static value of r-expression */
1479+ static_value = relocation + addend;
1480+
1481+ /* 3. Process module-id and offset */
1482+ if (! ((*offp) & 1) )
1483+ {
1484+ bfd_vma got_offset;
1485+
1486+ got_offset = (htab->sgot->output_section->vma
1487+ + htab->sgot->output_offset
1488+ + off);
1489+
1490+ /* Process module-id */
1491+ if (IS_TLS_LD(tls_type))
1492+ {
1493+ if (! bfd_link_pic (info))
1494+ {
1495+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1496+ }
1497+ else
1498+ {
1499+ microblaze_elf_output_dynamic_relocation (output_bfd,
1500+ htab->srelgot, htab->srelgot->reloc_count++,
1501+ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1502+ got_offset, 0);
1503+ }
1504+ }
1505+ else if (IS_TLS_GD(tls_type))
1506+ {
1507+ if (! need_relocs)
1508+ {
1509+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1510+ }
1511+ else
1512+ {
1513+ microblaze_elf_output_dynamic_relocation (output_bfd,
1514+ htab->srelgot,
1515+ htab->srelgot->reloc_count++,
1516+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1517+ got_offset, indx ? 0 : static_value);
1518+ }
1519+ }
1520+
1521+ /* Process Offset */
1522+ if (htab->srelgot == NULL)
1523+ abort ();
1524+
1525+ got_offset = (htab->sgot->output_section->vma
1526+ + htab->sgot->output_offset
1527+ + off2);
1528+ if (IS_TLS_LD(tls_type))
1529+ {
1530+ /* For LD, offset should be 0 */
1531+ *offp |= 1;
1532+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
1533+ }
1534+ else if (IS_TLS_GD(tls_type))
1535+ {
1536+ *offp |= 1;
1537+ static_value -= dtprel_base(info);
1538+ if (need_relocs)
1539+ {
1540+ microblaze_elf_output_dynamic_relocation (output_bfd,
1541+ htab->srelgot, htab->srelgot->reloc_count++,
1542+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1543+ got_offset, indx ? 0 : static_value);
1544+ }
1545+ else
1546+ {
1547+ bfd_put_32 (output_bfd, static_value,
1548+ htab->sgot->contents + off2);
1549+ }
1550+ }
1551+ else
1552+ {
1553+ bfd_put_32 (output_bfd, static_value,
1554+ htab->sgot->contents + off2);
1555+
1556+ /* Relocs for dyn symbols generated by
1557+ finish_dynamic_symbols */
1558+ if (bfd_link_pic (info) && h == NULL)
1559+ {
1560+ *offp |= 1;
1561+ microblaze_elf_output_dynamic_relocation (output_bfd,
1562+ htab->srelgot, htab->srelgot->reloc_count++,
1563+ /* symindex= */ indx, R_MICROBLAZE_REL,
1564+ got_offset, static_value);
1565+ }
1566+ }
1567+ }
1568+
1569+ /* 4. Fixup Relocation with GOT offset value
1570+ Compute relative address of GOT entry for applying
1571+ the current relocation */
1572+ relocation = htab->sgot->output_section->vma
1573+ + htab->sgot->output_offset
1574+ + off
1575+ - htab->sgotplt->output_section->vma
1576+ - htab->sgotplt->output_offset;
1577+
1578+ /* Apply Current Relocation */
1579+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1580+ contents + offset + endian);
1581+ bfd_put_16 (input_bfd, relocation & 0xffff,
1582+ contents + offset + endian + INST_WORD_SIZE);
1583+
1584+ unresolved_reloc = FALSE;
1585+ break;
1586+ }
1587+
1588+ case (int) R_MICROBLAZE_GOTOFF_64:
1589+ {
1590+ bfd_vma immediate;
1591+ unsigned short lo, high;
1592+ relocation += addend;
1593+ relocation -= htab->sgotplt->output_section->vma
1594+ + htab->sgotplt->output_offset;
1595+ /* Write this value into correct location. */
1596+ immediate = relocation;
1597+ lo = immediate & 0x0000ffff;
1598+ high = (immediate >> 16) & 0x0000ffff;
1599+ bfd_put_16 (input_bfd, high, contents + offset + endian);
1600+ bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
1601+ break;
1602+ }
1603+
1604+ case (int) R_MICROBLAZE_GOTOFF_32:
1605+ {
1606+ relocation += addend;
1607+ relocation -= htab->sgotplt->output_section->vma
1608+ + htab->sgotplt->output_offset;
1609+ /* Write this value into correct location. */
1610+ bfd_put_32 (input_bfd, relocation, contents + offset);
1611+ break;
1612+ }
1613+
1614+ case (int) R_MICROBLAZE_TLSDTPREL64:
1615+ relocation += addend;
1616+ relocation -= dtprel_base(info);
1617+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1618+ contents + offset + endian);
1619+ bfd_put_16 (input_bfd, relocation & 0xffff,
1620+ contents + offset + endian + INST_WORD_SIZE);
1621+ break;
1622+ case (int) R_MICROBLAZE_64_PCREL :
1623+ case (int) R_MICROBLAZE_64:
1624+ case (int) R_MICROBLAZE_32:
1625+ {
1626+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1627+ from removed linkonce sections, or sections discarded by
1628+ a linker script. */
1629+ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1630+ {
1631+ relocation += addend;
1632+ if (r_type == R_MICROBLAZE_32)
1633+ bfd_put_32 (input_bfd, relocation, contents + offset);
1634+ else
1635+ {
1636+ if (r_type == R_MICROBLAZE_64_PCREL)
1637+ relocation -= (input_section->output_section->vma
1638+ + input_section->output_offset
1639+ + offset + INST_WORD_SIZE);
1640+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1641+ contents + offset + endian);
1642+ bfd_put_16 (input_bfd, relocation & 0xffff,
1643+ contents + offset + endian + INST_WORD_SIZE);
1644+ }
1645+ break;
1646+ }
1647+
1648+ if ((bfd_link_pic (info)
1649+ && (h == NULL
1650+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1651+ || h->root.type != bfd_link_hash_undefweak)
1652+ && (!howto->pc_relative
1653+ || (h != NULL
1654+ && h->dynindx != -1
1655+ && (!info->symbolic
1656+ || !h->def_regular))))
1657+ || (!bfd_link_pic (info)
1658+ && h != NULL
1659+ && h->dynindx != -1
1660+ && !h->non_got_ref
1661+ && ((h->def_dynamic
1662+ && !h->def_regular)
1663+ || h->root.type == bfd_link_hash_undefweak
1664+ || h->root.type == bfd_link_hash_undefined)))
1665+ {
1666+ Elf_Internal_Rela outrel;
1667+ bfd_byte *loc;
1668+ bfd_boolean skip;
1669+
1670+ /* When generating a shared object, these relocations
1671+ are copied into the output file to be resolved at run
1672+ time. */
1673+
1674+ BFD_ASSERT (sreloc != NULL);
1675+
1676+ skip = FALSE;
1677+
1678+ outrel.r_offset =
1679+ _bfd_elf_section_offset (output_bfd, info, input_section,
1680+ rel->r_offset);
1681+ if (outrel.r_offset == (bfd_vma) -1)
1682+ skip = TRUE;
1683+ else if (outrel.r_offset == (bfd_vma) -2)
1684+ skip = TRUE;
1685+ outrel.r_offset += (input_section->output_section->vma
1686+ + input_section->output_offset);
1687+
1688+ if (skip)
1689+ memset (&outrel, 0, sizeof outrel);
1690+ /* h->dynindx may be -1 if the symbol was marked to
1691+ become local. */
1692+ else if (h != NULL
1693+ && ((! info->symbolic && h->dynindx != -1)
1694+ || !h->def_regular))
1695+ {
1696+ BFD_ASSERT (h->dynindx != -1);
1697+ outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
1698+ outrel.r_addend = addend;
1699+ }
1700+ else
1701+ {
1702+ if (r_type == R_MICROBLAZE_32)
1703+ {
1704+ outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
1705+ outrel.r_addend = relocation + addend;
1706+ }
1707+ else
1708+ {
1709+ BFD_FAIL ();
1710+ (*_bfd_error_handler)
1711+ (_("%B: probably compiled without -fPIC?"),
1712+ input_bfd);
1713+ bfd_set_error (bfd_error_bad_value);
1714+ return FALSE;
1715+ }
1716+ }
1717+
1718+ loc = sreloc->contents;
1719+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
1720+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
1721+ break;
1722+ }
1723+ else
1724+ {
1725+ relocation += addend;
1726+ if (r_type == R_MICROBLAZE_32)
1727+ bfd_put_32 (input_bfd, relocation, contents + offset);
1728+ else
1729+ {
1730+ if (r_type == R_MICROBLAZE_64_PCREL)
1731+ relocation -= (input_section->output_section->vma
1732+ + input_section->output_offset
1733+ + offset + INST_WORD_SIZE);
1734+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1735+ contents + offset + endian);
1736+ bfd_put_16 (input_bfd, relocation & 0xffff,
1737+ contents + offset + endian + INST_WORD_SIZE);
1738+ }
1739+ break;
1740+ }
1741+ }
1742+
1743+ default :
1744+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1745+ contents, offset,
1746+ relocation, addend);
1747+ break;
1748+ }
1749+ }
1750+
1751+ check_reloc:
1752+
1753+ if (r != bfd_reloc_ok)
1754+ {
1755+ /* FIXME: This should be generic enough to go in a utility. */
1756+ const char *name;
1757+
1758+ if (h != NULL)
1759+ name = h->root.root.string;
1760+ else
1761+ {
1762+ name = (bfd_elf_string_from_elf_section
1763+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
1764+ if (name == NULL || *name == '\0')
1765+ name = bfd_section_name (input_bfd, sec);
1766+ }
1767+
1768+ if (errmsg != NULL)
1769+ goto common_error;
1770+
1771+ switch (r)
1772+ {
1773+ case bfd_reloc_overflow:
1774+ (*info->callbacks->reloc_overflow)
1775+ (info, (h ? &h->root : NULL), name, howto->name,
1776+ (bfd_vma) 0, input_bfd, input_section, offset);
1777+ break;
1778+
1779+ case bfd_reloc_undefined:
1780+ (*info->callbacks->undefined_symbol)
1781+ (info, name, input_bfd, input_section, offset, TRUE);
1782+ break;
1783+
1784+ case bfd_reloc_outofrange:
1785+ errmsg = _("internal error: out of range error");
1786+ goto common_error;
1787+
1788+ case bfd_reloc_notsupported:
1789+ errmsg = _("internal error: unsupported relocation error");
1790+ goto common_error;
1791+
1792+ case bfd_reloc_dangerous:
1793+ errmsg = _("internal error: dangerous error");
1794+ goto common_error;
1795+
1796+ default:
1797+ errmsg = _("internal error: unknown error");
1798+ /* Fall through. */
1799+ common_error:
1800+ (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1801+ input_section, offset);
1802+ break;
1803+ }
1804+ }
1805+ }
1806+
1807+ return ret;
1808+}
1809+
1810+/* Merge backend specific data from an object file to the output
1811+ object file when linking.
1812+
1813+ Note: We only use this hook to catch endian mismatches. */
1814+static bfd_boolean
1815+microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1816+{
1817+ /* Check if we have the same endianess. */
1818+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
1819+ return FALSE;
1820+
1821+ return TRUE;
1822+}
1823+
1824+
1825+/* Calculate fixup value for reference. */
1826+
1827+static int
1828+calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1829+{
1830+ bfd_vma end = start + size;
1831+ int i, fixup = 0;
1832+
1833+ if (sec == NULL || sec->relax == NULL)
1834+ return 0;
1835+
1836+ /* Look for addr in relax table, total fixup value. */
1837+ for (i = 0; i < sec->relax_count; i++)
1838+ {
1839+ if (end <= sec->relax[i].addr)
1840+ break;
1841+ if ((end != start) && (start > sec->relax[i].addr))
1842+ continue;
1843+ fixup += sec->relax[i].size;
1844+ }
1845+ return fixup;
1846+}
1847+
1848+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
1849+ a 32-bit instruction. */
1850+static void
1851+microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1852+{
1853+ unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1854+ instr &= ~0x0000ffff;
1855+ instr |= (val & 0x0000ffff);
1856+ bfd_put_32 (abfd, instr, bfd_addr);
1857+}
1858+
1859+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
1860+ two consecutive 32-bit instructions. */
1861+static void
1862+microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1863+{
1864+ unsigned long instr_hi;
1865+ unsigned long instr_lo;
1866+
1867+ instr_hi = bfd_get_32 (abfd, bfd_addr);
1868+ instr_hi &= ~0x0000ffff;
1869+ instr_hi |= ((val >> 16) & 0x0000ffff);
1870+ bfd_put_32 (abfd, instr_hi, bfd_addr);
1871+
1872+ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1873+ instr_lo &= ~0x0000ffff;
1874+ instr_lo |= (val & 0x0000ffff);
1875+ bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1876+}
1877+
1878+static bfd_boolean
1879+microblaze_elf_relax_section (bfd *abfd,
1880+ asection *sec,
1881+ struct bfd_link_info *link_info,
1882+ bfd_boolean *again)
1883+{
1884+ Elf_Internal_Shdr *symtab_hdr;
1885+ Elf_Internal_Rela *internal_relocs;
1886+ Elf_Internal_Rela *free_relocs = NULL;
1887+ Elf_Internal_Rela *irel, *irelend;
1888+ bfd_byte *contents = NULL;
1889+ bfd_byte *free_contents = NULL;
1890+ int rel_count;
1891+ unsigned int shndx;
1892+ int i, sym_index;
1893+ asection *o;
1894+ struct elf_link_hash_entry *sym_hash;
1895+ Elf_Internal_Sym *isymbuf, *isymend;
1896+ Elf_Internal_Sym *isym;
1897+ int symcount;
1898+ int offset;
1899+ bfd_vma src, dest;
1900+
1901+ /* We only do this once per section. We may be able to delete some code
1902+ by running multiple passes, but it is not worth it. */
1903+ *again = FALSE;
1904+
1905+ /* Only do this for a text section. */
1906+ if (bfd_link_relocatable (link_info)
1907+ || (sec->flags & SEC_RELOC) == 0
1908+ || (sec->reloc_count == 0)
1909+ || (sec->flags & SEC_CODE) == 0)
1910+ return TRUE;
1911+
1912+ BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1913+
1914+ /* If this is the first time we have been called for this section,
1915+ initialize the cooked size. */
1916+ if (sec->size == 0)
1917+ sec->size = sec->rawsize;
1918+
1919+ /* Get symbols for this section. */
1920+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1921+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1922+ symcount = symtab_hdr->sh_size / sizeof (Elf64_External_Sym);
1923+ if (isymbuf == NULL)
1924+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1925+ 0, NULL, NULL, NULL);
1926+ BFD_ASSERT (isymbuf != NULL);
1927+
1928+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1929+ if (internal_relocs == NULL)
1930+ goto error_return;
1931+ if (! link_info->keep_memory)
1932+ free_relocs = internal_relocs;
1933+
1934+ sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1935+ * sizeof (struct relax_table));
1936+ if (sec->relax == NULL)
1937+ goto error_return;
1938+ sec->relax_count = 0;
1939+
1940+ irelend = internal_relocs + sec->reloc_count;
1941+ rel_count = 0;
1942+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1943+ {
1944+ bfd_vma symval;
1945+ if ((ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1946+ && (ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
1947+ continue; /* Can't delete this reloc. */
1948+
1949+ /* Get the section contents. */
1950+ if (contents == NULL)
1951+ {
1952+ if (elf_section_data (sec)->this_hdr.contents != NULL)
1953+ contents = elf_section_data (sec)->this_hdr.contents;
1954+ else
1955+ {
1956+ contents = (bfd_byte *) bfd_malloc (sec->size);
1957+ if (contents == NULL)
1958+ goto error_return;
1959+ free_contents = contents;
1960+
1961+ if (!bfd_get_section_contents (abfd, sec, contents,
1962+ (file_ptr) 0, sec->size))
1963+ goto error_return;
1964+ elf_section_data (sec)->this_hdr.contents = contents;
1965+ }
1966+ }
1967+
1968+ /* Get the value of the symbol referred to by the reloc. */
1969+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1970+ {
1971+ /* A local symbol. */
1972+ asection *sym_sec;
1973+
1974+ isym = isymbuf + ELF64_R_SYM (irel->r_info);
1975+ if (isym->st_shndx == SHN_UNDEF)
1976+ sym_sec = bfd_und_section_ptr;
1977+ else if (isym->st_shndx == SHN_ABS)
1978+ sym_sec = bfd_abs_section_ptr;
1979+ else if (isym->st_shndx == SHN_COMMON)
1980+ sym_sec = bfd_com_section_ptr;
1981+ else
1982+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1983+
1984+ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1985+ }
1986+ else
1987+ {
1988+ unsigned long indx;
1989+ struct elf_link_hash_entry *h;
1990+
1991+ indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1992+ h = elf_sym_hashes (abfd)[indx];
1993+ BFD_ASSERT (h != NULL);
1994+
1995+ if (h->root.type != bfd_link_hash_defined
1996+ && h->root.type != bfd_link_hash_defweak)
1997+ /* This appears to be a reference to an undefined
1998+ symbol. Just ignore it--it will be caught by the
1999+ regular reloc processing. */
2000+ continue;
2001+
2002+ symval = (h->root.u.def.value
2003+ + h->root.u.def.section->output_section->vma
2004+ + h->root.u.def.section->output_offset);
2005+ }
2006+
2007+ /* If this is a PC-relative reloc, subtract the instr offset from
2008+ the symbol value. */
2009+ if (ELF64_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
2010+ {
2011+ symval = symval + irel->r_addend
2012+ - (irel->r_offset
2013+ + sec->output_section->vma
2014+ + sec->output_offset);
2015+ }
2016+ else
2017+ symval += irel->r_addend;
2018+
2019+ if ((symval & 0xffff8000) == 0)
2020+ {
2021+ /* We can delete this instruction. */
2022+ sec->relax[sec->relax_count].addr = irel->r_offset;
2023+ sec->relax[sec->relax_count].size = INST_WORD_SIZE;
2024+ sec->relax_count++;
2025+
2026+ /* Rewrite relocation type. */
2027+ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info))
2028+ {
2029+ case R_MICROBLAZE_64_PCREL:
2030+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
2031+ (int) R_MICROBLAZE_32_PCREL_LO);
2032+ break;
2033+ case R_MICROBLAZE_64:
2034+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
2035+ (int) R_MICROBLAZE_32_LO);
2036+ break;
2037+ default:
2038+ /* Cannot happen. */
2039+ BFD_ASSERT (FALSE);
2040+ }
2041+ }
2042+ } /* Loop through all relocations. */
2043+
2044+ /* Loop through the relocs again, and see if anything needs to change. */
2045+ if (sec->relax_count > 0)
2046+ {
2047+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
2048+ rel_count = 0;
2049+ sec->relax[sec->relax_count].addr = sec->size;
2050+
2051+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
2052+ {
2053+ bfd_vma nraddr;
2054+
2055+ /* Get the new reloc address. */
2056+ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
2057+ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info))
2058+ {
2059+ default:
2060+ break;
2061+ case R_MICROBLAZE_64_PCREL:
2062+ break;
2063+ case R_MICROBLAZE_64:
2064+ case R_MICROBLAZE_32_LO:
2065+ /* If this reloc is against a symbol defined in this
2066+ section, we must check the addend to see it will put the value in
2067+ range to be adjusted, and hence must be changed. */
2068+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2069+ {
2070+ isym = isymbuf + ELF64_R_SYM (irel->r_info);
2071+ /* Only handle relocs against .text. */
2072+ if (isym->st_shndx == shndx
2073+ && ELF64_ST_TYPE (isym->st_info) == STT_SECTION)
2074+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
2075+ }
2076+ break;
2077+ case R_MICROBLAZE_NONE:
2078+ case R_MICROBLAZE_32_NONE:
2079+ {
2080+ /* This was a PC-relative instruction that was
2081+ completely resolved. */
2082+ int sfix, efix;
2083+ unsigned int val;
2084+ bfd_vma target_address;
2085+ target_address = irel->r_addend + irel->r_offset;
2086+ sfix = calc_fixup (irel->r_offset, 0, sec);
2087+ efix = calc_fixup (target_address, 0, sec);
2088+
2089+ /* Validate the in-band val. */
2090+ val = bfd_get_32 (abfd, contents + irel->r_offset);
2091+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
2092+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
2093+ }
2094+ irel->r_addend -= (efix - sfix);
2095+ /* Should use HOWTO. */
2096+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
2097+ irel->r_addend);
2098+ }
2099+ break;
2100+ case R_MICROBLAZE_64_NONE:
2101+ {
2102+ /* This was a PC-relative 64-bit instruction that was
2103+ completely resolved. */
2104+ int sfix, efix;
2105+ bfd_vma target_address;
2106+ target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
2107+ sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
2108+ efix = calc_fixup (target_address, 0, sec);
2109+ irel->r_addend -= (efix - sfix);
2110+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
2111+ + INST_WORD_SIZE, irel->r_addend);
2112+ }
2113+ break;
2114+ }
2115+ irel->r_offset = nraddr;
2116+ } /* Change all relocs in this section. */
2117+
2118+ /* Look through all other sections. */
2119+ for (o = abfd->sections; o != NULL; o = o->next)
2120+ {
2121+ Elf_Internal_Rela *irelocs;
2122+ Elf_Internal_Rela *irelscan, *irelscanend;
2123+ bfd_byte *ocontents;
2124+
2125+ if (o == sec
2126+ || (o->flags & SEC_RELOC) == 0
2127+ || o->reloc_count == 0)
2128+ continue;
2129+
2130+ /* We always cache the relocs. Perhaps, if info->keep_memory is
2131+ FALSE, we should free them, if we are permitted to. */
2132+
2133+ irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
2134+ if (irelocs == NULL)
2135+ goto error_return;
2136+
2137+ ocontents = NULL;
2138+ irelscanend = irelocs + o->reloc_count;
2139+ for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
2140+ {
2141+ if (1 && ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
2142+ {
2143+ unsigned int val;
2144+
2145+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2146+
2147+ /* hax: We only do the following fixup for debug location lists. */
2148+ if (strcmp(".debug_loc", o->name))
2149+ continue;
2150+
2151+ /* This was a PC-relative instruction that was completely resolved. */
2152+ if (ocontents == NULL)
2153+ {
2154+ if (elf_section_data (o)->this_hdr.contents != NULL)
2155+ ocontents = elf_section_data (o)->this_hdr.contents;
2156+ else
2157+ {
2158+ /* We always cache the section contents.
2159+ Perhaps, if info->keep_memory is FALSE, we
2160+ should free them, if we are permitted to. */
2161+
2162+ if (o->rawsize == 0)
2163+ o->rawsize = o->size;
2164+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2165+ if (ocontents == NULL)
2166+ goto error_return;
2167+ if (!bfd_get_section_contents (abfd, o, ocontents,
2168+ (file_ptr) 0,
2169+ o->rawsize))
2170+ goto error_return;
2171+ elf_section_data (o)->this_hdr.contents = ocontents;
2172+ }
2173+ }
2174+
2175+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2176+ if (val != irelscan->r_addend) {
2177+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
2178+ }
2179+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2180+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2181+ irelscan->r_addend);
2182+ }
2183+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
2184+ {
2185+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2186+
2187+ /* Look at the reloc only if the value has been resolved. */
2188+ if (isym->st_shndx == shndx
2189+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2190+ {
2191+ if (ocontents == NULL)
2192+ {
2193+ if (elf_section_data (o)->this_hdr.contents != NULL)
2194+ ocontents = elf_section_data (o)->this_hdr.contents;
2195+ else
2196+ {
2197+ /* We always cache the section contents.
2198+ Perhaps, if info->keep_memory is FALSE, we
2199+ should free them, if we are permitted to. */
2200+ if (o->rawsize == 0)
2201+ o->rawsize = o->size;
2202+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2203+ if (ocontents == NULL)
2204+ goto error_return;
2205+ if (!bfd_get_section_contents (abfd, o, ocontents,
2206+ (file_ptr) 0,
2207+ o->rawsize))
2208+ goto error_return;
2209+ elf_section_data (o)->this_hdr.contents = ocontents;
2210+ }
2211+
2212+ }
2213+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2214+ }
2215+ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
2216+ {
2217+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2218+
2219+ /* Look at the reloc only if the value has been resolved. */
2220+ if (ocontents == NULL)
2221+ {
2222+ if (elf_section_data (o)->this_hdr.contents != NULL)
2223+ ocontents = elf_section_data (o)->this_hdr.contents;
2224+ else
2225+ {
2226+ /* We always cache the section contents.
2227+ Perhaps, if info->keep_memory is FALSE, we
2228+ should free them, if we are permitted to. */
2229+
2230+ if (o->rawsize == 0)
2231+ o->rawsize = o->size;
2232+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2233+ if (ocontents == NULL)
2234+ goto error_return;
2235+ if (!bfd_get_section_contents (abfd, o, ocontents,
2236+ (file_ptr) 0,
2237+ o->rawsize))
2238+ goto error_return;
2239+ elf_section_data (o)->this_hdr.contents = ocontents;
2240+ }
2241+ }
2242+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
2243+ + isym->st_value,
2244+ 0,
2245+ sec);
2246+ }
2247+ }
2248+ else if ((ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
2249+ || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
2250+ {
2251+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2252+
2253+ /* Look at the reloc only if the value has been resolved. */
2254+ if (isym->st_shndx == shndx
2255+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2256+ {
2257+ bfd_vma immediate;
2258+ bfd_vma target_address;
2259+
2260+ if (ocontents == NULL)
2261+ {
2262+ if (elf_section_data (o)->this_hdr.contents != NULL)
2263+ ocontents = elf_section_data (o)->this_hdr.contents;
2264+ else
2265+ {
2266+ /* We always cache the section contents.
2267+ Perhaps, if info->keep_memory is FALSE, we
2268+ should free them, if we are permitted to. */
2269+ if (o->rawsize == 0)
2270+ o->rawsize = o->size;
2271+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2272+ if (ocontents == NULL)
2273+ goto error_return;
2274+ if (!bfd_get_section_contents (abfd, o, ocontents,
2275+ (file_ptr) 0,
2276+ o->rawsize))
2277+ goto error_return;
2278+ elf_section_data (o)->this_hdr.contents = ocontents;
2279+ }
2280+ }
2281+
2282+ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2283+ immediate = instr & 0x0000ffff;
2284+ target_address = immediate;
2285+ offset = calc_fixup (target_address, 0, sec);
2286+ immediate -= offset;
2287+ irelscan->r_addend -= offset;
2288+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2289+ irelscan->r_addend);
2290+ }
2291+ }
2292+
2293+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
2294+ {
2295+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2296+
2297+ /* Look at the reloc only if the value has been resolved. */
2298+ if (isym->st_shndx == shndx
2299+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2300+ {
2301+ bfd_vma immediate;
2302+
2303+ if (ocontents == NULL)
2304+ {
2305+ if (elf_section_data (o)->this_hdr.contents != NULL)
2306+ ocontents = elf_section_data (o)->this_hdr.contents;
2307+ else
2308+ {
2309+ /* We always cache the section contents.
2310+ Perhaps, if info->keep_memory is FALSE, we
2311+ should free them, if we are permitted to. */
2312+
2313+ if (o->rawsize == 0)
2314+ o->rawsize = o->size;
2315+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2316+ if (ocontents == NULL)
2317+ goto error_return;
2318+ if (!bfd_get_section_contents (abfd, o, ocontents,
2319+ (file_ptr) 0,
2320+ o->rawsize))
2321+ goto error_return;
2322+ elf_section_data (o)->this_hdr.contents = ocontents;
2323+ }
2324+ }
2325+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2326+ + irelscan->r_offset);
2327+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2328+ + irelscan->r_offset
2329+ + INST_WORD_SIZE);
2330+ immediate = (instr_hi & 0x0000ffff) << 16;
2331+ immediate |= (instr_lo & 0x0000ffff);
2332+ offset = calc_fixup (irelscan->r_addend, 0, sec);
2333+ immediate -= offset;
2334+ irelscan->r_addend -= offset;
2335+ }
2336+ }
2337+ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2338+ {
2339+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2340+
2341+ /* Look at the reloc only if the value has been resolved. */
2342+ if (isym->st_shndx == shndx
2343+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2344+ {
2345+ bfd_vma immediate;
2346+ bfd_vma target_address;
2347+
2348+ if (ocontents == NULL)
2349+ {
2350+ if (elf_section_data (o)->this_hdr.contents != NULL)
2351+ ocontents = elf_section_data (o)->this_hdr.contents;
2352+ else
2353+ {
2354+ /* We always cache the section contents.
2355+ Perhaps, if info->keep_memory is FALSE, we
2356+ should free them, if we are permitted to. */
2357+ if (o->rawsize == 0)
2358+ o->rawsize = o->size;
2359+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2360+ if (ocontents == NULL)
2361+ goto error_return;
2362+ if (!bfd_get_section_contents (abfd, o, ocontents,
2363+ (file_ptr) 0,
2364+ o->rawsize))
2365+ goto error_return;
2366+ elf_section_data (o)->this_hdr.contents = ocontents;
2367+ }
2368+ }
2369+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2370+ + irelscan->r_offset);
2371+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2372+ + irelscan->r_offset
2373+ + INST_WORD_SIZE);
2374+ immediate = (instr_hi & 0x0000ffff) << 16;
2375+ immediate |= (instr_lo & 0x0000ffff);
2376+ target_address = immediate;
2377+ offset = calc_fixup (target_address, 0, sec);
2378+ immediate -= offset;
2379+ irelscan->r_addend -= offset;
2380+ microblaze_bfd_write_imm_value_64 (abfd, ocontents
2381+ + irelscan->r_offset, immediate);
2382+ }
2383+ }
2384+ }
2385+ }
2386+
2387+ /* Adjust the local symbols defined in this section. */
2388+ isymend = isymbuf + symtab_hdr->sh_info;
2389+ for (isym = isymbuf; isym < isymend; isym++)
2390+ {
2391+ if (isym->st_shndx == shndx)
2392+ {
2393+ isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2394+ if (isym->st_size)
2395+ isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2396+ }
2397+ }
2398+
2399+ /* Now adjust the global symbols defined in this section. */
2400+ isym = isymbuf + symtab_hdr->sh_info;
2401+ symcount = (symtab_hdr->sh_size / sizeof (Elf64_External_Sym)) - symtab_hdr->sh_info;
2402+ for (sym_index = 0; sym_index < symcount; sym_index++)
2403+ {
2404+ sym_hash = elf_sym_hashes (abfd)[sym_index];
2405+ if ((sym_hash->root.type == bfd_link_hash_defined
2406+ || sym_hash->root.type == bfd_link_hash_defweak)
2407+ && sym_hash->root.u.def.section == sec)
2408+ {
2409+ sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2410+ 0, sec);
2411+ if (sym_hash->size)
2412+ sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2413+ sym_hash->size, sec);
2414+ }
2415+ }
2416+
2417+ /* Physically move the code and change the cooked size. */
2418+ dest = sec->relax[0].addr;
2419+ for (i = 0; i < sec->relax_count; i++)
2420+ {
2421+ int len;
2422+ src = sec->relax[i].addr + sec->relax[i].size;
2423+ len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
2424+
2425+ memmove (contents + dest, contents + src, len);
2426+ sec->size -= sec->relax[i].size;
2427+ dest += len;
2428+ }
2429+
2430+ elf_section_data (sec)->relocs = internal_relocs;
2431+ free_relocs = NULL;
2432+
2433+ elf_section_data (sec)->this_hdr.contents = contents;
2434+ free_contents = NULL;
2435+
2436+ symtab_hdr->contents = (bfd_byte *) isymbuf;
2437+ }
2438+
2439+ if (free_relocs != NULL)
2440+ {
2441+ free (free_relocs);
2442+ free_relocs = NULL;
2443+ }
2444+
2445+ if (free_contents != NULL)
2446+ {
2447+ if (!link_info->keep_memory)
2448+ free (free_contents);
2449+ else
2450+ /* Cache the section contents for elf_link_input_bfd. */
2451+ elf_section_data (sec)->this_hdr.contents = contents;
2452+ free_contents = NULL;
2453+ }
2454+
2455+ if (sec->relax_count == 0)
2456+ {
2457+ *again = FALSE;
2458+ free (sec->relax);
2459+ sec->relax = NULL;
2460+ }
2461+ else
2462+ *again = TRUE;
2463+ return TRUE;
2464+
2465+ error_return:
2466+ if (free_relocs != NULL)
2467+ free (free_relocs);
2468+ if (free_contents != NULL)
2469+ free (free_contents);
2470+ if (sec->relax != NULL)
2471+ {
2472+ free (sec->relax);
2473+ sec->relax = NULL;
2474+ sec->relax_count = 0;
2475+ }
2476+ return FALSE;
2477+}
2478+
2479+/* Return the section that should be marked against GC for a given
2480+ relocation. */
2481+
2482+static asection *
2483+microblaze_elf_gc_mark_hook (asection *sec,
2484+ struct bfd_link_info * info,
2485+ Elf_Internal_Rela * rel,
2486+ struct elf_link_hash_entry * h,
2487+ Elf_Internal_Sym * sym)
2488+{
2489+ if (h != NULL)
2490+ switch (ELF64_R_TYPE (rel->r_info))
2491+ {
2492+ case R_MICROBLAZE_GNU_VTINHERIT:
2493+ case R_MICROBLAZE_GNU_VTENTRY:
2494+ return NULL;
2495+ }
2496+
2497+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2498+}
2499+
2500+/* Update the got entry reference counts for the section being removed. */
2501+
2502+static bfd_boolean
2503+microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
2504+ struct bfd_link_info * info ATTRIBUTE_UNUSED,
2505+ asection * sec ATTRIBUTE_UNUSED,
2506+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
2507+{
2508+ return TRUE;
2509+}
2510+
2511+/* PIC support. */
2512+
2513+#define PLT_ENTRY_SIZE 16
2514+
2515+#define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2516+#define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2517+#define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2518+#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2519+#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2520+
2521+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
2522+ shortcuts to them in our hash table. */
2523+
2524+static bfd_boolean
2525+create_got_section (bfd *dynobj, struct bfd_link_info *info)
2526+{
2527+ struct elf64_mb_link_hash_table *htab;
2528+
2529+ if (! _bfd_elf_create_got_section (dynobj, info))
2530+ return FALSE;
2531+ htab = elf64_mb_hash_table (info);
2532+ if (htab == NULL)
2533+ return FALSE;
2534+
2535+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
2536+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
2537+ if (!htab->sgot || !htab->sgotplt)
2538+ return FALSE;
2539+
2540+ if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
2541+ htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
2542+ if (htab->srelgot == NULL
2543+ || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
2544+ | SEC_LOAD
2545+ | SEC_HAS_CONTENTS
2546+ | SEC_IN_MEMORY
2547+ | SEC_LINKER_CREATED
2548+ | SEC_READONLY)
2549+ || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
2550+ return FALSE;
2551+ return TRUE;
2552+}
2553+
2554+static bfd_boolean
2555+update_local_sym_info (bfd *abfd,
2556+ Elf_Internal_Shdr *symtab_hdr,
2557+ unsigned long r_symndx,
2558+ unsigned int tls_type)
2559+{
2560+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2561+ unsigned char *local_got_tls_masks;
2562+
2563+ if (local_got_refcounts == NULL)
2564+ {
2565+ bfd_size_type size = symtab_hdr->sh_info;
2566+
2567+ size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2568+ local_got_refcounts = bfd_zalloc (abfd, size);
2569+ if (local_got_refcounts == NULL)
2570+ return FALSE;
2571+ elf_local_got_refcounts (abfd) = local_got_refcounts;
2572+ }
2573+
2574+ local_got_tls_masks =
2575+ (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2576+ local_got_tls_masks[r_symndx] |= tls_type;
2577+ local_got_refcounts[r_symndx] += 1;
2578+
2579+ return TRUE;
2580+}
2581+/* Look through the relocs for a section during the first phase. */
2582+
2583+static bfd_boolean
2584+microblaze_elf_check_relocs (bfd * abfd,
2585+ struct bfd_link_info * info,
2586+ asection * sec,
2587+ const Elf_Internal_Rela * relocs)
2588+{
2589+ Elf_Internal_Shdr * symtab_hdr;
2590+ struct elf_link_hash_entry ** sym_hashes;
2591+ struct elf_link_hash_entry ** sym_hashes_end;
2592+ const Elf_Internal_Rela * rel;
2593+ const Elf_Internal_Rela * rel_end;
2594+ struct elf64_mb_link_hash_table *htab;
2595+ asection *sreloc = NULL;
2596+
2597+ if (bfd_link_relocatable (info))
2598+ return TRUE;
2599+
2600+ htab = elf64_mb_hash_table (info);
2601+ if (htab == NULL)
2602+ return FALSE;
2603+
2604+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2605+ sym_hashes = elf_sym_hashes (abfd);
2606+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf64_External_Sym);
2607+ if (!elf_bad_symtab (abfd))
2608+ sym_hashes_end -= symtab_hdr->sh_info;
2609+
2610+ rel_end = relocs + sec->reloc_count;
2611+
2612+ for (rel = relocs; rel < rel_end; rel++)
2613+ {
2614+ unsigned int r_type;
2615+ struct elf_link_hash_entry * h;
2616+ unsigned long r_symndx;
2617+ unsigned char tls_type = 0;
2618+
2619+ r_symndx = ELF64_R_SYM (rel->r_info);
2620+ r_type = ELF64_R_TYPE (rel->r_info);
2621+
2622+ if (r_symndx < symtab_hdr->sh_info)
2623+ h = NULL;
2624+ else
2625+ {
2626+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2627+
2628+ /* PR15323, ref flags aren't set for references in the same
2629+ object. */
2630+ h->root.non_ir_ref = 1;
2631+ }
2632+
2633+ switch (r_type)
2634+ {
2635+ /* This relocation describes the C++ object vtable hierarchy.
2636+ Reconstruct it for later use during GC. */
2637+ case R_MICROBLAZE_GNU_VTINHERIT:
2638+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2639+ return FALSE;
2640+ break;
2641+
2642+ /* This relocation describes which C++ vtable entries are actually
2643+ used. Record for later use during GC. */
2644+ case R_MICROBLAZE_GNU_VTENTRY:
2645+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2646+ return FALSE;
2647+ break;
2648+
2649+ /* This relocation requires .plt entry. */
2650+ case R_MICROBLAZE_PLT_64:
2651+ if (h != NULL)
2652+ {
2653+ h->needs_plt = 1;
2654+ h->plt.refcount += 1;
2655+ }
2656+ break;
2657+
2658+ /* This relocation requires .got entry. */
2659+ case R_MICROBLAZE_TLSGD:
2660+ tls_type |= (TLS_TLS | TLS_GD);
2661+ goto dogottls;
2662+ case R_MICROBLAZE_TLSLD:
2663+ tls_type |= (TLS_TLS | TLS_LD);
2664+ dogottls:
2665+ sec->has_tls_reloc = 1;
2666+ case R_MICROBLAZE_GOT_64:
2667+ if (htab->sgot == NULL)
2668+ {
2669+ if (htab->elf.dynobj == NULL)
2670+ htab->elf.dynobj = abfd;
2671+ if (!create_got_section (htab->elf.dynobj, info))
2672+ return FALSE;
2673+ }
2674+ if (h != NULL)
2675+ {
2676+ h->got.refcount += 1;
2677+ elf64_mb_hash_entry (h)->tls_mask |= tls_type;
2678+ }
2679+ else
2680+ {
2681+ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2682+ return FALSE;
2683+ }
2684+ break;
2685+
2686+ case R_MICROBLAZE_64:
2687+ case R_MICROBLAZE_64_PCREL:
2688+ case R_MICROBLAZE_32:
2689+ {
2690+ if (h != NULL && !bfd_link_pic (info))
2691+ {
2692+ /* we may need a copy reloc. */
2693+ h->non_got_ref = 1;
2694+
2695+ /* we may also need a .plt entry. */
2696+ h->plt.refcount += 1;
2697+ if (ELF64_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2698+ h->pointer_equality_needed = 1;
2699+ }
2700+
2701+
2702+ /* If we are creating a shared library, and this is a reloc
2703+ against a global symbol, or a non PC relative reloc
2704+ against a local symbol, then we need to copy the reloc
2705+ into the shared library. However, if we are linking with
2706+ -Bsymbolic, we do not need to copy a reloc against a
2707+ global symbol which is defined in an object we are
2708+ including in the link (i.e., DEF_REGULAR is set). At
2709+ this point we have not seen all the input files, so it is
2710+ possible that DEF_REGULAR is not set now but will be set
2711+ later (it is never cleared). In case of a weak definition,
2712+ DEF_REGULAR may be cleared later by a strong definition in
2713+ a shared library. We account for that possibility below by
2714+ storing information in the relocs_copied field of the hash
2715+ table entry. A similar situation occurs when creating
2716+ shared libraries and symbol visibility changes render the
2717+ symbol local.
2718+
2719+ If on the other hand, we are creating an executable, we
2720+ may need to keep relocations for symbols satisfied by a
2721+ dynamic library if we manage to avoid copy relocs for the
2722+ symbol. */
2723+
2724+ if ((bfd_link_pic (info)
2725+ && (sec->flags & SEC_ALLOC) != 0
2726+ && (r_type != R_MICROBLAZE_64_PCREL
2727+ || (h != NULL
2728+ && (! info->symbolic
2729+ || h->root.type == bfd_link_hash_defweak
2730+ || !h->def_regular))))
2731+ || (!bfd_link_pic (info)
2732+ && (sec->flags & SEC_ALLOC) != 0
2733+ && h != NULL
2734+ && (h->root.type == bfd_link_hash_defweak
2735+ || !h->def_regular)))
2736+ {
2737+ struct elf64_mb_dyn_relocs *p;
2738+ struct elf64_mb_dyn_relocs **head;
2739+
2740+ /* When creating a shared object, we must copy these
2741+ relocs into the output file. We create a reloc
2742+ section in dynobj and make room for the reloc. */
2743+
2744+ if (sreloc == NULL)
2745+ {
2746+ bfd *dynobj;
2747+
2748+ if (htab->elf.dynobj == NULL)
2749+ htab->elf.dynobj = abfd;
2750+ dynobj = htab->elf.dynobj;
2751+
2752+ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2753+ 2, abfd, 1);
2754+ if (sreloc == NULL)
2755+ return FALSE;
2756+ }
2757+
2758+ /* If this is a global symbol, we count the number of
2759+ relocations we need for this symbol. */
2760+ if (h != NULL)
2761+ head = &((struct elf64_mb_link_hash_entry *) h)->dyn_relocs;
2762+ else
2763+ {
2764+ /* Track dynamic relocs needed for local syms too.
2765+ We really need local syms available to do this
2766+ easily. Oh well. */
2767+
2768+ asection *s;
2769+ Elf_Internal_Sym *isym;
2770+ void *vpp;
2771+
2772+ isym = bfd_sym_from_r_symndx (&htab->sym_sec,
2773+ abfd, r_symndx);
2774+ if (isym == NULL)
2775+ return FALSE;
2776+
2777+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2778+ if (s == NULL)
2779+ return FALSE;
2780+
2781+ vpp = &elf_section_data (s)->local_dynrel;
2782+ head = (struct elf64_mb_dyn_relocs **) vpp;
2783+ }
2784+
2785+ p = *head;
2786+ if (p == NULL || p->sec != sec)
2787+ {
2788+ bfd_size_type amt = sizeof *p;
2789+ p = ((struct elf64_mb_dyn_relocs *)
2790+ bfd_alloc (htab->elf.dynobj, amt));
2791+ if (p == NULL)
2792+ return FALSE;
2793+ p->next = *head;
2794+ *head = p;
2795+ p->sec = sec;
2796+ p->count = 0;
2797+ p->pc_count = 0;
2798+ }
2799+
2800+ p->count += 1;
2801+ if (r_type == R_MICROBLAZE_64_PCREL)
2802+ p->pc_count += 1;
2803+ }
2804+ }
2805+ break;
2806+ }
2807+ }
2808+
2809+ return TRUE;
2810+}
2811+
2812+static bfd_boolean
2813+microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2814+{
2815+ struct elf64_mb_link_hash_table *htab;
2816+
2817+ htab = elf64_mb_hash_table (info);
2818+ if (htab == NULL)
2819+ return FALSE;
2820+
2821+ if (!htab->sgot && !create_got_section (dynobj, info))
2822+ return FALSE;
2823+
2824+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2825+ return FALSE;
2826+
2827+ htab->splt = bfd_get_linker_section (dynobj, ".plt");
2828+ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
2829+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
2830+ if (!bfd_link_pic (info))
2831+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
2832+
2833+ if (!htab->splt || !htab->srelplt || !htab->sdynbss
2834+ || (!bfd_link_pic (info) && !htab->srelbss))
2835+ abort ();
2836+
2837+ return TRUE;
2838+}
2839+
2840+/* Copy the extra info we tack onto an elf_link_hash_entry. */
2841+
2842+static void
2843+microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2844+ struct elf_link_hash_entry *dir,
2845+ struct elf_link_hash_entry *ind)
2846+{
2847+ struct elf64_mb_link_hash_entry *edir, *eind;
2848+
2849+ edir = (struct elf64_mb_link_hash_entry *) dir;
2850+ eind = (struct elf64_mb_link_hash_entry *) ind;
2851+
2852+ if (eind->dyn_relocs != NULL)
2853+ {
2854+ if (edir->dyn_relocs != NULL)
2855+ {
2856+ struct elf64_mb_dyn_relocs **pp;
2857+ struct elf64_mb_dyn_relocs *p;
2858+
2859+ if (ind->root.type == bfd_link_hash_indirect)
2860+ abort ();
2861+
2862+ /* Add reloc counts against the weak sym to the strong sym
2863+ list. Merge any entries against the same section. */
2864+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2865+ {
2866+ struct elf64_mb_dyn_relocs *q;
2867+
2868+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
2869+ if (q->sec == p->sec)
2870+ {
2871+ q->pc_count += p->pc_count;
2872+ q->count += p->count;
2873+ *pp = p->next;
2874+ break;
2875+ }
2876+ if (q == NULL)
2877+ pp = &p->next;
2878+ }
2879+ *pp = edir->dyn_relocs;
2880+ }
2881+
2882+ edir->dyn_relocs = eind->dyn_relocs;
2883+ eind->dyn_relocs = NULL;
2884+ }
2885+
2886+ edir->tls_mask |= eind->tls_mask;
2887+
2888+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2889+}
2890+
2891+static bfd_boolean
2892+microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2893+ struct elf_link_hash_entry *h)
2894+{
2895+ struct elf64_mb_link_hash_table *htab;
2896+ struct elf64_mb_link_hash_entry * eh;
2897+ struct elf64_mb_dyn_relocs *p;
2898+ asection *sdynbss, *s;
2899+ unsigned int power_of_two;
2900+ bfd *dynobj;
2901+
2902+ htab = elf64_mb_hash_table (info);
2903+ if (htab == NULL)
2904+ return FALSE;
2905+
2906+ /* If this is a function, put it in the procedure linkage table. We
2907+ will fill in the contents of the procedure linkage table later,
2908+ when we know the address of the .got section. */
2909+ if (h->type == STT_FUNC
2910+ || h->needs_plt)
2911+ {
2912+ if (h->plt.refcount <= 0
2913+ || SYMBOL_CALLS_LOCAL (info, h)
2914+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2915+ && h->root.type == bfd_link_hash_undefweak))
2916+ {
2917+ /* This case can occur if we saw a PLT reloc in an input
2918+ file, but the symbol was never referred to by a dynamic
2919+ object, or if all references were garbage collected. In
2920+ such a case, we don't actually need to build a procedure
2921+ linkage table, and we can just do a PC32 reloc instead. */
2922+ h->plt.offset = (bfd_vma) -1;
2923+ h->needs_plt = 0;
2924+ }
2925+
2926+ return TRUE;
2927+ }
2928+ else
2929+ /* It's possible that we incorrectly decided a .plt reloc was
2930+ needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2931+ check_relocs. We can't decide accurately between function and
2932+ non-function syms in check-relocs; Objects loaded later in
2933+ the link may change h->type. So fix it now. */
2934+ h->plt.offset = (bfd_vma) -1;
2935+
2936+ /* If this is a weak symbol, and there is a real definition, the
2937+ processor independent code will have arranged for us to see the
2938+ real definition first, and we can just use the same value. */
2939+ if (h->u.weakdef != NULL)
2940+ {
2941+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2942+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
2943+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
2944+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
2945+ return TRUE;
2946+ }
2947+
2948+ /* This is a reference to a symbol defined by a dynamic object which
2949+ is not a function. */
2950+
2951+ /* If we are creating a shared library, we must presume that the
2952+ only references to the symbol are via the global offset table.
2953+ For such cases we need not do anything here; the relocations will
2954+ be handled correctly by relocate_section. */
2955+ if (bfd_link_pic (info))
2956+ return TRUE;
2957+
2958+ /* If there are no references to this symbol that do not use the
2959+ GOT, we don't need to generate a copy reloc. */
2960+ if (!h->non_got_ref)
2961+ return TRUE;
2962+
2963+ /* If -z nocopyreloc was given, we won't generate them either. */
2964+ if (info->nocopyreloc)
2965+ {
2966+ h->non_got_ref = 0;
2967+ return TRUE;
2968+ }
2969+
2970+ eh = (struct elf64_mb_link_hash_entry *) h;
2971+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
2972+ {
2973+ s = p->sec->output_section;
2974+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
2975+ break;
2976+ }
2977+
2978+ /* If we didn't find any dynamic relocs in read-only sections, then
2979+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2980+ if (p == NULL)
2981+ {
2982+ h->non_got_ref = 0;
2983+ return TRUE;
2984+ }
2985+
2986+ /* We must allocate the symbol in our .dynbss section, which will
2987+ become part of the .bss section of the executable. There will be
2988+ an entry for this symbol in the .dynsym section. The dynamic
2989+ object will contain position independent code, so all references
2990+ from the dynamic object to this symbol will go through the global
2991+ offset table. The dynamic linker will use the .dynsym entry to
2992+ determine the address it must put in the global offset table, so
2993+ both the dynamic object and the regular object will refer to the
2994+ same memory location for the variable. */
2995+
2996+ /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2997+ to copy the initial value out of the dynamic object and into the
2998+ runtime process image. */
2999+ dynobj = elf_hash_table (info)->dynobj;
3000+ BFD_ASSERT (dynobj != NULL);
3001+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
3002+ {
3003+ htab->srelbss->size += sizeof (Elf64_External_Rela);
3004+ h->needs_copy = 1;
3005+ }
3006+
3007+ /* We need to figure out the alignment required for this symbol. I
3008+ have no idea how ELF linkers handle this. */
3009+ power_of_two = bfd_log2 (h->size);
3010+ if (power_of_two > 3)
3011+ power_of_two = 3;
3012+
3013+ sdynbss = htab->sdynbss;
3014+ /* Apply the required alignment. */
3015+ sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
3016+ if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
3017+ {
3018+ if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
3019+ return FALSE;
3020+ }
3021+
3022+ /* Define the symbol as being at this point in the section. */
3023+ h->root.u.def.section = sdynbss;
3024+ h->root.u.def.value = sdynbss->size;
3025+
3026+ /* Increment the section size to make room for the symbol. */
3027+ sdynbss->size += h->size;
3028+ return TRUE;
3029+}
3030+
3031+/* Allocate space in .plt, .got and associated reloc sections for
3032+ dynamic relocs. */
3033+
3034+static bfd_boolean
3035+allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
3036+{
3037+ struct bfd_link_info *info;
3038+ struct elf64_mb_link_hash_table *htab;
3039+ struct elf64_mb_link_hash_entry *eh;
3040+ struct elf64_mb_dyn_relocs *p;
3041+
3042+ if (h->root.type == bfd_link_hash_indirect)
3043+ return TRUE;
3044+
3045+ info = (struct bfd_link_info *) dat;
3046+ htab = elf64_mb_hash_table (info);
3047+ if (htab == NULL)
3048+ return FALSE;
3049+
3050+ if (htab->elf.dynamic_sections_created
3051+ && h->plt.refcount > 0)
3052+ {
3053+ /* Make sure this symbol is output as a dynamic symbol.
3054+ Undefined weak syms won't yet be marked as dynamic. */
3055+ if (h->dynindx == -1
3056+ && !h->forced_local)
3057+ {
3058+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
3059+ return FALSE;
3060+ }
3061+
3062+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
3063+ {
3064+ asection *s = htab->splt;
3065+
3066+ /* The first entry in .plt is reserved. */
3067+ if (s->size == 0)
3068+ s->size = PLT_ENTRY_SIZE;
3069+
3070+ h->plt.offset = s->size;
3071+
3072+ /* If this symbol is not defined in a regular file, and we are
3073+ not generating a shared library, then set the symbol to this
3074+ location in the .plt. This is required to make function
3075+ pointers compare as equal between the normal executable and
3076+ the shared library. */
3077+ if (! bfd_link_pic (info)
3078+ && !h->def_regular)
3079+ {
3080+ h->root.u.def.section = s;
3081+ h->root.u.def.value = h->plt.offset;
3082+ }
3083+
3084+ /* Make room for this entry. */
3085+ s->size += PLT_ENTRY_SIZE;
3086+
3087+ /* We also need to make an entry in the .got.plt section, which
3088+ will be placed in the .got section by the linker script. */
3089+ htab->sgotplt->size += 4;
3090+
3091+ /* We also need to make an entry in the .rel.plt section. */
3092+ htab->srelplt->size += sizeof (Elf64_External_Rela);
3093+ }
3094+ else
3095+ {
3096+ h->plt.offset = (bfd_vma) -1;
3097+ h->needs_plt = 0;
3098+ }
3099+ }
3100+ else
3101+ {
3102+ h->plt.offset = (bfd_vma) -1;
3103+ h->needs_plt = 0;
3104+ }
3105+
3106+ eh = (struct elf64_mb_link_hash_entry *) h;
3107+ if (h->got.refcount > 0)
3108+ {
3109+ unsigned int need;
3110+ asection *s;
3111+
3112+ /* Make sure this symbol is output as a dynamic symbol.
3113+ Undefined weak syms won't yet be marked as dynamic. */
3114+ if (h->dynindx == -1
3115+ && !h->forced_local)
3116+ {
3117+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
3118+ return FALSE;
3119+ }
3120+
3121+ need = 0;
3122+ if ((eh->tls_mask & TLS_TLS) != 0)
3123+ {
3124+ /* Handle TLS Symbol */
3125+ if ((eh->tls_mask & TLS_LD) != 0)
3126+ {
3127+ if (!eh->elf.def_dynamic)
3128+ /* We'll just use htab->tlsld_got.offset. This should
3129+ always be the case. It's a little odd if we have
3130+ a local dynamic reloc against a non-local symbol. */
3131+ htab->tlsld_got.refcount += 1;
3132+ else
3133+ need += 8;
3134+ }
3135+ if ((eh->tls_mask & TLS_GD) != 0)
3136+ need += 8;
3137+ }
3138+ else
3139+ {
3140+ /* Regular (non-TLS) symbol */
3141+ need += 4;
3142+ }
3143+ if (need == 0)
3144+ {
3145+ h->got.offset = (bfd_vma) -1;
3146+ }
3147+ else
3148+ {
3149+ s = htab->sgot;
3150+ h->got.offset = s->size;
3151+ s->size += need;
3152+ htab->srelgot->size += need * (sizeof (Elf64_External_Rela) / 4);
3153+ }
3154+ }
3155+ else
3156+ h->got.offset = (bfd_vma) -1;
3157+
3158+ if (eh->dyn_relocs == NULL)
3159+ return TRUE;
3160+
3161+ /* In the shared -Bsymbolic case, discard space allocated for
3162+ dynamic pc-relative relocs against symbols which turn out to be
3163+ defined in regular objects. For the normal shared case, discard
3164+ space for pc-relative relocs that have become local due to symbol
3165+ visibility changes. */
3166+
3167+ if (bfd_link_pic (info))
3168+ {
3169+ if (h->def_regular
3170+ && (h->forced_local
3171+ || info->symbolic))
3172+ {
3173+ struct elf64_mb_dyn_relocs **pp;
3174+
3175+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
3176+ {
3177+ p->count -= p->pc_count;
3178+ p->pc_count = 0;
3179+ if (p->count == 0)
3180+ *pp = p->next;
3181+ else
3182+ pp = &p->next;
3183+ }
3184+ }
3185+ }
3186+ else
3187+ {
3188+ /* For the non-shared case, discard space for relocs against
3189+ symbols which turn out to need copy relocs or are not
3190+ dynamic. */
3191+
3192+ if (!h->non_got_ref
3193+ && ((h->def_dynamic
3194+ && !h->def_regular)
3195+ || (htab->elf.dynamic_sections_created
3196+ && (h->root.type == bfd_link_hash_undefweak
3197+ || h->root.type == bfd_link_hash_undefined))))
3198+ {
3199+ /* Make sure this symbol is output as a dynamic symbol.
3200+ Undefined weak syms won't yet be marked as dynamic. */
3201+ if (h->dynindx == -1
3202+ && !h->forced_local)
3203+ {
3204+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
3205+ return FALSE;
3206+ }
3207+
3208+ /* If that succeeded, we know we'll be keeping all the
3209+ relocs. */
3210+ if (h->dynindx != -1)
3211+ goto keep;
3212+ }
3213+
3214+ eh->dyn_relocs = NULL;
3215+
3216+ keep: ;
3217+ }
3218+
3219+ /* Finally, allocate space. */
3220+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
3221+ {
3222+ asection *sreloc = elf_section_data (p->sec)->sreloc;
3223+ sreloc->size += p->count * sizeof (Elf64_External_Rela);
3224+ }
3225+
3226+ return TRUE;
3227+}
3228+
3229+/* Set the sizes of the dynamic sections. */
3230+
3231+static bfd_boolean
3232+microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
3233+ struct bfd_link_info *info)
3234+{
3235+ struct elf64_mb_link_hash_table *htab;
3236+ bfd *dynobj;
3237+ asection *s;
3238+ bfd *ibfd;
3239+
3240+ htab = elf64_mb_hash_table (info);
3241+ if (htab == NULL)
3242+ return FALSE;
3243+
3244+ dynobj = htab->elf.dynobj;
3245+ BFD_ASSERT (dynobj != NULL);
3246+
3247+ /* Set up .got offsets for local syms, and space for local dynamic
3248+ relocs. */
3249+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
3250+ {
3251+ bfd_signed_vma *local_got;
3252+ bfd_signed_vma *end_local_got;
3253+ bfd_size_type locsymcount;
3254+ Elf_Internal_Shdr *symtab_hdr;
3255+ unsigned char *lgot_masks;
3256+ asection *srel;
3257+
3258+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
3259+ continue;
3260+
3261+ for (s = ibfd->sections; s != NULL; s = s->next)
3262+ {
3263+ struct elf64_mb_dyn_relocs *p;
3264+
3265+ for (p = ((struct elf64_mb_dyn_relocs *)
3266+ elf_section_data (s)->local_dynrel);
3267+ p != NULL;
3268+ p = p->next)
3269+ {
3270+ if (!bfd_is_abs_section (p->sec)
3271+ && bfd_is_abs_section (p->sec->output_section))
3272+ {
3273+ /* Input section has been discarded, either because
3274+ it is a copy of a linkonce section or due to
3275+ linker script /DISCARD/, so we'll be discarding
3276+ the relocs too. */
3277+ }
3278+ else if (p->count != 0)
3279+ {
3280+ srel = elf_section_data (p->sec)->sreloc;
3281+ srel->size += p->count * sizeof (Elf64_External_Rela);
3282+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3283+ info->flags |= DF_TEXTREL;
3284+ }
3285+ }
3286+ }
3287+
3288+ local_got = elf_local_got_refcounts (ibfd);
3289+ if (!local_got)
3290+ continue;
3291+
3292+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3293+ locsymcount = symtab_hdr->sh_info;
3294+ end_local_got = local_got + locsymcount;
3295+ lgot_masks = (unsigned char *) end_local_got;
3296+ s = htab->sgot;
3297+ srel = htab->srelgot;
3298+
3299+ for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3300+ {
3301+ if (*local_got > 0)
3302+ {
3303+ unsigned int need = 0;
3304+ if ((*lgot_masks & TLS_TLS) != 0)
3305+ {
3306+ if ((*lgot_masks & TLS_GD) != 0)
3307+ need += 8;
3308+ if ((*lgot_masks & TLS_LD) != 0)
3309+ htab->tlsld_got.refcount += 1;
3310+ }
3311+ else
3312+ need += 4;
3313+
3314+ if (need == 0)
3315+ {
3316+ *local_got = (bfd_vma) -1;
3317+ }
3318+ else
3319+ {
3320+ *local_got = s->size;
3321+ s->size += need;
3322+ if (bfd_link_pic (info))
3323+ srel->size += need * (sizeof (Elf64_External_Rela) / 4);
3324+ }
3325+ }
3326+ else
3327+ *local_got = (bfd_vma) -1;
3328+ }
3329+ }
3330+
3331+ /* Allocate global sym .plt and .got entries, and space for global
3332+ sym dynamic relocs. */
3333+ elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3334+
3335+ if (htab->tlsld_got.refcount > 0)
3336+ {
3337+ htab->tlsld_got.offset = htab->sgot->size;
3338+ htab->sgot->size += 8;
3339+ if (bfd_link_pic (info))
3340+ htab->srelgot->size += sizeof (Elf64_External_Rela);
3341+ }
3342+ else
3343+ htab->tlsld_got.offset = (bfd_vma) -1;
3344+
3345+ if (elf_hash_table (info)->dynamic_sections_created)
3346+ {
3347+ /* Make space for the trailing nop in .plt. */
3348+ if (htab->splt->size > 0)
3349+ htab->splt->size += 4;
3350+ }
3351+
3352+ /* The check_relocs and adjust_dynamic_symbol entry points have
3353+ determined the sizes of the various dynamic sections. Allocate
3354+ memory for them. */
3355+ for (s = dynobj->sections; s != NULL; s = s->next)
3356+ {
3357+ const char *name;
3358+ bfd_boolean strip = FALSE;
3359+
3360+ if ((s->flags & SEC_LINKER_CREATED) == 0)
3361+ continue;
3362+
3363+ /* It's OK to base decisions on the section name, because none
3364+ of the dynobj section names depend upon the input files. */
3365+ name = bfd_get_section_name (dynobj, s);
3366+
3367+ if (strncmp (name, ".rela", 5) == 0)
3368+ {
3369+ if (s->size == 0)
3370+ {
3371+ /* If we don't need this section, strip it from the
3372+ output file. This is to handle .rela.bss and
3373+ .rela.plt. We must create it in
3374+ create_dynamic_sections, because it must be created
3375+ before the linker maps input sections to output
3376+ sections. The linker does that before
3377+ adjust_dynamic_symbol is called, and it is that
3378+ function which decides whether anything needs to go
3379+ into these sections. */
3380+ strip = TRUE;
3381+ }
3382+ else
3383+ {
3384+ /* We use the reloc_count field as a counter if we need
3385+ to copy relocs into the output file. */
3386+ s->reloc_count = 0;
3387+ }
3388+ }
3389+ else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
3390+ {
3391+ /* It's not one of our sections, so don't allocate space. */
3392+ continue;
3393+ }
3394+
3395+ if (strip)
3396+ {
3397+ s->flags |= SEC_EXCLUDE;
3398+ continue;
3399+ }
3400+
3401+ /* Allocate memory for the section contents. */
3402+ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3403+ Unused entries should be reclaimed before the section's contents
3404+ are written out, but at the moment this does not happen. Thus in
3405+ order to prevent writing out garbage, we initialise the section's
3406+ contents to zero. */
3407+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3408+ if (s->contents == NULL && s->size != 0)
3409+ return FALSE;
3410+ }
3411+
3412+ if (elf_hash_table (info)->dynamic_sections_created)
3413+ {
3414+ /* Add some entries to the .dynamic section. We fill in the
3415+ values later, in microblaze_elf_finish_dynamic_sections, but we
3416+ must add the entries now so that we get the correct size for
3417+ the .dynamic section. The DT_DEBUG entry is filled in by the
3418+ dynamic linker and used by the debugger. */
3419+#define add_dynamic_entry(TAG, VAL) \
3420+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3421+
3422+ if (bfd_link_executable (info))
3423+ {
3424+ if (!add_dynamic_entry (DT_DEBUG, 0))
3425+ return FALSE;
3426+ }
3427+
3428+ if (!add_dynamic_entry (DT_RELA, 0)
3429+ || !add_dynamic_entry (DT_RELASZ, 0)
3430+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
3431+ return FALSE;
3432+
3433+ if (htab->splt->size != 0)
3434+ {
3435+ if (!add_dynamic_entry (DT_PLTGOT, 0)
3436+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
3437+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3438+ || !add_dynamic_entry (DT_JMPREL, 0)
3439+ || !add_dynamic_entry (DT_BIND_NOW, 1))
3440+ return FALSE;
3441+ }
3442+
3443+ if (info->flags & DF_TEXTREL)
3444+ {
3445+ if (!add_dynamic_entry (DT_TEXTREL, 0))
3446+ return FALSE;
3447+ }
3448+ }
3449+#undef add_dynamic_entry
3450+ return TRUE;
3451+}
3452+
3453+/* Finish up dynamic symbol handling. We set the contents of various
3454+ dynamic sections here. */
3455+
3456+static bfd_boolean
3457+microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3458+ struct bfd_link_info *info,
3459+ struct elf_link_hash_entry *h,
3460+ Elf_Internal_Sym *sym)
3461+{
3462+ struct elf64_mb_link_hash_table *htab;
3463+ struct elf64_mb_link_hash_entry *eh = elf64_mb_hash_entry(h);
3464+
3465+ htab = elf64_mb_hash_table (info);
3466+ if (htab == NULL)
3467+ return FALSE;
3468+
3469+ if (h->plt.offset != (bfd_vma) -1)
3470+ {
3471+ asection *splt;
3472+ asection *srela;
3473+ asection *sgotplt;
3474+ Elf_Internal_Rela rela;
3475+ bfd_byte *loc;
3476+ bfd_vma plt_index;
3477+ bfd_vma got_offset;
3478+ bfd_vma got_addr;
3479+
3480+ /* This symbol has an entry in the procedure linkage table. Set
3481+ it up. */
3482+ BFD_ASSERT (h->dynindx != -1);
3483+
3484+ splt = htab->splt;
3485+ srela = htab->srelplt;
3486+ sgotplt = htab->sgotplt;
3487+ BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3488+
3489+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3490+ got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3491+ got_addr = got_offset;
3492+
3493+ /* For non-PIC objects we need absolute address of the GOT entry. */
3494+ if (!bfd_link_pic (info))
3495+ got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
3496+
3497+ /* Fill in the entry in the procedure linkage table. */
3498+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3499+ splt->contents + h->plt.offset);
3500+ if (bfd_link_pic (info))
3501+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3502+ splt->contents + h->plt.offset + 4);
3503+ else
3504+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3505+ splt->contents + h->plt.offset + 4);
3506+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3507+ splt->contents + h->plt.offset + 8);
3508+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3509+ splt->contents + h->plt.offset + 12);
3510+
3511+ /* Any additions to the .got section??? */
3512+ /* bfd_put_32 (output_bfd,
3513+ splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3514+ sgotplt->contents + got_offset); */
3515+
3516+ /* Fill in the entry in the .rela.plt section. */
3517+ rela.r_offset = (sgotplt->output_section->vma
3518+ + sgotplt->output_offset
3519+ + got_offset);
3520+ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3521+ rela.r_addend = 0;
3522+ loc = srela->contents;
3523+ loc += plt_index * sizeof (Elf64_External_Rela);
3524+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
3525+
3526+ if (!h->def_regular)
3527+ {
3528+ /* Mark the symbol as undefined, rather than as defined in
3529+ the .plt section. Zero the value. */
3530+ sym->st_shndx = SHN_UNDEF;
3531+ sym->st_value = 0;
3532+ }
3533+ }
3534+
3535+ /* h->got.refcount to be checked ? */
3536+ if (h->got.offset != (bfd_vma) -1 &&
3537+ ! ((h->got.offset & 1) ||
3538+ IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3539+ {
3540+ asection *sgot;
3541+ asection *srela;
3542+ bfd_vma offset;
3543+
3544+ /* This symbol has an entry in the global offset table. Set it
3545+ up. */
3546+
3547+ sgot = htab->sgot;
3548+ srela = htab->srelgot;
3549+ BFD_ASSERT (sgot != NULL && srela != NULL);
3550+
3551+ offset = (sgot->output_section->vma + sgot->output_offset
3552+ + (h->got.offset &~ (bfd_vma) 1));
3553+
3554+ /* If this is a -Bsymbolic link, and the symbol is defined
3555+ locally, we just want to emit a RELATIVE reloc. Likewise if
3556+ the symbol was forced to be local because of a version file.
3557+ The entry in the global offset table will already have been
3558+ initialized in the relocate_section function. */
3559+ if (bfd_link_pic (info)
3560+ && ((info->symbolic && h->def_regular)
3561+ || h->dynindx == -1))
3562+ {
3563+ asection *sec = h->root.u.def.section;
3564+ microblaze_elf_output_dynamic_relocation (output_bfd,
3565+ srela, srela->reloc_count++,
3566+ /* symindex= */ 0,
3567+ R_MICROBLAZE_REL, offset,
3568+ h->root.u.def.value
3569+ + sec->output_section->vma
3570+ + sec->output_offset);
3571+ }
3572+ else
3573+ {
3574+ microblaze_elf_output_dynamic_relocation (output_bfd,
3575+ srela, srela->reloc_count++,
3576+ h->dynindx,
3577+ R_MICROBLAZE_GLOB_DAT,
3578+ offset, 0);
3579+ }
3580+
3581+ bfd_put_32 (output_bfd, (bfd_vma) 0,
3582+ sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3583+ }
3584+
3585+ if (h->needs_copy)
3586+ {
3587+ asection *s;
3588+ Elf_Internal_Rela rela;
3589+ bfd_byte *loc;
3590+
3591+ /* This symbols needs a copy reloc. Set it up. */
3592+
3593+ BFD_ASSERT (h->dynindx != -1);
3594+
3595+ s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
3596+ BFD_ASSERT (s != NULL);
3597+
3598+ rela.r_offset = (h->root.u.def.value
3599+ + h->root.u.def.section->output_section->vma
3600+ + h->root.u.def.section->output_offset);
3601+ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3602+ rela.r_addend = 0;
3603+ loc = s->contents + s->reloc_count++ * sizeof (Elf64_External_Rela);
3604+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
3605+ }
3606+
3607+ /* Mark some specially defined symbols as absolute. */
3608+ if (h == htab->elf.hdynamic
3609+ || h == htab->elf.hgot
3610+ || h == htab->elf.hplt)
3611+ sym->st_shndx = SHN_ABS;
3612+
3613+ return TRUE;
3614+}
3615+
3616+
3617+/* Finish up the dynamic sections. */
3618+
3619+static bfd_boolean
3620+microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3621+ struct bfd_link_info *info)
3622+{
3623+ bfd *dynobj;
3624+ asection *sdyn, *sgot;
3625+ struct elf64_mb_link_hash_table *htab;
3626+
3627+ htab = elf64_mb_hash_table (info);
3628+ if (htab == NULL)
3629+ return FALSE;
3630+
3631+ dynobj = htab->elf.dynobj;
3632+
3633+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3634+
3635+ if (htab->elf.dynamic_sections_created)
3636+ {
3637+ asection *splt;
3638+ Elf64_External_Dyn *dyncon, *dynconend;
3639+
3640+ splt = bfd_get_linker_section (dynobj, ".plt");
3641+ BFD_ASSERT (splt != NULL && sdyn != NULL);
3642+
3643+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
3644+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
3645+ for (; dyncon < dynconend; dyncon++)
3646+ {
3647+ Elf_Internal_Dyn dyn;
3648+ const char *name;
3649+ bfd_boolean size;
3650+
3651+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
3652+
3653+ switch (dyn.d_tag)
3654+ {
3655+ case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
3656+ case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
3657+ case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
3658+ case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
3659+ case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
3660+ default: name = NULL; size = FALSE; break;
3661+ }
3662+
3663+ if (name != NULL)
3664+ {
3665+ asection *s;
3666+
3667+ s = bfd_get_section_by_name (output_bfd, name);
3668+ if (s == NULL)
3669+ dyn.d_un.d_val = 0;
3670+ else
3671+ {
3672+ if (! size)
3673+ dyn.d_un.d_ptr = s->vma;
3674+ else
3675+ dyn.d_un.d_val = s->size;
3676+ }
3677+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
3678+ }
3679+ }
3680+
3681+ /* Clear the first entry in the procedure linkage table,
3682+ and put a nop in the last four bytes. */
3683+ if (splt->size > 0)
3684+ {
3685+ memset (splt->contents, 0, PLT_ENTRY_SIZE);
3686+ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3687+ splt->contents + splt->size - 4);
3688+ }
3689+
3690+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3691+ }
3692+
3693+ /* Set the first entry in the global offset table to the address of
3694+ the dynamic section. */
3695+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
3696+ if (sgot && sgot->size > 0)
3697+ {
3698+ if (sdyn == NULL)
3699+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3700+ else
3701+ bfd_put_32 (output_bfd,
3702+ sdyn->output_section->vma + sdyn->output_offset,
3703+ sgot->contents);
3704+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3705+ }
3706+
3707+ if (htab->sgot && htab->sgot->size > 0)
3708+ elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
3709+
3710+ return TRUE;
3711+}
3712+
3713+/* Hook called by the linker routine which adds symbols from an object
3714+ file. We use it to put .comm items in .sbss, and not .bss. */
3715+
3716+static bfd_boolean
3717+microblaze_elf_add_symbol_hook (bfd *abfd,
3718+ struct bfd_link_info *info,
3719+ Elf_Internal_Sym *sym,
3720+ const char **namep ATTRIBUTE_UNUSED,
3721+ flagword *flagsp ATTRIBUTE_UNUSED,
3722+ asection **secp,
3723+ bfd_vma *valp)
3724+{
3725+ if (sym->st_shndx == SHN_COMMON
3726+ && !bfd_link_relocatable (info)
3727+ && sym->st_size <= elf_gp_size (abfd))
3728+ {
3729+ /* Common symbols less than or equal to -G nn bytes are automatically
3730+ put into .sbss. */
3731+ *secp = bfd_make_section_old_way (abfd, ".sbss");
3732+ if (*secp == NULL
3733+ || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
3734+ return FALSE;
3735+
3736+ *valp = sym->st_size;
3737+ }
3738+
3739+ return TRUE;
3740+}
3741+
3742+#define TARGET_LITTLE_SYM microblaze_elf64_le_vec
3743+#define TARGET_LITTLE_NAME "elf64-microblazeel"
3744+
3745+#define TARGET_BIG_SYM microblaze_elf64_vec
3746+#define TARGET_BIG_NAME "elf64-microblaze"
3747+
3748+#define ELF_ARCH bfd_arch_microblaze
3749+#define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3750+#define ELF_MACHINE_CODE EM_MICROBLAZE
3751+#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3752+#define ELF_MAXPAGESIZE 0x1000
3753+#define elf_info_to_howto microblaze_elf_info_to_howto
3754+#define elf_info_to_howto_rel NULL
3755+
3756+#define bfd_elf64_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3757+#define bfd_elf64_bfd_is_local_label_name microblaze_elf_is_local_label_name
3758+#define elf_backend_relocate_section microblaze_elf_relocate_section
3759+#define bfd_elf64_bfd_relax_section microblaze_elf_relax_section
3760+#define bfd_elf64_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
3761+#define bfd_elf64_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3762+
3763+#define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3764+#define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3765+#define elf_backend_check_relocs microblaze_elf_check_relocs
3766+#define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3767+#define bfd_elf64_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3768+#define elf_backend_can_gc_sections 1
3769+#define elf_backend_can_refcount 1
3770+#define elf_backend_want_got_plt 1
3771+#define elf_backend_plt_readonly 1
3772+#define elf_backend_got_header_size 12
3773+#define elf_backend_rela_normal 1
3774+
3775+#define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3776+#define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3777+#define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3778+#define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3779+#define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3780+#define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3781+
3782+#include "elf64-target.h"
3783diff --git a/bfd/targets.c b/bfd/targets.c
3784index 158168cb3b..ef567a30c8 100644
3785--- a/bfd/targets.c
3786+++ b/bfd/targets.c
3787@@ -706,6 +706,8 @@ extern const bfd_target mep_elf32_le_vec;
3788 extern const bfd_target metag_elf32_vec;
3789 extern const bfd_target microblaze_elf32_vec;
3790 extern const bfd_target microblaze_elf32_le_vec;
3791+extern const bfd_target microblaze_elf64_vec;
3792+extern const bfd_target microblaze_elf64_le_vec;
3793 extern const bfd_target mips_ecoff_be_vec;
3794 extern const bfd_target mips_ecoff_le_vec;
3795 extern const bfd_target mips_ecoff_bele_vec;
3796@@ -1073,6 +1075,10 @@ static const bfd_target * const _bfd_target_vector[] =
3797
3798 &metag_elf32_vec,
3799
3800+#ifdef BFD64
3801+ &microblaze_elf64_vec,
3802+ &microblaze_elf64_le_vec,
3803+#endif
3804 &microblaze_elf32_vec,
3805
3806 &mips_ecoff_be_vec,
3807diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
3808index 16b10d00a9..c79434785a 100644
3809--- a/gas/config/tc-microblaze.c
3810+++ b/gas/config/tc-microblaze.c
3811@@ -35,10 +35,13 @@
3812 #define streq(a,b) (strcmp (a, b) == 0)
3813 #endif
3814
3815+static int microblaze_arch_size = 0;
3816+
3817 #define OPTION_EB (OPTION_MD_BASE + 0)
3818 #define OPTION_EL (OPTION_MD_BASE + 1)
3819 #define OPTION_LITTLE (OPTION_MD_BASE + 2)
3820 #define OPTION_BIG (OPTION_MD_BASE + 3)
3821+#define OPTION_M64 (OPTION_MD_BASE + 4)
3822
3823 void microblaze_generate_symbol (char *sym);
3824 static bfd_boolean check_spl_reg (unsigned *);
3825@@ -773,6 +776,74 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
3826 return new_pointer;
3827 }
3828
3829+ static char *
3830+parse_imml (char * s, expressionS * e, long min, long max)
3831+{
3832+ char *new_pointer;
3833+ char *atp;
3834+ int itype, ilen;
3835+
3836+ ilen = 0;
3837+
3838+ /* Find the start of "@GOT" or "@PLT" suffix (if any) */
3839+ for (atp = s; *atp != '@'; atp++)
3840+ if (is_end_of_line[(unsigned char) *atp])
3841+ break;
3842+
3843+ if (*atp == '@')
3844+ {
3845+ itype = match_imm (atp + 1, &ilen);
3846+ if (itype != 0)
3847+ {
3848+ *atp = 0;
3849+ e->X_md = itype;
3850+ }
3851+ else
3852+ {
3853+ atp = NULL;
3854+ e->X_md = 0;
3855+ ilen = 0;
3856+ }
3857+ *atp = 0;
3858+ }
3859+ else
3860+ {
3861+ atp = NULL;
3862+ e->X_md = 0;
3863+ }
3864+
3865+ if (atp && !GOT_symbol)
3866+ {
3867+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
3868+ }
3869+
3870+ new_pointer = parse_exp (s, e);
3871+
3872+ if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20))
3873+ {
3874+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
3875+ }
3876+
3877+ if (e->X_op == O_absent)
3878+ ; /* An error message has already been emitted. */
3879+ else if ((e->X_op != O_constant && e->X_op != O_symbol) )
3880+ as_fatal (_("operand must be a constant or a label"));
3881+ else if ((e->X_op == O_constant) && ((long) e->X_add_number < min
3882+ || (long) e->X_add_number > max))
3883+ {
3884+ as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"),
3885+ min, max, (long) e->X_add_number);
3886+ }
3887+
3888+ if (atp)
3889+ {
3890+ *atp = '@'; /* restore back (needed?) */
3891+ if (new_pointer >= atp)
3892+ new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
3893+ }
3894+ return new_pointer;
3895+}
3896+
3897 static char *
3898 check_got (int * got_type, int * got_len)
3899 {
3900@@ -920,6 +991,7 @@ md_assemble (char * str)
3901 unsigned int immed, immed2, temp;
3902 expressionS exp;
3903 char name[20];
3904+ long immedl;
3905
3906 /* Drop leading whitespace. */
3907 while (ISSPACE (* str))
3908@@ -1129,7 +1201,7 @@ md_assemble (char * str)
3909 }
3910 break;
3911
3912- case INST_TYPE_RD_R1_IMM5:
3913+ case INST_TYPE_RD_R1_IMMS:
3914 if (strcmp (op_end, ""))
3915 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
3916 else
3917@@ -1163,16 +1235,22 @@ md_assemble (char * str)
3918 immed = exp.X_add_number;
3919 }
3920
3921- if (immed != (immed % 32))
3922+ if ((immed != (immed % 32)) &&
3923+ (opcode->instr == bslli || opcode->instr == bsrai || opcode->instr == bsrli))
3924 {
3925 as_warn (_("Shift value > 32. using <value %% 32>"));
3926 immed = immed % 32;
3927 }
3928+ else if (immed != (immed % 64))
3929+ {
3930+ as_warn (_("Shift value > 64. using <value %% 64>"));
3931+ immed = immed % 64;
3932+ }
3933 inst |= (reg1 << RD_LOW) & RD_MASK;
3934 inst |= (reg2 << RA_LOW) & RA_MASK;
3935- inst |= (immed << IMM_LOW) & IMM5_MASK;
3936+ inst |= (immed << IMM_LOW) & IMM6_MASK;
3937 break;
3938- case INST_TYPE_RD_R1_IMM5_IMM5:
3939+ case INST_TYPE_RD_R1_IMMW_IMMS:
3940 if (strcmp (op_end, ""))
3941 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
3942 else
3943@@ -1196,7 +1274,7 @@ md_assemble (char * str)
3944
3945 /* Width immediate value. */
3946 if (strcmp (op_end, ""))
3947- op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH);
3948+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM);
3949 else
3950 as_fatal (_("Error in statement syntax"));
3951 if (exp.X_op != O_constant)
3952@@ -1208,6 +1286,8 @@ md_assemble (char * str)
3953 immed = exp.X_add_number;
3954 if (opcode->instr == bsefi && immed > 31)
3955 as_fatal (_("Width value must be less than 32"));
3956+ else if (opcode->instr == bslefi && immed > 63)
3957+ as_fatal (_("Width value must be less than 64"));
3958
3959 /* Shift immediate value. */
3960 if (strcmp (op_end, ""))
3961@@ -1215,32 +1295,40 @@ md_assemble (char * str)
3962 else
3963 as_fatal (_("Error in statement syntax"));
3964 if (exp.X_op != O_constant)
3965- {
3966+ {
3967 as_warn (_("Symbol used as immediate shift value for bit field instruction"));
3968 immed2 = 0;
3969 }
3970 else
3971- {
3972+ {
3973 output = frag_more (isize);
3974 immed2 = exp.X_add_number;
3975- }
3976- if (immed2 != (immed2 % 32))
3977- {
3978- as_warn (_("Shift value greater than 32. using <value %% 32>"));
3979+ }
3980+ if ((immed2 != (immed2 % 32)) && (opcode->instr == bsefi || opcode->instr == bsifi))
3981+ {
3982+
3983+ as_warn (_("Shift value greater than 32. using <value %% 32>"));
3984 immed2 = immed2 % 32;
3985 }
3986+ else if (immed2 != (immed2 % 64))
3987+ {
3988+ as_warn (_("Shift value greater than 64. using <value %% 64>"));
3989+ immed2 = immed2 % 64;
3990+ }
3991
3992 /* Check combined value. */
3993- if (immed + immed2 > 32)
3994+ if ((immed + immed2 > 32) && (opcode->instr == bsefi || opcode->instr == bsifi))
3995 as_fatal (_("Width value + shift value must not be greater than 32"));
3996
3997+ else if (immed + immed2 > 64)
3998+ as_fatal (_("Width value + shift value must not be greater than 64"));
3999 inst |= (reg1 << RD_LOW) & RD_MASK;
4000 inst |= (reg2 << RA_LOW) & RA_MASK;
4001- if (opcode->instr == bsefi)
4002- inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */
4003+ if (opcode->instr == bsefi || opcode->instr == bslefi)
4004+ inst |= (immed & IMM6_MASK) << IMM_WIDTH_LOW; /* bsefi or bslefi */
4005 else
4006- inst |= ((immed + immed2 - 1) & IMM5_MASK) << IMM_WIDTH_LOW; /* bsifi */
4007- inst |= (immed2 << IMM_LOW) & IMM5_MASK;
4008+ inst |= ((immed + immed2 - 1) & IMM6_MASK) << IMM_WIDTH_LOW; /* bsifi or bslifi */
4009+ inst |= (immed2 << IMM_LOW) & IMM6_MASK;
4010 break;
4011 case INST_TYPE_R1_R2:
4012 if (strcmp (op_end, ""))
4013@@ -1808,6 +1896,142 @@ md_assemble (char * str)
4014 }
4015 inst |= (immed << IMM_MBAR);
4016 break;
4017+ /* For 64-bit instructions */
4018+ case INST_TYPE_RD_R1_IMML:
4019+ if (strcmp (op_end, ""))
4020+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
4021+ else
4022+ {
4023+ as_fatal (_("Error in statement syntax"));
4024+ reg1 = 0;
4025+ }
4026+ if (strcmp (op_end, ""))
4027+ op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
4028+ else
4029+ {
4030+ as_fatal (_("Error in statement syntax"));
4031+ reg2 = 0;
4032+ }
4033+ if (strcmp (op_end, ""))
4034+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
4035+ else
4036+ as_fatal (_("Error in statement syntax"));
4037+
4038+ /* Check for spl registers. */
4039+ if (check_spl_reg (& reg1))
4040+ as_fatal (_("Cannot use special register with this instruction"));
4041+ if (check_spl_reg (& reg2))
4042+ as_fatal (_("Cannot use special register with this instruction"));
4043+
4044+ if (exp.X_op != O_constant)
4045+ {
4046+ char *opc = NULL;
4047+ relax_substateT subtype;
4048+
4049+ if (exp.X_md != 0)
4050+ subtype = get_imm_otype(exp.X_md);
4051+ else
4052+ subtype = opcode->inst_offset_type;
4053+
4054+ output = frag_var (rs_machine_dependent,
4055+ isize * 2, /* maxm of 2 words. */
4056+ isize * 2, /* minm of 2 words. */
4057+ subtype, /* PC-relative or not. */
4058+ exp.X_add_symbol,
4059+ exp.X_add_number,
4060+ opc);
4061+ immedl = 0L;
4062+ }
4063+ else
4064+ {
4065+ output = frag_more (isize);
4066+ immedl = exp.X_add_number;
4067+
4068+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
4069+ if (opcode1 == NULL)
4070+ {
4071+ as_bad (_("unknown opcode \"%s\""), "imml");
4072+ return;
4073+ }
4074+
4075+ inst1 = opcode1->bit_sequence;
4076+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
4077+ output[0] = INST_BYTE0 (inst1);
4078+ output[1] = INST_BYTE1 (inst1);
4079+ output[2] = INST_BYTE2 (inst1);
4080+ output[3] = INST_BYTE3 (inst1);
4081+ output = frag_more (isize);
4082+ }
4083+
4084+ inst |= (reg1 << RD_LOW) & RD_MASK;
4085+ inst |= (reg2 << RA_LOW) & RA_MASK;
4086+ inst |= (immedl << IMM_LOW) & IMM_MASK;
4087+ break;
4088+
4089+ case INST_TYPE_R1_IMML:
4090+ if (strcmp (op_end, ""))
4091+ op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
4092+ else
4093+ {
4094+ as_fatal (_("Error in statement syntax"));
4095+ reg1 = 0;
4096+ }
4097+ if (strcmp (op_end, ""))
4098+ op_end = parse_imml (op_end + 1, & exp, MIN_IMM, MAX_IMM);
4099+ else
4100+ as_fatal (_("Error in statement syntax"));
4101+
4102+ /* Check for spl registers. */
4103+ if (check_spl_reg (&reg1))
4104+ as_fatal (_("Cannot use special register with this instruction"));
4105+
4106+ if (exp.X_op != O_constant)
4107+ {
4108+ char *opc = NULL;
4109+ relax_substateT subtype;
4110+
4111+ if (exp.X_md != 0)
4112+ subtype = get_imm_otype(exp.X_md);
4113+ else
4114+ subtype = opcode->inst_offset_type;
4115+
4116+ output = frag_var (rs_machine_dependent,
4117+ isize * 2, /* maxm of 2 words. */
4118+ isize * 2, /* minm of 2 words. */
4119+ subtype, /* PC-relative or not. */
4120+ exp.X_add_symbol,
4121+ exp.X_add_number,
4122+ opc);
4123+ immedl = 0L;
4124+ }
4125+ else
4126+ {
4127+ output = frag_more (isize);
4128+ immedl = exp.X_add_number;
4129+
4130+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
4131+ if (opcode1 == NULL)
4132+ {
4133+ as_bad (_("unknown opcode \"%s\""), "imml");
4134+ return;
4135+ }
4136+
4137+ inst1 = opcode1->bit_sequence;
4138+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
4139+ output[0] = INST_BYTE0 (inst1);
4140+ output[1] = INST_BYTE1 (inst1);
4141+ output[2] = INST_BYTE2 (inst1);
4142+ output[3] = INST_BYTE3 (inst1);
4143+ output = frag_more (isize);
4144+ }
4145+
4146+ inst |= (reg1 << RA_LOW) & RA_MASK;
4147+ inst |= (immedl << IMM_LOW) & IMM_MASK;
4148+ break;
4149+
4150+ case INST_TYPE_IMML:
4151+ as_fatal (_("An IMML instruction should not be present in the .s file"));
4152+ break;
4153
4154 default:
4155 as_fatal (_("unimplemented opcode \"%s\""), name);
4156@@ -1918,6 +2142,7 @@ struct option md_longopts[] =
4157 {"EL", no_argument, NULL, OPTION_EL},
4158 {"mlittle-endian", no_argument, NULL, OPTION_LITTLE},
4159 {"mbig-endian", no_argument, NULL, OPTION_BIG},
4160+ {"m64", no_argument, NULL, OPTION_M64},
4161 { NULL, no_argument, NULL, 0}
4162 };
4163
4164@@ -2569,6 +2794,18 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
4165 return rel;
4166 }
4167
4168+/* Called by TARGET_FORMAT. */
4169+const char *
4170+microblaze_target_format (void)
4171+{
4172+
4173+ if (microblaze_arch_size == 64)
4174+ return "elf64-microblazeel";
4175+ else
4176+ return target_big_endian ? "elf32-microblaze" : "elf32-microblazeel";
4177+}
4178+
4179+
4180 int
4181 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
4182 {
4183@@ -2582,6 +2819,10 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
4184 case OPTION_LITTLE:
4185 target_big_endian = 0;
4186 break;
4187+ case OPTION_M64:
4188+ //if (arg != NULL && strcmp (arg, "64") == 0)
4189+ microblaze_arch_size = 64;
4190+ break;
4191 default:
4192 return 0;
4193 }
4194@@ -2597,6 +2838,7 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
4195 fprintf (stream, _(" MicroBlaze specific assembler options:\n"));
4196 fprintf (stream, " -%-23s%s\n", "mbig-endian", N_("assemble for a big endian cpu"));
4197 fprintf (stream, " -%-23s%s\n", "mlittle-endian", N_("assemble for a little endian cpu"));
4198+ fprintf (stream, " -%-23s%s\n", "m64", N_("generate 64-bit elf"));
4199 }
4200
4201
4202diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h
4203index ca9dbb861f..9d38d2ced5 100644
4204--- a/gas/config/tc-microblaze.h
4205+++ b/gas/config/tc-microblaze.h
4206@@ -78,7 +78,9 @@ extern const struct relax_type md_relax_table[];
4207
4208 #ifdef OBJ_ELF
4209
4210-#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel")
4211+#define TARGET_FORMAT microblaze_target_format()
4212+extern const char *microblaze_target_format (void);
4213+//#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel")
4214
4215 #define ELF_TC_SPECIAL_SECTIONS \
4216 { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
4217diff --git a/include/elf/common.h b/include/elf/common.h
4218index 996acf9703..2f1e5be366 100644
4219--- a/include/elf/common.h
4220+++ b/include/elf/common.h
4221@@ -339,6 +339,7 @@
4222 #define EM_RISCV 243 /* RISC-V */
4223 #define EM_LANAI 244 /* Lanai 32-bit processor. */
4224 #define EM_BPF 247 /* Linux BPF – in-kernel virtual machine. */
4225+#define EM_MB_64 248 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
4226 #define EM_NFP 250 /* Netronome Flow Processor. */
4227 #define EM_CSKY 252 /* C-SKY processor family. */
4228
4229diff --git a/ld/Makefile.am b/ld/Makefile.am
4230index c2c798b4fe..b272f537e4 100644
4231--- a/ld/Makefile.am
4232+++ b/ld/Makefile.am
4233@@ -422,6 +422,8 @@ ALL_64_EMULATION_SOURCES = \
4234 eelf32ltsmipn32.c \
4235 eelf32ltsmipn32_fbsd.c \
4236 eelf32mipswindiss.c \
4237+ eelf64microblazeel.c \
4238+ eelf64microblaze.c \
4239 eelf64_aix.c \
4240 eelf64_ia64.c \
4241 eelf64_ia64_fbsd.c \
4242@@ -1702,6 +1704,12 @@ eelf32_x86_64_nacl.c: $(srcdir)/emulparams/elf32_x86_64_nacl.sh \
4243 $(srcdir)/emulparams/elf_nacl.sh \
4244 $(ELF_X86_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
4245
4246+eelf64microblazeel.c: $(srcdir)/emulparams/elf64microblazeel.sh \
4247+ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
4248+
4249+eelf64microblaze.c: $(srcdir)/emulparams/elf64microblaze.sh \
4250+ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
4251+
4252 eelf64_aix.c: $(srcdir)/emulparams/elf64_aix.sh \
4253 $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
4254
4255diff --git a/ld/Makefile.in b/ld/Makefile.in
4256index fc687fc516..1a530ad729 100644
4257--- a/ld/Makefile.in
4258+++ b/ld/Makefile.in
4259@@ -907,6 +907,8 @@ ALL_64_EMULATION_SOURCES = \
4260 eelf32ltsmipn32.c \
4261 eelf32ltsmipn32_fbsd.c \
4262 eelf32mipswindiss.c \
4263+ eelf64microblazeel.c \
4264+ eelf64microblaze.c \
4265 eelf64_aix.c \
4266 eelf64_ia64.c \
4267 eelf64_ia64_fbsd.c \
4268@@ -1355,6 +1357,8 @@ distclean-compile:
4269 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xc16xs.Po@am__quote@
4270 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@
4271 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@
4272+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblazeel.Po@am__quote@
4273+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblaze.Po@am__quote@
4274 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@
4275 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@
4276 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@
4277@@ -3306,6 +3310,12 @@ eelf32_x86_64_nacl.c: $(srcdir)/emulparams/elf32_x86_64_nacl.sh \
4278 $(srcdir)/emulparams/elf_nacl.sh \
4279 $(ELF_X86_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
4280
4281+eelf64microblazeel.c: $(srcdir)/emulparams/elf64microblazeel.sh \
4282+ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
4283+
4284+eelf64microblaze.c: $(srcdir)/emulparams/elf64microblaze.sh \
4285+ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
4286+
4287 eelf64_aix.c: $(srcdir)/emulparams/elf64_aix.sh \
4288 $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
4289
4290diff --git a/ld/configure.tgt b/ld/configure.tgt
4291index beba17ef51..5109799f2b 100644
4292--- a/ld/configure.tgt
4293+++ b/ld/configure.tgt
4294@@ -423,6 +423,9 @@ microblaze*-linux*) targ_emul="elf32mb_linux"
4295 microblazeel*) targ_emul=elf32microblazeel
4296 targ_extra_emuls=elf32microblaze
4297 ;;
4298+microblazeel64*) targ_emul=elf64microblazeel
4299+ targ_extra_emuls=elf64microblaze
4300+ ;;
4301 microblaze*) targ_emul=elf32microblaze
4302 targ_extra_emuls=elf32microblazeel
4303 ;;
4304diff --git a/ld/emulparams/elf64microblaze.sh b/ld/emulparams/elf64microblaze.sh
4305new file mode 100644
4306index 0000000000..9c7b0eb708
4307--- /dev/null
4308+++ b/ld/emulparams/elf64microblaze.sh
4309@@ -0,0 +1,23 @@
4310+SCRIPT_NAME=elfmicroblaze
4311+OUTPUT_FORMAT="elf64-microblazeel"
4312+#BIG_OUTPUT_FORMAT="elf64-microblaze"
4313+LITTLE_OUTPUT_FORMAT="elf64-microblazeel"
4314+#TEXT_START_ADDR=0
4315+NONPAGED_TEXT_START_ADDR=0x28
4316+ALIGNMENT=4
4317+MAXPAGESIZE=4
4318+ARCH=microblaze
4319+EMBEDDED=yes
4320+
4321+NOP=0x80000000
4322+
4323+# Hmmm, there's got to be a better way. This sets the stack to the
4324+# top of the simulator memory (2^19 bytes).
4325+#PAGE_SIZE=0x1000
4326+#DATA_ADDR=0x10000
4327+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }'
4328+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
4329+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
4330+
4331+TEMPLATE_NAME=elf32
4332+#GENERATE_SHLIB_SCRIPT=yes
4333diff --git a/ld/emulparams/elf64microblazeel.sh b/ld/emulparams/elf64microblazeel.sh
4334new file mode 100644
4335index 0000000000..9c7b0eb708
4336--- /dev/null
4337+++ b/ld/emulparams/elf64microblazeel.sh
4338@@ -0,0 +1,23 @@
4339+SCRIPT_NAME=elfmicroblaze
4340+OUTPUT_FORMAT="elf64-microblazeel"
4341+#BIG_OUTPUT_FORMAT="elf64-microblaze"
4342+LITTLE_OUTPUT_FORMAT="elf64-microblazeel"
4343+#TEXT_START_ADDR=0
4344+NONPAGED_TEXT_START_ADDR=0x28
4345+ALIGNMENT=4
4346+MAXPAGESIZE=4
4347+ARCH=microblaze
4348+EMBEDDED=yes
4349+
4350+NOP=0x80000000
4351+
4352+# Hmmm, there's got to be a better way. This sets the stack to the
4353+# top of the simulator memory (2^19 bytes).
4354+#PAGE_SIZE=0x1000
4355+#DATA_ADDR=0x10000
4356+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }'
4357+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
4358+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
4359+
4360+TEMPLATE_NAME=elf32
4361+#GENERATE_SHLIB_SCRIPT=yes
4362diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
4363index f8aaf27873..20ea6a885a 100644
4364--- a/opcodes/microblaze-dis.c
4365+++ b/opcodes/microblaze-dis.c
4366@@ -33,6 +33,7 @@
4367 #define get_field_r1(instr) get_field (instr, RA_MASK, RA_LOW)
4368 #define get_field_r2(instr) get_field (instr, RB_MASK, RB_LOW)
4369 #define get_int_field_imm(instr) ((instr & IMM_MASK) >> IMM_LOW)
4370+#define get_int_field_imml(instr) ((instr & IMML_MASK) >> IMM_LOW)
4371 #define get_int_field_r1(instr) ((instr & RA_MASK) >> RA_LOW)
4372
4373
4374@@ -56,11 +57,20 @@ get_field_imm (long instr)
4375 }
4376
4377 static char *
4378-get_field_imm5 (long instr)
4379+get_field_imml (long instr)
4380 {
4381 char tmpstr[25];
4382
4383- sprintf (tmpstr, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
4384+ sprintf (tmpstr, "%d", (short)((instr & IMML_MASK) >> IMM_LOW));
4385+ return (strdup (tmpstr));
4386+}
4387+
4388+static char *
4389+get_field_imms (long instr)
4390+{
4391+ char tmpstr[25];
4392+
4393+ sprintf (tmpstr, "%d", (short)((instr & IMM6_MASK) >> IMM_LOW));
4394 return (strdup (tmpstr));
4395 }
4396
4397@@ -74,14 +84,14 @@ get_field_imm5_mbar (long instr)
4398 }
4399
4400 static char *
4401-get_field_imm5width (long instr)
4402+get_field_immw (long instr)
4403 {
4404 char tmpstr[25];
4405
4406 if (instr & 0x00004000)
4407- sprintf (tmpstr, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
4408+ sprintf (tmpstr, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
4409 else
4410- sprintf (tmpstr, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >> IMM_LOW) + 1)); /* bsifi */
4411+ sprintf (tmpstr, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM6_MASK) >> IMM_LOW) + 1)); /* bsifi */
4412 return (strdup (tmpstr));
4413 }
4414
4415@@ -286,9 +296,13 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
4416 }
4417 }
4418 break;
4419- case INST_TYPE_RD_R1_IMM5:
4420+ case INST_TYPE_RD_R1_IMML:
4421+ print_func (stream, "\t%s, %s, %s", get_field_rd (inst),
4422+ get_field_r1(inst), get_field_imm (inst));
4423+ /* TODO: Also print symbol */
4424+ case INST_TYPE_RD_R1_IMMS:
4425 print_func (stream, "\t%s, %s, %s", get_field_rd (inst),
4426- get_field_r1(inst), get_field_imm5 (inst));
4427+ get_field_r1(inst), get_field_imms (inst));
4428 break;
4429 case INST_TYPE_RD_RFSL:
4430 print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_rfsl (inst));
4431@@ -386,6 +400,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
4432 }
4433 }
4434 break;
4435+ case INST_TYPE_IMML:
4436+ print_func (stream, "\t%s", get_field_imml (inst));
4437+ /* TODO: Also print symbol */
4438+ break;
4439 case INST_TYPE_RD_R2:
4440 print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_r2 (inst));
4441 break;
4442@@ -409,9 +427,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
4443 case INST_TYPE_NONE:
4444 break;
4445 /* For bit field insns. */
4446- case INST_TYPE_RD_R1_IMM5_IMM5:
4447- print_func (stream, "\t%s, %s, %s, %s", get_field_rd (inst),get_field_r1(inst),get_field_imm5width (inst), get_field_imm5 (inst));
4448- break;
4449+ case INST_TYPE_RD_R1_IMMW_IMMS:
4450+ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (inst), get_field_r1(inst),
4451+ get_field_immw (inst), get_field_imms (inst));
4452+ break;
4453 /* For tuqula instruction */
4454 case INST_TYPE_RD:
4455 print_func (stream, "\t%s", get_field_rd (inst));
4456diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
4457index ce8ac351b5..985834b8df 100644
4458--- a/opcodes/microblaze-opc.h
4459+++ b/opcodes/microblaze-opc.h
4460@@ -40,7 +40,7 @@
4461 #define INST_TYPE_RD_SPECIAL 11
4462 #define INST_TYPE_R1 12
4463 /* New instn type for barrel shift imms. */
4464-#define INST_TYPE_RD_R1_IMM5 13
4465+#define INST_TYPE_RD_R1_IMMS 13
4466 #define INST_TYPE_RD_RFSL 14
4467 #define INST_TYPE_R1_RFSL 15
4468
4469@@ -60,7 +60,13 @@
4470 #define INST_TYPE_IMM5 20
4471
4472 /* For bsefi and bsifi */
4473-#define INST_TYPE_RD_R1_IMM5_IMM5 21
4474+#define INST_TYPE_RD_R1_IMMW_IMMS 21
4475+
4476+/* For 64-bit instructions */
4477+#define INST_TYPE_IMML 22
4478+#define INST_TYPE_RD_R1_IMML 23
4479+#define INST_TYPE_R1_IMML 24
4480+#define INST_TYPE_RD_R1_IMMW_IMMS 21
4481
4482 #define INST_TYPE_NONE 25
4483
4484@@ -91,13 +97,14 @@
4485 #define OPCODE_MASK_H24 0xFC1F07FF /* High 6, bits 20-16 and low 11 bits. */
4486 #define OPCODE_MASK_H124 0xFFFF07FF /* High 16, and low 11 bits. */
4487 #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits. */
4488-#define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */
4489-#define OPCODE_MASK_H3B 0xFC00C600 /* High 6 bits and bits 16, 17, 21, 22. */
4490+#define OPCODE_MASK_H3 0xFC000700 /* High 6 bits and bits 21, 22, 23. */
4491+#define OPCODE_MASK_H3B 0xFC00E600 /* High 6 bits and bits 16, 17, 18, 21, 22. */
4492 #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */
4493-#define OPCODE_MASK_H32B 0xFC00C000 /* High 6 bits and bit 16, 17. */
4494+#define OPCODE_MASK_H32B 0xFC00E000 /* High 6 bits and bit 16, 17, 18. */
4495 #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */
4496 #define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */
4497 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
4498+#define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */
4499
4500 /* New Mask for msrset, msrclr insns. */
4501 #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
4502@@ -107,7 +114,7 @@
4503 #define DELAY_SLOT 1
4504 #define NO_DELAY_SLOT 0
4505
4506-#define MAX_OPCODES 301
4507+#define MAX_OPCODES 412
4508
4509 struct op_code_struct
4510 {
4511@@ -125,6 +132,7 @@ struct op_code_struct
4512 /* More info about output format here. */
4513 } opcodes[MAX_OPCODES] =
4514 {
4515+ /* 32-bit instructions */
4516 {"add", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000000, OPCODE_MASK_H4, add, arithmetic_inst },
4517 {"rsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H4, rsub, arithmetic_inst },
4518 {"addc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000000, OPCODE_MASK_H4, addc, arithmetic_inst },
4519@@ -161,11 +169,11 @@ struct op_code_struct
4520 {"ncget", INST_TYPE_RD_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst },
4521 {"ncput", INST_TYPE_R1_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst },
4522 {"muli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst },
4523- {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst },
4524- {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst },
4525- {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst },
4526- {"bsefi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst },
4527- {"bsifi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst },
4528+ {"bslli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3B, bslli, barrel_shift_inst },
4529+ {"bsrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3B, bsrai, barrel_shift_inst },
4530+ {"bsrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3B, bsrli, barrel_shift_inst },
4531+ {"bsefi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst },
4532+ {"bsifi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst },
4533 {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, microblaze_or, logical_inst },
4534 {"and", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000000, OPCODE_MASK_H4, microblaze_and, logical_inst },
4535 {"xor", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000000, OPCODE_MASK_H4, microblaze_xor, logical_inst },
4536@@ -425,6 +433,129 @@ struct op_code_struct
4537 {"suspend", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBB020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 24. */
4538 {"swapb", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E0, OPCODE_MASK_H4, swapb, arithmetic_inst },
4539 {"swaph", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E2, OPCODE_MASK_H4, swaph, arithmetic_inst },
4540+
4541+ /* 64-bit instructions */
4542+ {"addl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000100, OPCODE_MASK_H4, addl, arithmetic_inst },
4543+ {"rsubl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000100, OPCODE_MASK_H4, rsubl, arithmetic_inst },
4544+ {"addlc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000100, OPCODE_MASK_H4, addlc, arithmetic_inst },
4545+ {"rsublc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x0C000100, OPCODE_MASK_H4, rsublc, arithmetic_inst },
4546+ {"addlk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x10000100, OPCODE_MASK_H4, addlk, arithmetic_inst },
4547+ {"rsublk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000100, OPCODE_MASK_H4, rsublk, arithmetic_inst },
4548+ {"addlkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x18000100, OPCODE_MASK_H4, addlkc, arithmetic_inst },
4549+ {"rsublkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x1C000100, OPCODE_MASK_H4, rsublkc, arithmetic_inst },
4550+ {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst },
4551+ {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst },
4552+ {"addli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4553+ {"rsubli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4554+ {"addlic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4555+ {"rsublic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4556+ {"addlik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4557+ {"rsublik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4558+ {"addlikc", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4559+ {"rsublikc",INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
4560+ {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst },
4561+ {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst },
4562+ {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst },
4563+ {"bslrl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000100, OPCODE_MASK_H3, bslrl, barrel_shift_inst },
4564+ {"bsllli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002400, OPCODE_MASK_H3B, bsllli, barrel_shift_inst },
4565+ {"bslrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002200, OPCODE_MASK_H3B, bslrai, barrel_shift_inst },
4566+ {"bslrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002000, OPCODE_MASK_H3B, bslrli, barrel_shift_inst },
4567+ {"bslefi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64006000, OPCODE_MASK_H32B, bslefi, barrel_shift_inst },
4568+ {"bslifi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6400a000, OPCODE_MASK_H32B, bslifi, barrel_shift_inst },
4569+ {"orl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000100, OPCODE_MASK_H4, orl, logical_inst },
4570+ {"andl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000100, OPCODE_MASK_H4, andl, logical_inst },
4571+ {"xorl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000100, OPCODE_MASK_H4, xorl, logical_inst },
4572+ {"andnl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000100, OPCODE_MASK_H4, andnl, logical_inst },
4573+ {"pcmplbf", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000500, OPCODE_MASK_H4, pcmplbf, logical_inst },
4574+ {"pcmpleq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000500, OPCODE_MASK_H4, pcmpleq, logical_inst },
4575+ {"pcmplne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000500, OPCODE_MASK_H4, pcmplne, logical_inst },
4576+ {"srla", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000101, OPCODE_MASK_H34, srla, logical_inst },
4577+ {"srlc", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000121, OPCODE_MASK_H34, srlc, logical_inst },
4578+ {"srll", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000141, OPCODE_MASK_H34, srll, logical_inst },
4579+ {"sextl8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000160, OPCODE_MASK_H34, sextl8, logical_inst },
4580+ {"sextl16", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000161, OPCODE_MASK_H34, sextl16, logical_inst },
4581+ {"sextl32", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000162, OPCODE_MASK_H34, sextl32, logical_inst },
4582+ {"brea", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98010000, OPCODE_MASK_H124, brea, branch_inst },
4583+ {"bread", INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98110000, OPCODE_MASK_H124, bread, branch_inst },
4584+ {"breald", INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98150000, OPCODE_MASK_H24, breald, branch_inst },
4585+ {"beaeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000000, OPCODE_MASK_H14, beaeq, branch_inst },
4586+ {"bealeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000100, OPCODE_MASK_H14, bealeq, branch_inst },
4587+ {"beaeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000000, OPCODE_MASK_H14, beaeqd, branch_inst },
4588+ {"bealeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000100, OPCODE_MASK_H14, bealeqd, branch_inst },
4589+ {"beane", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200000, OPCODE_MASK_H14, beane, branch_inst },
4590+ {"bealne", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200100, OPCODE_MASK_H14, bealne, branch_inst },
4591+ {"beaned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200000, OPCODE_MASK_H14, beaned, branch_inst },
4592+ {"bealned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200100, OPCODE_MASK_H14, bealned, branch_inst },
4593+ {"bealt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400000, OPCODE_MASK_H14, bealt, branch_inst },
4594+ {"beallt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400100, OPCODE_MASK_H14, beallt, branch_inst },
4595+ {"bealtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400000, OPCODE_MASK_H14, bealtd, branch_inst },
4596+ {"bealltd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400100, OPCODE_MASK_H14, bealltd, branch_inst },
4597+ {"beale", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600000, OPCODE_MASK_H14, beale, branch_inst },
4598+ {"bealle", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600100, OPCODE_MASK_H14, bealle, branch_inst },
4599+ {"bealed", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600000, OPCODE_MASK_H14, bealed, branch_inst },
4600+ {"bealled", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600100, OPCODE_MASK_H14, bealled, branch_inst },
4601+ {"beagt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800000, OPCODE_MASK_H14, beagt, branch_inst },
4602+ {"bealgt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800100, OPCODE_MASK_H14, bealgt, branch_inst },
4603+ {"beagtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800000, OPCODE_MASK_H14, beagtd, branch_inst },
4604+ {"bealgtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800100, OPCODE_MASK_H14, bealgtd, branch_inst },
4605+ {"beage", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00000, OPCODE_MASK_H14, beage, branch_inst },
4606+ {"bealge", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00100, OPCODE_MASK_H14, bealge, branch_inst },
4607+ {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst },
4608+ {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst },
4609+ {"orli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
4610+ {"andli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
4611+ {"xorli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
4612+ {"andnli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
4613+ {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst },
4614+ {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst },
4615+ {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst },
4616+ {"brealid", INST_TYPE_RD_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8150000, OPCODE_MASK_H2, brealid, branch_inst },
4617+ {"beaeqi", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, beaeqi, branch_inst },
4618+ {"bealeqi", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaeqi */
4619+ {"beaeqid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, beaeqid, branch_inst },
4620+ {"bealeqid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaeqid */
4621+ {"beanei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, beanei, branch_inst },
4622+ {"bealnei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beanei */
4623+ {"beaneid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, beaneid, branch_inst },
4624+ {"bealneid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaneid */
4625+ {"bealti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, bealti, branch_inst },
4626+ {"beallti", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealti */
4627+ {"bealtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, bealtid, branch_inst },
4628+ {"bealltid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealtid */
4629+ {"bealei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, bealei, branch_inst },
4630+ {"beallei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealei */
4631+ {"bealeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, bealeid, branch_inst },
4632+ {"bealleid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealeid */
4633+ {"beagti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, beagti, branch_inst },
4634+ {"bealgti", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagti */
4635+ {"beagtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, beagtid, branch_inst },
4636+ {"bealgtid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagtid */
4637+ {"beagei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, beagei, branch_inst },
4638+ {"bealgei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagei */
4639+ {"beageid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, beageid, branch_inst },
4640+ {"bealgeid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beageid */
4641+ {"ll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000100, OPCODE_MASK_H4, ll, memory_load_inst },
4642+ {"llr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000300, OPCODE_MASK_H4, llr, memory_load_inst },
4643+ {"sl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000100, OPCODE_MASK_H4, sl, memory_store_inst },
4644+ {"slr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000300, OPCODE_MASK_H4, slr, memory_store_inst },
4645+ {"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 */
4646+ {"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 */
4647+ {"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 */
4648+ {"dadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000400, OPCODE_MASK_H4, dadd, arithmetic_inst },
4649+ {"drsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000480, OPCODE_MASK_H4, drsub, arithmetic_inst },
4650+ {"dmul", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000500, OPCODE_MASK_H4, dmul, arithmetic_inst },
4651+ {"ddiv", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000580, OPCODE_MASK_H4, ddiv, arithmetic_inst },
4652+ {"dcmp.lt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000610, OPCODE_MASK_H4, dcmp_lt, arithmetic_inst },
4653+ {"dcmp.eq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000620, OPCODE_MASK_H4, dcmp_eq, arithmetic_inst },
4654+ {"dcmp.le", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000630, OPCODE_MASK_H4, dcmp_le, arithmetic_inst },
4655+ {"dcmp.gt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000640, OPCODE_MASK_H4, dcmp_gt, arithmetic_inst },
4656+ {"dcmp.ne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000650, OPCODE_MASK_H4, dcmp_ne, arithmetic_inst },
4657+ {"dcmp.ge", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000660, OPCODE_MASK_H4, dcmp_ge, arithmetic_inst },
4658+ {"dcmp.un", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000600, OPCODE_MASK_H4, dcmp_un, arithmetic_inst },
4659+ {"dbl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000680, OPCODE_MASK_H4, dbl, arithmetic_inst },
4660+ {"dlong", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000700, OPCODE_MASK_H4, dlong, arithmetic_inst },
4661+ {"dsqrt", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000780, OPCODE_MASK_H4, dsqrt, arithmetic_inst },
4662+
4663 {"", 0, 0, 0, 0, 0, 0, 0, 0},
4664 };
4665
4666@@ -445,8 +576,17 @@ char pvr_register_prefix[] = "rpvr";
4667 #define MIN_IMM5 ((int) 0x00000000)
4668 #define MAX_IMM5 ((int) 0x0000001f)
4669
4670+#define MIN_IMM6 ((int) 0x00000000)
4671+#define MAX_IMM6 ((int) 0x0000003f)
4672+
4673 #define MIN_IMM_WIDTH ((int) 0x00000001)
4674 #define MAX_IMM_WIDTH ((int) 0x00000020)
4675
4676+#define MIN_IMM6_WIDTH ((int) 0x00000001)
4677+#define MAX_IMM6_WIDTH ((int) 0x00000040)
4678+
4679+#define MIN_IMML ((long) 0xffffff8000000000L)
4680+#define MAX_IMML ((long) 0x0000007fffffffffL)
4681+
4682 #endif /* MICROBLAZE_OPC */
4683
4684diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
4685index 28662694cd..076dbcd0b3 100644
4686--- a/opcodes/microblaze-opcm.h
4687+++ b/opcodes/microblaze-opcm.h
4688@@ -25,6 +25,7 @@
4689
4690 enum microblaze_instr
4691 {
4692+ /* 32-bit instructions */
4693 add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu,
4694 addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
4695 mulh, mulhu, mulhsu,swapb,swaph,
4696@@ -58,6 +59,18 @@ enum microblaze_instr
4697 aputd, taputd, caputd, tcaputd, naputd, tnaputd, ncaputd, tncaputd,
4698 eagetd, teagetd, ecagetd, tecagetd, neagetd, tneagetd, necagetd, tnecagetd,
4699 eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd,
4700+
4701+ /* 64-bit instructions */
4702+ addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
4703+ bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl,
4704+ andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32,
4705+ brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned,
4706+ bealned, bealt, beallt, bealtd, bealltd, beale, bealle, bealed, bealled, beagt,
4707+ bealgt, beagtd, bealgtd, beage, bealge, beaged, bealged, breai, breaid, brealid,
4708+ beaeqi, beaeqid, beanei, beaneid, bealti, bealtid, bealei, bealeid, beagti,
4709+ beagtid, beagei, beageid, imml, ll, llr, sl, slr,
4710+ dadd, drsub, dmul, ddiv, dcmp_lt, dcmp_eq, dcmp_le, dcmp_gt, dcmp_ne, dcmp_ge,
4711+ dcmp_un, dbl, dlong, dsqrt,
4712 invalid_inst
4713 };
4714
4715@@ -135,15 +148,18 @@ enum microblaze_instr_type
4716 #define RA_MASK 0x001F0000
4717 #define RB_MASK 0x0000F800
4718 #define IMM_MASK 0x0000FFFF
4719+#define IMML_MASK 0x00FFFFFF
4720
4721-/* Imm mask for barrel shifts. */
4722+/* Imm masks for barrel shifts. */
4723 #define IMM5_MASK 0x0000001F
4724+#define IMM6_MASK 0x0000003F
4725
4726 /* Imm mask for mbar. */
4727 #define IMM5_MBAR_MASK 0x03E00000
4728
4729-/* Imm mask for extract/insert width. */
4730+/* Imm masks for extract/insert width. */
4731 #define IMM5_WIDTH_MASK 0x000007C0
4732+#define IMM6_WIDTH_MASK 0x00000FC0
4733
4734 /* FSL imm mask for get, put instructions. */
4735 #define RFSL_MASK 0x000000F
4736--
47372.17.1
4738
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0016-MB-X-initial-commit.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0016-MB-X-initial-commit.patch
new file mode 100644
index 00000000..0c3da95a
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0016-MB-X-initial-commit.patch
@@ -0,0 +1,691 @@
1From bcd4263219c9756b9c1c1df64c6fef1311057fac Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Sun, 30 Sep 2018 16:31:26 +0530
4Subject: [PATCH 16/43] MB-X initial commit code cleanup is needed.
5
6---
7 bfd/bfd-in2.h | 10 +++
8 bfd/elf32-microblaze.c | 65 +++++++++++++++-
9 bfd/elf64-microblaze.c | 61 ++++++++++++++-
10 bfd/libbfd.h | 2 +
11 bfd/reloc.c | 12 +++
12 gas/config/tc-microblaze.c | 152 ++++++++++++++++++++++++++++++-------
13 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
19index 721531886a..4f777059d8 100644
20--- a/bfd/bfd-in2.h
21+++ b/bfd/bfd-in2.h
22@@ -5876,11 +5876,21 @@ done here - only used for relaxing */
23 * +done here - only used for relaxing */
24 BFD_RELOC_MICROBLAZE_64_NONE,
25
26+/* This is a 64 bit reloc that stores the 32 bit pc relative
27+ * +value in two words (with an imml instruction). No relocation is
28+ * +done here - only used for relaxing */
29+ BFD_RELOC_MICROBLAZE_64,
30+
31 /* This is a 64 bit reloc that stores the 32 bit pc relative
32 value in two words (with an imm instruction). The relocation is
33 PC-relative GOT offset */
34 BFD_RELOC_MICROBLAZE_64_GOTPC,
35
36+/* This is a 64 bit reloc that stores the 32 bit pc relative
37+value in two words (with an imml instruction). The relocation is
38+PC-relative GOT offset */
39+ BFD_RELOC_MICROBLAZE_64_GPC,
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 GOT offset */
44diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
45index d001437b3f..035e71f311 100644
46--- 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
159index 0f43ae6ea8..56a45f2a05 100644
160--- a/bfd/elf64-microblaze.c
161+++ b/bfd/elf64-microblaze.c
162@@ -116,6 +116,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
163 0x0000ffff, /* Dest Mask. */
164 TRUE), /* PC relative offset? */
165
166+ /* A 64 bit relocation. Table entry not really used. */
167+ 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+
181 /* A 64 bit relocation. Table entry not really used. */
182 HOWTO (R_MICROBLAZE_64, /* Type. */
183 0, /* Rightshift. */
184@@ -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
269index feb9fada1e..450653f2d8 100644
270--- 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
283index 87753ae4f0..ccf29f54cf 100644
284--- a/bfd/reloc.c
285+++ b/bfd/reloc.c
286@@ -6803,12 +6803,24 @@ ENUMDOC
287 done here - only used for relaxing
288 ENUM
289 BFD_RELOC_MICROBLAZE_64_NONE
290+ENUMDOC
291+ 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
296 ENUMDOC
297 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
300 ENUM
301 BFD_RELOC_MICROBLAZE_64_GOTPC
302+ENUMDOC
303+ This is a 64 bit reloc that stores the 32 bit pc relative
304+ 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
308 ENUMDOC
309 This is a 64 bit reloc that stores the 32 bit pc relative
310 value in two words (with an imm instruction). The relocation is
311diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
312index c79434785a..3f90b7c892 100644
313--- 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
647index 6ee0966444..16b2736577 100644
648--- 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
660index 985834b8df..9b6264b61c 100644
661--- 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
675index 076dbcd0b3..5f2e190d23 100644
676--- 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,
689--
6902.17.1
691
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch
new file mode 100644
index 00000000..a6428534
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch
@@ -0,0 +1,36 @@
1From 7f6533a7c442b8966f30bbe7f0e872b1ef6a0d3f Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 11 Sep 2018 13:48:33 +0530
4Subject: [PATCH 17/43] [Patch,Microblaze] : negl instruction is overriding
5 rsubl,fixed it by changing the instruction order...
6
7---
8 opcodes/microblaze-opc.h | 4 ++--
9 1 file changed, 2 insertions(+), 2 deletions(-)
10
11diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
12index 9b6264b61c..824afc0ab0 100644
13--- a/opcodes/microblaze-opc.h
14+++ b/opcodes/microblaze-opc.h
15@@ -275,9 +275,7 @@ struct op_code_struct
16 {"la", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* la translates to addik. */
17 {"tuqula",INST_TYPE_RD, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3000002A, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* tuqula rd translates to addik rd, r0, 42. */
18 {"not", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA800FFFF, OPCODE_MASK_H34, invalid_inst, logical_inst }, /* not translates to xori rd,ra,-1. */
19- {"neg", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* neg translates to rsub rd, ra, r0. */
20 {"rtb", INST_TYPE_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6000004, OPCODE_MASK_H1, invalid_inst, return_inst }, /* rtb translates to rts rd, 4. */
21- {"sub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* sub translates to rsub rd, rb, ra. */
22 {"lmi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst },
23 {"smi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst },
24 {"msrset",INST_TYPE_RD_IMM15, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94100000, OPCODE_MASK_H23N, msrset, special_inst },
25@@ -555,6 +553,8 @@ struct op_code_struct
26 {"dbl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000680, OPCODE_MASK_H4, dbl, arithmetic_inst },
27 {"dlong", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000700, OPCODE_MASK_H4, dlong, arithmetic_inst },
28 {"dsqrt", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000780, OPCODE_MASK_H4, dsqrt, arithmetic_inst },
29+ {"neg", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* neg translates to rsub rd, ra, r0. */
30+ {"sub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* sub translates to rsub rd, rb, ra. */
31
32 {"", 0, 0, 0, 0, 0, 0, 0, 0},
33 };
34--
352.17.1
36
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0018-Added-relocations-for-MB-X.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0018-Added-relocations-for-MB-X.patch
new file mode 100644
index 00000000..99c5f62a
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0018-Added-relocations-for-MB-X.patch
@@ -0,0 +1,346 @@
1From 6d241a6865abf8196ba0cfa2aed7e847df087b6e Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Tue, 11 Sep 2018 17:30:17 +0530
4Subject: [PATCH 18/43] Added relocations for MB-X
5
6---
7 bfd/bfd-in2.h | 11 +++--
8 bfd/libbfd.h | 4 +-
9 bfd/reloc.c | 26 ++++++-----
10 gas/config/tc-microblaze.c | 90 ++++++++++++++++----------------------
11 4 files changed, 62 insertions(+), 69 deletions(-)
12
13diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
14index 4f777059d8..de46e78902 100644
15--- a/bfd/bfd-in2.h
16+++ b/bfd/bfd-in2.h
17@@ -5872,15 +5872,20 @@ done here - only used for relaxing */
18 BFD_RELOC_MICROBLAZE_32_NONE,
19
20 /* This is a 64 bit reloc that stores the 32 bit pc relative
21- * +value in two words (with an imm instruction). No relocation is
22+ * +value in two words (with an imml instruction). No relocation is
23 * +done here - only used for relaxing */
24- BFD_RELOC_MICROBLAZE_64_NONE,
25+ BFD_RELOC_MICROBLAZE_64_PCREL,
26
27-/* This is a 64 bit reloc that stores the 32 bit pc relative
28+/* This is a 64 bit reloc that stores the 32 bit relative
29 * +value in two words (with an imml instruction). No relocation is
30 * +done here - only used for relaxing */
31 BFD_RELOC_MICROBLAZE_64,
32
33+/* This is a 64 bit reloc that stores the 32 bit pc relative
34+ * +value in two words (with an imm instruction). No relocation is
35+ * +done here - only used for relaxing */
36+ BFD_RELOC_MICROBLAZE_64_NONE,
37+
38 /* This is a 64 bit reloc that stores the 32 bit pc relative
39 value in two words (with an imm instruction). The relocation is
40 PC-relative GOT offset */
41diff --git a/bfd/libbfd.h b/bfd/libbfd.h
42index 450653f2d8..d87a183d5e 100644
43--- a/bfd/libbfd.h
44+++ b/bfd/libbfd.h
45@@ -2903,14 +2903,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
46 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
47 "BFD_RELOC_MICROBLAZE_32_NONE",
48 "BFD_RELOC_MICROBLAZE_64_NONE",
49- "BFD_RELOC_MICROBLAZE_64",
50 "BFD_RELOC_MICROBLAZE_64_GOTPC",
51- "BFD_RELOC_MICROBLAZE_64_GPC",
52 "BFD_RELOC_MICROBLAZE_64_GOT",
53 "BFD_RELOC_MICROBLAZE_64_PLT",
54 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
55 "BFD_RELOC_MICROBLAZE_32_GOTOFF",
56 "BFD_RELOC_MICROBLAZE_COPY",
57+ "BFD_RELOC_MICROBLAZE_64",
58+ "BFD_RELOC_MICROBLAZE_64_PCREL",
59 "BFD_RELOC_MICROBLAZE_64_TLS",
60 "BFD_RELOC_MICROBLAZE_64_TLSGD",
61 "BFD_RELOC_MICROBLAZE_64_TLSLD",
62diff --git a/bfd/reloc.c b/bfd/reloc.c
63index ccf29f54cf..861f2d48c0 100644
64--- a/bfd/reloc.c
65+++ b/bfd/reloc.c
66@@ -6803,24 +6803,12 @@ ENUMDOC
67 done here - only used for relaxing
68 ENUM
69 BFD_RELOC_MICROBLAZE_64_NONE
70-ENUMDOC
71- This is a 32 bit reloc that stores the 32 bit pc relative
72- value in two words (with an imml instruction). No relocation is
73- done here - only used for relaxing
74-ENUM
75- BFD_RELOC_MICROBLAZE_64
76 ENUMDOC
77 This is a 64 bit reloc that stores the 32 bit pc relative
78 value in two words (with an imm instruction). No relocation is
79 done here - only used for relaxing
80 ENUM
81 BFD_RELOC_MICROBLAZE_64_GOTPC
82-ENUMDOC
83- This is a 64 bit reloc that stores the 32 bit pc relative
84- value in two words (with an imml instruction). No relocation is
85- done here - only used for relaxing
86-ENUM
87- BFD_RELOC_MICROBLAZE_64_GPC
88 ENUMDOC
89 This is a 64 bit reloc that stores the 32 bit pc relative
90 value in two words (with an imm instruction). The relocation is
91@@ -6906,6 +6894,20 @@ ENUMDOC
92 value in two words (with an imm instruction). The relocation is
93 relative offset from start of TEXT.
94
95+ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
96+ to two words (uses imml instruction).
97+ENUM
98+BFD_RELOC_MICROBLAZE_64,
99+ENUMDOC
100+ This is a 64 bit reloc that stores the 64 bit pc relative
101+ value in two words (with an imml instruction). No relocation is
102+ done here - only used for relaxing
103+ENUM
104+BFD_RELOC_MICROBLAZE_64_PCREL,
105+ENUMDOC
106+ This is a 32 bit reloc that stores the 32 bit pc relative
107+ value in two words (with an imml instruction). No relocation is
108+ done here - only used for relaxing
109 ENUM
110 BFD_RELOC_AARCH64_RELOC_START
111 ENUMDOC
112diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
113index 3f90b7c892..587a4d56ec 100644
114--- a/gas/config/tc-microblaze.c
115+++ b/gas/config/tc-microblaze.c
116@@ -95,6 +95,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
117 #define TEXT_OFFSET 17
118 #define TEXT_PC_OFFSET 18
119 #define DEFINED_64_OFFSET 19
120+#define DEFINED_64_PC_OFFSET 20
121
122 /* Initialize the relax table. */
123 const relax_typeS md_relax_table[] =
124@@ -119,7 +120,8 @@ const relax_typeS md_relax_table[] =
125 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
126 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
127 // { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
128- { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 17: DEFINED_64_OFFSET. */
129+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 19: DEFINED_64_OFFSET. */
130+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
131 };
132
133 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
134@@ -1180,33 +1182,6 @@ md_assemble (char * str)
135 inst |= (immed << IMM_LOW) & IMM_MASK;
136 }
137 }
138-#if 0 //revisit
139- else if (streq (name, "lli") || streq (name, "sli"))
140- {
141- temp = immed & 0xFFFFFFFFFFFF8000;
142- if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
143- {
144- /* Needs an immediate inst. */
145- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
146- if (opcode1 == NULL)
147- {
148- as_bad (_("unknown opcode \"%s\""), "imml");
149- return;
150- }
151-
152- inst1 = opcode1->bit_sequence;
153- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
154- output[0] = INST_BYTE0 (inst1);
155- output[1] = INST_BYTE1 (inst1);
156- output[2] = INST_BYTE2 (inst1);
157- output[3] = INST_BYTE3 (inst1);
158- output = frag_more (isize);
159- }
160- inst |= (reg1 << RD_LOW) & RD_MASK;
161- inst |= (reg2 << RA_LOW) & RA_MASK;
162- inst |= (immed << IMM_LOW) & IMM_MASK;
163- }
164-#endif
165 else
166 {
167 temp = immed & 0xFFFF8000;
168@@ -1958,8 +1933,8 @@ md_assemble (char * str)
169
170 if (exp.X_op != O_constant)
171 {
172- char *opc = NULL;
173- //char *opc = str_microblaze_64;
174+ //char *opc = NULL;
175+ char *opc = str_microblaze_64;
176 relax_substateT subtype;
177
178 if (exp.X_md != 0)
179@@ -2221,13 +2196,19 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
180 fragP->fr_fix += INST_WORD_SIZE * 2;
181 fragP->fr_var = 0;
182 break;
183+ case DEFINED_64_PC_OFFSET:
184+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
185+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PCREL);
186+ fragP->fr_fix += INST_WORD_SIZE * 2;
187+ fragP->fr_var = 0;
188+ break;
189 case DEFINED_64_OFFSET:
190 if (fragP->fr_symbol == GOT_symbol)
191 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
192- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GPC);
193+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GPC);
194 else
195 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
196- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64);
197+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64);
198 fragP->fr_fix += INST_WORD_SIZE * 2;
199 fragP->fr_var = 0;
200 break;
201@@ -2237,7 +2218,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
202 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
203 else
204 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
205- fragP->fr_offset, TRUE, BFD_RELOC_64);
206+ fragP->fr_offset, FALSE, BFD_RELOC_64);
207 fragP->fr_fix += INST_WORD_SIZE * 2;
208 fragP->fr_var = 0;
209 break;
210@@ -2457,14 +2438,17 @@ md_apply_fix (fixS * fixP,
211 }
212 }
213 break;
214+
215 case BFD_RELOC_64_PCREL:
216 case BFD_RELOC_64:
217 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
218 case BFD_RELOC_MICROBLAZE_64:
219+ case BFD_RELOC_MICROBLAZE_64_PCREL:
220 /* Add an imm instruction. First save the current instruction. */
221 for (i = 0; i < INST_WORD_SIZE; i++)
222 buf[i + INST_WORD_SIZE] = buf[i];
223- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
224+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
225+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
226 {
227 /* Generate the imm instruction. */
228 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
229@@ -2477,6 +2461,10 @@ md_apply_fix (fixS * fixP,
230 inst1 = opcode1->bit_sequence;
231 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
232 inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
233+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
234+ fixP->fx_r_type = BFD_RELOC_64;
235+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
236+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
237 }
238 else
239 {
240@@ -2487,7 +2475,7 @@ md_apply_fix (fixS * fixP,
241 as_bad (_("unknown opcode \"%s\""), "imm");
242 return;
243 }
244-
245+
246 inst1 = opcode1->bit_sequence;
247 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
248 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
249@@ -2534,7 +2522,7 @@ md_apply_fix (fixS * fixP,
250 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
251 if (opcode1 == NULL)
252 {
253- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
254+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
255 as_bad (_("unknown opcode \"%s\""), "imml");
256 else
257 as_bad (_("unknown opcode \"%s\""), "imm");
258@@ -2561,8 +2549,6 @@ md_apply_fix (fixS * fixP,
259 moves code around due to relaxing. */
260 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
261 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
262- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
263- fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
264 else if (fixP->fx_r_type == BFD_RELOC_32)
265 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
266 else
267@@ -2613,33 +2599,24 @@ md_estimate_size_before_relax (fragS * fragP,
268 if(streq (fragP->fr_opcode, str_microblaze_64))
269 {
270 /* Used as an absolute value. */
271- fragP->fr_subtype = DEFINED_64_OFFSET;
272+ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
273 /* Variable part does not change. */
274- fragP->fr_var = INST_WORD_SIZE;
275+ fragP->fr_var = INST_WORD_SIZE*2;
276 }
277 else
278 {
279 fragP->fr_subtype = DEFINED_PC_OFFSET;
280- /* Don't know now whether we need an imm instruction. */
281+ /* Don't know now whether we need an imm instruction. */
282 fragP->fr_var = INST_WORD_SIZE;
283 }
284 }
285 else
286 {
287 fragP->fr_subtype = DEFINED_PC_OFFSET;
288- /* Don't know now whether we need an imm instruction. */
289+ /* Don't know now whether we need an imm instruction. */
290 fragP->fr_var = INST_WORD_SIZE;
291 }
292 }
293- #if 0
294- else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
295- !S_IS_WEAK (fragP->fr_symbol))
296- {
297- fragP->fr_subtype = DEFINED_PC_OFFSET;
298- /* Don't know now whether we need an imm instruction. */
299- fragP->fr_var = INST_WORD_SIZE;
300- }
301-#endif
302 else if (S_IS_DEFINED (fragP->fr_symbol)
303 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
304 {
305@@ -2669,6 +2646,13 @@ md_estimate_size_before_relax (fragS * fragP,
306 /* Variable part does not change. */
307 fragP->fr_var = INST_WORD_SIZE*2;
308 }
309+ else if (streq (fragP->fr_opcode, str_microblaze_64))
310+ {
311+ /* Used as an absolute value. */
312+ fragP->fr_subtype = DEFINED_64_OFFSET;
313+ /* Variable part does not change. */
314+ fragP->fr_var = INST_WORD_SIZE;
315+ }
316 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
317 {
318 /* It is accessed using the small data read only anchor. */
319@@ -2743,6 +2727,7 @@ md_estimate_size_before_relax (fragS * fragP,
320 case TLSTPREL_OFFSET:
321 case TLSDTPREL_OFFSET:
322 case DEFINED_64_OFFSET:
323+ case DEFINED_64_PC_OFFSET:
324 fragP->fr_var = INST_WORD_SIZE*2;
325 break;
326 case DEFINED_RO_SEGMENT:
327@@ -2796,7 +2781,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
328 else
329 {
330 /* The case where we are going to resolve things... */
331- if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
332+ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
333 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
334 else
335 return fixp->fx_where + fixp->fx_frag->fr_address;
336@@ -2831,6 +2816,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
337 case BFD_RELOC_MICROBLAZE_64_GOTPC:
338 case BFD_RELOC_MICROBLAZE_64_GPC:
339 case BFD_RELOC_MICROBLAZE_64:
340+ case BFD_RELOC_MICROBLAZE_64_PCREL:
341 case BFD_RELOC_MICROBLAZE_64_GOT:
342 case BFD_RELOC_MICROBLAZE_64_PLT:
343 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
344--
3452.17.1
346
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0019-Fixed-MB-x-relocation-issues.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0019-Fixed-MB-x-relocation-issues.patch
new file mode 100644
index 00000000..edbfac0c
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0019-Fixed-MB-x-relocation-issues.patch
@@ -0,0 +1,373 @@
1From bb6c70cfa1402a685995103ac90e7ceeccdd0991 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Fri, 28 Sep 2018 12:04:55 +0530
4Subject: [PATCH 19/43] -Fixed MB-x relocation issues -Added imml for required
5 MB-x instructions
6
7---
8 bfd/elf64-microblaze.c | 68 ++++++++++++++---
9 gas/config/tc-microblaze.c | 152 +++++++++++++++++++++++++++----------
10 gas/tc.h | 2 +-
11 3 files changed, 167 insertions(+), 55 deletions(-)
12
13diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
14index 56a45f2a05..54a2461037 100644
15--- a/bfd/elf64-microblaze.c
16+++ b/bfd/elf64-microblaze.c
17@@ -1476,8 +1476,17 @@ microblaze_elf_relocate_section (bfd *output_bfd,
18 relocation -= (input_section->output_section->vma
19 + input_section->output_offset
20 + offset + INST_WORD_SIZE);
21- bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
22+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
23+ if (insn == 0xb2000000 || insn == 0xb2ffffff)
24+ {
25+ insn &= ~0x00ffffff;
26+ insn |= (relocation >> 16) & 0xffffff;
27+ bfd_put_32 (input_bfd, insn,
28 contents + offset + endian);
29+ }
30+ else
31+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
32+ contents + offset + endian);
33 bfd_put_16 (input_bfd, relocation & 0xffff,
34 contents + offset + endian + INST_WORD_SIZE);
35 }
36@@ -1567,11 +1576,28 @@ microblaze_elf_relocate_section (bfd *output_bfd,
37 else
38 {
39 if (r_type == R_MICROBLAZE_64_PCREL)
40- relocation -= (input_section->output_section->vma
41- + input_section->output_offset
42- + offset + INST_WORD_SIZE);
43- bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
44+ {
45+ if (!input_section->output_section->vma &&
46+ !input_section->output_offset && !offset)
47+ relocation -= (input_section->output_section->vma
48+ + input_section->output_offset
49+ + offset);
50+ else
51+ relocation -= (input_section->output_section->vma
52+ + input_section->output_offset
53+ + offset + INST_WORD_SIZE);
54+ }
55+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
56+ if (insn == 0xb2000000 || insn == 0xb2ffffff)
57+ {
58+ insn &= ~0x00ffffff;
59+ insn |= (relocation >> 16) & 0xffffff;
60+ bfd_put_32 (input_bfd, insn,
61 contents + offset + endian);
62+ }
63+ else
64+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
65+ contents + offset + endian);
66 bfd_put_16 (input_bfd, relocation & 0xffff,
67 contents + offset + endian + INST_WORD_SIZE);
68 }
69@@ -1690,9 +1716,19 @@ static void
70 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
71 {
72 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
73- instr &= ~0x0000ffff;
74- instr |= (val & 0x0000ffff);
75- bfd_put_32 (abfd, instr, bfd_addr);
76+
77+ if (instr == 0xb2000000 || instr == 0xb2ffffff)
78+ {
79+ instr &= ~0x00ffffff;
80+ instr |= (val & 0xffffff);
81+ bfd_put_32 (abfd, instr, bfd_addr);
82+ }
83+ else
84+ {
85+ instr &= ~0x0000ffff;
86+ instr |= (val & 0x0000ffff);
87+ bfd_put_32 (abfd, instr, bfd_addr);
88+ }
89 }
90
91 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
92@@ -1704,10 +1740,18 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
93 unsigned long instr_lo;
94
95 instr_hi = bfd_get_32 (abfd, bfd_addr);
96- instr_hi &= ~0x0000ffff;
97- instr_hi |= ((val >> 16) & 0x0000ffff);
98- bfd_put_32 (abfd, instr_hi, bfd_addr);
99-
100+ if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff)
101+ {
102+ instr_hi &= ~0x00ffffff;
103+ instr_hi |= (val >> 16) & 0xffffff;
104+ bfd_put_32 (abfd, instr_hi,bfd_addr);
105+ }
106+ else
107+ {
108+ instr_hi &= ~0x0000ffff;
109+ instr_hi |= ((val >> 16) & 0x0000ffff);
110+ bfd_put_32 (abfd, instr_hi, bfd_addr);
111+ }
112 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
113 instr_lo &= ~0x0000ffff;
114 instr_lo |= (val & 0x0000ffff);
115diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
116index 587a4d56ec..fa437b6c98 100644
117--- a/gas/config/tc-microblaze.c
118+++ b/gas/config/tc-microblaze.c
119@@ -392,7 +392,7 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
120 Integer arg to pass to the function. */
121 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
122 and then in the read.c table. */
123-const pseudo_typeS md_pseudo_table[] =
124+pseudo_typeS md_pseudo_table[] =
125 {
126 {"lcomm", microblaze_s_lcomm, 1},
127 {"data", microblaze_s_data, 0},
128@@ -401,7 +401,7 @@ const pseudo_typeS md_pseudo_table[] =
129 {"data32", cons, 4}, /* Same as word. */
130 {"ent", s_func, 0}, /* Treat ent as function entry point. */
131 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
132- {"gpword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
133+ {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
134 {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
135 {"weakext", microblaze_s_weakext, 0},
136 {"rodata", microblaze_s_rdata, 0},
137@@ -996,7 +996,7 @@ md_assemble (char * str)
138 unsigned reg2;
139 unsigned reg3;
140 unsigned isize;
141- unsigned int immed, immed2, temp;
142+ unsigned long immed, immed2, temp;
143 expressionS exp;
144 char name[20];
145 long immedl;
146@@ -1118,8 +1118,9 @@ md_assemble (char * str)
147 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
148 else if (streq (name, "smi"))
149 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
150-
151- if (reg2 == REG_ROSDP)
152+ if(streq (name, "lli") || streq (name, "sli"))
153+ opc = str_microblaze_64;
154+ else if (reg2 == REG_ROSDP)
155 opc = str_microblaze_ro_anchor;
156 else if (reg2 == REG_RWSDP)
157 opc = str_microblaze_rw_anchor;
158@@ -1182,31 +1183,55 @@ md_assemble (char * str)
159 inst |= (immed << IMM_LOW) & IMM_MASK;
160 }
161 }
162- else
163- {
164- temp = immed & 0xFFFF8000;
165- if ((temp != 0) && (temp != 0xFFFF8000))
166- {
167+ else if (streq (name, "lli") || streq (name, "sli"))
168+ {
169+ temp = immed & 0xFFFFFF8000;
170+ if (temp != 0 && temp != 0xFFFFFF8000)
171+ {
172 /* Needs an immediate inst. */
173- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
174+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
175 if (opcode1 == NULL)
176 {
177- as_bad (_("unknown opcode \"%s\""), "imm");
178+ as_bad (_("unknown opcode \"%s\""), "imml");
179 return;
180 }
181-
182 inst1 = opcode1->bit_sequence;
183- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
184+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
185 output[0] = INST_BYTE0 (inst1);
186 output[1] = INST_BYTE1 (inst1);
187 output[2] = INST_BYTE2 (inst1);
188 output[3] = INST_BYTE3 (inst1);
189 output = frag_more (isize);
190- }
191- inst |= (reg1 << RD_LOW) & RD_MASK;
192- inst |= (reg2 << RA_LOW) & RA_MASK;
193- inst |= (immed << IMM_LOW) & IMM_MASK;
194- }
195+ }
196+ inst |= (reg1 << RD_LOW) & RD_MASK;
197+ inst |= (reg2 << RA_LOW) & RA_MASK;
198+ inst |= (immed << IMM_LOW) & IMM_MASK;
199+ }
200+ else
201+ {
202+ temp = immed & 0xFFFF8000;
203+ if ((temp != 0) && (temp != 0xFFFF8000))
204+ {
205+ /* Needs an immediate inst. */
206+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
207+ if (opcode1 == NULL)
208+ {
209+ as_bad (_("unknown opcode \"%s\""), "imm");
210+ return;
211+ }
212+
213+ inst1 = opcode1->bit_sequence;
214+ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
215+ output[0] = INST_BYTE0 (inst1);
216+ output[1] = INST_BYTE1 (inst1);
217+ output[2] = INST_BYTE2 (inst1);
218+ output[3] = INST_BYTE3 (inst1);
219+ output = frag_more (isize);
220+ }
221+ inst |= (reg1 << RD_LOW) & RD_MASK;
222+ inst |= (reg2 << RA_LOW) & RA_MASK;
223+ inst |= (immed << IMM_LOW) & IMM_MASK;
224+ }
225 break;
226
227 case INST_TYPE_RD_R1_IMMS:
228@@ -1832,12 +1857,20 @@ md_assemble (char * str)
229 case INST_TYPE_IMM:
230 if (streq (name, "imm"))
231 as_fatal (_("An IMM instruction should not be present in the .s file"));
232-
233- op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
234+ if (microblaze_arch_size == 64)
235+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
236+ else
237+ op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
238
239 if (exp.X_op != O_constant)
240 {
241- char *opc = NULL;
242+ char *opc;
243+ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
244+ streq (name, "breaid") ||
245+ streq (name, "brai") || streq (name, "braid")))
246+ opc = str_microblaze_64;
247+ else
248+ opc = NULL;
249 relax_substateT subtype;
250
251 if (exp.X_md != 0)
252@@ -1860,27 +1893,54 @@ md_assemble (char * str)
253 immed = exp.X_add_number;
254 }
255
256+ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
257+ streq (name, "breaid") ||
258+ streq (name, "brai") || streq (name, "braid")))
259+ {
260+ temp = immed & 0xFFFFFF8000;
261+ if (temp != 0)
262+ {
263+ /* Needs an immediate inst. */
264+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
265+ if (opcode1 == NULL)
266+ {
267+ as_bad (_("unknown opcode \"%s\""), "imml");
268+ return;
269+ }
270
271- temp = immed & 0xFFFF8000;
272- if ((temp != 0) && (temp != 0xFFFF8000))
273- {
274- /* Needs an immediate inst. */
275- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
276- if (opcode1 == NULL)
277- {
278- as_bad (_("unknown opcode \"%s\""), "imm");
279- return;
280+ inst1 = opcode1->bit_sequence;
281+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
282+ output[0] = INST_BYTE0 (inst1);
283+ output[1] = INST_BYTE1 (inst1);
284+ output[2] = INST_BYTE2 (inst1);
285+ output[3] = INST_BYTE3 (inst1);
286+ output = frag_more (isize);
287 }
288+ inst |= (immed << IMM_LOW) & IMM_MASK;
289+ }
290+ else
291+ {
292+ temp = immed & 0xFFFF8000;
293+ if ((temp != 0) && (temp != 0xFFFF8000))
294+ {
295+ /* Needs an immediate inst. */
296+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
297+ if (opcode1 == NULL)
298+ {
299+ as_bad (_("unknown opcode \"%s\""), "imm");
300+ return;
301+ }
302
303- inst1 = opcode1->bit_sequence;
304- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
305- output[0] = INST_BYTE0 (inst1);
306- output[1] = INST_BYTE1 (inst1);
307- output[2] = INST_BYTE2 (inst1);
308- output[3] = INST_BYTE3 (inst1);
309- output = frag_more (isize);
310- }
311- inst |= (immed << IMM_LOW) & IMM_MASK;
312+ inst1 = opcode1->bit_sequence;
313+ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
314+ output[0] = INST_BYTE0 (inst1);
315+ output[1] = INST_BYTE1 (inst1);
316+ output[2] = INST_BYTE2 (inst1);
317+ output[3] = INST_BYTE3 (inst1);
318+ output = frag_more (isize);
319+ }
320+ inst |= (immed << IMM_LOW) & IMM_MASK;
321+ }
322 break;
323
324 case INST_TYPE_NONE:
325@@ -2460,7 +2520,7 @@ md_apply_fix (fixS * fixP,
326
327 inst1 = opcode1->bit_sequence;
328 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
329- inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
330+ inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK;
331 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
332 fixP->fx_r_type = BFD_RELOC_64;
333 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
334@@ -2628,7 +2688,14 @@ md_estimate_size_before_relax (fragS * fragP,
335 }
336 else
337 {
338- fragP->fr_subtype = UNDEFINED_PC_OFFSET;
339+ if (fragP->fr_opcode != NULL) {
340+ if (streq (fragP->fr_opcode, str_microblaze_64))
341+ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
342+ else
343+ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
344+ }
345+ else
346+ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
347 fragP->fr_var = INST_WORD_SIZE*2;
348 }
349 break;
350@@ -2905,6 +2972,7 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
351 case OPTION_M64:
352 //if (arg != NULL && strcmp (arg, "64") == 0)
353 microblaze_arch_size = 64;
354+ md_pseudo_table[7].poc_val = 8;
355 break;
356 default:
357 return 0;
358diff --git a/gas/tc.h b/gas/tc.h
359index 0a50a6985b..529a73b43b 100644
360--- a/gas/tc.h
361+++ b/gas/tc.h
362@@ -22,7 +22,7 @@
363 /* In theory (mine, at least!) the machine dependent part of the assembler
364 should only have to include one file. This one. -- JF */
365
366-extern const pseudo_typeS md_pseudo_table[];
367+extern pseudo_typeS md_pseudo_table[];
368
369 const char * md_atof (int, char *, int *);
370 int md_parse_option (int, const char *);
371--
3722.17.1
373
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0020-Fixing-the-branch-related-issues.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0020-Fixing-the-branch-related-issues.patch
new file mode 100644
index 00000000..528c9279
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0020-Fixing-the-branch-related-issues.patch
@@ -0,0 +1,25 @@
1From 8375ef893eb327ae4a5dc9207041ffc0e9bc6e2b Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Sun, 30 Sep 2018 17:06:58 +0530
4Subject: [PATCH 20/43] Fixing the branch related issues
5
6---
7 bfd/elf64-microblaze.c | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
11index 54a2461037..e9b3cf3a86 100644
12--- a/bfd/elf64-microblaze.c
13+++ b/bfd/elf64-microblaze.c
14@@ -2532,7 +2532,7 @@ microblaze_elf_check_relocs (bfd * abfd,
15
16 /* PR15323, ref flags aren't set for references in the same
17 object. */
18- h->root.non_ir_ref = 1;
19+ h->root.non_ir_ref_regular = 1;
20 }
21
22 switch (r_type)
23--
242.17.1
25
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0021-Fixed-address-computation-issues-with-64bit-address.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0021-Fixed-address-computation-issues-with-64bit-address.patch
new file mode 100644
index 00000000..d62f0ed2
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0021-Fixed-address-computation-issues-with-64bit-address.patch
@@ -0,0 +1,220 @@
1From 9f13e07180c09f814665676ac6c04cb7a2cd7c11 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Tue, 9 Oct 2018 10:14:22 +0530
4Subject: [PATCH 21/43] - Fixed address computation issues with 64bit address -
5 Fixed imml dissassamble issue
6
7---
8 bfd/bfd-in2.h | 5 +++
9 bfd/elf64-microblaze.c | 14 ++++----
10 gas/config/tc-microblaze.c | 74 +++++++++++++++++++++++++++++++++-----
11 opcodes/microblaze-dis.c | 2 +-
12 4 files changed, 79 insertions(+), 16 deletions(-)
13
14diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
15index de46e78902..33c9cb62d9 100644
16--- a/bfd/bfd-in2.h
17+++ b/bfd/bfd-in2.h
18@@ -5881,6 +5881,11 @@ done here - only used for relaxing */
19 * +done here - only used for relaxing */
20 BFD_RELOC_MICROBLAZE_64,
21
22+/* This is a 64 bit reloc that stores the 32 bit relative
23+ * +value in two words (with an imml instruction). No relocation is
24+ * +done here - only used for relaxing */
25+ BFD_RELOC_MICROBLAZE_EA64,
26+
27 /* This is a 64 bit reloc that stores the 32 bit pc relative
28 * +value in two words (with an imm instruction). No relocation is
29 * +done here - only used for relaxing */
30diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
31index e9b3cf3a86..40f10aac6d 100644
32--- a/bfd/elf64-microblaze.c
33+++ b/bfd/elf64-microblaze.c
34@@ -121,15 +121,15 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
35 0, /* Rightshift. */
36 4, /* Size (0 = byte, 1 = short, 2 = long). */
37 64, /* Bitsize. */
38- TRUE, /* PC_relative. */
39+ FALSE, /* PC_relative. */
40 0, /* Bitpos. */
41 complain_overflow_dont, /* Complain on overflow. */
42 bfd_elf_generic_reloc,/* Special Function. */
43 "R_MICROBLAZE_IMML_64", /* Name. */
44 FALSE, /* Partial Inplace. */
45 0, /* Source Mask. */
46- 0x0000ffff, /* Dest Mask. */
47- TRUE), /* PC relative offset? */
48+ 0xffffffffffffff, /* Dest Mask. */
49+ FALSE), /* PC relative offset? */
50
51 /* A 64 bit relocation. Table entry not really used. */
52 HOWTO (R_MICROBLAZE_64, /* Type. */
53@@ -585,9 +585,9 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
54 case BFD_RELOC_32:
55 microblaze_reloc = R_MICROBLAZE_32;
56 break;
57- /* RVA is treated the same as 32 */
58+ /* RVA is treated the same as 64 */
59 case BFD_RELOC_RVA:
60- microblaze_reloc = R_MICROBLAZE_32;
61+ microblaze_reloc = R_MICROBLAZE_IMML_64;
62 break;
63 case BFD_RELOC_32_PCREL:
64 microblaze_reloc = R_MICROBLAZE_32_PCREL;
65@@ -619,7 +619,7 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
66 case BFD_RELOC_VTABLE_ENTRY:
67 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
68 break;
69- case BFD_RELOC_MICROBLAZE_64:
70+ case BFD_RELOC_MICROBLAZE_EA64:
71 microblaze_reloc = R_MICROBLAZE_IMML_64;
72 break;
73 case BFD_RELOC_MICROBLAZE_64_GOTPC:
74@@ -1969,7 +1969,7 @@ microblaze_elf_relax_section (bfd *abfd,
75 efix = calc_fixup (target_address, 0, sec);
76
77 /* Validate the in-band val. */
78- val = bfd_get_32 (abfd, contents + irel->r_offset);
79+ val = bfd_get_64 (abfd, contents + irel->r_offset);
80 if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
81 fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
82 }
83diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
84index fa437b6c98..46df32e72f 100644
85--- a/gas/config/tc-microblaze.c
86+++ b/gas/config/tc-microblaze.c
87@@ -402,7 +402,6 @@ pseudo_typeS md_pseudo_table[] =
88 {"ent", s_func, 0}, /* Treat ent as function entry point. */
89 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
90 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
91- {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
92 {"weakext", microblaze_s_weakext, 0},
93 {"rodata", microblaze_s_rdata, 0},
94 {"sdata2", microblaze_s_rdata, 1},
95@@ -2479,18 +2478,74 @@ md_apply_fix (fixS * fixP,
96 case BFD_RELOC_RVA:
97 case BFD_RELOC_32_PCREL:
98 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
99+ /* Don't do anything if the symbol is not defined. */
100+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
101+ {
102+ if ((fixP->fx_r_type == BFD_RELOC_RVA) && (microblaze_arch_size == 64))
103+ {
104+ if (target_big_endian)
105+ {
106+ buf[0] |= ((val >> 56) & 0xff);
107+ buf[1] |= ((val >> 48) & 0xff);
108+ buf[2] |= ((val >> 40) & 0xff);
109+ buf[3] |= ((val >> 32) & 0xff);
110+ buf[4] |= ((val >> 24) & 0xff);
111+ buf[5] |= ((val >> 16) & 0xff);
112+ buf[6] |= ((val >> 8) & 0xff);
113+ buf[7] |= (val & 0xff);
114+ }
115+ else
116+ {
117+ buf[7] |= ((val >> 56) & 0xff);
118+ buf[6] |= ((val >> 48) & 0xff);
119+ buf[5] |= ((val >> 40) & 0xff);
120+ buf[4] |= ((val >> 32) & 0xff);
121+ buf[3] |= ((val >> 24) & 0xff);
122+ buf[2] |= ((val >> 16) & 0xff);
123+ buf[1] |= ((val >> 8) & 0xff);
124+ buf[0] |= (val & 0xff);
125+ }
126+ }
127+ else {
128+ if (target_big_endian)
129+ {
130+ buf[0] |= ((val >> 24) & 0xff);
131+ buf[1] |= ((val >> 16) & 0xff);
132+ buf[2] |= ((val >> 8) & 0xff);
133+ buf[3] |= (val & 0xff);
134+ }
135+ else
136+ {
137+ buf[3] |= ((val >> 24) & 0xff);
138+ buf[2] |= ((val >> 16) & 0xff);
139+ buf[1] |= ((val >> 8) & 0xff);
140+ buf[0] |= (val & 0xff);
141+ }
142+ }
143+ }
144+ break;
145+
146+ case BFD_RELOC_MICROBLAZE_EA64:
147 /* Don't do anything if the symbol is not defined. */
148 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
149 {
150 if (target_big_endian)
151 {
152- buf[0] |= ((val >> 24) & 0xff);
153- buf[1] |= ((val >> 16) & 0xff);
154- buf[2] |= ((val >> 8) & 0xff);
155- buf[3] |= (val & 0xff);
156+ buf[0] |= ((val >> 56) & 0xff);
157+ buf[1] |= ((val >> 48) & 0xff);
158+ buf[2] |= ((val >> 40) & 0xff);
159+ buf[3] |= ((val >> 32) & 0xff);
160+ buf[4] |= ((val >> 24) & 0xff);
161+ buf[5] |= ((val >> 16) & 0xff);
162+ buf[6] |= ((val >> 8) & 0xff);
163+ buf[7] |= (val & 0xff);
164 }
165 else
166 {
167+ buf[7] |= ((val >> 56) & 0xff);
168+ buf[6] |= ((val >> 48) & 0xff);
169+ buf[5] |= ((val >> 40) & 0xff);
170+ buf[4] |= ((val >> 32) & 0xff);
171 buf[3] |= ((val >> 24) & 0xff);
172 buf[2] |= ((val >> 16) & 0xff);
173 buf[1] |= ((val >> 8) & 0xff);
174@@ -2611,6 +2666,8 @@ md_apply_fix (fixS * fixP,
175 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
176 else if (fixP->fx_r_type == BFD_RELOC_32)
177 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
178+ else if(fixP->fx_r_type == BFD_RELOC_MICROBLAZE_EA64)
179+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_EA64;
180 else
181 fixP->fx_r_type = BFD_RELOC_NONE;
182 fixP->fx_addsy = section_symbol (absolute_section);
183@@ -2882,6 +2939,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
184 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
185 case BFD_RELOC_MICROBLAZE_64_GOTPC:
186 case BFD_RELOC_MICROBLAZE_64_GPC:
187+ case BFD_RELOC_MICROBLAZE_EA64:
188 case BFD_RELOC_MICROBLAZE_64:
189 case BFD_RELOC_MICROBLAZE_64_PCREL:
190 case BFD_RELOC_MICROBLAZE_64_GOT:
191@@ -3027,10 +3085,10 @@ cons_fix_new_microblaze (fragS * frag,
192 r = BFD_RELOC_32;
193 break;
194 case 8:
195- if (microblaze_arch_size == 64)
196+ /*if (microblaze_arch_size == 64)
197 r = BFD_RELOC_32;
198- else
199- r = BFD_RELOC_64;
200+ else*/
201+ r = BFD_RELOC_MICROBLAZE_EA64;
202 break;
203 default:
204 as_bad (_("unsupported BFD relocation size %u"), size);
205diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
206index 20ea6a885a..f679a43606 100644
207--- a/opcodes/microblaze-dis.c
208+++ b/opcodes/microblaze-dis.c
209@@ -61,7 +61,7 @@ get_field_imml (long instr)
210 {
211 char tmpstr[25];
212
213- sprintf (tmpstr, "%d", (short)((instr & IMML_MASK) >> IMM_LOW));
214+ sprintf (tmpstr, "%d", (int)((instr & IMML_MASK) >> IMM_LOW));
215 return (strdup (tmpstr));
216 }
217
218--
2192.17.1
220
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0022-Adding-new-relocation-to-support-64bit-rodata.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0022-Adding-new-relocation-to-support-64bit-rodata.patch
new file mode 100644
index 00000000..ec82926d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0022-Adding-new-relocation-to-support-64bit-rodata.patch
@@ -0,0 +1,166 @@
1From beeceebb05a4eeaeca697f4ba7e214485b10369a Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Sat, 13 Oct 2018 21:17:01 +0530
4Subject: [PATCH 22/43] Adding new relocation to support 64bit rodata
5
6---
7 bfd/elf64-microblaze.c | 11 +++++++--
8 gas/config/tc-microblaze.c | 49 ++++++++++++++++++++++++++++++++++----
9 2 files changed, 54 insertions(+), 6 deletions(-)
10
11diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
12index 40f10aac6d..4d9b90647f 100644
13--- a/bfd/elf64-microblaze.c
14+++ b/bfd/elf64-microblaze.c
15@@ -1461,6 +1461,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
16 case (int) R_MICROBLAZE_64_PCREL :
17 case (int) R_MICROBLAZE_64:
18 case (int) R_MICROBLAZE_32:
19+ case (int) R_MICROBLAZE_IMML_64:
20 {
21 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
22 from removed linkonce sections, or sections discarded by
23@@ -1470,6 +1471,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
24 relocation += addend;
25 if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
26 bfd_put_32 (input_bfd, relocation, contents + offset);
27+ else if (r_type == R_MICROBLAZE_IMML_64)
28+ bfd_put_64 (input_bfd, relocation, contents + offset);
29 else
30 {
31 if (r_type == R_MICROBLAZE_64_PCREL)
32@@ -1547,7 +1550,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
33 }
34 else
35 {
36- if (r_type == R_MICROBLAZE_32)
37+ if (r_type == R_MICROBLAZE_32 || r_type == R_MICROBLAZE_IMML_64)
38 {
39 outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
40 outrel.r_addend = relocation + addend;
41@@ -1573,6 +1576,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
42 relocation += addend;
43 if (r_type == R_MICROBLAZE_32)
44 bfd_put_32 (input_bfd, relocation, contents + offset);
45+ else if (r_type == R_MICROBLAZE_IMML_64)
46+ bfd_put_64 (input_bfd, relocation, contents + offset + endian);
47 else
48 {
49 if (r_type == R_MICROBLAZE_64_PCREL)
50@@ -2085,7 +2090,8 @@ microblaze_elf_relax_section (bfd *abfd,
51 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
52 irelscan->r_addend);
53 }
54- if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
55+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32
56+ || ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
57 {
58 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
59
60@@ -2591,6 +2597,7 @@ microblaze_elf_check_relocs (bfd * abfd,
61 case R_MICROBLAZE_64:
62 case R_MICROBLAZE_64_PCREL:
63 case R_MICROBLAZE_32:
64+ case R_MICROBLAZE_IMML_64:
65 {
66 if (h != NULL && !bfd_link_pic (info))
67 {
68diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
69index 46df32e72f..c6d2e4c82d 100644
70--- a/gas/config/tc-microblaze.c
71+++ b/gas/config/tc-microblaze.c
72@@ -1119,6 +1119,13 @@ md_assemble (char * str)
73 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
74 if(streq (name, "lli") || streq (name, "sli"))
75 opc = str_microblaze_64;
76+ else if ((microblaze_arch_size == 64) && ((streq (name, "lbui")
77+ || streq (name, "lhui") || streq (name, "lwi") || streq (name, "sbi")
78+ || streq (name, "shi") || streq (name, "swi"))))
79+ {
80+ opc = str_microblaze_64;
81+ subtype = opcode->inst_offset_type;
82+ }
83 else if (reg2 == REG_ROSDP)
84 opc = str_microblaze_ro_anchor;
85 else if (reg2 == REG_RWSDP)
86@@ -1182,7 +1189,10 @@ md_assemble (char * str)
87 inst |= (immed << IMM_LOW) & IMM_MASK;
88 }
89 }
90- else if (streq (name, "lli") || streq (name, "sli"))
91+ else if (streq (name, "lli") || streq (name, "sli") || ((microblaze_arch_size == 64)
92+ && ((streq (name, "lbui")) || streq (name, "lhui")
93+ || streq (name, "lwi") || streq (name, "sbi")
94+ || streq (name, "shi") || streq (name, "swi"))))
95 {
96 temp = immed & 0xFFFFFF8000;
97 if (temp != 0 && temp != 0xFFFFFF8000)
98@@ -1794,6 +1804,11 @@ md_assemble (char * str)
99
100 if (exp.X_md != 0)
101 subtype = get_imm_otype(exp.X_md);
102+ else if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
103+ {
104+ opc = str_microblaze_64;
105+ subtype = opcode->inst_offset_type;
106+ }
107 else
108 subtype = opcode->inst_offset_type;
109
110@@ -1811,6 +1826,31 @@ md_assemble (char * str)
111 output = frag_more (isize);
112 immed = exp.X_add_number;
113 }
114+ if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
115+ {
116+ temp = immed & 0xFFFFFF8000;
117+ if (temp != 0 && temp != 0xFFFFFF8000)
118+ {
119+ /* Needs an immediate inst. */
120+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
121+ if (opcode1 == NULL)
122+ {
123+ as_bad (_("unknown opcode \"%s\""), "imml");
124+ return;
125+ }
126+ inst1 = opcode1->bit_sequence;
127+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
128+ output[0] = INST_BYTE0 (inst1);
129+ output[1] = INST_BYTE1 (inst1);
130+ output[2] = INST_BYTE2 (inst1);
131+ output[3] = INST_BYTE3 (inst1);
132+ output = frag_more (isize);
133+ }
134+ inst |= (reg1 << RD_LOW) & RD_MASK;
135+ inst |= (immed << IMM_LOW) & IMM_MASK;
136+ }
137+ else
138+ {
139
140 temp = immed & 0xFFFF8000;
141 if ((temp != 0) && (temp != 0xFFFF8000))
142@@ -1834,6 +1874,7 @@ md_assemble (char * str)
143
144 inst |= (reg1 << RD_LOW) & RD_MASK;
145 inst |= (immed << IMM_LOW) & IMM_MASK;
146+ }
147 break;
148
149 case INST_TYPE_R2:
150@@ -3085,10 +3126,10 @@ cons_fix_new_microblaze (fragS * frag,
151 r = BFD_RELOC_32;
152 break;
153 case 8:
154- /*if (microblaze_arch_size == 64)
155- r = BFD_RELOC_32;
156- else*/
157+ if (microblaze_arch_size == 64)
158 r = BFD_RELOC_MICROBLAZE_EA64;
159+ else
160+ r = BFD_RELOC_64;
161 break;
162 default:
163 as_bad (_("unsupported BFD relocation size %u"), size);
164--
1652.17.1
166
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0023-fixing-the-.bss-relocation-issue.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0023-fixing-the-.bss-relocation-issue.patch
new file mode 100644
index 00000000..d1ec5dbf
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0023-fixing-the-.bss-relocation-issue.patch
@@ -0,0 +1,76 @@
1From 3f031961082caec9e172ff0224a51c08ab6e19c3 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Wed, 24 Oct 2018 12:34:37 +0530
4Subject: [PATCH 23/43] fixing the .bss relocation issue
5
6---
7 bfd/elf64-microblaze.c | 18 ++++++++++++------
8 1 file changed, 12 insertions(+), 6 deletions(-)
9
10diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
11index 4d9b90647f..184b7d560d 100644
12--- a/bfd/elf64-microblaze.c
13+++ b/bfd/elf64-microblaze.c
14@@ -1480,7 +1480,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
15 + input_section->output_offset
16 + offset + INST_WORD_SIZE);
17 unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
18- if (insn == 0xb2000000 || insn == 0xb2ffffff)
19+ if ((insn & 0xff000000) == 0xb2000000)
20 {
21 insn &= ~0x00ffffff;
22 insn |= (relocation >> 16) & 0xffffff;
23@@ -1593,7 +1593,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
24 + offset + INST_WORD_SIZE);
25 }
26 unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
27- if (insn == 0xb2000000 || insn == 0xb2ffffff)
28+ if ((insn & 0xff000000) == 0xb2000000)
29 {
30 insn &= ~0x00ffffff;
31 insn |= (relocation >> 16) & 0xffffff;
32@@ -1722,7 +1722,7 @@ microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
33 {
34 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
35
36- if (instr == 0xb2000000 || instr == 0xb2ffffff)
37+ if ((instr & 0xff000000) == 0xb2000000)
38 {
39 instr &= ~0x00ffffff;
40 instr |= (val & 0xffffff);
41@@ -1745,7 +1745,7 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
42 unsigned long instr_lo;
43
44 instr_hi = bfd_get_32 (abfd, bfd_addr);
45- if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff)
46+ if ((instr_hi & 0xff000000) == 0xb2000000)
47 {
48 instr_hi &= ~0x00ffffff;
49 instr_hi |= (val >> 16) & 0xffffff;
50@@ -2238,7 +2238,10 @@ microblaze_elf_relax_section (bfd *abfd,
51 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
52 + irelscan->r_offset
53 + INST_WORD_SIZE);
54- immediate = (instr_hi & 0x0000ffff) << 16;
55+ if ((instr_hi & 0xff000000) == 0xb2000000)
56+ immediate = (instr_hi & 0x00ffffff) << 24;
57+ else
58+ immediate = (instr_hi & 0x0000ffff) << 16;
59 immediate |= (instr_lo & 0x0000ffff);
60 offset = calc_fixup (irelscan->r_addend, 0, sec);
61 immediate -= offset;
62@@ -2282,7 +2285,10 @@ microblaze_elf_relax_section (bfd *abfd,
63 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
64 + irelscan->r_offset
65 + INST_WORD_SIZE);
66- immediate = (instr_hi & 0x0000ffff) << 16;
67+ if ((instr_hi & 0xff000000) == 0xb2000000)
68+ immediate = (instr_hi & 0x00ffffff) << 24;
69+ else
70+ immediate = (instr_hi & 0x0000ffff) << 16;
71 immediate |= (instr_lo & 0x0000ffff);
72 target_address = immediate;
73 offset = calc_fixup (target_address, 0, sec);
74--
752.17.1
76
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch
new file mode 100644
index 00000000..20752939
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch
@@ -0,0 +1,44 @@
1From 843b73643718b0776462bce6aba6b2c6fdb33d85 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Wed, 28 Nov 2018 14:00:29 +0530
4Subject: [PATCH 24/43] Fixed the bug in the R_MICROBLAZE_64_NONE relocation.
5 It was adjusting only lower 16bits.
6
7---
8 bfd/elf32-microblaze.c | 4 ++--
9 bfd/elf64-microblaze.c | 4 ++--
10 2 files changed, 4 insertions(+), 4 deletions(-)
11
12diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
13index 035e71f311..2d8c062a42 100644
14--- a/bfd/elf32-microblaze.c
15+++ b/bfd/elf32-microblaze.c
16@@ -2022,8 +2022,8 @@ microblaze_elf_relax_section (bfd *abfd,
17 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
18 efix = calc_fixup (target_address, 0, sec);
19 irel->r_addend -= (efix - sfix);
20- microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
21- + INST_WORD_SIZE, irel->r_addend);
22+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
23+ irel->r_addend);
24 }
25 break;
26 }
27diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
28index 184b7d560d..ef6a87062b 100644
29--- a/bfd/elf64-microblaze.c
30+++ b/bfd/elf64-microblaze.c
31@@ -2017,8 +2017,8 @@ microblaze_elf_relax_section (bfd *abfd,
32 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
33 efix = calc_fixup (target_address, 0, sec);
34 irel->r_addend -= (efix - sfix);
35- microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
36- + INST_WORD_SIZE, irel->r_addend);
37+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
38+ irel->r_addend);
39 }
40 break;
41 }
42--
432.17.1
44
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch
new file mode 100644
index 00000000..50179787
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch
@@ -0,0 +1,68 @@
1From 3a5e6a9c614c3f6abcf8bf853527ef07a5370f80 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Sun, 2 Dec 2018 14:49:14 +0530
4Subject: [PATCH 25/43] [Patch,MicroBlaze]: fixed Build issue which are due to
5 conflicts in patches.
6
7---
8 bfd/elf32-microblaze.c | 1 +
9 bfd/elf64-microblaze.c | 12 ++++++------
10 gas/config/tc-microblaze.c | 4 ++--
11 3 files changed, 9 insertions(+), 8 deletions(-)
12
13diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
14index 2d8c062a42..6a795c5069 100644
15--- a/bfd/elf32-microblaze.c
16+++ b/bfd/elf32-microblaze.c
17@@ -1996,6 +1996,7 @@ microblaze_elf_relax_section (bfd *abfd,
18 /* This was a PC-relative instruction that was
19 completely resolved. */
20 int sfix, efix;
21+ unsigned int val;
22 bfd_vma target_address;
23 target_address = irel->r_addend + irel->r_offset;
24 sfix = calc_fixup (irel->r_offset, 0, sec);
25diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
26index ef6a87062b..bed534e7dd 100644
27--- a/bfd/elf64-microblaze.c
28+++ b/bfd/elf64-microblaze.c
29@@ -2854,14 +2854,14 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
30 /* If this is a weak symbol, and there is a real definition, the
31 processor independent code will have arranged for us to see the
32 real definition first, and we can just use the same value. */
33- if (h->u.weakdef != NULL)
34+ if (h->is_weakalias)
35 {
36- BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
37- || h->u.weakdef->root.type == bfd_link_hash_defweak);
38- h->root.u.def.section = h->u.weakdef->root.u.def.section;
39- h->root.u.def.value = h->u.weakdef->root.u.def.value;
40+ struct elf_link_hash_entry *def = weakdef (h);
41+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
42+ h->root.u.def.section = def->root.u.def.section;
43+ h->root.u.def.value = def->root.u.def.value;
44 return TRUE;
45- }
46+ }
47
48 /* This is a reference to a symbol defined by a dynamic object which
49 is not a function. */
50diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
51index c6d2e4c82d..b3e49f0cf0 100644
52--- a/gas/config/tc-microblaze.c
53+++ b/gas/config/tc-microblaze.c
54@@ -118,9 +118,9 @@ const relax_typeS md_relax_table[] =
55 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
56 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
57 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
58- { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
59+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 18: TEXT_PC_OFFSET. */
60 // { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
61- { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 19: DEFINED_64_OFFSET. */
62+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 }, /* 19: DEFINED_64_OFFSET. */
63 { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
64 };
65
66--
672.17.1
68
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch
new file mode 100644
index 00000000..aef46b3f
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch
@@ -0,0 +1,31 @@
1From e7f43c3afe90faa42c09f368671972c26c2b7b38 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 26 Feb 2019 17:31:41 +0530
4Subject: [PATCH 26/43] [Patch,Microblaze] : changes of "PR22458, failure to
5 choose a matching ELF target" is causing "Multiple Prevailing definition
6 errors",added check for best_match elf.
7
8---
9 bfd/format.c | 5 +++++
10 1 file changed, 5 insertions(+)
11
12diff --git a/bfd/format.c b/bfd/format.c
13index 97a92291a8..3a74cc49d2 100644
14--- a/bfd/format.c
15+++ b/bfd/format.c
16@@ -292,7 +292,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
17
18 /* Don't check the default target twice. */
19 if (*target == &binary_vec
20+#if !BFD_SUPPORTS_PLUGINS
21 || (!abfd->target_defaulted && *target == save_targ))
22+#else
23+ || (!abfd->target_defaulted && *target == save_targ)
24+ || (*target)->match_priority > best_match)
25+#endif
26 continue;
27
28 /* If we already tried a match, the bfd is modified and may
29--
302.17.1
31
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state.patch
new file mode 100644
index 00000000..b0fe8231
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state.patch
@@ -0,0 +1,76 @@
1From 69b77a73f4e609883cd7a0946b407becd46bf918 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 27 Feb 2019 15:12:32 +0530
4Subject: [PATCH 27/43] Revert "ld: Remove unused expression state"
5
6This reverts commit 65f14869fd3fbee8ed4c4ca49de8aaa86dbc66cb.
7
8Conflicts:
9 ld/ChangeLog
10---
11 ld/ldexp.c | 8 +++++---
12 ld/ldexp.h | 1 +
13 2 files changed, 6 insertions(+), 3 deletions(-)
14
15diff --git a/ld/ldexp.c b/ld/ldexp.c
16index 60b17ef576..dac4b52450 100644
17--- a/ld/ldexp.c
18+++ b/ld/ldexp.c
19@@ -1354,6 +1354,7 @@ static etree_type *
20 exp_assop (const char *dst,
21 etree_type *src,
22 enum node_tree_enum class,
23+ bfd_boolean defsym,
24 bfd_boolean hidden)
25 {
26 etree_type *n;
27@@ -1365,6 +1366,7 @@ exp_assop (const char *dst,
28 n->assign.type.node_class = class;
29 n->assign.src = src;
30 n->assign.dst = dst;
31+ n->assign.defsym = defsym;
32 n->assign.hidden = hidden;
33 return n;
34 }
35@@ -1374,7 +1376,7 @@ exp_assop (const char *dst,
36 etree_type *
37 exp_assign (const char *dst, etree_type *src, bfd_boolean hidden)
38 {
39- return exp_assop (dst, src, etree_assign, hidden);
40+ return exp_assop (dst, src, etree_assign, FALSE, hidden);
41 }
42
43 /* Handle --defsym command-line option. */
44@@ -1382,7 +1384,7 @@ exp_assign (const char *dst, etree_type *src, bfd_boolean hidden)
45 etree_type *
46 exp_defsym (const char *dst, etree_type *src)
47 {
48- return exp_assop (dst, src, etree_assign, FALSE);
49+ return exp_assop (dst, src, etree_assign, TRUE, FALSE);
50 }
51
52 /* Handle PROVIDE. */
53@@ -1390,7 +1392,7 @@ exp_defsym (const char *dst, etree_type *src)
54 etree_type *
55 exp_provide (const char *dst, etree_type *src, bfd_boolean hidden)
56 {
57- return exp_assop (dst, src, etree_provide, hidden);
58+ return exp_assop (dst, src, etree_provide, FALSE, hidden);
59 }
60
61 /* Handle ASSERT. */
62diff --git a/ld/ldexp.h b/ld/ldexp.h
63index 71395bc6c4..f94b00aedb 100644
64--- a/ld/ldexp.h
65+++ b/ld/ldexp.h
66@@ -66,6 +66,7 @@ typedef union etree_union {
67 node_type type;
68 const char *dst;
69 union etree_union *src;
70+ bfd_boolean defsym;
71 bfd_boolean hidden;
72 } assign;
73 struct {
74--
752.17.1
76
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-Microblaze-Binutils-security-check-is-causing-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-Microblaze-Binutils-security-check-is-causing-.patch
new file mode 100644
index 00000000..0fd14f6d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-Microblaze-Binutils-security-check-is-causing-.patch
@@ -0,0 +1,33 @@
1From 282a60ab92e6705853dac30fd38aaf298d7f02b0 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 11 Mar 2019 14:23:58 +0530
4Subject: [PATCH 28/43] [Patch,Microblaze] : Binutils security check is causing
5 build error for windows builds.commenting for now.
6
7---
8 bfd/elf-attrs.c | 2 ++
9 1 file changed, 2 insertions(+)
10
11diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
12index bfe135e7fb..feb5cb37f5 100644
13--- a/bfd/elf-attrs.c
14+++ b/bfd/elf-attrs.c
15@@ -440,6 +440,7 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
16 /* PR 17512: file: 2844a11d. */
17 if (hdr->sh_size == 0)
18 return;
19+ #if 0
20 if (hdr->sh_size > bfd_get_file_size (abfd))
21 {
22 /* xgettext:c-format */
23@@ -448,6 +449,7 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
24 bfd_set_error (bfd_error_invalid_operation);
25 return;
26 }
27+ #endif
28
29 contents = (bfd_byte *) bfd_malloc (hdr->sh_size + 1);
30 if (!contents)
31--
322.17.1
33
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0029-fixing-the-long-long-long-mingw-toolchain-issue.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0029-fixing-the-long-long-long-mingw-toolchain-issue.patch
new file mode 100644
index 00000000..dbafc786
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0029-fixing-the-long-long-long-mingw-toolchain-issue.patch
@@ -0,0 +1,57 @@
1From 26662110955e26c62629f4263a999216dac326ef Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Thu, 29 Nov 2018 17:59:25 +0530
4Subject: [PATCH 29/43] fixing the long & long long mingw toolchain issue
5
6---
7 gas/config/tc-microblaze.c | 10 +++++-----
8 opcodes/microblaze-opc.h | 4 ++--
9 2 files changed, 7 insertions(+), 7 deletions(-)
10
11diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
12index b3e49f0cf0..5b506d3348 100644
13--- a/gas/config/tc-microblaze.c
14+++ b/gas/config/tc-microblaze.c
15@@ -783,7 +783,7 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
16 }
17
18 static char *
19-parse_imml (char * s, expressionS * e, long min, long max)
20+parse_imml (char * s, expressionS * e, long long min, long long max)
21 {
22 char *new_pointer;
23 char *atp;
24@@ -834,11 +834,11 @@ parse_imml (char * s, expressionS * e, long min, long max)
25 ; /* An error message has already been emitted. */
26 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
27 as_fatal (_("operand must be a constant or a label"));
28- else if ((e->X_op == O_constant) && ((long) e->X_add_number < min
29- || (long) e->X_add_number > max))
30+ else if ((e->X_op == O_constant) && ((long long) e->X_add_number < min
31+ || (long long) e->X_add_number > max))
32 {
33- as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"),
34- min, max, (long) e->X_add_number);
35+ as_fatal (_("operand must be absolute in range %lld..%lld, not %lld"),
36+ min, max, (long long) e->X_add_number);
37 }
38
39 if (atp)
40diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
41index 824afc0ab0..d59ee0a95f 100644
42--- a/opcodes/microblaze-opc.h
43+++ b/opcodes/microblaze-opc.h
44@@ -585,8 +585,8 @@ char pvr_register_prefix[] = "rpvr";
45 #define MIN_IMM6_WIDTH ((int) 0x00000001)
46 #define MAX_IMM6_WIDTH ((int) 0x00000040)
47
48-#define MIN_IMML ((long) 0xffffff8000000000L)
49-#define MAX_IMML ((long) 0x0000007fffffffffL)
50+#define MIN_IMML ((long long) 0xffffff8000000000L)
51+#define MAX_IMML ((long long) 0x0000007fffffffffL)
52
53 #endif /* MICROBLAZE_OPC */
54
55--
562.17.1
57
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch
new file mode 100644
index 00000000..8141095a
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0030-Added-support-to-new-arithmetic-single-register-inst.patch
@@ -0,0 +1,359 @@
1From 7b332d61cb3dbcae69021ce706f2c408c85af193 Mon Sep 17 00:00:00 2001
2From: Nagaraju <nmekala@xilinx.com>
3Date: Fri, 23 Aug 2019 16:18:43 +0530
4Subject: [PATCH 30/43] Added support to new arithmetic single register
5 instructions
6
7---
8 gas/config/tc-microblaze.c | 147 ++++++++++++++++++++++++++++++++++++-
9 opcodes/microblaze-dis.c | 12 +++
10 opcodes/microblaze-opc.h | 43 ++++++++++-
11 opcodes/microblaze-opcm.h | 5 +-
12 4 files changed, 201 insertions(+), 6 deletions(-)
13
14diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
15index 5b506d3348..12eef24a29 100644
16--- a/gas/config/tc-microblaze.c
17+++ b/gas/config/tc-microblaze.c
18@@ -423,12 +423,33 @@ void
19 md_begin (void)
20 {
21 struct op_code_struct * opcode;
22+ const char *prev_name = "";
23
24 opcode_hash_control = hash_new ();
25
26 /* Insert unique names into hash table. */
27- for (opcode = opcodes; opcode->name; opcode ++)
28- hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
29+ for (opcode = (struct opcodes *)opcodes; opcode->name; opcode ++)
30+ {
31+ if (strcmp (prev_name, opcode->name))
32+ {
33+ prev_name = (char *) opcode->name;
34+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
35+ }
36+ }
37+}
38+
39+static int
40+is_reg (char * s)
41+{
42+ int is_reg = 0;
43+ /* Strip leading whitespace. */
44+ while (ISSPACE (* s))
45+ ++ s;
46+ if (TOLOWER (s[0]) == 'r')
47+ {
48+ is_reg =1;
49+ }
50+ return is_reg;
51 }
52
53 /* Try to parse a reg name. */
54@@ -986,6 +1007,7 @@ md_assemble (char * str)
55 {
56 char * op_start;
57 char * op_end;
58+ char * temp_op_end;
59 struct op_code_struct * opcode, *opcode1;
60 char * output = NULL;
61 int nlen = 0;
62@@ -996,9 +1018,10 @@ md_assemble (char * str)
63 unsigned reg3;
64 unsigned isize;
65 unsigned long immed, immed2, temp;
66- expressionS exp;
67+ expressionS exp,exp1;
68 char name[20];
69 long immedl;
70+ int reg=0;
71
72 /* Drop leading whitespace. */
73 while (ISSPACE (* str))
74@@ -1029,7 +1052,78 @@ md_assemble (char * str)
75 as_bad (_("unknown opcode \"%s\""), name);
76 return;
77 }
78-
79+
80+ if ((microblaze_arch_size == 64) && (streq (name, "addli") || streq (name, "addlic") ||
81+ streq (name, "addlik") || streq (name, "addlikc") || streq (name, "rsubli")
82+ || streq (name, "rsublic") || streq (name, "rsublik") || streq (name, "rsublikc")
83+ || streq (name, "andli") || streq (name, "andnli") || streq (name, "orli")
84+ || streq (name, "xorli")))
85+ {
86+ temp_op_end = op_end;
87+ if (strcmp (temp_op_end, ""))
88+ temp_op_end = parse_reg (temp_op_end + 1, &reg1); /* Get rd. */
89+ if (strcmp (temp_op_end, ""))
90+ reg = is_reg (temp_op_end + 1);
91+ if (reg)
92+ {
93+
94+ opcode->inst_type=INST_TYPE_RD_R1_IMML;
95+ opcode->inst_offset_type = OPCODE_MASK_H;
96+ if (streq (name, "addli"))
97+ opcode->bit_sequence = ADDLI_MASK;
98+ else if (streq (name, "addlic"))
99+ opcode->bit_sequence = ADDLIC_MASK;
100+ else if (streq (name, "addlik"))
101+ opcode->bit_sequence = ADDLIK_MASK;
102+ else if (streq (name, "addlikc"))
103+ opcode->bit_sequence = ADDLIKC_MASK;
104+ else if (streq (name, "rsubli"))
105+ opcode->bit_sequence = RSUBLI_MASK;
106+ else if (streq (name, "rsublic"))
107+ opcode->bit_sequence = RSUBLIC_MASK;
108+ else if (streq (name, "rsublik"))
109+ opcode->bit_sequence = RSUBLIK_MASK;
110+ else if (streq (name, "rsublikc"))
111+ opcode->bit_sequence = RSUBLIKC_MASK;
112+ else if (streq (name, "andli"))
113+ opcode->bit_sequence = ANDLI_MASK;
114+ else if (streq (name, "andnli"))
115+ opcode->bit_sequence = ANDLNI_MASK;
116+ else if (streq (name, "orli"))
117+ opcode->bit_sequence = ORLI_MASK;
118+ else if (streq (name, "xorli"))
119+ opcode->bit_sequence = XORLI_MASK;
120+ }
121+ else
122+ {
123+ opcode->inst_type=INST_TYPE_RD_IMML;
124+ opcode->inst_offset_type = OPCODE_MASK_LIMM;
125+ if (streq (name, "addli"))
126+ opcode->bit_sequence = ADDLI_ONE_REG_MASK;
127+ else if (streq (name, "addlic"))
128+ opcode->bit_sequence = ADDLIC_ONE_REG_MASK;
129+ else if (streq (name, "addlik"))
130+ opcode->bit_sequence = ADDLIK_ONE_REG_MASK;
131+ else if (streq (name, "addlikc"))
132+ opcode->bit_sequence = ADDLIKC_ONE_REG_MASK;
133+ else if (streq (name, "rsubli"))
134+ opcode->bit_sequence = RSUBLI_ONE_REG_MASK;
135+ else if (streq (name, "rsublic"))
136+ opcode->bit_sequence = RSUBLIC_ONE_REG_MASK;
137+ else if (streq (name, "rsublik"))
138+ opcode->bit_sequence = RSUBLIK_ONE_REG_MASK;
139+ else if (streq (name, "rsublikc"))
140+ opcode->bit_sequence = RSUBLIKC_ONE_REG_MASK;
141+ else if (streq (name, "andli"))
142+ opcode->bit_sequence = ANDLI_ONE_REG_MASK;
143+ else if (streq (name, "andnli"))
144+ opcode->bit_sequence = ANDLNI_ONE_REG_MASK;
145+ else if (streq (name, "orli"))
146+ opcode->bit_sequence = ORLI_ONE_REG_MASK;
147+ else if (streq (name, "xorli"))
148+ opcode->bit_sequence = XORLI_ONE_REG_MASK;
149+ }
150+ }
151 inst = opcode->bit_sequence;
152 isize = 4;
153
154@@ -1480,6 +1574,51 @@ md_assemble (char * str)
155 inst |= (immed << IMM_LOW) & IMM15_MASK;
156 break;
157
158+ case INST_TYPE_RD_IMML:
159+ if (strcmp (op_end, ""))
160+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
161+ else
162+ {
163+ as_fatal (_("Error in statement syntax"));
164+ reg1 = 0;
165+ }
166+
167+ if (strcmp (op_end, ""))
168+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
169+ else
170+ as_fatal (_("Error in statement syntax"));
171+
172+ /* Check for spl registers. */
173+ if (check_spl_reg (&reg1))
174+ as_fatal (_("Cannot use special register with this instruction"));
175+ if (exp.X_op != O_constant)
176+ {
177+ char *opc = NULL;
178+ relax_substateT subtype;
179+
180+ if (exp.X_md != 0)
181+ subtype = get_imm_otype(exp.X_md);
182+ else
183+ subtype = opcode->inst_offset_type;
184+
185+ output = frag_var (rs_machine_dependent,
186+ isize * 2,
187+ isize * 2,
188+ subtype,
189+ exp.X_add_symbol,
190+ exp.X_add_number,
191+ (char *) opc);
192+ immedl = 0L;
193+ }
194+ else
195+ {
196+ output = frag_more (isize);
197+ immed = exp.X_add_number;
198+ }
199+ inst |= (reg1 << RD_LOW) & RD_MASK;
200+ inst |= (immed << IMM_LOW) & IMM16_MASK;
201+ break;
202+
203 case INST_TYPE_R1_RFSL:
204 if (strcmp (op_end, ""))
205 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
206diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
207index f679a43606..e5e880cb1c 100644
208--- a/opcodes/microblaze-dis.c
209+++ b/opcodes/microblaze-dis.c
210@@ -114,6 +114,15 @@ get_field_imm15 (long instr)
211 return (strdup (tmpstr));
212 }
213
214+static char *
215+get_field_imm16 (long instr)
216+{
217+ char tmpstr[25];
218+
219+ sprintf (tmpstr, "%d", (short)((instr & IMM16_MASK) >> IMM_LOW));
220+ return (strdup (tmpstr));
221+}
222+
223 static char *
224 get_field_special (long instr, struct op_code_struct * op)
225 {
226@@ -419,6 +428,9 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
227 case INST_TYPE_RD_IMM15:
228 print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm15 (inst));
229 break;
230+ case INST_TYPE_RD_IMML:
231+ print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm16 (inst));
232+ break;
233 /* For mbar insn. */
234 case INST_TYPE_IMM5:
235 print_func (stream, "\t%s", get_field_imm5_mbar (inst));
236diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
237index d59ee0a95f..0774f70e08 100644
238--- a/opcodes/microblaze-opc.h
239+++ b/opcodes/microblaze-opc.h
240@@ -69,6 +69,7 @@
241 #define INST_TYPE_RD_R1_IMMW_IMMS 21
242
243 #define INST_TYPE_NONE 25
244+#define INST_TYPE_RD_IMML 26
245
246
247
248@@ -84,6 +85,7 @@
249 #define IMMVAL_MASK_MFS 0x0000
250
251 #define OPCODE_MASK_H 0xFC000000 /* High 6 bits only. */
252+#define OPCODE_MASK_LIMM 0xFC1F0000 /* High 6 bits and 12-16 bits */
253 #define OPCODE_MASK_H1 0xFFE00000 /* High 11 bits. */
254 #define OPCODE_MASK_H2 0xFC1F0000 /* High 6 and bits 20-16. */
255 #define OPCODE_MASK_H12 0xFFFF0000 /* High 16. */
256@@ -106,6 +108,33 @@
257 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
258 #define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */
259
260+/*Defines to identify 64-bit single reg instructions */
261+#define ADDLI_ONE_REG_MASK 0x68000000
262+#define ADDLIC_ONE_REG_MASK 0x68020000
263+#define ADDLIK_ONE_REG_MASK 0x68040000
264+#define ADDLIKC_ONE_REG_MASK 0x68060000
265+#define RSUBLI_ONE_REG_MASK 0x68010000
266+#define RSUBLIC_ONE_REG_MASK 0x68030000
267+#define RSUBLIK_ONE_REG_MASK 0x68050000
268+#define RSUBLIKC_ONE_REG_MASK 0x68070000
269+#define ORLI_ONE_REG_MASK 0x68100000
270+#define ANDLI_ONE_REG_MASK 0x68110000
271+#define XORLI_ONE_REG_MASK 0x68120000
272+#define ANDLNI_ONE_REG_MASK 0x68130000
273+#define ADDLI_MASK 0x20000000
274+#define ADDLIC_MASK 0x28000000
275+#define ADDLIK_MASK 0x30000000
276+#define ADDLIKC_MASK 0x38000000
277+#define RSUBLI_MASK 0x24000000
278+#define RSUBLIC_MASK 0x2C000000
279+#define RSUBLIK_MASK 0x34000000
280+#define RSUBLIKC_MASK 0x3C000000
281+#define ANDLI_MASK 0xA4000000
282+#define ANDLNI_MASK 0xAC000000
283+#define ORLI_MASK 0xA0000000
284+#define XORLI_MASK 0xA8000000
285+
286+
287 /* New Mask for msrset, msrclr insns. */
288 #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
289 /* Mask for mbar insn. */
290@@ -114,7 +143,7 @@
291 #define DELAY_SLOT 1
292 #define NO_DELAY_SLOT 0
293
294-#define MAX_OPCODES 412
295+#define MAX_OPCODES 424
296
297 struct op_code_struct
298 {
299@@ -444,13 +473,21 @@ struct op_code_struct
300 {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst },
301 {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst },
302 {"addli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
303+ {"addli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68000000, OPCODE_MASK_LIMM, addli, arithmetic_inst },
304 {"rsubli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
305+ {"rsubli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68010000, OPCODE_MASK_LIMM, rsubli, arithmetic_inst },
306 {"addlic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
307+ {"addlic", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68020000, OPCODE_MASK_LIMM, addlic, arithmetic_inst },
308 {"rsublic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
309+ {"rsublic", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68030000, OPCODE_MASK_LIMM, rsublic, arithmetic_inst },
310 {"addlik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
311+ {"addlik", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68040000, OPCODE_MASK_LIMM, addlik, arithmetic_inst },
312 {"rsublik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
313+ {"rsublik", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68050000, OPCODE_MASK_LIMM, rsublik, arithmetic_inst },
314 {"addlikc", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
315+ {"addlikc", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68060000, OPCODE_MASK_LIMM, addlikc, arithmetic_inst },
316 {"rsublikc",INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
317+ {"rsublikc", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68070000, OPCODE_MASK_LIMM, rsublikc, arithmetic_inst },
318 {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst },
319 {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst },
320 {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst },
321@@ -501,9 +538,13 @@ struct op_code_struct
322 {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst },
323 {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst },
324 {"orli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
325+ {"orli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68100000, OPCODE_MASK_LIMM, orli, arithmetic_inst },
326 {"andli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
327+ {"andli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68110000, OPCODE_MASK_LIMM, andli, arithmetic_inst },
328 {"xorli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
329+ {"xorli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68120000, OPCODE_MASK_LIMM, xorli, arithmetic_inst },
330 {"andnli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
331+ {"andnli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68130000, OPCODE_MASK_LIMM, andnli, arithmetic_inst },
332 {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst },
333 {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst },
334 {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst },
335diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
336index 5f2e190d23..4d2ee2dd0d 100644
337--- a/opcodes/microblaze-opcm.h
338+++ b/opcodes/microblaze-opcm.h
339@@ -61,7 +61,9 @@ enum microblaze_instr
340 eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd,
341
342 /* 64-bit instructions */
343- addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
344+ addl, addli, addlic, addlik, addlikc, rsubl, rsubli, rsublic, rsublik, rsublikc,
345+ addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
346+ andli, andnli, orli, xorli,
347 bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl,
348 andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32,
349 brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned,
350@@ -166,5 +168,6 @@ enum microblaze_instr_type
351
352 /* Imm mask for msrset, msrclr instructions. */
353 #define IMM15_MASK 0x00007FFF
354+#define IMM16_MASK 0x0000FFFF
355
356 #endif /* MICROBLAZE-OPCM */
357--
3582.17.1
359
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0031-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0031-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch
new file mode 100644
index 00000000..f9f0fc55
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0031-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch
@@ -0,0 +1,551 @@
1From 213df2cac38d404619614939de0c9d3dcbf7557d Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 26 Aug 2019 15:29:42 +0530
4Subject: [PATCH 31/43] [Patch,MicroBlaze] : double imml generation for 64 bit
5 values.
6
7---
8 gas/config/tc-microblaze.c | 322 ++++++++++++++++++++++++++++++-------
9 opcodes/microblaze-opc.h | 4 +-
10 2 files changed, 263 insertions(+), 63 deletions(-)
11
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index 12eef24a29..3ff6a14baf 100644
14--- a/gas/config/tc-microblaze.c
15+++ b/gas/config/tc-microblaze.c
16@@ -1008,7 +1008,7 @@ md_assemble (char * str)
17 char * op_start;
18 char * op_end;
19 char * temp_op_end;
20- struct op_code_struct * opcode, *opcode1;
21+ struct op_code_struct * opcode, *opcode1, *opcode2;
22 char * output = NULL;
23 int nlen = 0;
24 int i;
25@@ -1192,7 +1192,12 @@ md_assemble (char * str)
26 reg2 = 0;
27 }
28 if (strcmp (op_end, ""))
29+ {
30+ if(microblaze_arch_size == 64)
31+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
32+ else
33 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
34+ }
35 else
36 as_fatal (_("Error in statement syntax"));
37
38@@ -1288,24 +1293,51 @@ md_assemble (char * str)
39 || streq (name, "lwi") || streq (name, "sbi")
40 || streq (name, "shi") || streq (name, "swi"))))
41 {
42- temp = immed & 0xFFFFFF8000;
43- if (temp != 0 && temp != 0xFFFFFF8000)
44+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
45+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000)
46 {
47 /* Needs an immediate inst. */
48- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
49- if (opcode1 == NULL)
50+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
51+ {
52+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
53+ if (opcode1 == NULL)
54+ {
55+ as_bad (_("unknown opcode \"%s\""), "imml");
56+ return;
57+ }
58+ inst1 = opcode1->bit_sequence;
59+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
60+ output[0] = INST_BYTE0 (inst1);
61+ output[1] = INST_BYTE1 (inst1);
62+ output[2] = INST_BYTE2 (inst1);
63+ output[3] = INST_BYTE3 (inst1);
64+ output = frag_more (isize);
65+ }
66+ else
67+ {
68+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
69+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
70+ if (opcode1 == NULL || opcode2 == NULL)
71 {
72 as_bad (_("unknown opcode \"%s\""), "imml");
73 return;
74 }
75+ inst1 = opcode2->bit_sequence;
76+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
77+ output[0] = INST_BYTE0 (inst1);
78+ output[1] = INST_BYTE1 (inst1);
79+ output[2] = INST_BYTE2 (inst1);
80+ output[3] = INST_BYTE3 (inst1);
81+ output = frag_more (isize);
82 inst1 = opcode1->bit_sequence;
83- inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
84+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
85 output[0] = INST_BYTE0 (inst1);
86 output[1] = INST_BYTE1 (inst1);
87 output[2] = INST_BYTE2 (inst1);
88 output[3] = INST_BYTE3 (inst1);
89 output = frag_more (isize);
90 }
91+ }
92 inst |= (reg1 << RD_LOW) & RD_MASK;
93 inst |= (reg2 << RA_LOW) & RA_MASK;
94 inst |= (immed << IMM_LOW) & IMM_MASK;
95@@ -1316,14 +1348,13 @@ md_assemble (char * str)
96 if ((temp != 0) && (temp != 0xFFFF8000))
97 {
98 /* Needs an immediate inst. */
99- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
100+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
101 if (opcode1 == NULL)
102 {
103 as_bad (_("unknown opcode \"%s\""), "imm");
104 return;
105 }
106-
107- inst1 = opcode1->bit_sequence;
108+ inst1 = opcode1->bit_sequence;
109 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
110 output[0] = INST_BYTE0 (inst1);
111 output[1] = INST_BYTE1 (inst1);
112@@ -1564,7 +1595,7 @@ md_assemble (char * str)
113 as_fatal (_("Cannot use special register with this instruction"));
114
115 if (exp.X_op != O_constant)
116- as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
117+ as_fatal (_("Symbol used as immediate value for arithmetic long instructions"));
118 else
119 {
120 output = frag_more (isize);
121@@ -1898,8 +1929,9 @@ md_assemble (char * str)
122 temp = immed & 0xFFFF8000;
123 if ((temp != 0) && (temp != 0xFFFF8000))
124 {
125+
126 /* Needs an immediate inst. */
127- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
128+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
129 if (opcode1 == NULL)
130 {
131 as_bad (_("unknown opcode \"%s\""), "imm");
132@@ -1928,7 +1960,12 @@ md_assemble (char * str)
133 reg1 = 0;
134 }
135 if (strcmp (op_end, ""))
136+ {
137+ if(microblaze_arch_size == 64)
138+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
139+ else
140 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
141+ }
142 else
143 as_fatal (_("Error in statement syntax"));
144
145@@ -1967,30 +2004,55 @@ md_assemble (char * str)
146 }
147 if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
148 {
149- temp = immed & 0xFFFFFF8000;
150- if (temp != 0 && temp != 0xFFFFFF8000)
151+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
152+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000)
153 {
154 /* Needs an immediate inst. */
155- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
156+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
157+ {
158+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
159 if (opcode1 == NULL)
160 {
161 as_bad (_("unknown opcode \"%s\""), "imml");
162 return;
163 }
164 inst1 = opcode1->bit_sequence;
165- inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
166+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
167 output[0] = INST_BYTE0 (inst1);
168 output[1] = INST_BYTE1 (inst1);
169 output[2] = INST_BYTE2 (inst1);
170 output[3] = INST_BYTE3 (inst1);
171 output = frag_more (isize);
172 }
173+ else {
174+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
175+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
176+ if (opcode1 == NULL || opcode2 == NULL)
177+ {
178+ as_bad (_("unknown opcode \"%s\""), "imml");
179+ return;
180+ }
181+ inst1 = opcode2->bit_sequence;
182+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
183+ output[0] = INST_BYTE0 (inst1);
184+ output[1] = INST_BYTE1 (inst1);
185+ output[2] = INST_BYTE2 (inst1);
186+ output[3] = INST_BYTE3 (inst1);
187+ output = frag_more (isize);
188+ inst1 = opcode1->bit_sequence;
189+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
190+ output[0] = INST_BYTE0 (inst1);
191+ output[1] = INST_BYTE1 (inst1);
192+ output[2] = INST_BYTE2 (inst1);
193+ output[3] = INST_BYTE3 (inst1);
194+ output = frag_more (isize);
195+ }
196+ }
197 inst |= (reg1 << RD_LOW) & RD_MASK;
198 inst |= (immed << IMM_LOW) & IMM_MASK;
199 }
200 else
201 {
202-
203 temp = immed & 0xFFFF8000;
204 if ((temp != 0) && (temp != 0xFFFF8000))
205 {
206@@ -2076,25 +2138,50 @@ md_assemble (char * str)
207 streq (name, "breaid") ||
208 streq (name, "brai") || streq (name, "braid")))
209 {
210- temp = immed & 0xFFFFFF8000;
211+ temp = immed & 0xFFFFFFFFFFFF8000;
212 if (temp != 0)
213 {
214 /* Needs an immediate inst. */
215- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
216+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
217+ {
218+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
219 if (opcode1 == NULL)
220 {
221 as_bad (_("unknown opcode \"%s\""), "imml");
222 return;
223 }
224-
225 inst1 = opcode1->bit_sequence;
226- inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
227+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
228+ output[0] = INST_BYTE0 (inst1);
229+ output[1] = INST_BYTE1 (inst1);
230+ output[2] = INST_BYTE2 (inst1);
231+ output[3] = INST_BYTE3 (inst1);
232+ output = frag_more (isize);
233+ }
234+ else {
235+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
236+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
237+ if (opcode1 == NULL || opcode2 == NULL)
238+ {
239+ as_bad (_("unknown opcode \"%s\""), "imml");
240+ return;
241+ }
242+ inst1 = opcode2->bit_sequence;
243+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
244+ output[0] = INST_BYTE0 (inst1);
245+ output[1] = INST_BYTE1 (inst1);
246+ output[2] = INST_BYTE2 (inst1);
247+ output[3] = INST_BYTE3 (inst1);
248+ output = frag_more (isize);
249+ inst1 = opcode1->bit_sequence;
250+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
251 output[0] = INST_BYTE0 (inst1);
252 output[1] = INST_BYTE1 (inst1);
253 output[2] = INST_BYTE2 (inst1);
254 output[3] = INST_BYTE3 (inst1);
255 output = frag_more (isize);
256 }
257+ }
258 inst |= (immed << IMM_LOW) & IMM_MASK;
259 }
260 else
261@@ -2194,21 +2281,45 @@ md_assemble (char * str)
262 {
263 output = frag_more (isize);
264 immedl = exp.X_add_number;
265-
266- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
267- if (opcode1 == NULL)
268- {
269- as_bad (_("unknown opcode \"%s\""), "imml");
270- return;
271- }
272-
273- inst1 = opcode1->bit_sequence;
274- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
275- output[0] = INST_BYTE0 (inst1);
276- output[1] = INST_BYTE1 (inst1);
277- output[2] = INST_BYTE2 (inst1);
278- output[3] = INST_BYTE3 (inst1);
279- output = frag_more (isize);
280+ if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
281+ {
282+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
283+ if (opcode1 == NULL)
284+ {
285+ as_bad (_("unknown opcode \"%s\""), "imml");
286+ return;
287+ }
288+ inst1 = opcode1->bit_sequence;
289+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
290+ output[0] = INST_BYTE0 (inst1);
291+ output[1] = INST_BYTE1 (inst1);
292+ output[2] = INST_BYTE2 (inst1);
293+ output[3] = INST_BYTE3 (inst1);
294+ output = frag_more (isize);
295+ }
296+ else {
297+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
298+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
299+ if (opcode2 == NULL || opcode1 == NULL)
300+ {
301+ as_bad (_("unknown opcode \"%s\""), "imml");
302+ return;
303+ }
304+ inst1 = opcode2->bit_sequence;
305+ inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
306+ output[0] = INST_BYTE0 (inst1);
307+ output[1] = INST_BYTE1 (inst1);
308+ output[2] = INST_BYTE2 (inst1);
309+ output[3] = INST_BYTE3 (inst1);
310+ output = frag_more (isize);
311+ inst1 = opcode1->bit_sequence;
312+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
313+ output[0] = INST_BYTE0 (inst1);
314+ output[1] = INST_BYTE1 (inst1);
315+ output[2] = INST_BYTE2 (inst1);
316+ output[3] = INST_BYTE3 (inst1);
317+ output = frag_more (isize);
318+ }
319 }
320
321 inst |= (reg1 << RD_LOW) & RD_MASK;
322@@ -2257,21 +2368,46 @@ md_assemble (char * str)
323 {
324 output = frag_more (isize);
325 immedl = exp.X_add_number;
326- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
327- if (opcode1 == NULL)
328- {
329- as_bad (_("unknown opcode \"%s\""), "imml");
330- return;
331- }
332-
333+ if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
334+ {
335+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
336+ if (opcode1 == NULL)
337+ {
338+ as_bad (_("unknown opcode \"%s\""), "imml");
339+ return;
340+ }
341+ inst1 = opcode1->bit_sequence;
342+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
343+ output[0] = INST_BYTE0 (inst1);
344+ output[1] = INST_BYTE1 (inst1);
345+ output[2] = INST_BYTE2 (inst1);
346+ output[3] = INST_BYTE3 (inst1);
347+ output = frag_more (isize);
348+ }
349+ else {
350+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
351+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
352+ if (opcode2 == NULL || opcode1 == NULL)
353+ {
354+ as_bad (_("unknown opcode \"%s\""), "imml");
355+ return;
356+ }
357+ inst1 = opcode2->bit_sequence;
358+ inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
359+ output[0] = INST_BYTE0 (inst1);
360+ output[1] = INST_BYTE1 (inst1);
361+ output[2] = INST_BYTE2 (inst1);
362+ output[3] = INST_BYTE3 (inst1);
363+ output = frag_more (isize);
364 inst1 = opcode1->bit_sequence;
365- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
366+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
367 output[0] = INST_BYTE0 (inst1);
368 output[1] = INST_BYTE1 (inst1);
369 output[2] = INST_BYTE2 (inst1);
370 output[3] = INST_BYTE3 (inst1);
371 output = frag_more (isize);
372 }
373+ }
374
375 inst |= (reg1 << RA_LOW) & RA_MASK;
376 inst |= (immedl << IMM_LOW) & IMM_MASK;
377@@ -2554,8 +2690,8 @@ md_apply_fix (fixS * fixP,
378 /* Note: use offsetT because it is signed, valueT is unsigned. */
379 offsetT val = (offsetT) * valp;
380 int i;
381- struct op_code_struct * opcode1;
382- unsigned long inst1;
383+ struct op_code_struct * opcode1, * opcode2;
384+ unsigned long inst1,inst2;
385
386 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
387
388@@ -2739,30 +2875,75 @@ md_apply_fix (fixS * fixP,
389 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
390 case BFD_RELOC_MICROBLAZE_64:
391 case BFD_RELOC_MICROBLAZE_64_PCREL:
392- /* Add an imm instruction. First save the current instruction. */
393- for (i = 0; i < INST_WORD_SIZE; i++)
394- buf[i + INST_WORD_SIZE] = buf[i];
395 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
396 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
397 {
398 /* Generate the imm instruction. */
399+ if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887)
400+ {
401+ /* Add an imm instruction. First save the current instruction. */
402+ for (i = 0; i < INST_WORD_SIZE; i++)
403+ buf[i + INST_WORD_SIZE] = buf[i];
404 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
405 if (opcode1 == NULL)
406- {
407- as_bad (_("unknown opcode \"%s\""), "imml");
408- return;
409- }
410+ {
411+ as_bad (_("unknown opcode \"%s\""), "imml");
412+ return;
413+ }
414
415 inst1 = opcode1->bit_sequence;
416 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
417- inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK;
418+ inst1 |= ((val & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
419+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
420+ fixP->fx_r_type = BFD_RELOC_64;
421+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
422+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
423+ buf[0] = INST_BYTE0 (inst1);
424+ buf[1] = INST_BYTE1 (inst1);
425+ buf[2] = INST_BYTE2 (inst1);
426+ buf[3] = INST_BYTE3 (inst1);
427+ }
428+ else {
429+ /* Add an imm instruction. First save the current instruction. */
430+ for (i = 0; i < INST_WORD_SIZE; i++)
431+ buf[i + INST_WORD_SIZE + 4] = buf[i];
432+
433+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
434+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
435+ if (opcode1 == NULL || opcode2 ==NULL)
436+ {
437+ as_bad (_("unknown opcode \"%s\""), "imml");
438+ return;
439+ }
440+ inst1 = opcode2->bit_sequence;
441+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
442+ inst1 |= ((val & 0x000000FFFFFF0000L) >> 40) & IMML_MASK;
443+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
444+ fixP->fx_r_type = BFD_RELOC_64;
445+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
446+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
447+ inst2 = opcode1->bit_sequence;
448+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
449+ inst1 |= ((val & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
450 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
451- fixP->fx_r_type = BFD_RELOC_64;
452+ fixP->fx_r_type = BFD_RELOC_64;
453 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
454- fixP->fx_r_type = BFD_RELOC_64_PCREL;
455+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
456+ buf[0] = INST_BYTE0 (inst1);
457+ buf[1] = INST_BYTE1 (inst1);
458+ buf[2] = INST_BYTE2 (inst1);
459+ buf[3] = INST_BYTE3 (inst1);
460+ buf[4] = INST_BYTE0 (inst2);
461+ buf[5] = INST_BYTE1 (inst2);
462+ buf[6] = INST_BYTE2 (inst2);
463+ buf[7] = INST_BYTE3 (inst2);
464+ }
465 }
466 else
467 {
468+ /* Add an imm instruction. First save the current instruction. */
469+ for (i = 0; i < INST_WORD_SIZE; i++)
470+ buf[i + INST_WORD_SIZE] = buf[i];
471 /* Generate the imm instruction. */
472 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
473 if (opcode1 == NULL)
474@@ -2774,12 +2955,11 @@ md_apply_fix (fixS * fixP,
475 inst1 = opcode1->bit_sequence;
476 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
477 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
478- }
479 buf[0] = INST_BYTE0 (inst1);
480 buf[1] = INST_BYTE1 (inst1);
481 buf[2] = INST_BYTE2 (inst1);
482 buf[3] = INST_BYTE3 (inst1);
483-
484+ }
485 /* Add the value only if the symbol is defined. */
486 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
487 {
488@@ -2811,21 +2991,41 @@ md_apply_fix (fixS * fixP,
489 /* Add an imm instruction. First save the current instruction. */
490 for (i = 0; i < INST_WORD_SIZE; i++)
491 buf[i + INST_WORD_SIZE] = buf[i];
492- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
493- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
494+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC) {
495+ if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887)
496+ {
497+ for (i = 0; i < INST_WORD_SIZE; i++)
498+ buf[i + INST_WORD_SIZE] = buf[i];
499+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
500+ }
501+ else {
502+ for (i = 0; i < INST_WORD_SIZE; i++)
503+ buf[i + INST_WORD_SIZE + 4] = buf[i];
504+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
505+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
506+ inst2 = opcode2->bit_sequence;
507+
508+ /* We can fixup call to a defined non-global address
509+ * within the same section only. */
510+ buf[4] = INST_BYTE0 (inst2);
511+ buf[5] = INST_BYTE1 (inst2);
512+ buf[6] = INST_BYTE2 (inst2);
513+ buf[7] = INST_BYTE3 (inst2);
514+ }
515+ }
516 else
517 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
518 if (opcode1 == NULL)
519 {
520+ for (i = 0; i < INST_WORD_SIZE; i++)
521+ buf[i + INST_WORD_SIZE] = buf[i];
522 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
523 as_bad (_("unknown opcode \"%s\""), "imml");
524 else
525 as_bad (_("unknown opcode \"%s\""), "imm");
526 return;
527 }
528-
529 inst1 = opcode1->bit_sequence;
530-
531 /* We can fixup call to a defined non-global address
532 within the same section only. */
533 buf[0] = INST_BYTE0 (inst1);
534diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
535index 0774f70e08..bd9d91cd57 100644
536--- a/opcodes/microblaze-opc.h
537+++ b/opcodes/microblaze-opc.h
538@@ -626,8 +626,8 @@ char pvr_register_prefix[] = "rpvr";
539 #define MIN_IMM6_WIDTH ((int) 0x00000001)
540 #define MAX_IMM6_WIDTH ((int) 0x00000040)
541
542-#define MIN_IMML ((long long) 0xffffff8000000000L)
543-#define MAX_IMML ((long long) 0x0000007fffffffffL)
544+#define MIN_IMML ((long long) -9223372036854775808)
545+#define MAX_IMML ((long long) 9223372036854775807)
546
547 #endif /* MICROBLAZE_OPC */
548
549--
5502.17.1
551
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0032-Add-initial-port-of-linux-gdbserver.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0032-Add-initial-port-of-linux-gdbserver.patch
new file mode 100644
index 00000000..7ac89d2d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0032-Add-initial-port-of-linux-gdbserver.patch
@@ -0,0 +1,435 @@
1From c347f9727cc86bb0174dc001446c0670e7306692 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 23 Jan 2017 19:07:44 +0530
4Subject: [PATCH 32/43] Add initial port of linux gdbserver add
5 gdb_proc_service_h to gdbserver microblaze-linux
6
7gdbserver needs to initialise the microblaze registers
8
9other archs use this step to run a *_arch_setup() to carry out all
10architecture specific setup - may need to add in future
11
12 * add linux-ptrace.o to gdbserver configure
13 * Update breakpoint opcode
14 * fix segfault on connecting gdbserver
15 * add microblaze_linux_memory_remove_breakpoint
16 * add set_solib_svr4_fetch_link_map_offsets
17 * add set_gdbarch_fetch_tls_load_module_address
18 * Force reading of r0 as 0, prevent stores
19
20Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
21Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
22---
23 gdb/configure.host | 3 +
24 gdb/gdbserver/linux-microblaze-low.c | 189 +++++++++++++++++++++++++++
25 gdb/microblaze-linux-tdep.c | 29 +++-
26 gdb/microblaze-tdep.c | 35 ++++-
27 gdb/microblaze-tdep.h | 4 +-
28 gdb/regformats/reg-microblaze.dat | 41 ++++++
29 6 files changed, 298 insertions(+), 3 deletions(-)
30 create mode 100644 gdb/gdbserver/linux-microblaze-low.c
31 create mode 100644 gdb/regformats/reg-microblaze.dat
32
33diff --git a/gdb/configure.host b/gdb/configure.host
34index c87f997abc..de8d6b00f3 100644
35--- a/gdb/configure.host
36+++ b/gdb/configure.host
37@@ -65,6 +65,7 @@ hppa*) gdb_host_cpu=pa ;;
38 i[34567]86*) gdb_host_cpu=i386 ;;
39 m68*) gdb_host_cpu=m68k ;;
40 mips*) gdb_host_cpu=mips ;;
41+microblaze*) gdb_host_cpu=microblaze ;;
42 powerpc* | rs6000) gdb_host_cpu=powerpc ;;
43 sparcv9 | sparc64) gdb_host_cpu=sparc ;;
44 s390*) gdb_host_cpu=s390 ;;
45@@ -133,6 +134,8 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
46 mips*-*-freebsd*) gdb_host=fbsd ;;
47 mips64*-*-openbsd*) gdb_host=obsd64 ;;
48
49+microblaze*-*linux*) gdb_host=linux ;;
50+
51 powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
52 gdb_host=aix ;;
53 powerpc*-*-freebsd*) gdb_host=fbsd ;;
54diff --git a/gdb/gdbserver/linux-microblaze-low.c b/gdb/gdbserver/linux-microblaze-low.c
55new file mode 100644
56index 0000000000..cba5d6fc58
57--- /dev/null
58+++ b/gdb/gdbserver/linux-microblaze-low.c
59@@ -0,0 +1,189 @@
60+/* GNU/Linux/Microblaze specific low level interface, for the remote server for
61+ GDB.
62+ Copyright (C) 1995-2013 Free Software Foundation, Inc.
63+
64+ This file is part of GDB.
65+
66+ This program is free software; you can redistribute it and/or modify
67+ it under the terms of the GNU General Public License as published by
68+ the Free Software Foundation; either version 3 of the License, or
69+ (at your option) any later version.
70+
71+ This program is distributed in the hope that it will be useful,
72+ but WITHOUT ANY WARRANTY; without even the implied warranty of
73+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
74+ GNU General Public License for more details.
75+
76+ You should have received a copy of the GNU General Public License
77+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
78+
79+#include "server.h"
80+#include "linux-low.h"
81+
82+#include <asm/ptrace.h>
83+#include <sys/procfs.h>
84+#include <sys/ptrace.h>
85+
86+#include "gdb_proc_service.h"
87+
88+static int microblaze_regmap[] =
89+ {PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3),
90+ PT_GPR(4), PT_GPR(5), PT_GPR(6), PT_GPR(7),
91+ PT_GPR(8), PT_GPR(9), PT_GPR(10), PT_GPR(11),
92+ PT_GPR(12), PT_GPR(13), PT_GPR(14), PT_GPR(15),
93+ PT_GPR(16), PT_GPR(17), PT_GPR(18), PT_GPR(19),
94+ PT_GPR(20), PT_GPR(21), PT_GPR(22), PT_GPR(23),
95+ PT_GPR(24), PT_GPR(25), PT_GPR(26), PT_GPR(27),
96+ PT_GPR(28), PT_GPR(29), PT_GPR(30), PT_GPR(31),
97+ PT_PC, PT_MSR, PT_EAR, PT_ESR,
98+ PT_FSR
99+ };
100+
101+#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0])
102+
103+/* Defined in auto-generated file microblaze-linux.c. */
104+void init_registers_microblaze (void);
105+
106+static int
107+microblaze_cannot_store_register (int regno)
108+{
109+ if (microblaze_regmap[regno] == -1 || regno == 0)
110+ return 1;
111+
112+ return 0;
113+}
114+
115+static int
116+microblaze_cannot_fetch_register (int regno)
117+{
118+ return 0;
119+}
120+
121+static CORE_ADDR
122+microblaze_get_pc (struct regcache *regcache)
123+{
124+ unsigned long pc;
125+
126+ collect_register_by_name (regcache, "pc", &pc);
127+ return (CORE_ADDR) pc;
128+}
129+
130+static void
131+microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc)
132+{
133+ unsigned long newpc = pc;
134+
135+ supply_register_by_name (regcache, "pc", &newpc);
136+}
137+
138+/* dbtrap insn */
139+/* brki r16, 0x18; */
140+static const unsigned long microblaze_breakpoint = 0xba0c0018;
141+#define microblaze_breakpoint_len 4
142+
143+static int
144+microblaze_breakpoint_at (CORE_ADDR where)
145+{
146+ unsigned long insn;
147+
148+ (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
149+ if (insn == microblaze_breakpoint)
150+ return 1;
151+ /* If necessary, recognize more trap instructions here. GDB only uses the
152+ one. */
153+ return 0;
154+}
155+
156+static CORE_ADDR
157+microblaze_reinsert_addr (struct regcache *regcache)
158+{
159+ unsigned long pc;
160+ collect_register_by_name (regcache, "r15", &pc);
161+ return pc;
162+}
163+
164+#ifdef HAVE_PTRACE_GETREGS
165+
166+static void
167+microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
168+{
169+ int size = register_size (regno);
170+
171+ memset (buf, 0, sizeof (long));
172+
173+ if (size < sizeof (long))
174+ collect_register (regcache, regno, buf + sizeof (long) - size);
175+ else
176+ collect_register (regcache, regno, buf);
177+}
178+
179+static void
180+microblaze_supply_ptrace_register (struct regcache *regcache,
181+ int regno, const char *buf)
182+{
183+ int size = register_size (regno);
184+
185+ if (regno == 0) {
186+ unsigned long regbuf_0 = 0;
187+ /* clobbering r0 so that it is always 0 as enforced by hardware */
188+ supply_register (regcache, regno, (const char*)&regbuf_0);
189+ } else {
190+ if (size < sizeof (long))
191+ supply_register (regcache, regno, buf + sizeof (long) - size);
192+ else
193+ supply_register (regcache, regno, buf);
194+ }
195+}
196+
197+/* Provide only a fill function for the general register set. ps_lgetregs
198+ will use this for NPTL support. */
199+
200+static void microblaze_fill_gregset (struct regcache *regcache, void *buf)
201+{
202+ int i;
203+
204+ for (i = 0; i < 32; i++)
205+ microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]);
206+}
207+
208+static void
209+microblaze_store_gregset (struct regcache *regcache, const void *buf)
210+{
211+ int i;
212+
213+ for (i = 0; i < 32; i++)
214+ supply_register (regcache, i, (char *) buf + microblaze_regmap[i]);
215+}
216+
217+#endif /* HAVE_PTRACE_GETREGS */
218+
219+struct regset_info target_regsets[] = {
220+#ifdef HAVE_PTRACE_GETREGS
221+ { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
222+ { 0, 0, 0, -1, -1, NULL, NULL },
223+#endif /* HAVE_PTRACE_GETREGS */
224+ { 0, 0, 0, -1, -1, NULL, NULL }
225+};
226+
227+struct linux_target_ops the_low_target = {
228+ init_registers_microblaze,
229+ microblaze_num_regs,
230+ microblaze_regmap,
231+ NULL,
232+ microblaze_cannot_fetch_register,
233+ microblaze_cannot_store_register,
234+ NULL, /* fetch_register */
235+ microblaze_get_pc,
236+ microblaze_set_pc,
237+ (const unsigned char *) &microblaze_breakpoint,
238+ microblaze_breakpoint_len,
239+ microblaze_reinsert_addr,
240+ 0,
241+ microblaze_breakpoint_at,
242+ NULL,
243+ NULL,
244+ NULL,
245+ NULL,
246+ microblaze_collect_ptrace_register,
247+ microblaze_supply_ptrace_register,
248+};
249diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
250index 4e5f60cd4e..7ab650a1cc 100644
251--- a/gdb/microblaze-linux-tdep.c
252+++ b/gdb/microblaze-linux-tdep.c
253@@ -37,6 +37,22 @@
254 #include "tramp-frame.h"
255 #include "linux-tdep.h"
256
257+static int microblaze_debug_flag = 0;
258+
259+static void
260+microblaze_debug (const char *fmt, ...)
261+{
262+ if (microblaze_debug_flag)
263+ {
264+ va_list args;
265+
266+ va_start (args, fmt);
267+ printf_unfiltered ("MICROBLAZE LINUX: ");
268+ vprintf_unfiltered (fmt, args);
269+ va_end (args);
270+ }
271+}
272+
273 static int
274 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
275 struct bp_target_info *bp_tgt)
276@@ -46,18 +62,25 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
277 int val;
278 int bplen;
279 gdb_byte old_contents[BREAKPOINT_MAX];
280+ struct cleanup *cleanup;
281
282 /* Determine appropriate breakpoint contents and size for this address. */
283 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
284
285+ /* Make sure we see the memory breakpoints. */
286+ cleanup = make_show_memory_breakpoints_cleanup (1);
287 val = target_read_memory (addr, old_contents, bplen);
288
289 /* If our breakpoint is no longer at the address, this means that the
290 program modified the code on us, so it is wrong to put back the
291 old value. */
292 if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
293- val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
294+ {
295+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
296+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
297+ }
298
299+ do_cleanups (cleanup);
300 return val;
301 }
302
303@@ -129,6 +152,10 @@ microblaze_linux_init_abi (struct gdbarch_info info,
304 /* Trampolines. */
305 tramp_frame_prepend_unwinder (gdbarch,
306 &microblaze_linux_sighandler_tramp_frame);
307+
308+ /* Enable TLS support. */
309+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
310+ svr4_fetch_objfile_link_map);
311 }
312
313 void
314diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
315index 1248acbdc9..730a2b281f 100644
316--- a/gdb/microblaze-tdep.c
317+++ b/gdb/microblaze-tdep.c
318@@ -137,7 +137,38 @@ microblaze_fetch_instruction (CORE_ADDR pc)
319 constexpr gdb_byte microblaze_break_insn[] = MICROBLAZE_BREAKPOINT;
320
321 typedef BP_MANIPULATION (microblaze_break_insn) microblaze_breakpoint;
322-
323+static int
324+microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
325+ struct bp_target_info *bp_tgt)
326+{
327+ CORE_ADDR addr = bp_tgt->placed_address;
328+ const unsigned char *bp;
329+ int val;
330+ int bplen;
331+ gdb_byte old_contents[BREAKPOINT_MAX];
332+ struct cleanup *cleanup;
333+
334+ /* Determine appropriate breakpoint contents and size for this address. */
335+ bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
336+ if (bp == NULL)
337+ error (_("Software breakpoints not implemented for this target."));
338+
339+ /* Make sure we see the memory breakpoints. */
340+ cleanup = make_show_memory_breakpoints_cleanup (1);
341+ val = target_read_memory (addr, old_contents, bplen);
342+
343+ /* If our breakpoint is no longer at the address, this means that the
344+ program modified the code on us, so it is wrong to put back the
345+ old value. */
346+ if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
347+ {
348+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
349+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
350+ }
351+
352+ do_cleanups (cleanup);
353+ return val;
354+}
355
356 /* Allocate and initialize a frame cache. */
357
358@@ -731,6 +762,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
359 microblaze_breakpoint::kind_from_pc);
360 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
361 microblaze_breakpoint::bp_from_kind);
362+ set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
363
364 set_gdbarch_frame_args_skip (gdbarch, 8);
365
366@@ -770,4 +802,5 @@ When non-zero, microblaze specific debugging is enabled."),
367 NULL,
368 &setdebuglist, &showdebuglist);
369
370+
371 }
372diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
373index a0048148e4..63aab84ef6 100644
374--- a/gdb/microblaze-tdep.h
375+++ b/gdb/microblaze-tdep.h
376@@ -117,6 +117,8 @@ struct microblaze_frame_cache
377
378 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
379 Only used for native debugging. */
380-#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60}
381+#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
382+#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
383+
384
385 #endif /* microblaze-tdep.h */
386diff --git a/gdb/regformats/reg-microblaze.dat b/gdb/regformats/reg-microblaze.dat
387new file mode 100644
388index 0000000000..bd8a438442
389--- /dev/null
390+++ b/gdb/regformats/reg-microblaze.dat
391@@ -0,0 +1,41 @@
392+name:microblaze
393+expedite:r1,pc
394+32:r0
395+32:r1
396+32:r2
397+32:r3
398+32:r4
399+32:r5
400+32:r6
401+32:r7
402+32:r8
403+32:r9
404+32:r10
405+32:r11
406+32:r12
407+32:r13
408+32:r14
409+32:r15
410+32:r16
411+32:r17
412+32:r18
413+32:r19
414+32:r20
415+32:r21
416+32:r22
417+32:r23
418+32:r24
419+32:r25
420+32:r26
421+32:r27
422+32:r28
423+32:r29
424+32:r30
425+32:r31
426+32:pc
427+32:msr
428+32:ear
429+32:esr
430+32:fsr
431+32:slr
432+32:shr
433--
4342.17.1
435
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0033-Initial-port-of-core-reading-support.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0033-Initial-port-of-core-reading-support.patch
new file mode 100644
index 00000000..e6bbf2b7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0033-Initial-port-of-core-reading-support.patch
@@ -0,0 +1,388 @@
1From 0fd864ff792d7bcbbcbed5ee0ae9f429f1fd2353 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 24 Jan 2017 14:55:56 +0530
4Subject: [PATCH 33/43] Initial port of core reading support Added support for
5 reading notes in linux core dumps Support for reading of PRSTATUS and PSINFO
6 information for rebuilding ".reg" sections of core dumps at run time.
7
8Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
9Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
10---
11 bfd/elf32-microblaze.c | 84 ++++++++++++++++++++++++++++++++++
12 gdb/configure.tgt | 2 +-
13 gdb/microblaze-linux-tdep.c | 57 +++++++++++++++++++++++
14 gdb/microblaze-tdep.c | 90 +++++++++++++++++++++++++++++++++++++
15 gdb/microblaze-tdep.h | 27 +++++++++++
16 5 files changed, 259 insertions(+), 1 deletion(-)
17
18diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
19index 6a795c5069..c280431df6 100644
20--- a/bfd/elf32-microblaze.c
21+++ b/bfd/elf32-microblaze.c
22@@ -767,6 +767,87 @@ microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
23 return _bfd_elf_is_local_label_name (abfd, name);
24 }
25
26+/* Support for core dump NOTE sections. */
27+static bfd_boolean
28+microblaze_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
29+{
30+ int offset;
31+ unsigned int size;
32+
33+ switch (note->descsz)
34+ {
35+ default:
36+ return FALSE;
37+
38+ case 228: /* Linux/MicroBlaze */
39+ /* pr_cursig */
40+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
41+
42+ /* pr_pid */
43+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
44+
45+ /* pr_reg */
46+ offset = 72;
47+ size = 50 * 4;
48+
49+ break;
50+ }
51+
52+ /* Make a ".reg/999" section. */
53+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
54+ size, note->descpos + offset);
55+}
56+
57+static bfd_boolean
58+microblaze_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
59+{
60+ switch (note->descsz)
61+ {
62+ default:
63+ return FALSE;
64+
65+ case 128: /* Linux/MicroBlaze elf_prpsinfo */
66+ elf_tdata (abfd)->core->program
67+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
68+ elf_tdata (abfd)->core->command
69+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
70+ }
71+
72+ /* Note that for some reason, a spurious space is tacked
73+ onto the end of the args in some (at least one anyway)
74+ implementations, so strip it off if it exists. */
75+
76+ {
77+ char *command = elf_tdata (abfd)->core->command;
78+ int n = strlen (command);
79+
80+ if (0 < n && command[n - 1] == ' ')
81+ command[n - 1] = '\0';
82+ }
83+
84+ return TRUE;
85+}
86+
87+/* The microblaze linker (like many others) needs to keep track of
88+ the number of relocs that it decides to copy as dynamic relocs in
89+ check_relocs for each symbol. This is so that it can later discard
90+ them if they are found to be unnecessary. We store the information
91+ in a field extending the regular ELF linker hash table. */
92+
93+struct elf32_mb_dyn_relocs
94+{
95+ struct elf32_mb_dyn_relocs *next;
96+
97+ /* The input section of the reloc. */
98+ asection *sec;
99+
100+ /* Total number of relocs copied for the input section. */
101+ bfd_size_type count;
102+
103+ /* Number of pc-relative relocs copied for the input section. */
104+ bfd_size_type pc_count;
105+};
106+
107 /* ELF linker hash entry. */
108
109 struct elf32_mb_link_hash_entry
110@@ -3672,4 +3753,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
111 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
112 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
113
114+#define elf_backend_grok_prstatus microblaze_elf_grok_prstatus
115+#define elf_backend_grok_psinfo microblaze_elf_grok_psinfo
116+
117 #include "elf32-target.h"
118diff --git a/gdb/configure.tgt b/gdb/configure.tgt
119index 27f122ad04..622bd486b3 100644
120--- a/gdb/configure.tgt
121+++ b/gdb/configure.tgt
122@@ -397,7 +397,7 @@ mep-*-*)
123
124 microblaze*-linux-*|microblaze*-*-linux*)
125 # Target: Xilinx MicroBlaze running Linux
126- gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \
127+ gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o glibc-tdep.o \
128 symfile-mem.o linux-tdep.o"
129 gdb_sim=../sim/microblaze/libsim.a
130 ;;
131diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
132index 7ab650a1cc..e2225d778a 100644
133--- a/gdb/microblaze-linux-tdep.c
134+++ b/gdb/microblaze-linux-tdep.c
135@@ -135,11 +135,54 @@ static struct tramp_frame microblaze_linux_sighandler_tramp_frame =
136 microblaze_linux_sighandler_cache_init
137 };
138
139+const struct microblaze_gregset microblaze_linux_core_gregset;
140+
141+static void
142+microblaze_linux_supply_core_gregset (const struct regset *regset,
143+ struct regcache *regcache,
144+ int regnum, const void *gregs, size_t len)
145+{
146+ microblaze_supply_gregset (&microblaze_linux_core_gregset, regcache,
147+ regnum, gregs);
148+}
149+
150+static void
151+microblaze_linux_collect_core_gregset (const struct regset *regset,
152+ const struct regcache *regcache,
153+ int regnum, void *gregs, size_t len)
154+{
155+ microblaze_collect_gregset (&microblaze_linux_core_gregset, regcache,
156+ regnum, gregs);
157+}
158+
159+static void
160+microblaze_linux_supply_core_fpregset (const struct regset *regset,
161+ struct regcache *regcache,
162+ int regnum, const void *fpregs, size_t len)
163+{
164+ /* FIXME. */
165+ microblaze_supply_fpregset (regcache, regnum, fpregs);
166+}
167+
168+static void
169+microblaze_linux_collect_core_fpregset (const struct regset *regset,
170+ const struct regcache *regcache,
171+ int regnum, void *fpregs, size_t len)
172+{
173+ /* FIXME. */
174+ microblaze_collect_fpregset (regcache, regnum, fpregs);
175+}
176
177 static void
178 microblaze_linux_init_abi (struct gdbarch_info info,
179 struct gdbarch *gdbarch)
180 {
181+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
182+
183+ tdep->gregset = regset_alloc (gdbarch, microblaze_linux_supply_core_gregset,
184+ microblaze_linux_collect_core_gregset);
185+ tdep->sizeof_gregset = 200;
186+
187 linux_init_abi (info, gdbarch);
188
189 set_gdbarch_memory_remove_breakpoint (gdbarch,
190@@ -153,6 +196,20 @@ microblaze_linux_init_abi (struct gdbarch_info info,
191 tramp_frame_prepend_unwinder (gdbarch,
192 &microblaze_linux_sighandler_tramp_frame);
193
194+ /* BFD target for core files. */
195+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
196+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
197+ else
198+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
199+
200+
201+ /* Shared library handling. */
202+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
203+ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
204+
205+ set_gdbarch_regset_from_core_section (gdbarch,
206+ microblaze_regset_from_core_section);
207+
208 /* Enable TLS support. */
209 set_gdbarch_fetch_tls_load_module_address (gdbarch,
210 svr4_fetch_objfile_link_map);
211diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
212index 730a2b281f..49713ea9b1 100644
213--- a/gdb/microblaze-tdep.c
214+++ b/gdb/microblaze-tdep.c
215@@ -137,6 +137,14 @@ microblaze_fetch_instruction (CORE_ADDR pc)
216 constexpr gdb_byte microblaze_break_insn[] = MICROBLAZE_BREAKPOINT;
217
218 typedef BP_MANIPULATION (microblaze_break_insn) microblaze_breakpoint;
219+static CORE_ADDR
220+microblaze_store_arguments (struct regcache *regcache, int nargs,
221+ struct value **args, CORE_ADDR sp,
222+ int struct_return, CORE_ADDR struct_addr)
223+{
224+ error (_("store_arguments not implemented"));
225+ return sp;
226+}
227 static int
228 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
229 struct bp_target_info *bp_tgt)
230@@ -541,6 +549,12 @@ microblaze_frame_base_address (struct frame_info *next_frame,
231 return cache->base;
232 }
233
234+static const struct frame_unwind *
235+microblaze_frame_sniffer (struct frame_info *next_frame)
236+{
237+ return &microblaze_frame_unwind;
238+}
239+
240 static const struct frame_base microblaze_frame_base =
241 {
242 &microblaze_frame_unwind,
243@@ -677,6 +691,71 @@ microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
244 tdesc_microblaze_with_stack_protect);
245 }
246
247+void
248+microblaze_supply_gregset (const struct microblaze_gregset *gregset,
249+ struct regcache *regcache,
250+ int regnum, const void *gregs)
251+{
252+ unsigned int *regs = gregs;
253+ if (regnum >= 0)
254+ regcache_raw_supply (regcache, regnum, regs + regnum);
255+
256+ if (regnum == -1) {
257+ int i;
258+
259+ for (i = 0; i < 50; i++) {
260+ regcache_raw_supply (regcache, i, regs + i);
261+ }
262+ }
263+}
264+
265+
266+void
267+microblaze_collect_gregset (const struct microblaze_gregset *gregset,
268+ const struct regcache *regcache,
269+ int regnum, void *gregs)
270+{
271+ /* FIXME. */
272+}
273+
274+void
275+microblaze_supply_fpregset (struct regcache *regcache,
276+ int regnum, const void *fpregs)
277+{
278+ /* FIXME. */
279+}
280+
281+void
282+microblaze_collect_fpregset (const struct regcache *regcache,
283+ int regnum, void *fpregs)
284+{
285+ /* FIXME. */
286+}
287+
288+
289+/* Return the appropriate register set for the core section identified
290+ by SECT_NAME and SECT_SIZE. */
291+
292+const struct regset *
293+microblaze_regset_from_core_section (struct gdbarch *gdbarch,
294+ const char *sect_name, size_t sect_size)
295+{
296+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
297+
298+ microblaze_debug ("microblaze_regset_from_core_section, sect_name = %s\n", sect_name);
299+
300+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
301+ return tdep->gregset;
302+
303+ if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset)
304+ return tdep->fpregset;
305+
306+ microblaze_debug ("microblaze_regset_from_core_section returning null :-( \n");
307+ return NULL;
308+}
309+
310+
311+
312 static struct gdbarch *
313 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
314 {
315@@ -733,6 +812,10 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
316 tdep = XCNEW (struct gdbarch_tdep);
317 gdbarch = gdbarch_alloc (&info, tdep);
318
319+ tdep->gregset = NULL;
320+ tdep->sizeof_gregset = 0;
321+ tdep->fpregset = NULL;
322+ tdep->sizeof_fpregset = 0;
323 set_gdbarch_long_double_bit (gdbarch, 128);
324
325 set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
326@@ -781,6 +864,13 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
327 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
328 if (tdesc_data != NULL)
329 tdesc_use_registers (gdbarch, tdesc, tdesc_data);
330+ //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
331+
332+ /* If we have register sets, enable the generic core file support. */
333+ if (tdep->gregset) {
334+ set_gdbarch_regset_from_core_section (gdbarch,
335+ microblaze_regset_from_core_section);
336+ }
337
338 return gdbarch;
339 }
340diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
341index 63aab84ef6..02650f61d9 100644
342--- a/gdb/microblaze-tdep.h
343+++ b/gdb/microblaze-tdep.h
344@@ -22,8 +22,22 @@
345
346
347 /* Microblaze architecture-specific information. */
348+struct microblaze_gregset
349+{
350+ unsigned int gregs[32];
351+ unsigned int fpregs[32];
352+ unsigned int pregs[16];
353+};
354+
355 struct gdbarch_tdep
356 {
357+ int dummy; // declare something.
358+
359+ /* Register sets. */
360+ struct regset *gregset;
361+ size_t sizeof_gregset;
362+ struct regset *fpregset;
363+ size_t sizeof_fpregset;
364 };
365
366 /* Register numbers. */
367@@ -120,5 +134,18 @@ struct microblaze_frame_cache
368 #define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
369 #define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
370
371+extern void microblaze_supply_gregset (const struct microblaze_gregset *gregset,
372+ struct regcache *regcache,
373+ int regnum, const void *gregs);
374+extern void microblaze_collect_gregset (const struct microblaze_gregset *gregset,
375+ const struct regcache *regcache,
376+ int regnum, void *gregs);
377+extern void microblaze_supply_fpregset (struct regcache *regcache,
378+ int regnum, const void *fpregs);
379+extern void microblaze_collect_fpregset (const struct regcache *regcache,
380+ int regnum, void *fpregs);
381+
382+extern const struct regset * microblaze_regset_from_core_section (struct gdbarch *gdbarch,
383+ const char *sect_name, size_t sect_size);
384
385 #endif /* microblaze-tdep.h */
386--
3872.17.1
388
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0034-Fix-debug-message-when-register-is-unavailable.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0034-Fix-debug-message-when-register-is-unavailable.patch
new file mode 100644
index 00000000..df5b3db3
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0034-Fix-debug-message-when-register-is-unavailable.patch
@@ -0,0 +1,40 @@
1From e44a27432ce56bb48eb9785ffaae14bc3a12bd27 Mon Sep 17 00:00:00 2001
2From: Nathan Rossi <nathan.rossi@petalogix.com>
3Date: Tue, 8 May 2012 18:11:17 +1000
4Subject: [PATCH 34/43] Fix debug message when register is unavailable
5
6Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
7---
8 gdb/frame.c | 13 ++++++++++---
9 1 file changed, 10 insertions(+), 3 deletions(-)
10
11diff --git a/gdb/frame.c b/gdb/frame.c
12index d8b5f819f1..49706dc97c 100644
13--- a/gdb/frame.c
14+++ b/gdb/frame.c
15@@ -1227,12 +1227,19 @@ frame_unwind_register_value (frame_info *next_frame, int regnum)
16 else
17 {
18 int i;
19- const gdb_byte *buf = value_contents (value);
20+ const gdb_byte *buf = NULL;
21+ if (value_entirely_available(value)) {
22+ buf = value_contents (value);
23+ }
24
25 fprintf_unfiltered (gdb_stdlog, " bytes=");
26 fprintf_unfiltered (gdb_stdlog, "[");
27- for (i = 0; i < register_size (gdbarch, regnum); i++)
28- fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
29+ if (buf != NULL) {
30+ for (i = 0; i < register_size (gdbarch, regnum); i++)
31+ fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
32+ } else {
33+ fprintf_unfiltered (gdb_stdlog, "unavailable");
34+ }
35 fprintf_unfiltered (gdb_stdlog, "]");
36 }
37 }
38--
392.17.1
40
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0035-revert-master-rebase-changes-to-gdbserver.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0035-revert-master-rebase-changes-to-gdbserver.patch
new file mode 100644
index 00000000..ddb53a07
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0035-revert-master-rebase-changes-to-gdbserver.patch
@@ -0,0 +1,31 @@
1From 1c5dbbd272854e6e7912e2602bdfd78b64399319 Mon Sep 17 00:00:00 2001
2From: David Holsgrove <david.holsgrove@xilinx.com>
3Date: Mon, 22 Jul 2013 11:16:05 +1000
4Subject: [PATCH 35/43] revert master-rebase changes to gdbserver
5
6Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
7---
8 gdb/gdbserver/configure.srv | 7 +++++++
9 1 file changed, 7 insertions(+)
10
11diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
12index d19d22b3a3..7a0be5b072 100644
13--- a/gdb/gdbserver/configure.srv
14+++ b/gdb/gdbserver/configure.srv
15@@ -210,6 +210,13 @@ case "${target}" in
16 srv_linux_usrregs=yes
17 srv_linux_thread_db=yes
18 ;;
19+ microblaze*-*-linux*) srv_regobj=microblaze-linux.o
20+ srv_tgtobj="linux-low.o linux-osdata.o linux-microblaze-low.o "
21+ srv_tgtobj="${srv_tgtobj} linux-procfs.o linux-ptrace.o"
22+ srv_linux_regsets=yes
23+ srv_linux_usrregs=yes
24+ srv_linux_thread_db=yes
25+ ;;
26 powerpc*-*-linux*) srv_regobj="powerpc-32l.o"
27 srv_regobj="${srv_regobj} powerpc-altivec32l.o"
28 srv_regobj="${srv_regobj} powerpc-cell32l.o"
29--
302.17.1
31
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0036-revert-master-rebase-changes-to-gdbserver-previous-c.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0036-revert-master-rebase-changes-to-gdbserver-previous-c.patch
new file mode 100644
index 00000000..f2e5e951
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0036-revert-master-rebase-changes-to-gdbserver-previous-c.patch
@@ -0,0 +1,33 @@
1From bd55e11af18006afb87a8b0fbd93bb0920354e0e Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 30 Apr 2018 17:09:55 +0530
4Subject: [PATCH 36/43] revert master-rebase changes to gdbserver , previous
5 commit typo's
6
7---
8 gdb/gdbserver/Makefile.in | 2 ++
9 1 file changed, 2 insertions(+)
10
11diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
12index 4ae13692a2..45d95e6cab 100644
13--- a/gdb/gdbserver/Makefile.in
14+++ b/gdb/gdbserver/Makefile.in
15@@ -169,6 +169,7 @@ SFILES = \
16 $(srcdir)/linux-low.c \
17 $(srcdir)/linux-m32r-low.c \
18 $(srcdir)/linux-m68k-low.c \
19+ $(srcdir)/linux-microblaze-low.c \
20 $(srcdir)/linux-mips-low.c \
21 $(srcdir)/linux-nios2-low.c \
22 $(srcdir)/linux-ppc-low.c \
23@@ -226,6 +227,7 @@ SFILES = \
24 $(srcdir)/nat/linux-osdata.c \
25 $(srcdir)/nat/linux-personality.c \
26 $(srcdir)/nat/mips-linux-watch.c \
27+ $(srcdir)/nat/microblaze-linux.c \
28 $(srcdir)/nat/ppc-linux.c \
29 $(srcdir)/nat/fork-inferior.c \
30 $(srcdir)/target/waitstatus.c
31--
322.17.1
33
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0037-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0037-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch
new file mode 100644
index 00000000..e2b601b6
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0037-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch
@@ -0,0 +1,32 @@
1From 988a9a41ac91ce3293af8708c1c88c51c48a2a72 Mon Sep 17 00:00:00 2001
2From: David Holsgrove <david.holsgrove@xilinx.com>
3Date: Mon, 16 Dec 2013 16:37:32 +1000
4Subject: [PATCH 37/43] microblaze: Add build_gdbserver=yes to top level
5 configure.tgt
6
7For Microblaze linux toolchains, set the build_gdbserver=yes
8to allow driving gdbserver configuration from the upper level
9
10This patch has been absorbed into the original patch to add
11linux gdbserver support for Microblaze.
12
13Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
14---
15 gdb/configure.tgt | 1 +
16 1 file changed, 1 insertion(+)
17
18diff --git a/gdb/configure.tgt b/gdb/configure.tgt
19index 622bd486b3..989523735b 100644
20--- a/gdb/configure.tgt
21+++ b/gdb/configure.tgt
22@@ -405,6 +405,7 @@ microblaze*-*-*)
23 # Target: Xilinx MicroBlaze running standalone
24 gdb_target_obs="microblaze-tdep.o"
25 gdb_sim=../sim/microblaze/libsim.a
26+ build_gdbserver=yes
27 ;;
28
29 mips*-*-linux*)
30--
312.17.1
32
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0038-Initial-support-for-native-gdb.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0038-Initial-support-for-native-gdb.patch
new file mode 100644
index 00000000..1a50f0a6
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0038-Initial-support-for-native-gdb.patch
@@ -0,0 +1,511 @@
1From aa9cb6db79c663dc944cb67928d16e63f2a69f74 Mon Sep 17 00:00:00 2001
2From: David Holsgrove <david.holsgrove@petalogix.com>
3Date: Fri, 20 Jul 2012 15:18:35 +1000
4Subject: [PATCH 38/43] Initial support for native gdb
5
6microblaze: Follow PPC method of getting setting registers
7using PTRACE PEEK/POKE
8
9Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
10
11Conflicts:
12 gdb/Makefile.in
13---
14 gdb/Makefile.in | 4 +-
15 gdb/config/microblaze/linux.mh | 9 +
16 gdb/microblaze-linux-nat.c | 431 +++++++++++++++++++++++++++++++++
17 3 files changed, 443 insertions(+), 1 deletion(-)
18 create mode 100644 gdb/config/microblaze/linux.mh
19 create mode 100644 gdb/microblaze-linux-nat.c
20
21diff --git a/gdb/Makefile.in b/gdb/Makefile.in
22index 215ef7933c..8c9a3c07c0 100644
23--- a/gdb/Makefile.in
24+++ b/gdb/Makefile.in
25@@ -1316,6 +1316,7 @@ HFILES_NO_SRCDIR = \
26 memory-map.h \
27 memrange.h \
28 microblaze-tdep.h \
29+ microblaze-linux-tdep.h \
30 mips-linux-tdep.h \
31 mips-nbsd-tdep.h \
32 mips-tdep.h \
33@@ -1349,6 +1350,7 @@ HFILES_NO_SRCDIR = \
34 prologue-value.h \
35 psympriv.h \
36 psymtab.h \
37+ ia64-hpux-tdep.h \
38 ravenscar-thread.h \
39 record.h \
40 record-full.h \
41@@ -2263,6 +2265,7 @@ ALLDEPFILES = \
42 m68k-tdep.c \
43 microblaze-linux-tdep.c \
44 microblaze-tdep.c \
45+ microblaze-linux-nat.c \
46 mingw-hdep.c \
47 mips-fbsd-nat.c \
48 mips-fbsd-tdep.c \
49@@ -2365,7 +2368,6 @@ ALLDEPFILES = \
50 xtensa-linux-tdep.c \
51 xtensa-tdep.c \
52 xtensa-xtregs.c \
53- common/mingw-strerror.c \
54 common/posix-strerror.c
55
56 # Some files need explicit build rules (due to -Werror problems) or due
57diff --git a/gdb/config/microblaze/linux.mh b/gdb/config/microblaze/linux.mh
58new file mode 100644
59index 0000000000..a4eaf540e1
60--- /dev/null
61+++ b/gdb/config/microblaze/linux.mh
62@@ -0,0 +1,9 @@
63+# Host: Microblaze, running Linux
64+
65+NAT_FILE= config/nm-linux.h
66+NATDEPFILES= inf-ptrace.o fork-child.o \
67+ microblaze-linux-nat.o proc-service.o linux-thread-db.o \
68+ linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
69+NAT_CDEPS = $(srcdir)/proc-service.list
70+
71+LOADLIBES = -ldl $(RDYNAMIC)
72diff --git a/gdb/microblaze-linux-nat.c b/gdb/microblaze-linux-nat.c
73new file mode 100644
74index 0000000000..e9b8c9c522
75--- /dev/null
76+++ b/gdb/microblaze-linux-nat.c
77@@ -0,0 +1,431 @@
78+/* Microblaze GNU/Linux native support.
79+
80+ Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free
81+ Software Foundation, Inc.
82+
83+ This file is part of GDB.
84+
85+ This program is free software; you can redistribute it and/or modify
86+ it under the terms of the GNU General Public License as published by
87+ the Free Software Foundation; either version 3 of the License, or
88+ (at your option) any later version.
89+
90+ This program is distributed in the hope that it will be useful,
91+ but WITHOUT ANY WARRANTY; without even the implied warranty of
92+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
93+ GNU General Public License for more details.
94+
95+ You should have received a copy of the GNU General Public License
96+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
97+
98+#include "defs.h"
99+#include "arch-utils.h"
100+#include "dis-asm.h"
101+#include "frame.h"
102+#include "trad-frame.h"
103+#include "symtab.h"
104+#include "value.h"
105+#include "gdbcmd.h"
106+#include "breakpoint.h"
107+#include "inferior.h"
108+#include "regcache.h"
109+#include "target.h"
110+#include "frame.h"
111+#include "frame-base.h"
112+#include "frame-unwind.h"
113+#include "dwarf2-frame.h"
114+#include "osabi.h"
115+
116+#include "gdb_assert.h"
117+#include "gdb_string.h"
118+#include "target-descriptions.h"
119+#include "opcodes/microblaze-opcm.h"
120+#include "opcodes/microblaze-dis.h"
121+
122+#include "linux-nat.h"
123+#include "target-descriptions.h"
124+
125+#include <sys/user.h>
126+#include <sys/utsname.h>
127+#include <sys/procfs.h>
128+#include <sys/ptrace.h>
129+
130+/* Prototypes for supply_gregset etc. */
131+#include "gregset.h"
132+
133+#include "microblaze-tdep.h"
134+
135+#include <elf/common.h>
136+#include "auxv.h"
137+
138+/* Defines ps_err_e, struct ps_prochandle. */
139+#include "gdb_proc_service.h"
140+
141+/* On GNU/Linux, threads are implemented as pseudo-processes, in which
142+ case we may be tracing more than one process at a time. In that
143+ case, inferior_ptid will contain the main process ID and the
144+ individual thread (process) ID. get_thread_id () is used to get
145+ the thread id if it's available, and the process id otherwise. */
146+
147+int
148+get_thread_id (ptid_t ptid)
149+{
150+ int tid = TIDGET (ptid);
151+ if (0 == tid)
152+ tid = PIDGET (ptid);
153+ return tid;
154+}
155+
156+#define GET_THREAD_ID(PTID) get_thread_id (PTID)
157+
158+/* Non-zero if our kernel may support the PTRACE_GETREGS and
159+ PTRACE_SETREGS requests, for reading and writing the
160+ general-purpose registers. Zero if we've tried one of
161+ them and gotten an error. */
162+int have_ptrace_getsetregs = 1;
163+
164+static int
165+microblaze_register_u_addr (struct gdbarch *gdbarch, int regno)
166+{
167+ int u_addr = -1;
168+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
169+ /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
170+ interface, and not the wordsize of the program's ABI. */
171+ int wordsize = sizeof (long);
172+
173+ /* General purpose registers occupy 1 slot each in the buffer. */
174+ if (regno >= MICROBLAZE_R0_REGNUM
175+ && regno <= MICROBLAZE_FSR_REGNUM)
176+ u_addr = (regno * wordsize);
177+
178+ return u_addr;
179+}
180+
181+
182+static void
183+fetch_register (struct regcache *regcache, int tid, int regno)
184+{
185+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
186+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
187+ /* This isn't really an address. But ptrace thinks of it as one. */
188+ CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
189+ int bytes_transferred;
190+ unsigned int offset; /* Offset of registers within the u area. */
191+ char buf[MAX_REGISTER_SIZE];
192+
193+ if (regaddr == -1)
194+ {
195+ memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */
196+ regcache_raw_supply (regcache, regno, buf);
197+ return;
198+ }
199+
200+ /* Read the raw register using sizeof(long) sized chunks. On a
201+ 32-bit platform, 64-bit floating-point registers will require two
202+ transfers. */
203+ for (bytes_transferred = 0;
204+ bytes_transferred < register_size (gdbarch, regno);
205+ bytes_transferred += sizeof (long))
206+ {
207+ long l;
208+
209+ errno = 0;
210+ l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
211+ regaddr += sizeof (long);
212+ if (errno != 0)
213+ {
214+ char message[128];
215+ sprintf (message, "reading register %s (#%d)",
216+ gdbarch_register_name (gdbarch, regno), regno);
217+ perror_with_name (message);
218+ }
219+ memcpy (&buf[bytes_transferred], &l, sizeof (l));
220+ }
221+
222+ /* Now supply the register. Keep in mind that the regcache's idea
223+ of the register's size may not be a multiple of sizeof
224+ (long). */
225+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
226+ {
227+ /* Little-endian values are always found at the left end of the
228+ bytes transferred. */
229+ regcache_raw_supply (regcache, regno, buf);
230+ }
231+ else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
232+ {
233+ /* Big-endian values are found at the right end of the bytes
234+ transferred. */
235+ size_t padding = (bytes_transferred - register_size (gdbarch, regno));
236+ regcache_raw_supply (regcache, regno, buf + padding);
237+ }
238+ else
239+ internal_error (__FILE__, __LINE__,
240+ _("fetch_register: unexpected byte order: %d"),
241+ gdbarch_byte_order (gdbarch));
242+}
243+
244+/* This function actually issues the request to ptrace, telling
245+ it to get all general-purpose registers and put them into the
246+ specified regset.
247+
248+ If the ptrace request does not exist, this function returns 0
249+ and properly sets the have_ptrace_* flag. If the request fails,
250+ this function calls perror_with_name. Otherwise, if the request
251+ succeeds, then the regcache gets filled and 1 is returned. */
252+static int
253+fetch_all_gp_regs (struct regcache *regcache, int tid)
254+{
255+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
256+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
257+ gdb_gregset_t gregset;
258+
259+ if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
260+ {
261+ if (errno == EIO)
262+ {
263+ have_ptrace_getsetregs = 0;
264+ return 0;
265+ }
266+ perror_with_name (_("Couldn't get general-purpose registers."));
267+ }
268+
269+ supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
270+
271+ return 1;
272+}
273+
274+
275+/* This is a wrapper for the fetch_all_gp_regs function. It is
276+ responsible for verifying if this target has the ptrace request
277+ that can be used to fetch all general-purpose registers at one
278+ shot. If it doesn't, then we should fetch them using the
279+ old-fashioned way, which is to iterate over the registers and
280+ request them one by one. */
281+static void
282+fetch_gp_regs (struct regcache *regcache, int tid)
283+{
284+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
285+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
286+ int i;
287+
288+ if (have_ptrace_getsetregs)
289+ if (fetch_all_gp_regs (regcache, tid))
290+ return;
291+
292+ /* If we've hit this point, it doesn't really matter which
293+ architecture we are using. We just need to read the
294+ registers in the "old-fashioned way". */
295+ for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
296+ fetch_register (regcache, tid, i);
297+}
298+
299+
300+static void
301+store_register (const struct regcache *regcache, int tid, int regno)
302+{
303+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
304+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
305+ /* This isn't really an address. But ptrace thinks of it as one. */
306+ CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
307+ int i;
308+ size_t bytes_to_transfer;
309+ char buf[MAX_REGISTER_SIZE];
310+
311+ if (regaddr == -1)
312+ return;
313+
314+ /* First collect the register. Keep in mind that the regcache's
315+ idea of the register's size may not be a multiple of sizeof
316+ (long). */
317+ memset (buf, 0, sizeof buf);
318+ bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long));
319+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
320+ {
321+ /* Little-endian values always sit at the left end of the buffer. */
322+ regcache_raw_collect (regcache, regno, buf);
323+ }
324+ else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
325+ {
326+ /* Big-endian values sit at the right end of the buffer. */
327+ size_t padding = (bytes_to_transfer - register_size (gdbarch, regno));
328+ regcache_raw_collect (regcache, regno, buf + padding);
329+ }
330+
331+ for (i = 0; i < bytes_to_transfer; i += sizeof (long))
332+ {
333+ long l;
334+
335+ memcpy (&l, &buf[i], sizeof (l));
336+ errno = 0;
337+ ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l);
338+ regaddr += sizeof (long);
339+
340+ if (errno != 0)
341+ {
342+ char message[128];
343+ sprintf (message, "writing register %s (#%d)",
344+ gdbarch_register_name (gdbarch, regno), regno);
345+ perror_with_name (message);
346+ }
347+ }
348+}
349+
350+/* This function actually issues the request to ptrace, telling
351+ it to store all general-purpose registers present in the specified
352+ regset.
353+
354+ If the ptrace request does not exist, this function returns 0
355+ and properly sets the have_ptrace_* flag. If the request fails,
356+ this function calls perror_with_name. Otherwise, if the request
357+ succeeds, then the regcache is stored and 1 is returned. */
358+static int
359+store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
360+{
361+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
362+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
363+ gdb_gregset_t gregset;
364+
365+ if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
366+ {
367+ if (errno == EIO)
368+ {
369+ have_ptrace_getsetregs = 0;
370+ return 0;
371+ }
372+ perror_with_name (_("Couldn't get general-purpose registers."));
373+ }
374+
375+ fill_gregset (regcache, &gregset, regno);
376+
377+ if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0)
378+ {
379+ if (errno == EIO)
380+ {
381+ have_ptrace_getsetregs = 0;
382+ return 0;
383+ }
384+ perror_with_name (_("Couldn't set general-purpose registers."));
385+ }
386+
387+ return 1;
388+}
389+
390+/* This is a wrapper for the store_all_gp_regs function. It is
391+ responsible for verifying if this target has the ptrace request
392+ that can be used to store all general-purpose registers at one
393+ shot. If it doesn't, then we should store them using the
394+ old-fashioned way, which is to iterate over the registers and
395+ store them one by one. */
396+static void
397+store_gp_regs (const struct regcache *regcache, int tid, int regno)
398+{
399+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
400+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
401+ int i;
402+
403+ if (have_ptrace_getsetregs)
404+ if (store_all_gp_regs (regcache, tid, regno))
405+ return;
406+
407+ /* If we hit this point, it doesn't really matter which
408+ architecture we are using. We just need to store the
409+ registers in the "old-fashioned way". */
410+ for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
411+ store_register (regcache, tid, i);
412+}
413+
414+
415+/* Fetch registers from the child process. Fetch all registers if
416+ regno == -1, otherwise fetch all general registers or all floating
417+ point registers depending upon the value of regno. */
418+
419+static void
420+microblaze_linux_fetch_inferior_registers (struct target_ops *ops,
421+ struct regcache *regcache, int regno)
422+{
423+ /* Get the thread id for the ptrace call. */
424+ int tid = GET_THREAD_ID (inferior_ptid);
425+
426+ if (regno == -1)
427+ fetch_gp_regs (regcache, tid);
428+ else
429+ fetch_register (regcache, tid, regno);
430+}
431+
432+/* Store registers back into the inferior. Store all registers if
433+ regno == -1, otherwise store all general registers or all floating
434+ point registers depending upon the value of regno. */
435+
436+static void
437+microblaze_linux_store_inferior_registers (struct target_ops *ops,
438+ struct regcache *regcache, int regno)
439+{
440+ /* Get the thread id for the ptrace call. */
441+ int tid = GET_THREAD_ID (inferior_ptid);
442+
443+ if (regno >= 0)
444+ store_register (regcache, tid, regno);
445+ else
446+ store_gp_regs (regcache, tid, -1);
447+}
448+
449+/* Wrapper functions for the standard regset handling, used by
450+ thread debugging. */
451+
452+void
453+fill_gregset (const struct regcache *regcache,
454+ gdb_gregset_t *gregsetp, int regno)
455+{
456+ microblaze_collect_gregset (NULL, regcache, regno, gregsetp);
457+}
458+
459+void
460+supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
461+{
462+ microblaze_supply_gregset (NULL, regcache, -1, gregsetp);
463+}
464+
465+void
466+fill_fpregset (const struct regcache *regcache,
467+ gdb_fpregset_t *fpregsetp, int regno)
468+{
469+ /* FIXME. */
470+}
471+
472+void
473+supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
474+{
475+ /* FIXME. */
476+}
477+
478+static const struct target_desc *
479+microblaze_linux_read_description (struct target_ops *ops)
480+{
481+ CORE_ADDR microblaze_hwcap = 0;
482+
483+ if (target_auxv_search (ops, AT_HWCAP, &microblaze_hwcap) != 1)
484+ return NULL;
485+
486+ return NULL;
487+}
488+
489+
490+void _initialize_microblaze_linux_nat (void);
491+
492+void
493+_initialize_microblaze_linux_nat (void)
494+{
495+ struct target_ops *t;
496+
497+ /* Fill in the generic GNU/Linux methods. */
498+ t = linux_target ();
499+
500+ /* Add our register access methods. */
501+ t->to_fetch_registers = microblaze_linux_fetch_inferior_registers;
502+ t->to_store_registers = microblaze_linux_store_inferior_registers;
503+
504+ t->to_read_description = microblaze_linux_read_description;
505+
506+ /* Register the target. */
507+ linux_nat_add_target (t);
508+}
509--
5102.17.1
511
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0039-Fixing-the-issues-related-to-GDB-7.12.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0039-Fixing-the-issues-related-to-GDB-7.12.patch
new file mode 100644
index 00000000..0b1475a7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0039-Fixing-the-issues-related-to-GDB-7.12.patch
@@ -0,0 +1,309 @@
1From 0b5b76d6c9757ebb1c9677772c24272957190345 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Fri, 17 Feb 2017 14:09:40 +0530
4Subject: [PATCH 39/43] Fixing the issues related to GDB-7.12 added all the
5 required function which are new in 7.12 and removed few deprecated functions
6 from 7.6
7
8---
9 gdb/config/microblaze/linux.mh | 4 +-
10 gdb/gdbserver/configure.srv | 3 +-
11 gdb/gdbserver/linux-microblaze-low.c | 97 ++++++++++++++++++++++++----
12 gdb/microblaze-linux-tdep.c | 68 +++++++++++++++++--
13 gdb/microblaze-tdep.h | 1 +
14 5 files changed, 153 insertions(+), 20 deletions(-)
15
16diff --git a/gdb/config/microblaze/linux.mh b/gdb/config/microblaze/linux.mh
17index a4eaf540e1..74a53b854a 100644
18--- a/gdb/config/microblaze/linux.mh
19+++ b/gdb/config/microblaze/linux.mh
20@@ -1,9 +1,11 @@
21 # Host: Microblaze, running Linux
22
23+#linux-nat.o linux-waitpid.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
24 NAT_FILE= config/nm-linux.h
25 NATDEPFILES= inf-ptrace.o fork-child.o \
26 microblaze-linux-nat.o proc-service.o linux-thread-db.o \
27- linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
28+ linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
29+ linux-waitpid.o linux-personality.o linux-namespaces.o
30 NAT_CDEPS = $(srcdir)/proc-service.list
31
32 LOADLIBES = -ldl $(RDYNAMIC)
33diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
34index 7a0be5b072..c421790bd0 100644
35--- a/gdb/gdbserver/configure.srv
36+++ b/gdb/gdbserver/configure.srv
37@@ -211,8 +211,7 @@ case "${target}" in
38 srv_linux_thread_db=yes
39 ;;
40 microblaze*-*-linux*) srv_regobj=microblaze-linux.o
41- srv_tgtobj="linux-low.o linux-osdata.o linux-microblaze-low.o "
42- srv_tgtobj="${srv_tgtobj} linux-procfs.o linux-ptrace.o"
43+ srv_tgtobj="$srv_linux_obj linux-microblaze-low.o "
44 srv_linux_regsets=yes
45 srv_linux_usrregs=yes
46 srv_linux_thread_db=yes
47diff --git a/gdb/gdbserver/linux-microblaze-low.c b/gdb/gdbserver/linux-microblaze-low.c
48index cba5d6fc58..a2733f3c21 100644
49--- a/gdb/gdbserver/linux-microblaze-low.c
50+++ b/gdb/gdbserver/linux-microblaze-low.c
51@@ -39,10 +39,11 @@ static int microblaze_regmap[] =
52 PT_FSR
53 };
54
55-#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0])
56+#define microblaze_num_regs (sizeof (microblaze_regmap) / sizeof (microblaze_regmap[0]))
57
58 /* Defined in auto-generated file microblaze-linux.c. */
59 void init_registers_microblaze (void);
60+extern const struct target_desc *tdesc_microblaze;
61
62 static int
63 microblaze_cannot_store_register (int regno)
64@@ -81,6 +82,15 @@ microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc)
65 static const unsigned long microblaze_breakpoint = 0xba0c0018;
66 #define microblaze_breakpoint_len 4
67
68+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
69+
70+static const gdb_byte *
71+microblaze_sw_breakpoint_from_kind (int kind, int *size)
72+{
73+ *size = microblaze_breakpoint_len;
74+ return (const gdb_byte *) &microblaze_breakpoint;
75+}
76+
77 static int
78 microblaze_breakpoint_at (CORE_ADDR where)
79 {
80@@ -107,7 +117,7 @@ microblaze_reinsert_addr (struct regcache *regcache)
81 static void
82 microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
83 {
84- int size = register_size (regno);
85+ int size = register_size (regcache->tdesc, regno);
86
87 memset (buf, 0, sizeof (long));
88
89@@ -121,7 +131,7 @@ static void
90 microblaze_supply_ptrace_register (struct regcache *regcache,
91 int regno, const char *buf)
92 {
93- int size = register_size (regno);
94+ int size = register_size (regcache->tdesc, regno);
95
96 if (regno == 0) {
97 unsigned long regbuf_0 = 0;
98@@ -157,33 +167,94 @@ microblaze_store_gregset (struct regcache *regcache, const void *buf)
99
100 #endif /* HAVE_PTRACE_GETREGS */
101
102-struct regset_info target_regsets[] = {
103+static struct regset_info microblaze_regsets[] = {
104 #ifdef HAVE_PTRACE_GETREGS
105 { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
106- { 0, 0, 0, -1, -1, NULL, NULL },
107+ { 0, 0, 0, -1, GENERAL_REGS, NULL, NULL },
108 #endif /* HAVE_PTRACE_GETREGS */
109- { 0, 0, 0, -1, -1, NULL, NULL }
110+ { 0, 0, 0, -1, GENERAL_REGS, NULL, NULL },
111+ NULL_REGSET
112 };
113
114+static struct usrregs_info microblaze_usrregs_info =
115+ {
116+ microblaze_num_regs,
117+ microblaze_regmap,
118+ };
119+
120+static struct regsets_info microblaze_regsets_info =
121+ {
122+ microblaze_regsets, /* regsets */
123+ 0, /* num_regsets */
124+ NULL, /* disabled_regsets */
125+ };
126+
127+static struct regs_info regs_info =
128+ {
129+ NULL, /* regset_bitmap */
130+ &microblaze_usrregs_info,
131+ &microblaze_regsets_info
132+ };
133+
134+static const struct regs_info *
135+microblaze_regs_info (void)
136+{
137+ return &regs_info;
138+}
139+
140+/* Support for hardware single step. */
141+
142+static int
143+microblaze_supports_hardware_single_step (void)
144+{
145+ return 1;
146+}
147+
148+
149+static void
150+microblaze_arch_setup (void)
151+{
152+ current_process ()->tdesc = tdesc_microblaze;
153+}
154+
155 struct linux_target_ops the_low_target = {
156- init_registers_microblaze,
157- microblaze_num_regs,
158- microblaze_regmap,
159- NULL,
160+ microblaze_arch_setup,
161+ microblaze_regs_info,
162 microblaze_cannot_fetch_register,
163 microblaze_cannot_store_register,
164 NULL, /* fetch_register */
165 microblaze_get_pc,
166 microblaze_set_pc,
167- (const unsigned char *) &microblaze_breakpoint,
168- microblaze_breakpoint_len,
169- microblaze_reinsert_addr,
170+ NULL,
171+ microblaze_sw_breakpoint_from_kind,
172+ NULL,
173 0,
174 microblaze_breakpoint_at,
175 NULL,
176 NULL,
177 NULL,
178 NULL,
179+ NULL,
180 microblaze_collect_ptrace_register,
181 microblaze_supply_ptrace_register,
182+ NULL, /* siginfo_fixup */
183+ NULL, /* new_process */
184+ NULL, /* new_thread */
185+ NULL, /* new_fork */
186+ NULL, /* prepare_to_resume */
187+ NULL, /* process_qsupported */
188+ NULL, /* supports_tracepoints */
189+ NULL, /* get_thread_area */
190+ NULL, /* install_fast_tracepoint_jump_pad */
191+ NULL, /* emit_ops */
192+ NULL, /* get_min_fast_tracepoint_insn_len */
193+ NULL, /* supports_range_stepping */
194+ NULL, /* breakpoint_kind_from_current_state */
195+ microblaze_supports_hardware_single_step,
196 };
197+
198+void
199+initialize_low_arch (void)
200+{
201+ init_registers_microblaze ();
202+}
203diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
204index e2225d778a..011e513941 100644
205--- a/gdb/microblaze-linux-tdep.c
206+++ b/gdb/microblaze-linux-tdep.c
207@@ -29,13 +29,76 @@
208 #include "regcache.h"
209 #include "value.h"
210 #include "osabi.h"
211-#include "regset.h"
212 #include "solib-svr4.h"
213 #include "microblaze-tdep.h"
214 #include "trad-frame.h"
215 #include "frame-unwind.h"
216 #include "tramp-frame.h"
217 #include "linux-tdep.h"
218+#include "glibc-tdep.h"
219+
220+#include "gdb_assert.h"
221+
222+#ifndef REGSET_H
223+#define REGSET_H 1
224+
225+struct gdbarch;
226+struct regcache;
227+
228+/* Data structure for the supported register notes in a core file. */
229+struct core_regset_section
230+{
231+ const char *sect_name;
232+ int size;
233+ const char *human_name;
234+};
235+
236+/* Data structure describing a register set. */
237+
238+typedef void (supply_regset_ftype) (const struct regset *, struct regcache *,
239+ int, const void *, size_t);
240+typedef void (collect_regset_ftype) (const struct regset *,
241+ const struct regcache *,
242+ int, void *, size_t);
243+
244+struct regset
245+{
246+ /* Data pointer for private use by the methods below, presumably
247+ providing some sort of description of the register set. */
248+ const void *descr;
249+
250+ /* Function supplying values in a register set to a register cache. */
251+ supply_regset_ftype *supply_regset;
252+
253+ /* Function collecting values in a register set from a register cache. */
254+ collect_regset_ftype *collect_regset;
255+
256+ /* Architecture associated with the register set. */
257+ struct gdbarch *arch;
258+};
259+
260+#endif
261+
262+/* Allocate a fresh 'struct regset' whose supply_regset function is
263+ SUPPLY_REGSET, and whose collect_regset function is COLLECT_REGSET.
264+ If the regset has no collect_regset function, pass NULL for
265+ COLLECT_REGSET.
266+
267+ The object returned is allocated on ARCH's obstack. */
268+
269+struct regset *
270+regset_alloc (struct gdbarch *arch,
271+ supply_regset_ftype *supply_regset,
272+ collect_regset_ftype *collect_regset)
273+{
274+ struct regset *regset = GDBARCH_OBSTACK_ZALLOC (arch, struct regset);
275+
276+ regset->arch = arch;
277+ regset->supply_regset = supply_regset;
278+ regset->collect_regset = collect_regset;
279+
280+ return regset;
281+}
282
283 static int microblaze_debug_flag = 0;
284
285@@ -207,9 +270,6 @@ microblaze_linux_init_abi (struct gdbarch_info info,
286 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
287 set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
288
289- set_gdbarch_regset_from_core_section (gdbarch,
290- microblaze_regset_from_core_section);
291-
292 /* Enable TLS support. */
293 set_gdbarch_fetch_tls_load_module_address (gdbarch,
294 svr4_fetch_objfile_link_map);
295diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
296index 02650f61d9..3777cbb6a8 100644
297--- a/gdb/microblaze-tdep.h
298+++ b/gdb/microblaze-tdep.h
299@@ -24,6 +24,7 @@
300 /* Microblaze architecture-specific information. */
301 struct microblaze_gregset
302 {
303+ microblaze_gregset() {}
304 unsigned int gregs[32];
305 unsigned int fpregs[32];
306 unsigned int pregs[16];
307--
3082.17.1
309
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-microblaze-Adding-64-bit-MB-support.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-microblaze-Adding-64-bit-MB-support.patch
new file mode 100644
index 00000000..6582af01
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-microblaze-Adding-64-bit-MB-support.patch
@@ -0,0 +1,1168 @@
1From 34e572e123b166122cc54a8d8e66676c36515711 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Thu, 31 Jan 2019 14:36:00 +0530
4Subject: [PATCH 40/43] [Patch, microblaze]: Adding 64 bit MB support Added new
5 architecture to Microblaze 64-bit support to GDB Signed-off-by :Nagaraju
6 Mekala <nmekala@xilix.com>
7
8Merged on top of binutils work.
9
10Signed-off-by: Mark Hatle <mark.hatle@xilinx.com>
11---
12 bfd/archures.c | 2 +
13 bfd/bfd-in2.h | 2 +
14 bfd/cpu-microblaze.c | 12 +-
15 bfd/elf32-microblaze.c | 93 +-------
16 gas/config/tc-microblaze.c | 16 +-
17 gas/config/tc-microblaze.h | 4 +
18 gdb/Makefile.in | 2 +-
19 gdb/features/Makefile | 3 +
20 gdb/features/microblaze-core.xml | 6 +-
21 gdb/features/microblaze-stack-protect.xml | 4 +-
22 gdb/features/microblaze-with-stack-protect.c | 8 +-
23 gdb/features/microblaze.c | 6 +-
24 gdb/features/microblaze64-core.xml | 69 ++++++
25 gdb/features/microblaze64-stack-protect.xml | 12 +
26 .../microblaze64-with-stack-protect.c | 79 +++++++
27 .../microblaze64-with-stack-protect.xml | 12 +
28 gdb/features/microblaze64.c | 77 +++++++
29 gdb/features/microblaze64.xml | 11 +
30 gdb/microblaze-tdep.c | 207 ++++++++++++++++--
31 gdb/microblaze-tdep.h | 8 +-
32 .../microblaze-with-stack-protect.dat | 4 +-
33 opcodes/microblaze-opc.h | 1 -
34 22 files changed, 504 insertions(+), 134 deletions(-)
35 create mode 100644 gdb/features/microblaze64-core.xml
36 create mode 100644 gdb/features/microblaze64-stack-protect.xml
37 create mode 100644 gdb/features/microblaze64-with-stack-protect.c
38 create mode 100644 gdb/features/microblaze64-with-stack-protect.xml
39 create mode 100644 gdb/features/microblaze64.c
40 create mode 100644 gdb/features/microblaze64.xml
41
42diff --git a/bfd/archures.c b/bfd/archures.c
43index 647cf0d8d4..3fdf7c3c0e 100644
44--- a/bfd/archures.c
45+++ b/bfd/archures.c
46@@ -512,6 +512,8 @@ DESCRIPTION
47 . bfd_arch_lm32, {* Lattice Mico32. *}
48 .#define bfd_mach_lm32 1
49 . bfd_arch_microblaze,{* Xilinx MicroBlaze. *}
50+.#define bfd_mach_microblaze 1
51+.#define bfd_mach_microblaze64 2
52 . bfd_arch_tilepro, {* Tilera TILEPro. *}
53 . bfd_arch_tilegx, {* Tilera TILE-Gx. *}
54 .#define bfd_mach_tilepro 1
55diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
56index 33c9cb62d9..db624c62b9 100644
57--- a/bfd/bfd-in2.h
58+++ b/bfd/bfd-in2.h
59@@ -2411,6 +2411,8 @@ enum bfd_architecture
60 bfd_arch_lm32, /* Lattice Mico32. */
61 #define bfd_mach_lm32 1
62 bfd_arch_microblaze,/* Xilinx MicroBlaze. */
63+#define bfd_mach_microblaze 1
64+#define bfd_mach_microblaze64 2
65 bfd_arch_tilepro, /* Tilera TILEPro. */
66 bfd_arch_tilegx, /* Tilera TILE-Gx. */
67 #define bfd_mach_tilepro 1
68diff --git a/bfd/cpu-microblaze.c b/bfd/cpu-microblaze.c
69index c91ba46f75..8e7bcead28 100644
70--- a/bfd/cpu-microblaze.c
71+++ b/bfd/cpu-microblaze.c
72@@ -30,8 +30,8 @@ const bfd_arch_info_type bfd_microblaze_arch[] =
73 64, /* 32 bits in a word. */
74 64, /* 32 bits in an address. */
75 8, /* 8 bits in a byte. */
76- bfd_arch_microblaze, /* Architecture. */
77- 0, /* Machine number - 0 for now. */
78+ bfd_arch_microblaze, /* Architecture. */
79+ bfd_mach_microblaze64, /* 64 bit Machine */
80 "microblaze", /* Architecture name. */
81 "MicroBlaze", /* Printable name. */
82 3, /* Section align power. */
83@@ -46,7 +46,7 @@ const bfd_arch_info_type bfd_microblaze_arch[] =
84 32, /* 32 bits in an address. */
85 8, /* 8 bits in a byte. */
86 bfd_arch_microblaze, /* Architecture. */
87- 0, /* Machine number - 0 for now. */
88+ bfd_mach_microblaze, /* 32 bit Machine */
89 "microblaze", /* Architecture name. */
90 "MicroBlaze", /* Printable name. */
91 3, /* Section align power. */
92@@ -62,7 +62,7 @@ const bfd_arch_info_type bfd_microblaze_arch[] =
93 32, /* 32 bits in an address. */
94 8, /* 8 bits in a byte. */
95 bfd_arch_microblaze, /* Architecture. */
96- 0, /* Machine number - 0 for now. */
97+ bfd_mach_microblaze, /* 32 bit Machine */
98 "microblaze", /* Architecture name. */
99 "MicroBlaze", /* Printable name. */
100 3, /* Section align power. */
101@@ -76,8 +76,8 @@ const bfd_arch_info_type bfd_microblaze_arch[] =
102 64, /* 32 bits in a word. */
103 64, /* 32 bits in an address. */
104 8, /* 8 bits in a byte. */
105- bfd_arch_microblaze, /* Architecture. */
106- 0, /* Machine number - 0 for now. */
107+ bfd_arch_microblaze, /* Architecture. */
108+ bfd_mach_microblaze64, /* 64 bit Machine */
109 "microblaze", /* Architecture name. */
110 "MicroBlaze", /* Printable name. */
111 3, /* Section align power. */
112diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
113index c280431df6..f9996eae12 100644
114--- a/bfd/elf32-microblaze.c
115+++ b/bfd/elf32-microblaze.c
116@@ -767,87 +767,6 @@ microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
117 return _bfd_elf_is_local_label_name (abfd, name);
118 }
119
120-/* Support for core dump NOTE sections. */
121-static bfd_boolean
122-microblaze_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
123-{
124- int offset;
125- unsigned int size;
126-
127- switch (note->descsz)
128- {
129- default:
130- return FALSE;
131-
132- case 228: /* Linux/MicroBlaze */
133- /* pr_cursig */
134- elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
135-
136- /* pr_pid */
137- elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
138-
139- /* pr_reg */
140- offset = 72;
141- size = 50 * 4;
142-
143- break;
144- }
145-
146- /* Make a ".reg/999" section. */
147- return _bfd_elfcore_make_pseudosection (abfd, ".reg",
148- size, note->descpos + offset);
149-}
150-
151-static bfd_boolean
152-microblaze_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
153-{
154- switch (note->descsz)
155- {
156- default:
157- return FALSE;
158-
159- case 128: /* Linux/MicroBlaze elf_prpsinfo */
160- elf_tdata (abfd)->core->program
161- = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
162- elf_tdata (abfd)->core->command
163- = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
164- }
165-
166- /* Note that for some reason, a spurious space is tacked
167- onto the end of the args in some (at least one anyway)
168- implementations, so strip it off if it exists. */
169-
170- {
171- char *command = elf_tdata (abfd)->core->command;
172- int n = strlen (command);
173-
174- if (0 < n && command[n - 1] == ' ')
175- command[n - 1] = '\0';
176- }
177-
178- return TRUE;
179-}
180-
181-/* The microblaze linker (like many others) needs to keep track of
182- the number of relocs that it decides to copy as dynamic relocs in
183- check_relocs for each symbol. This is so that it can later discard
184- them if they are found to be unnecessary. We store the information
185- in a field extending the regular ELF linker hash table. */
186-
187-struct elf32_mb_dyn_relocs
188-{
189- struct elf32_mb_dyn_relocs *next;
190-
191- /* The input section of the reloc. */
192- asection *sec;
193-
194- /* Total number of relocs copied for the input section. */
195- bfd_size_type count;
196-
197- /* Number of pc-relative relocs copied for the input section. */
198- bfd_size_type pc_count;
199-};
200-
201 /* ELF linker hash entry. */
202
203 struct elf32_mb_link_hash_entry
204@@ -3683,6 +3602,14 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
205 return TRUE;
206 }
207
208+
209+static bfd_boolean
210+elf_microblaze_object_p (bfd *abfd)
211+{
212+ /* Set the right machine number for an s390 elf32 file. */
213+ return bfd_default_set_arch_mach (abfd, bfd_arch_microblaze, bfd_mach_microblaze);
214+}
215+
216 /* Hook called by the linker routine which adds symbols from an object
217 file. We use it to put .comm items in .sbss, and not .bss. */
218
219@@ -3752,8 +3679,6 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
220 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
221 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
222 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
223-
224-#define elf_backend_grok_prstatus microblaze_elf_grok_prstatus
225-#define elf_backend_grok_psinfo microblaze_elf_grok_psinfo
226+#define elf_backend_object_p elf_microblaze_object_p
227
228 #include "elf32-target.h"
229diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
230index 3ff6a14baf..95a1e69729 100644
231--- a/gas/config/tc-microblaze.c
232+++ b/gas/config/tc-microblaze.c
233@@ -426,7 +426,10 @@ md_begin (void)
234 const char *prev_name = "";
235
236 opcode_hash_control = hash_new ();
237-
238+ if (microblaze_arch_size == 64)
239+ bfd_set_arch_mach (stdoutput, bfd_arch_microblaze, bfd_mach_microblaze64);
240+ else
241+ bfd_set_arch_mach (stdoutput, bfd_arch_microblaze, bfd_mach_microblaze);
242 /* Insert unique names into hash table. */
243 for (opcode = (struct opcodes *)opcodes; opcode->name; opcode ++)
244 {
245@@ -1348,7 +1351,7 @@ md_assemble (char * str)
246 if ((temp != 0) && (temp != 0xFFFF8000))
247 {
248 /* Needs an immediate inst. */
249- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
250+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
251 if (opcode1 == NULL)
252 {
253 as_bad (_("unknown opcode \"%s\""), "imm");
254@@ -3431,6 +3434,15 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
255 }
256
257
258+unsigned long
259+microblaze_mach (void)
260+{
261+ if (microblaze_arch_size == 64)
262+ return bfd_mach_microblaze64;
263+ else
264+ return bfd_mach_microblaze;
265+}
266+
267 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
268 found a machine specific op in an expression,
269 then we create relocs accordingly. */
270diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h
271index 9d38d2ced5..13f58917e7 100644
272--- a/gas/config/tc-microblaze.h
273+++ b/gas/config/tc-microblaze.h
274@@ -23,6 +23,10 @@
275 #define TC_MICROBLAZE 1
276
277 #define TARGET_ARCH bfd_arch_microblaze
278+#define TARGET_MACH (microblaze_mach ())
279+#define DEFAULT_MACHINE bfd_mach_microblaze64
280+extern unsigned long microblaze_mach (void);
281+
282 #ifndef TARGET_BYTES_BIG_ENDIAN
283 /* Used to initialise target_big_endian. */
284 #define TARGET_BYTES_BIG_ENDIAN 1
285diff --git a/gdb/Makefile.in b/gdb/Makefile.in
286index 8c9a3c07c0..15387197c7 100644
287--- a/gdb/Makefile.in
288+++ b/gdb/Makefile.in
289@@ -2265,7 +2265,7 @@ ALLDEPFILES = \
290 m68k-tdep.c \
291 microblaze-linux-tdep.c \
292 microblaze-tdep.c \
293- microblaze-linux-nat.c \
294+ microblaze-linux-nat.c \
295 mingw-hdep.c \
296 mips-fbsd-nat.c \
297 mips-fbsd-tdep.c \
298diff --git a/gdb/features/Makefile b/gdb/features/Makefile
299index 3d84ca09a1..fdeec19753 100644
300--- a/gdb/features/Makefile
301+++ b/gdb/features/Makefile
302@@ -64,6 +64,7 @@ WHICH = aarch64 \
303 i386/x32-avx-avx512-linux \
304 mips-linux mips-dsp-linux \
305 microblaze-with-stack-protect \
306+ microblaze64-with-stack-protect \
307 mips64-linux mips64-dsp-linux \
308 nios2-linux \
309 rs6000/powerpc-32 \
310@@ -135,7 +136,9 @@ XMLTOC = \
311 arm/arm-with-vfpv2.xml \
312 arm/arm-with-vfpv3.xml \
313 microblaze-with-stack-protect.xml \
314+ microblaze64-with-stack-protect.xml \
315 microblaze.xml \
316+ microblaze64.xml \
317 mips-dsp-linux.xml \
318 mips-linux.xml \
319 mips64-dsp-linux.xml \
320diff --git a/gdb/features/microblaze-core.xml b/gdb/features/microblaze-core.xml
321index 88c93e5d66..5bc3e49f84 100644
322--- a/gdb/features/microblaze-core.xml
323+++ b/gdb/features/microblaze-core.xml
324@@ -8,7 +8,7 @@
325 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
326 <feature name="org.gnu.gdb.microblaze.core">
327 <reg name="r0" bitsize="32" regnum="0"/>
328- <reg name="r1" bitsize="32" type="data_ptr"/>
329+ <reg name="r1" bitsize="32"/>
330 <reg name="r2" bitsize="32"/>
331 <reg name="r3" bitsize="32"/>
332 <reg name="r4" bitsize="32"/>
333@@ -39,7 +39,7 @@
334 <reg name="r29" bitsize="32"/>
335 <reg name="r30" bitsize="32"/>
336 <reg name="r31" bitsize="32"/>
337- <reg name="rpc" bitsize="32" type="code_ptr"/>
338+ <reg name="rpc" bitsize="32"/>
339 <reg name="rmsr" bitsize="32"/>
340 <reg name="rear" bitsize="32"/>
341 <reg name="resr" bitsize="32"/>
342@@ -64,4 +64,6 @@
343 <reg name="rtlbsx" bitsize="32"/>
344 <reg name="rtlblo" bitsize="32"/>
345 <reg name="rtlbhi" bitsize="32"/>
346+ <reg name="slr" bitsize="32"/>
347+ <reg name="shr" bitsize="32"/>
348 </feature>
349diff --git a/gdb/features/microblaze-stack-protect.xml b/gdb/features/microblaze-stack-protect.xml
350index 870c148bb0..a7f27b903c 100644
351--- a/gdb/features/microblaze-stack-protect.xml
352+++ b/gdb/features/microblaze-stack-protect.xml
353@@ -7,6 +7,6 @@
354
355 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
356 <feature name="org.gnu.gdb.microblaze.stack-protect">
357- <reg name="rslr" bitsize="32"/>
358- <reg name="rshr" bitsize="32"/>
359+ <reg name="slr" bitsize="32"/>
360+ <reg name="shr" bitsize="32"/>
361 </feature>
362diff --git a/gdb/features/microblaze-with-stack-protect.c b/gdb/features/microblaze-with-stack-protect.c
363index b39aa19887..609934e2b4 100644
364--- a/gdb/features/microblaze-with-stack-protect.c
365+++ b/gdb/features/microblaze-with-stack-protect.c
366@@ -14,7 +14,7 @@ initialize_tdesc_microblaze_with_stack_protect (void)
367
368 feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze.core");
369 tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
370- tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "data_ptr");
371+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
372 tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
373 tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
374 tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
375@@ -45,7 +45,7 @@ initialize_tdesc_microblaze_with_stack_protect (void)
376 tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
377 tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
378 tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
379- tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "code_ptr");
380+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
381 tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
382 tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
383 tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
384@@ -72,8 +72,8 @@ initialize_tdesc_microblaze_with_stack_protect (void)
385 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
386
387 feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze.stack-protect");
388- tdesc_create_reg (feature, "rslr", 57, 1, NULL, 32, "int");
389- tdesc_create_reg (feature, "rshr", 58, 1, NULL, 32, "int");
390+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 32, "int");
391+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 32, "int");
392
393 tdesc_microblaze_with_stack_protect = result;
394 }
395diff --git a/gdb/features/microblaze.c b/gdb/features/microblaze.c
396index 6c86fc0770..ceb98ca8b8 100644
397--- a/gdb/features/microblaze.c
398+++ b/gdb/features/microblaze.c
399@@ -14,7 +14,7 @@ initialize_tdesc_microblaze (void)
400
401 feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze.core");
402 tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
403- tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "data_ptr");
404+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
405 tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
406 tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
407 tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
408@@ -45,7 +45,7 @@ initialize_tdesc_microblaze (void)
409 tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
410 tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
411 tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
412- tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "code_ptr");
413+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
414 tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
415 tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
416 tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
417@@ -70,6 +70,8 @@ initialize_tdesc_microblaze (void)
418 tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
419 tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
420 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
421+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
422+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
423
424 tdesc_microblaze = result;
425 }
426diff --git a/gdb/features/microblaze64-core.xml b/gdb/features/microblaze64-core.xml
427new file mode 100644
428index 0000000000..96e99e2fb2
429--- /dev/null
430+++ b/gdb/features/microblaze64-core.xml
431@@ -0,0 +1,69 @@
432+<?xml version="1.0"?>
433+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
434+
435+ Copying and distribution of this file, with or without modification,
436+ are permitted in any medium without royalty provided the copyright
437+ notice and this notice are preserved. -->
438+
439+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
440+<feature name="org.gnu.gdb.microblaze64.core">
441+ <reg name="r0" bitsize="64" regnum="0"/>
442+ <reg name="r1" bitsize="64"/>
443+ <reg name="r2" bitsize="64"/>
444+ <reg name="r3" bitsize="64"/>
445+ <reg name="r4" bitsize="64"/>
446+ <reg name="r5" bitsize="64"/>
447+ <reg name="r6" bitsize="64"/>
448+ <reg name="r7" bitsize="64"/>
449+ <reg name="r8" bitsize="64"/>
450+ <reg name="r9" bitsize="64"/>
451+ <reg name="r10" bitsize="64"/>
452+ <reg name="r11" bitsize="64"/>
453+ <reg name="r12" bitsize="64"/>
454+ <reg name="r13" bitsize="64"/>
455+ <reg name="r14" bitsize="64"/>
456+ <reg name="r15" bitsize="64"/>
457+ <reg name="r16" bitsize="64"/>
458+ <reg name="r17" bitsize="64"/>
459+ <reg name="r18" bitsize="64"/>
460+ <reg name="r19" bitsize="64"/>
461+ <reg name="r20" bitsize="64"/>
462+ <reg name="r21" bitsize="64"/>
463+ <reg name="r22" bitsize="64"/>
464+ <reg name="r23" bitsize="64"/>
465+ <reg name="r24" bitsize="64"/>
466+ <reg name="r25" bitsize="64"/>
467+ <reg name="r26" bitsize="64"/>
468+ <reg name="r27" bitsize="64"/>
469+ <reg name="r28" bitsize="64"/>
470+ <reg name="r29" bitsize="64"/>
471+ <reg name="r30" bitsize="64"/>
472+ <reg name="r31" bitsize="64"/>
473+ <reg name="rpc" bitsize="64"/>
474+ <reg name="rmsr" bitsize="32"/>
475+ <reg name="rear" bitsize="64"/>
476+ <reg name="resr" bitsize="32"/>
477+ <reg name="rfsr" bitsize="32"/>
478+ <reg name="rbtr" bitsize="64"/>
479+ <reg name="rpvr0" bitsize="32"/>
480+ <reg name="rpvr1" bitsize="32"/>
481+ <reg name="rpvr2" bitsize="32"/>
482+ <reg name="rpvr3" bitsize="32"/>
483+ <reg name="rpvr4" bitsize="32"/>
484+ <reg name="rpvr5" bitsize="32"/>
485+ <reg name="rpvr6" bitsize="32"/>
486+ <reg name="rpvr7" bitsize="32"/>
487+ <reg name="rpvr8" bitsize="64"/>
488+ <reg name="rpvr9" bitsize="64"/>
489+ <reg name="rpvr10" bitsize="32"/>
490+ <reg name="rpvr11" bitsize="32"/>
491+ <reg name="redr" bitsize="32"/>
492+ <reg name="rpid" bitsize="32"/>
493+ <reg name="rzpr" bitsize="32"/>
494+ <reg name="rtlbx" bitsize="32"/>
495+ <reg name="rtlbsx" bitsize="32"/>
496+ <reg name="rtlblo" bitsize="32"/>
497+ <reg name="rtlbhi" bitsize="32"/>
498+ <reg name="slr" bitsize="64"/>
499+ <reg name="shr" bitsize="64"/>
500+</feature>
501diff --git a/gdb/features/microblaze64-stack-protect.xml b/gdb/features/microblaze64-stack-protect.xml
502new file mode 100644
503index 0000000000..1bbf5fc3ce
504--- /dev/null
505+++ b/gdb/features/microblaze64-stack-protect.xml
506@@ -0,0 +1,12 @@
507+<?xml version="1.0"?>
508+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
509+
510+ Copying and distribution of this file, with or without modification,
511+ are permitted in any medium without royalty provided the copyright
512+ notice and this notice are preserved. -->
513+
514+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
515+<feature name="org.gnu.gdb.microblaze64.stack-protect">
516+ <reg name="slr" bitsize="64"/>
517+ <reg name="shr" bitsize="64"/>
518+</feature>
519diff --git a/gdb/features/microblaze64-with-stack-protect.c b/gdb/features/microblaze64-with-stack-protect.c
520new file mode 100644
521index 0000000000..f448c9a749
522--- /dev/null
523+++ b/gdb/features/microblaze64-with-stack-protect.c
524@@ -0,0 +1,79 @@
525+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
526+ Original: microblaze-with-stack-protect.xml */
527+
528+#include "defs.h"
529+#include "osabi.h"
530+#include "target-descriptions.h"
531+
532+struct target_desc *tdesc_microblaze64_with_stack_protect;
533+static void
534+initialize_tdesc_microblaze64_with_stack_protect (void)
535+{
536+ struct target_desc *result = allocate_target_description ();
537+ struct tdesc_feature *feature;
538+
539+ feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze64.core");
540+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64");
541+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64");
542+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64");
543+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64");
544+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64");
545+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64");
546+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64");
547+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64");
548+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64");
549+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64");
550+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64");
551+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64");
552+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64");
553+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64");
554+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64");
555+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64");
556+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64");
557+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64");
558+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64");
559+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64");
560+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64");
561+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64");
562+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64");
563+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64");
564+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64");
565+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64");
566+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64");
567+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64");
568+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64");
569+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64");
570+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64");
571+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64");
572+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 64, "uint64");
573+ tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
574+ tdesc_create_reg (feature, "rear", 34, 1, NULL, 64, "int");
575+ tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
576+ tdesc_create_reg (feature, "rfsr", 36, 1, NULL, 32, "int");
577+ tdesc_create_reg (feature, "rbtr", 37, 1, NULL, 64, "uint64");
578+ tdesc_create_reg (feature, "rpvr0", 38, 1, NULL, 32, "int");
579+ tdesc_create_reg (feature, "rpvr1", 39, 1, NULL, 32, "int");
580+ tdesc_create_reg (feature, "rpvr2", 40, 1, NULL, 32, "int");
581+ tdesc_create_reg (feature, "rpvr3", 41, 1, NULL, 32, "int");
582+ tdesc_create_reg (feature, "rpvr4", 42, 1, NULL, 32, "int");
583+ tdesc_create_reg (feature, "rpvr5", 43, 1, NULL, 32, "int");
584+ tdesc_create_reg (feature, "rpvr6", 44, 1, NULL, 32, "int");
585+ tdesc_create_reg (feature, "rpvr7", 45, 1, NULL, 32, "int");
586+ tdesc_create_reg (feature, "rpvr8", 46, 1, NULL, 64, "uint64");
587+ tdesc_create_reg (feature, "rpvr9", 47, 1, NULL, 64, "uint64");
588+ tdesc_create_reg (feature, "rpvr10", 48, 1, NULL, 32, "int");
589+ tdesc_create_reg (feature, "rpvr11", 49, 1, NULL, 32, "int");
590+ tdesc_create_reg (feature, "redr", 50, 1, NULL, 32, "int");
591+ tdesc_create_reg (feature, "rpid", 51, 1, NULL, 32, "int");
592+ tdesc_create_reg (feature, "rzpr", 52, 1, NULL, 32, "int");
593+ tdesc_create_reg (feature, "rtlbx", 53, 1, NULL, 32, "int");
594+ tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
595+ tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
596+ tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
597+
598+ feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze64.stack-protect");
599+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
600+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
601+
602+ tdesc_microblaze64_with_stack_protect = result;
603+}
604diff --git a/gdb/features/microblaze64-with-stack-protect.xml b/gdb/features/microblaze64-with-stack-protect.xml
605new file mode 100644
606index 0000000000..0e9f01611f
607--- /dev/null
608+++ b/gdb/features/microblaze64-with-stack-protect.xml
609@@ -0,0 +1,12 @@
610+<?xml version="1.0"?>
611+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
612+
613+ Copying and distribution of this file, with or without modification,
614+ are permitted in any medium without royalty provided the copyright
615+ notice and this notice are preserved. -->
616+
617+<!DOCTYPE target SYSTEM "gdb-target.dtd">
618+<target>
619+ <xi:include href="microblaze64-core.xml"/>
620+ <xi:include href="microblaze64-stack-protect.xml"/>
621+</target>
622diff --git a/gdb/features/microblaze64.c b/gdb/features/microblaze64.c
623new file mode 100644
624index 0000000000..1aa37c4512
625--- /dev/null
626+++ b/gdb/features/microblaze64.c
627@@ -0,0 +1,77 @@
628+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
629+ Original: microblaze.xml */
630+
631+#include "defs.h"
632+#include "osabi.h"
633+#include "target-descriptions.h"
634+
635+struct target_desc *tdesc_microblaze64;
636+static void
637+initialize_tdesc_microblaze64 (void)
638+{
639+ struct target_desc *result = allocate_target_description ();
640+ struct tdesc_feature *feature;
641+
642+ feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze64.core");
643+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64");
644+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64");
645+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64");
646+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64");
647+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64");
648+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64");
649+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64");
650+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64");
651+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64");
652+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64");
653+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64");
654+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64");
655+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64");
656+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64");
657+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64");
658+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64");
659+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64");
660+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64");
661+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64");
662+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64");
663+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64");
664+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64");
665+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64");
666+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64");
667+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64");
668+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64");
669+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64");
670+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64");
671+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64");
672+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64");
673+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64");
674+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64");
675+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 64, "uint64");
676+ tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
677+ tdesc_create_reg (feature, "rear", 34, 1, NULL, 64, "uint64");
678+ tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
679+ tdesc_create_reg (feature, "rfsr", 36, 1, NULL, 32, "int");
680+ tdesc_create_reg (feature, "rbtr", 37, 1, NULL, 64, "uint64");
681+ tdesc_create_reg (feature, "rpvr0", 38, 1, NULL, 32, "int");
682+ tdesc_create_reg (feature, "rpvr1", 39, 1, NULL, 32, "int");
683+ tdesc_create_reg (feature, "rpvr2", 40, 1, NULL, 32, "int");
684+ tdesc_create_reg (feature, "rpvr3", 41, 1, NULL, 32, "int");
685+ tdesc_create_reg (feature, "rpvr4", 42, 1, NULL, 32, "int");
686+ tdesc_create_reg (feature, "rpvr5", 43, 1, NULL, 32, "int");
687+ tdesc_create_reg (feature, "rpvr6", 44, 1, NULL, 32, "int");
688+ tdesc_create_reg (feature, "rpvr7", 45, 1, NULL, 32, "int");
689+ tdesc_create_reg (feature, "rpvr8", 46, 1, NULL, 64, "uint64");
690+ tdesc_create_reg (feature, "rpvr9", 47, 1, NULL, 64, "uint64");
691+ tdesc_create_reg (feature, "rpvr10", 48, 1, NULL, 32, "int");
692+ tdesc_create_reg (feature, "rpvr11", 49, 1, NULL, 32, "int");
693+ tdesc_create_reg (feature, "redr", 50, 1, NULL, 32, "int");
694+ tdesc_create_reg (feature, "rpid", 51, 1, NULL, 32, "int");
695+ tdesc_create_reg (feature, "rzpr", 52, 1, NULL, 32, "int");
696+ tdesc_create_reg (feature, "rtlbx", 53, 1, NULL, 32, "int");
697+ tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
698+ tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
699+ tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
700+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
701+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
702+
703+ tdesc_microblaze64 = result;
704+}
705diff --git a/gdb/features/microblaze64.xml b/gdb/features/microblaze64.xml
706new file mode 100644
707index 0000000000..515d18e65c
708--- /dev/null
709+++ b/gdb/features/microblaze64.xml
710@@ -0,0 +1,11 @@
711+<?xml version="1.0"?>
712+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
713+
714+ Copying and distribution of this file, with or without modification,
715+ are permitted in any medium without royalty provided the copyright
716+ notice and this notice are preserved. -->
717+
718+<!DOCTYPE target SYSTEM "gdb-target.dtd">
719+<target>
720+ <xi:include href="microblaze64-core.xml"/>
721+</target>
722diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
723index 49713ea9b1..0605283c9e 100644
724--- a/gdb/microblaze-tdep.c
725+++ b/gdb/microblaze-tdep.c
726@@ -40,7 +40,9 @@
727 #include "remote.h"
728
729 #include "features/microblaze-with-stack-protect.c"
730+#include "features/microblaze64-with-stack-protect.c"
731 #include "features/microblaze.c"
732+#include "features/microblaze64.c"
733
734 /* Instruction macros used for analyzing the prologue. */
735 /* This set of instruction macros need to be changed whenever the
736@@ -75,12 +77,13 @@ static const char *microblaze_register_names[] =
737 "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
738 "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
739 "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi",
740- "rslr", "rshr"
741+ "slr", "shr"
742 };
743
744 #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
745
746 static unsigned int microblaze_debug_flag = 0;
747+int reg_size = 4;
748
749 static void ATTRIBUTE_PRINTF (1, 2)
750 microblaze_debug (const char *fmt, ...)
751@@ -145,6 +148,7 @@ microblaze_store_arguments (struct regcache *regcache, int nargs,
752 error (_("store_arguments not implemented"));
753 return sp;
754 }
755+#if 0
756 static int
757 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
758 struct bp_target_info *bp_tgt)
759@@ -154,7 +158,7 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
760 int val;
761 int bplen;
762 gdb_byte old_contents[BREAKPOINT_MAX];
763- struct cleanup *cleanup;
764+ //struct cleanup *cleanup;
765
766 /* Determine appropriate breakpoint contents and size for this address. */
767 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
768@@ -162,7 +166,8 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
769 error (_("Software breakpoints not implemented for this target."));
770
771 /* Make sure we see the memory breakpoints. */
772- cleanup = make_show_memory_breakpoints_cleanup (1);
773+ scoped_restore
774+ cleanup = make_scoped_restore_show_memory_breakpoints (1);
775 val = target_read_memory (addr, old_contents, bplen);
776
777 /* If our breakpoint is no longer at the address, this means that the
778@@ -178,6 +183,7 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
779 return val;
780 }
781
782+#endif
783 /* Allocate and initialize a frame cache. */
784
785 static struct microblaze_frame_cache *
786@@ -570,17 +576,16 @@ microblaze_extract_return_value (struct type *type, struct regcache *regcache,
787 gdb_byte *valbuf)
788 {
789 gdb_byte buf[8];
790-
791 /* Copy the return value (starting) in RETVAL_REGNUM to VALBUF. */
792 switch (TYPE_LENGTH (type))
793 {
794 case 1: /* return last byte in the register. */
795 regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf);
796- memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 1, 1);
797+ memcpy(valbuf, buf + reg_size - 1, 1);
798 return;
799 case 2: /* return last 2 bytes in register. */
800 regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf);
801- memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 2, 2);
802+ memcpy(valbuf, buf + reg_size - 2, 2);
803 return;
804 case 4: /* for sizes 4 or 8, copy the required length. */
805 case 8:
806@@ -647,7 +652,119 @@ microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
807 return (TYPE_LENGTH (type) == 16);
808 }
809
810-
811+#if 0
812+static std::vector<CORE_ADDR>
813+microblaze_software_single_step (struct regcache *regcache)
814+{
815+// struct gdbarch *arch = get_frame_arch(frame);
816+ struct gdbarch *arch = get_regcache_arch (regcache);
817+ struct address_space *aspace = get_regcache_aspace (regcache);
818+// struct address_space *aspace = get_frame_address_space (frame);
819+ struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
820+ static char le_breakp[] = MICROBLAZE_BREAKPOINT_LE;
821+ static char be_breakp[] = MICROBLAZE_BREAKPOINT;
822+ enum bfd_endian byte_order = gdbarch_byte_order (arch);
823+ char *breakp = byte_order == BFD_ENDIAN_BIG ? be_breakp : le_breakp;
824+ std::vector<CORE_ADDR> ret = 0;
825+
826+ /* Save the address and the values of the next_pc and the target */
827+ static struct sstep_breaks
828+ {
829+ CORE_ADDR address;
830+ bfd_boolean valid;
831+ /* Shadow contents. */
832+ char data[INST_WORD_SIZE];
833+ } stepbreaks[2];
834+ int ii;
835+
836+ if (1)
837+ {
838+ CORE_ADDR pc;
839+ std::vector<CORE_ADDR> *next_pcs = NULL;
840+ long insn;
841+ enum microblaze_instr minstr;
842+ bfd_boolean isunsignednum;
843+ enum microblaze_instr_type insn_type;
844+ short delay_slots;
845+ int imm;
846+ bfd_boolean immfound = FALSE;
847+
848+ /* Set a breakpoint at the next instruction */
849+ /* If the current instruction is an imm, set it at the inst after */
850+ /* If the instruction has a delay slot, skip the delay slot */
851+ pc = regcache_read_pc (regcache);
852+ insn = microblaze_fetch_instruction (pc);
853+ minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
854+ if (insn_type == immediate_inst)
855+ {
856+ int rd, ra, rb;
857+ immfound = TRUE;
858+ minstr = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
859+ pc = pc + INST_WORD_SIZE;
860+ insn = microblaze_fetch_instruction (pc);
861+ minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
862+ }
863+ stepbreaks[0].address = pc + (delay_slots * INST_WORD_SIZE) + INST_WORD_SIZE;
864+ if (insn_type != return_inst) {
865+ stepbreaks[0].valid = TRUE;
866+ } else {
867+ stepbreaks[0].valid = FALSE;
868+ }
869+
870+ microblaze_debug ("single-step insn_type=%x insn=%x\n", insn_type, insn);
871+ /* Now check for branch or return instructions */
872+ if (insn_type == branch_inst || insn_type == return_inst) {
873+ int limm;
874+ int lrd, lra, lrb;
875+ int ra, rb;
876+ bfd_boolean targetvalid;
877+ bfd_boolean unconditionalbranch;
878+ microblaze_decode_insn(insn, &lrd, &lra, &lrb, &limm);
879+ if (lra >= 0 && lra < MICROBLAZE_NUM_REGS)
880+ ra = regcache_raw_get_unsigned(regcache, lra);
881+ else
882+ ra = 0;
883+ if (lrb >= 0 && lrb < MICROBLAZE_NUM_REGS)
884+ rb = regcache_raw_get_unsigned(regcache, lrb);
885+ else
886+ rb = 0;
887+ stepbreaks[1].address = microblaze_get_target_address (insn, immfound, imm, pc, ra, rb, &targetvalid, &unconditionalbranch);
888+ microblaze_debug ("single-step uncondbr=%d targetvalid=%d target=%x\n", unconditionalbranch, targetvalid, stepbreaks[1].address);
889+ if (unconditionalbranch)
890+ stepbreaks[0].valid = FALSE; /* This is a unconditional branch: will not come to the next address */
891+ if (targetvalid && (stepbreaks[0].valid == FALSE ||
892+ (stepbreaks[0].address != stepbreaks[1].address))
893+ && (stepbreaks[1].address != pc)) {
894+ stepbreaks[1].valid = TRUE;
895+ } else {
896+ stepbreaks[1].valid = FALSE;
897+ }
898+ } else {
899+ stepbreaks[1].valid = FALSE;
900+ }
901+
902+ /* Insert the breakpoints */
903+ for (ii = 0; ii < 2; ++ii)
904+ {
905+
906+ /* ignore invalid breakpoint. */
907+ if (stepbreaks[ii].valid) {
908+ VEC_safe_push (CORE_ADDR, next_pcs, stepbreaks[ii].address);;
909+// insert_single_step_breakpoint (arch, aspace, stepbreaks[ii].address);
910+ ret = next_pcs;
911+ }
912+ }
913+ }
914+ return ret;
915+}
916+#endif
917+
918+static void
919+microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
920+{
921+ regcache_cooked_write_unsigned (regcache, MICROBLAZE_PC_REGNUM, pc);
922+}
923+
924 static int dwarf2_to_reg_map[78] =
925 { 0 /* r0 */, 1 /* r1 */, 2 /* r2 */, 3 /* r3 */, /* 0- 3 */
926 4 /* r4 */, 5 /* r5 */, 6 /* r6 */, 7 /* r7 */, /* 4- 7 */
927@@ -682,13 +799,14 @@ microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
928 static void
929 microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
930 {
931+
932 register_remote_g_packet_guess (gdbarch,
933- 4 * MICROBLAZE_NUM_CORE_REGS,
934- tdesc_microblaze);
935+ 4 * MICROBLAZE_NUM_REGS,
936+ tdesc_microblaze64);
937
938 register_remote_g_packet_guess (gdbarch,
939 4 * MICROBLAZE_NUM_REGS,
940- tdesc_microblaze_with_stack_protect);
941+ tdesc_microblaze64_with_stack_protect);
942 }
943
944 void
945@@ -696,15 +814,15 @@ microblaze_supply_gregset (const struct microblaze_gregset *gregset,
946 struct regcache *regcache,
947 int regnum, const void *gregs)
948 {
949- unsigned int *regs = gregs;
950+ const gdb_byte *regs = (const gdb_byte *) gregs;
951 if (regnum >= 0)
952- regcache_raw_supply (regcache, regnum, regs + regnum);
953+ regcache->raw_supply (regnum, regs + regnum);
954
955 if (regnum == -1) {
956 int i;
957
958 for (i = 0; i < 50; i++) {
959- regcache_raw_supply (regcache, i, regs + i);
960+ regcache->raw_supply (regnum, regs + i);
961 }
962 }
963 }
964@@ -755,6 +873,17 @@ microblaze_regset_from_core_section (struct gdbarch *gdbarch,
965 }
966
967
968+static void
969+make_regs (struct gdbarch *arch)
970+{
971+ struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
972+ int mach = gdbarch_bfd_arch_info (arch)->mach;
973+
974+ if (mach == bfd_mach_microblaze64)
975+ {
976+ set_gdbarch_ptr_bit (arch, 64);
977+ }
978+}
979
980 static struct gdbarch *
981 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
982@@ -769,8 +898,15 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
983 if (arches != NULL)
984 return arches->gdbarch;
985 if (tdesc == NULL)
986- tdesc = tdesc_microblaze;
987-
988+ {
989+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
990+ {
991+ tdesc = tdesc_microblaze64;
992+ reg_size = 8;
993+ }
994+ else
995+ tdesc = tdesc_microblaze;
996+ }
997 /* Check any target description for validity. */
998 if (tdesc_has_registers (tdesc))
999 {
1000@@ -778,27 +914,35 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1001 int valid_p;
1002 int i;
1003
1004- feature = tdesc_find_feature (tdesc,
1005+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
1006+ feature = tdesc_find_feature (tdesc,
1007+ "org.gnu.gdb.microblaze64.core");
1008+ else
1009+ feature = tdesc_find_feature (tdesc,
1010 "org.gnu.gdb.microblaze.core");
1011 if (feature == NULL)
1012 return NULL;
1013 tdesc_data = tdesc_data_alloc ();
1014
1015 valid_p = 1;
1016- for (i = 0; i < MICROBLAZE_NUM_CORE_REGS; i++)
1017+ for (i = 0; i < MICROBLAZE_NUM_REGS; i++)
1018 valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
1019 microblaze_register_names[i]);
1020- feature = tdesc_find_feature (tdesc,
1021+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
1022+ feature = tdesc_find_feature (tdesc,
1023+ "org.gnu.gdb.microblaze64.stack-protect");
1024+ else
1025+ feature = tdesc_find_feature (tdesc,
1026 "org.gnu.gdb.microblaze.stack-protect");
1027 if (feature != NULL)
1028 {
1029 valid_p = 1;
1030 valid_p &= tdesc_numbered_register (feature, tdesc_data,
1031 MICROBLAZE_SLR_REGNUM,
1032- "rslr");
1033+ "slr");
1034 valid_p &= tdesc_numbered_register (feature, tdesc_data,
1035 MICROBLAZE_SHR_REGNUM,
1036- "rshr");
1037+ "shr");
1038 }
1039
1040 if (!valid_p)
1041@@ -806,6 +950,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1042 tdesc_data_cleanup (tdesc_data);
1043 return NULL;
1044 }
1045+
1046 }
1047
1048 /* Allocate space for the new architecture. */
1049@@ -825,7 +970,17 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1050 /* Register numbers of various important registers. */
1051 set_gdbarch_sp_regnum (gdbarch, MICROBLAZE_SP_REGNUM);
1052 set_gdbarch_pc_regnum (gdbarch, MICROBLAZE_PC_REGNUM);
1053+
1054+ /* Register set.
1055+ make_regs (gdbarch); */
1056+ switch (info.bfd_arch_info->mach)
1057+ {
1058+ case bfd_mach_microblaze64:
1059+ set_gdbarch_ptr_bit (gdbarch, 64);
1060+ break;
1061+ }
1062
1063+
1064 /* Map Dwarf2 registers to GDB registers. */
1065 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, microblaze_dwarf2_reg_to_regnum);
1066
1067@@ -845,13 +1000,15 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1068 microblaze_breakpoint::kind_from_pc);
1069 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
1070 microblaze_breakpoint::bp_from_kind);
1071- set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
1072+// set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
1073+
1074+// set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
1075
1076 set_gdbarch_frame_args_skip (gdbarch, 8);
1077
1078 set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc);
1079
1080- microblaze_register_g_packet_guesses (gdbarch);
1081+ //microblaze_register_g_packet_guesses (gdbarch);
1082
1083 frame_base_set_default (gdbarch, &microblaze_frame_base);
1084
1085@@ -866,11 +1023,11 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1086 tdesc_use_registers (gdbarch, tdesc, tdesc_data);
1087 //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
1088
1089- /* If we have register sets, enable the generic core file support. */
1090+ /* If we have register sets, enable the generic core file support.
1091 if (tdep->gregset) {
1092 set_gdbarch_regset_from_core_section (gdbarch,
1093 microblaze_regset_from_core_section);
1094- }
1095+ }*/
1096
1097 return gdbarch;
1098 }
1099@@ -882,6 +1039,8 @@ _initialize_microblaze_tdep (void)
1100
1101 initialize_tdesc_microblaze_with_stack_protect ();
1102 initialize_tdesc_microblaze ();
1103+ initialize_tdesc_microblaze64_with_stack_protect ();
1104+ initialize_tdesc_microblaze64 ();
1105 /* Debug this files internals. */
1106 add_setshow_zuinteger_cmd ("microblaze", class_maintenance,
1107 &microblaze_debug_flag, _("\
1108diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
1109index 3777cbb6a8..55f5dd1962 100644
1110--- a/gdb/microblaze-tdep.h
1111+++ b/gdb/microblaze-tdep.h
1112@@ -27,7 +27,7 @@ struct microblaze_gregset
1113 microblaze_gregset() {}
1114 unsigned int gregs[32];
1115 unsigned int fpregs[32];
1116- unsigned int pregs[16];
1117+ unsigned int pregs[18];
1118 };
1119
1120 struct gdbarch_tdep
1121@@ -101,9 +101,9 @@ enum microblaze_regnum
1122 MICROBLAZE_RTLBSX_REGNUM,
1123 MICROBLAZE_RTLBLO_REGNUM,
1124 MICROBLAZE_RTLBHI_REGNUM,
1125- MICROBLAZE_SLR_REGNUM, MICROBLAZE_NUM_CORE_REGS = MICROBLAZE_SLR_REGNUM,
1126+ MICROBLAZE_SLR_REGNUM,
1127 MICROBLAZE_SHR_REGNUM,
1128- MICROBLAZE_NUM_REGS
1129+ MICROBLAZE_NUM_REGS, MICROBLAZE_NUM_CORE_REGS = MICROBLAZE_NUM_REGS
1130 };
1131
1132 struct microblaze_frame_cache
1133@@ -128,7 +128,7 @@ struct microblaze_frame_cache
1134 struct trad_frame_saved_reg *saved_regs;
1135 };
1136 /* All registers are 32 bits. */
1137-#define MICROBLAZE_REGISTER_SIZE 4
1138+//#define MICROBLAZE_REGISTER_SIZE 8
1139
1140 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
1141 Only used for native debugging. */
1142diff --git a/gdb/regformats/microblaze-with-stack-protect.dat b/gdb/regformats/microblaze-with-stack-protect.dat
1143index 8040a7b3fd..450e321d49 100644
1144--- a/gdb/regformats/microblaze-with-stack-protect.dat
1145+++ b/gdb/regformats/microblaze-with-stack-protect.dat
1146@@ -60,5 +60,5 @@ expedite:r1,rpc
1147 32:rtlbsx
1148 32:rtlblo
1149 32:rtlbhi
1150-32:rslr
1151-32:rshr
1152+32:slr
1153+32:shr
1154diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
1155index bd9d91cd57..12d4456bc2 100644
1156--- a/opcodes/microblaze-opc.h
1157+++ b/opcodes/microblaze-opc.h
1158@@ -134,7 +134,6 @@
1159 #define ORLI_MASK 0xA0000000
1160 #define XORLI_MASK 0xA8000000
1161
1162-
1163 /* New Mask for msrset, msrclr insns. */
1164 #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
1165 /* Mask for mbar insn. */
1166--
11672.17.1
1168
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0041-patch-MicroBlaze-porting-GDB-for-linux.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0041-patch-MicroBlaze-porting-GDB-for-linux.patch
new file mode 100644
index 00000000..1a0153b8
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0041-patch-MicroBlaze-porting-GDB-for-linux.patch
@@ -0,0 +1,155 @@
1From 07757f455d343beb50ac04815c77b04075bf9534 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Thu, 12 Dec 2019 14:56:17 +0530
4Subject: [PATCH 41/43] [patch,MicroBlaze] : porting GDB for linux
5
6---
7 gdb/features/microblaze-linux.xml | 12 ++++++++++
8 gdb/gdbserver/Makefile.in | 2 ++
9 gdb/gdbserver/configure.srv | 3 ++-
10 gdb/microblaze-linux-tdep.c | 39 ++++++++++++++++++++++++-------
11 4 files changed, 47 insertions(+), 9 deletions(-)
12 create mode 100644 gdb/features/microblaze-linux.xml
13
14diff --git a/gdb/features/microblaze-linux.xml b/gdb/features/microblaze-linux.xml
15new file mode 100644
16index 0000000000..8983e66eb3
17--- /dev/null
18+++ b/gdb/features/microblaze-linux.xml
19@@ -0,0 +1,12 @@
20+<?xml version="1.0"?>
21+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
22+
23+ Copying and distribution of this file, with or without modification,
24+ are permitted in any medium without royalty provided the copyright
25+ notice and this notice are preserved. -->
26+
27+<!DOCTYPE target SYSTEM "gdb-target.dtd">
28+<target>
29+ <osabi>GNU/Linux</osabi>
30+ <xi:include href="microblaze-core.xml"/>
31+</target>
32diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
33index 45d95e6cab..7c8fa3c246 100644
34--- a/gdb/gdbserver/Makefile.in
35+++ b/gdb/gdbserver/Makefile.in
36@@ -633,6 +633,8 @@ common/%.o: ../common/%.c
37
38 %-generated.c: ../regformats/rs6000/%.dat | $(regdat_sh)
39 $(ECHO_REGDAT) $(SHELL) $(regdat_sh) $< $@
40+microblaze-linux.c : $(srcdir)/../regformats/reg-microblaze.dat $(regdat_sh)
41+ $(ECHO_REGDAT) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-microblaze.dat microblaze-linux.c
42
43 #
44 # Dependency tracking.
45diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
46index c421790bd0..6ad0ac9fa6 100644
47--- a/gdb/gdbserver/configure.srv
48+++ b/gdb/gdbserver/configure.srv
49@@ -210,8 +210,9 @@ case "${target}" in
50 srv_linux_usrregs=yes
51 srv_linux_thread_db=yes
52 ;;
53- microblaze*-*-linux*) srv_regobj=microblaze-linux.o
54+ microblaze*-*-linux*) srv_regobj="microblaze-linux.o"
55 srv_tgtobj="$srv_linux_obj linux-microblaze-low.o "
56+ srv_xmlfiles="microblaze-linux.xml"
57 srv_linux_regsets=yes
58 srv_linux_usrregs=yes
59 srv_linux_thread_db=yes
60diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
61index 011e513941..e3d2a7508d 100644
62--- a/gdb/microblaze-linux-tdep.c
63+++ b/gdb/microblaze-linux-tdep.c
64@@ -41,7 +41,7 @@
65
66 #ifndef REGSET_H
67 #define REGSET_H 1
68-
69+int MICROBLAZE_REGISTER_SIZE=4;
70 struct gdbarch;
71 struct regcache;
72
73@@ -115,7 +115,7 @@ microblaze_debug (const char *fmt, ...)
74 va_end (args);
75 }
76 }
77-
78+#if 0
79 static int
80 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
81 struct bp_target_info *bp_tgt)
82@@ -131,7 +131,7 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
83 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
84
85 /* Make sure we see the memory breakpoints. */
86- cleanup = make_show_memory_breakpoints_cleanup (1);
87+ cleanup = make_scoped_restore_show_memory_breakpoints (1);
88 val = target_read_memory (addr, old_contents, bplen);
89
90 /* If our breakpoint is no longer at the address, this means that the
91@@ -146,6 +146,7 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
92 do_cleanups (cleanup);
93 return val;
94 }
95+#endif
96
97 static void
98 microblaze_linux_sigtramp_cache (struct frame_info *next_frame,
99@@ -248,8 +249,8 @@ microblaze_linux_init_abi (struct gdbarch_info info,
100
101 linux_init_abi (info, gdbarch);
102
103- set_gdbarch_memory_remove_breakpoint (gdbarch,
104- microblaze_linux_memory_remove_breakpoint);
105+// set_gdbarch_memory_remove_breakpoint (gdbarch,
106+// microblaze_linux_memory_remove_breakpoint);
107
108 /* Shared library handling. */
109 set_solib_svr4_fetch_link_map_offsets (gdbarch,
110@@ -261,10 +262,30 @@ microblaze_linux_init_abi (struct gdbarch_info info,
111
112 /* BFD target for core files. */
113 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
114- set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
115+ {
116+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64) {
117+ set_gdbarch_gcore_bfd_target (gdbarch, "elf64-microblaze");
118+ MICROBLAZE_REGISTER_SIZE=8;
119+ }
120+ else
121+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
122+ }
123 else
124- set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
125+ {
126+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64) {
127+ set_gdbarch_gcore_bfd_target (gdbarch, "elf64-microblazeel");
128+ MICROBLAZE_REGISTER_SIZE=8;
129+ }
130+ else
131+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
132+ }
133
134+ switch (info.bfd_arch_info->mach)
135+ {
136+ case bfd_mach_microblaze64:
137+ set_gdbarch_ptr_bit (gdbarch, 64);
138+ break;
139+ }
140
141 /* Shared library handling. */
142 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
143@@ -278,6 +299,8 @@ microblaze_linux_init_abi (struct gdbarch_info info,
144 void
145 _initialize_microblaze_linux_tdep (void)
146 {
147- gdbarch_register_osabi (bfd_arch_microblaze, 0, GDB_OSABI_LINUX,
148+ gdbarch_register_osabi (bfd_arch_microblaze, bfd_mach_microblaze, GDB_OSABI_LINUX,
149+ microblaze_linux_init_abi);
150+ gdbarch_register_osabi (bfd_arch_microblaze, bfd_mach_microblaze64, GDB_OSABI_LINUX,
151 microblaze_linux_init_abi);
152 }
153--
1542.17.1
155
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0042-Correcting-the-register-names-from-slr-shr-to-rslr-r.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0042-Correcting-the-register-names-from-slr-shr-to-rslr-r.patch
new file mode 100644
index 00000000..ad8dcb53
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0042-Correcting-the-register-names-from-slr-shr-to-rslr-r.patch
@@ -0,0 +1,146 @@
1From c2a4667e87bd610a48a6690fcc9fdc6761398bcf Mon Sep 17 00:00:00 2001
2From: Nagaraju <nmekala@xilinx.com>
3Date: Thu, 19 Dec 2019 12:22:04 +0530
4Subject: [PATCH 42/43] Correcting the register names from slr & shr to rslr &
5 rshr
6
7---
8 gdb/features/microblaze-core.xml | 4 ++--
9 gdb/features/microblaze-stack-protect.xml | 4 ++--
10 gdb/features/microblaze-with-stack-protect.c | 4 ++--
11 gdb/features/microblaze.c | 4 ++--
12 gdb/features/microblaze64-core.xml | 4 ++--
13 gdb/features/microblaze64-stack-protect.xml | 4 ++--
14 gdb/features/microblaze64-with-stack-protect.c | 4 ++--
15 gdb/features/microblaze64.c | 4 ++--
16 gdb/microblaze-tdep.c | 2 +-
17 9 files changed, 17 insertions(+), 17 deletions(-)
18
19diff --git a/gdb/features/microblaze-core.xml b/gdb/features/microblaze-core.xml
20index 5bc3e49f84..6f73f4eb84 100644
21--- a/gdb/features/microblaze-core.xml
22+++ b/gdb/features/microblaze-core.xml
23@@ -64,6 +64,6 @@
24 <reg name="rtlbsx" bitsize="32"/>
25 <reg name="rtlblo" bitsize="32"/>
26 <reg name="rtlbhi" bitsize="32"/>
27- <reg name="slr" bitsize="32"/>
28- <reg name="shr" bitsize="32"/>
29+ <reg name="rslr" bitsize="32"/>
30+ <reg name="rshr" bitsize="32"/>
31 </feature>
32diff --git a/gdb/features/microblaze-stack-protect.xml b/gdb/features/microblaze-stack-protect.xml
33index a7f27b903c..870c148bb0 100644
34--- a/gdb/features/microblaze-stack-protect.xml
35+++ b/gdb/features/microblaze-stack-protect.xml
36@@ -7,6 +7,6 @@
37
38 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
39 <feature name="org.gnu.gdb.microblaze.stack-protect">
40- <reg name="slr" bitsize="32"/>
41- <reg name="shr" bitsize="32"/>
42+ <reg name="rslr" bitsize="32"/>
43+ <reg name="rshr" bitsize="32"/>
44 </feature>
45diff --git a/gdb/features/microblaze-with-stack-protect.c b/gdb/features/microblaze-with-stack-protect.c
46index 609934e2b4..ab162fd258 100644
47--- a/gdb/features/microblaze-with-stack-protect.c
48+++ b/gdb/features/microblaze-with-stack-protect.c
49@@ -72,8 +72,8 @@ initialize_tdesc_microblaze_with_stack_protect (void)
50 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
51
52 feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze.stack-protect");
53- tdesc_create_reg (feature, "slr", 57, 1, NULL, 32, "int");
54- tdesc_create_reg (feature, "shr", 58, 1, NULL, 32, "int");
55+ tdesc_create_reg (feature, "rslr", 57, 1, NULL, 32, "int");
56+ tdesc_create_reg (feature, "rshr", 58, 1, NULL, 32, "int");
57
58 tdesc_microblaze_with_stack_protect = result;
59 }
60diff --git a/gdb/features/microblaze.c b/gdb/features/microblaze.c
61index ceb98ca8b8..7919ac96e6 100644
62--- a/gdb/features/microblaze.c
63+++ b/gdb/features/microblaze.c
64@@ -70,8 +70,8 @@ initialize_tdesc_microblaze (void)
65 tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
66 tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
67 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
68- tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
69- tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
70+ tdesc_create_reg (feature, "rslr", 57, 1, NULL, 64, "uint64");
71+ tdesc_create_reg (feature, "rshr", 58, 1, NULL, 64, "uint64");
72
73 tdesc_microblaze = result;
74 }
75diff --git a/gdb/features/microblaze64-core.xml b/gdb/features/microblaze64-core.xml
76index 96e99e2fb2..b9adadfade 100644
77--- a/gdb/features/microblaze64-core.xml
78+++ b/gdb/features/microblaze64-core.xml
79@@ -64,6 +64,6 @@
80 <reg name="rtlbsx" bitsize="32"/>
81 <reg name="rtlblo" bitsize="32"/>
82 <reg name="rtlbhi" bitsize="32"/>
83- <reg name="slr" bitsize="64"/>
84- <reg name="shr" bitsize="64"/>
85+ <reg name="rslr" bitsize="64"/>
86+ <reg name="rshr" bitsize="64"/>
87 </feature>
88diff --git a/gdb/features/microblaze64-stack-protect.xml b/gdb/features/microblaze64-stack-protect.xml
89index 1bbf5fc3ce..9d7ea8b9fd 100644
90--- a/gdb/features/microblaze64-stack-protect.xml
91+++ b/gdb/features/microblaze64-stack-protect.xml
92@@ -7,6 +7,6 @@
93
94 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
95 <feature name="org.gnu.gdb.microblaze64.stack-protect">
96- <reg name="slr" bitsize="64"/>
97- <reg name="shr" bitsize="64"/>
98+ <reg name="rslr" bitsize="64"/>
99+ <reg name="rshr" bitsize="64"/>
100 </feature>
101diff --git a/gdb/features/microblaze64-with-stack-protect.c b/gdb/features/microblaze64-with-stack-protect.c
102index f448c9a749..249cb534da 100644
103--- a/gdb/features/microblaze64-with-stack-protect.c
104+++ b/gdb/features/microblaze64-with-stack-protect.c
105@@ -72,8 +72,8 @@ initialize_tdesc_microblaze64_with_stack_protect (void)
106 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
107
108 feature = tdesc_create_feature (result, "org.gnu.gdb.microblaze64.stack-protect");
109- tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
110- tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
111+ tdesc_create_reg (feature, "rslr", 57, 1, NULL, 64, "uint64");
112+ tdesc_create_reg (feature, "rshr", 58, 1, NULL, 64, "uint64");
113
114 tdesc_microblaze64_with_stack_protect = result;
115 }
116diff --git a/gdb/features/microblaze64.c b/gdb/features/microblaze64.c
117index 1aa37c4512..5d3e2c8cd9 100644
118--- a/gdb/features/microblaze64.c
119+++ b/gdb/features/microblaze64.c
120@@ -70,8 +70,8 @@ initialize_tdesc_microblaze64 (void)
121 tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
122 tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
123 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
124- tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
125- tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
126+ tdesc_create_reg (feature, "rslr", 57, 1, NULL, 64, "uint64");
127+ tdesc_create_reg (feature, "rshr", 58, 1, NULL, 64, "uint64");
128
129 tdesc_microblaze64 = result;
130 }
131diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
132index 0605283c9e..7a0c2527f4 100644
133--- a/gdb/microblaze-tdep.c
134+++ b/gdb/microblaze-tdep.c
135@@ -77,7 +77,7 @@ static const char *microblaze_register_names[] =
136 "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
137 "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
138 "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi",
139- "slr", "shr"
140+ "rslr", "rshr"
141 };
142
143 #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
144--
1452.17.1
146
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0043-Removing-the-header-gdb_assert.h-from-MB-target-file.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0043-Removing-the-header-gdb_assert.h-from-MB-target-file.patch
new file mode 100644
index 00000000..930e161c
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0043-Removing-the-header-gdb_assert.h-from-MB-target-file.patch
@@ -0,0 +1,24 @@
1From 9562530bc48c76d8f824b8f4901ad90dd2969086 Mon Sep 17 00:00:00 2001
2From: Nagaraju <nmekala@xilinx.com>
3Date: Fri, 17 Jan 2020 15:45:48 +0530
4Subject: [PATCH 43/43] Removing the header "gdb_assert.h" from MB target file
5
6---
7 gdb/microblaze-linux-tdep.c | 1 -
8 1 file changed, 1 deletion(-)
9
10diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
11index e3d2a7508d..5ef937219c 100644
12--- a/gdb/microblaze-linux-tdep.c
13+++ b/gdb/microblaze-linux-tdep.c
14@@ -37,7 +37,6 @@
15 #include "linux-tdep.h"
16 #include "glibc-tdep.h"
17
18-#include "gdb_assert.h"
19
20 #ifndef REGSET_H
21 #define REGSET_H 1
22--
232.17.1
24
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch
new file mode 100644
index 00000000..29e198cd
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch
@@ -0,0 +1,364 @@
1From 4f0e06249d23629e1d56b296e7a040b6968484e9 Mon Sep 17 00:00:00 2001
2From: Mark Hatle <mark.hatle@xilinx.com>
3Date: Mon, 20 Jan 2020 12:48:13 -0800
4Subject: [PATCH 44/45] gdb/microblaze-linux-nat.c: Fix target compilation of
5 gdb
6
7Add the nat to the configure file
8
9Remove gdb_assert.h and gdb_string.h.
10
11Adjust include for opcodes as well.
12
13Update to match latest style of components, similar to ppc-linux-nat.c
14
15Update:
16 get_regcache_arch(regcache) to regcache->arch()
17 regcache_raw_supply(regcache, ...) to regcache->raw_supply(...)
18 regcache_raw_collect(regcache, ...) to regcache->raw_collect(...)
19
20Signed-off-by: Mark Hatle <mark.hatle@xilinx.com>
21---
22 gdb/configure.nat | 4 +
23 gdb/microblaze-linux-nat.c | 149 +++++++++++++------------------------
24 gdb/microblaze-tdep.c | 3 +-
25 3 files changed, 57 insertions(+), 99 deletions(-)
26
27diff --git a/gdb/configure.nat b/gdb/configure.nat
28index 3118263ac6..b8dc7398a5 100644
29--- a/gdb/configure.nat
30+++ b/gdb/configure.nat
31@@ -260,6 +260,10 @@ case ${gdb_host} in
32 # Host: Motorola m68k running GNU/Linux.
33 NATDEPFILES="${NATDEPFILES} m68k-linux-nat.o"
34 ;;
35+ microblaze*)
36+ # Host: Microblaze, running Linux
37+ NATDEPFILES="${NATDEPFILES} microblaze-linux-nat.o"
38+ ;;
39 mips)
40 # Host: Linux/MIPS
41 NATDEPFILES="${NATDEPFILES} linux-nat-trad.o \
42diff --git a/gdb/microblaze-linux-nat.c b/gdb/microblaze-linux-nat.c
43index e9b8c9c522..e09a86bb3f 100644
44--- a/gdb/microblaze-linux-nat.c
45+++ b/gdb/microblaze-linux-nat.c
46@@ -36,11 +36,9 @@
47 #include "dwarf2-frame.h"
48 #include "osabi.h"
49
50-#include "gdb_assert.h"
51-#include "gdb_string.h"
52 #include "target-descriptions.h"
53-#include "opcodes/microblaze-opcm.h"
54-#include "opcodes/microblaze-dis.h"
55+#include "../opcodes/microblaze-opcm.h"
56+#include "../opcodes/microblaze-dis.h"
57
58 #include "linux-nat.h"
59 #include "target-descriptions.h"
60@@ -61,34 +59,27 @@
61 /* Defines ps_err_e, struct ps_prochandle. */
62 #include "gdb_proc_service.h"
63
64-/* On GNU/Linux, threads are implemented as pseudo-processes, in which
65- case we may be tracing more than one process at a time. In that
66- case, inferior_ptid will contain the main process ID and the
67- individual thread (process) ID. get_thread_id () is used to get
68- the thread id if it's available, and the process id otherwise. */
69-
70-int
71-get_thread_id (ptid_t ptid)
72-{
73- int tid = TIDGET (ptid);
74- if (0 == tid)
75- tid = PIDGET (ptid);
76- return tid;
77-}
78-
79-#define GET_THREAD_ID(PTID) get_thread_id (PTID)
80-
81 /* Non-zero if our kernel may support the PTRACE_GETREGS and
82 PTRACE_SETREGS requests, for reading and writing the
83 general-purpose registers. Zero if we've tried one of
84 them and gotten an error. */
85 int have_ptrace_getsetregs = 1;
86
87+struct microblaze_linux_nat_target final : public linux_nat_target
88+{
89+ /* Add our register access methods. */
90+ void fetch_registers (struct regcache *, int) override;
91+ void store_registers (struct regcache *, int) override;
92+
93+ const struct target_desc *read_description () override;
94+};
95+
96+static microblaze_linux_nat_target the_microblaze_linux_nat_target;
97+
98 static int
99 microblaze_register_u_addr (struct gdbarch *gdbarch, int regno)
100 {
101 int u_addr = -1;
102- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
103 /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
104 interface, and not the wordsize of the program's ABI. */
105 int wordsize = sizeof (long);
106@@ -105,18 +96,16 @@ microblaze_register_u_addr (struct gdbarch *gdbarch, int regno)
107 static void
108 fetch_register (struct regcache *regcache, int tid, int regno)
109 {
110- struct gdbarch *gdbarch = get_regcache_arch (regcache);
111- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
112+ struct gdbarch *gdbarch = regcache->arch();
113 /* This isn't really an address. But ptrace thinks of it as one. */
114 CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
115 int bytes_transferred;
116- unsigned int offset; /* Offset of registers within the u area. */
117- char buf[MAX_REGISTER_SIZE];
118+ char buf[sizeof(long)];
119
120 if (regaddr == -1)
121 {
122 memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */
123- regcache_raw_supply (regcache, regno, buf);
124+ regcache->raw_supply (regno, buf);
125 return;
126 }
127
128@@ -149,14 +138,14 @@ fetch_register (struct regcache *regcache, int tid, int regno)
129 {
130 /* Little-endian values are always found at the left end of the
131 bytes transferred. */
132- regcache_raw_supply (regcache, regno, buf);
133+ regcache->raw_supply (regno, buf);
134 }
135 else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
136 {
137 /* Big-endian values are found at the right end of the bytes
138 transferred. */
139 size_t padding = (bytes_transferred - register_size (gdbarch, regno));
140- regcache_raw_supply (regcache, regno, buf + padding);
141+ regcache->raw_supply (regno, buf + padding);
142 }
143 else
144 internal_error (__FILE__, __LINE__,
145@@ -175,8 +164,6 @@ fetch_register (struct regcache *regcache, int tid, int regno)
146 static int
147 fetch_all_gp_regs (struct regcache *regcache, int tid)
148 {
149- struct gdbarch *gdbarch = get_regcache_arch (regcache);
150- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
151 gdb_gregset_t gregset;
152
153 if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
154@@ -204,8 +191,6 @@ fetch_all_gp_regs (struct regcache *regcache, int tid)
155 static void
156 fetch_gp_regs (struct regcache *regcache, int tid)
157 {
158- struct gdbarch *gdbarch = get_regcache_arch (regcache);
159- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
160 int i;
161
162 if (have_ptrace_getsetregs)
163@@ -219,17 +204,29 @@ fetch_gp_regs (struct regcache *regcache, int tid)
164 fetch_register (regcache, tid, i);
165 }
166
167+/* Fetch registers from the child process. Fetch all registers if
168+ regno == -1, otherwise fetch all general registers or all floating
169+ point registers depending upon the value of regno. */
170+void
171+microblaze_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
172+{
173+ pid_t tid = get_ptrace_pid (regcache->ptid ());
174+
175+ if (regno == -1)
176+ fetch_gp_regs (regcache, tid);
177+ else
178+ fetch_register (regcache, tid, regno);
179+}
180
181 static void
182 store_register (const struct regcache *regcache, int tid, int regno)
183 {
184- struct gdbarch *gdbarch = get_regcache_arch (regcache);
185- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
186+ struct gdbarch *gdbarch = regcache->arch();
187 /* This isn't really an address. But ptrace thinks of it as one. */
188 CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
189 int i;
190 size_t bytes_to_transfer;
191- char buf[MAX_REGISTER_SIZE];
192+ char buf[sizeof(long)];
193
194 if (regaddr == -1)
195 return;
196@@ -242,13 +239,13 @@ store_register (const struct regcache *regcache, int tid, int regno)
197 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
198 {
199 /* Little-endian values always sit at the left end of the buffer. */
200- regcache_raw_collect (regcache, regno, buf);
201+ regcache->raw_collect (regno, buf);
202 }
203 else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
204 {
205 /* Big-endian values sit at the right end of the buffer. */
206 size_t padding = (bytes_to_transfer - register_size (gdbarch, regno));
207- regcache_raw_collect (regcache, regno, buf + padding);
208+ regcache->raw_collect (regno, buf + padding);
209 }
210
211 for (i = 0; i < bytes_to_transfer; i += sizeof (long))
212@@ -281,8 +278,6 @@ store_register (const struct regcache *regcache, int tid, int regno)
213 static int
214 store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
215 {
216- struct gdbarch *gdbarch = get_regcache_arch (regcache);
217- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
218 gdb_gregset_t gregset;
219
220 if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
221@@ -319,8 +314,6 @@ store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
222 static void
223 store_gp_regs (const struct regcache *regcache, int tid, int regno)
224 {
225- struct gdbarch *gdbarch = get_regcache_arch (regcache);
226- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
227 int i;
228
229 if (have_ptrace_getsetregs)
230@@ -335,33 +328,10 @@ store_gp_regs (const struct regcache *regcache, int tid, int regno)
231 }
232
233
234-/* Fetch registers from the child process. Fetch all registers if
235- regno == -1, otherwise fetch all general registers or all floating
236- point registers depending upon the value of regno. */
237-
238-static void
239-microblaze_linux_fetch_inferior_registers (struct target_ops *ops,
240- struct regcache *regcache, int regno)
241-{
242- /* Get the thread id for the ptrace call. */
243- int tid = GET_THREAD_ID (inferior_ptid);
244-
245- if (regno == -1)
246- fetch_gp_regs (regcache, tid);
247- else
248- fetch_register (regcache, tid, regno);
249-}
250-
251-/* Store registers back into the inferior. Store all registers if
252- regno == -1, otherwise store all general registers or all floating
253- point registers depending upon the value of regno. */
254-
255-static void
256-microblaze_linux_store_inferior_registers (struct target_ops *ops,
257- struct regcache *regcache, int regno)
258+void
259+microblaze_linux_nat_target::store_registers (struct regcache *regcache, int regno)
260 {
261- /* Get the thread id for the ptrace call. */
262- int tid = GET_THREAD_ID (inferior_ptid);
263+ pid_t tid = get_ptrace_pid (regcache->ptid ());
264
265 if (regno >= 0)
266 store_register (regcache, tid, regno);
267@@ -373,59 +343,44 @@ microblaze_linux_store_inferior_registers (struct target_ops *ops,
268 thread debugging. */
269
270 void
271-fill_gregset (const struct regcache *regcache,
272- gdb_gregset_t *gregsetp, int regno)
273+supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
274 {
275- microblaze_collect_gregset (NULL, regcache, regno, gregsetp);
276+ microblaze_supply_gregset (NULL, regcache, -1, gregsetp);
277 }
278
279 void
280-supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
281+fill_gregset (const struct regcache *regcache,
282+ gdb_gregset_t *gregsetp, int regno)
283 {
284- microblaze_supply_gregset (NULL, regcache, -1, gregsetp);
285+ microblaze_collect_gregset (NULL, regcache, regno, gregsetp);
286 }
287
288 void
289-fill_fpregset (const struct regcache *regcache,
290- gdb_fpregset_t *fpregsetp, int regno)
291+supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
292 {
293 /* FIXME. */
294+ return;
295 }
296
297 void
298-supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
299+fill_fpregset (const struct regcache *regcache,
300+ gdb_fpregset_t *fpregsetp, int regno)
301 {
302 /* FIXME. */
303+ return;
304 }
305
306-static const struct target_desc *
307-microblaze_linux_read_description (struct target_ops *ops)
308+const struct target_desc *
309+microblaze_linux_nat_target::read_description ()
310 {
311- CORE_ADDR microblaze_hwcap = 0;
312-
313- if (target_auxv_search (ops, AT_HWCAP, &microblaze_hwcap) != 1)
314- return NULL;
315-
316 return NULL;
317 }
318
319-
320-void _initialize_microblaze_linux_nat (void);
321-
322 void
323 _initialize_microblaze_linux_nat (void)
324 {
325- struct target_ops *t;
326-
327- /* Fill in the generic GNU/Linux methods. */
328- t = linux_target ();
329-
330- /* Add our register access methods. */
331- t->to_fetch_registers = microblaze_linux_fetch_inferior_registers;
332- t->to_store_registers = microblaze_linux_store_inferior_registers;
333-
334- t->to_read_description = microblaze_linux_read_description;
335+ linux_target = &the_microblaze_linux_nat_target;
336
337 /* Register the target. */
338- linux_nat_add_target (t);
339+ add_inf_child_target (linux_target);
340 }
341diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
342index 7a0c2527f4..23deb24d26 100644
343--- a/gdb/microblaze-tdep.c
344+++ b/gdb/microblaze-tdep.c
345@@ -657,7 +657,7 @@ static std::vector<CORE_ADDR>
346 microblaze_software_single_step (struct regcache *regcache)
347 {
348 // struct gdbarch *arch = get_frame_arch(frame);
349- struct gdbarch *arch = get_regcache_arch (regcache);
350+ struct gdbarch *arch = regcache->arch();
351 struct address_space *aspace = get_regcache_aspace (regcache);
352 // struct address_space *aspace = get_frame_address_space (frame);
353 struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
354@@ -876,7 +876,6 @@ microblaze_regset_from_core_section (struct gdbarch *gdbarch,
355 static void
356 make_regs (struct gdbarch *arch)
357 {
358- struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
359 int mach = gdbarch_bfd_arch_info (arch)->mach;
360
361 if (mach == bfd_mach_microblaze64)
362--
3632.17.1
364
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch
new file mode 100644
index 00000000..118c5629
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch
@@ -0,0 +1,86 @@
1From d64ce07a2b9206ce1e53d8958b28de02cc7cca2b Mon Sep 17 00:00:00 2001
2From: Nagaraju <nmekala@xilinx.com>
3Date: Wed, 22 Jan 2020 16:31:12 +0530
4Subject: [PATCH 45/45] Fixed bug in generation of IMML instruction for the new
5 MB-64 instructions with single register.
6
7---
8 gas/config/tc-microblaze.c | 50 +++++++++++++++++++++++++++++++++++---
9 1 file changed, 47 insertions(+), 3 deletions(-)
10
11diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
12index 95a1e69729..dc79328df6 100644
13--- a/gas/config/tc-microblaze.c
14+++ b/gas/config/tc-microblaze.c
15@@ -1642,12 +1642,56 @@ md_assemble (char * str)
16 exp.X_add_symbol,
17 exp.X_add_number,
18 (char *) opc);
19- immedl = 0L;
20+ immed = 0L;
21 }
22 else
23 {
24 output = frag_more (isize);
25 immed = exp.X_add_number;
26+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
27+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000 && temp != 0x8000)
28+ {
29+ /* Needs an immediate inst. */
30+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
31+ {
32+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
33+ if (opcode1 == NULL)
34+ {
35+ as_bad (_("unknown opcode \"%s\""), "imml");
36+ return;
37+ }
38+ inst1 = opcode1->bit_sequence;
39+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
40+ output[0] = INST_BYTE0 (inst1);
41+ output[1] = INST_BYTE1 (inst1);
42+ output[2] = INST_BYTE2 (inst1);
43+ output[3] = INST_BYTE3 (inst1);
44+ output = frag_more (isize);
45+ }
46+ else {
47+ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
48+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
49+ if (opcode1 == NULL || opcode2 == NULL)
50+ {
51+ as_bad (_("unknown opcode \"%s\""), "imml");
52+ return;
53+ }
54+ inst1 = opcode2->bit_sequence;
55+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
56+ output[0] = INST_BYTE0 (inst1);
57+ output[1] = INST_BYTE1 (inst1);
58+ output[2] = INST_BYTE2 (inst1);
59+ output[3] = INST_BYTE3 (inst1);
60+ output = frag_more (isize);
61+ inst1 = opcode1->bit_sequence;
62+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
63+ output[0] = INST_BYTE0 (inst1);
64+ output[1] = INST_BYTE1 (inst1);
65+ output[2] = INST_BYTE2 (inst1);
66+ output[3] = INST_BYTE3 (inst1);
67+ output = frag_more (isize);
68+ }
69+ }
70 }
71 inst |= (reg1 << RD_LOW) & RD_MASK;
72 inst |= (immed << IMM_LOW) & IMM16_MASK;
73@@ -2141,8 +2185,8 @@ md_assemble (char * str)
74 streq (name, "breaid") ||
75 streq (name, "brai") || streq (name, "braid")))
76 {
77- temp = immed & 0xFFFFFFFFFFFF8000;
78- if (temp != 0)
79+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
80+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000 && temp != 0x8000)
81 {
82 /* Needs an immediate inst. */
83 if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
84--
852.17.1
86
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0046-Patch-MicroBlaze-m64-This-patch-will-remove-imml-0-a.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0046-Patch-MicroBlaze-m64-This-patch-will-remove-imml-0-a.patch
new file mode 100644
index 00000000..7677ab35
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0046-Patch-MicroBlaze-m64-This-patch-will-remove-imml-0-a.patch
@@ -0,0 +1,38 @@
1From 9c8f4f1c11d324f0788da3a077b06c6bc9e6f2b8 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Thu, 16 Apr 2020 18:08:58 +0530
4Subject: [PATCH] [Patch,MicroBlaze m64] : This patch will remove imml 0 and
5 imml -1 instructions when the offset is less than 16 bit for Type A branch EA
6 instructions.
7
8---
9 gas/config/tc-microblaze.c | 6 ++----
10 1 file changed, 2 insertions(+), 4 deletions(-)
11
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index 088eae73a9..12fd145a03 100644
14--- a/gas/config/tc-microblaze.c
15+++ b/gas/config/tc-microblaze.c
16@@ -2150,9 +2150,7 @@ md_assemble (char * str)
17 if (exp.X_op != O_constant)
18 {
19 char *opc;
20- if (microblaze_arch_size == 64 && (streq (name, "breai") ||
21- streq (name, "breaid") ||
22- streq (name, "brai") || streq (name, "braid")))
23+ if (microblaze_arch_size == 64 && (streq (name, "brai") || streq (name, "braid")))
24 opc = str_microblaze_64;
25 else
26 opc = NULL;
27@@ -2920,7 +2918,7 @@ md_apply_fix (fixS * fixP,
28 case BFD_RELOC_MICROBLAZE_64:
29 case BFD_RELOC_MICROBLAZE_64_PCREL:
30 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
31- || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
32+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL || (fixP->fx_r_type == BFD_RELOC_64_PCREL && microblaze_arch_size == 64))
33 {
34 /* Generate the imm instruction. */
35 if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887)
36--
372.17.1
38
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0047-Patch-MicroBlaze-commit-for-triggering-build-to-remo.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0047-Patch-MicroBlaze-commit-for-triggering-build-to-remo.patch
new file mode 100644
index 00000000..93314594
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0047-Patch-MicroBlaze-commit-for-triggering-build-to-remo.patch
@@ -0,0 +1,25 @@
1From 2ab2547493c871b452adb2cb8754691b0adf5f03 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Sun, 19 Apr 2020 21:17:03 +0530
4Subject: [PATCH 47/49] [Patch,MicroBlaze] : commit for triggering build to
5 remove imml for Type A BEA insns.
6
7---
8 gas/config/tc-microblaze.c | 1 +
9 1 file changed, 1 insertion(+)
10
11diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
12index 12fd145a03..7ae0dbc018 100644
13--- a/gas/config/tc-microblaze.c
14+++ b/gas/config/tc-microblaze.c
15@@ -2150,6 +2150,7 @@ md_assemble (char * str)
16 if (exp.X_op != O_constant)
17 {
18 char *opc;
19+/* removal imml 0 and imml -1 for bea type A insns */
20 if (microblaze_arch_size == 64 && (streq (name, "brai") || streq (name, "braid")))
21 opc = str_microblaze_64;
22 else
23--
242.17.1
25
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0048-Patch-MicroBlaze-Adding-more-description-to-the-imml.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0048-Patch-MicroBlaze-Adding-more-description-to-the-imml.patch
new file mode 100644
index 00000000..30fbbe7b
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0048-Patch-MicroBlaze-Adding-more-description-to-the-imml.patch
@@ -0,0 +1,27 @@
1From 9b61edf44e44303f1937e98a02a7d78f750a9b24 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Thu, 30 Apr 2020 19:40:16 +0530
4Subject: [PATCH 48/49] [Patch,MicroBlaze] : Adding more description to the
5 imml removal for bea type B insns.
6
7---
8 gas/config/tc-microblaze.c | 3 ++-
9 1 file changed, 2 insertions(+), 1 deletion(-)
10
11diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
12index 7ae0dbc018..1d37af54bf 100644
13--- a/gas/config/tc-microblaze.c
14+++ b/gas/config/tc-microblaze.c
15@@ -2150,7 +2150,8 @@ md_assemble (char * str)
16 if (exp.X_op != O_constant)
17 {
18 char *opc;
19-/* removal imml 0 and imml -1 for bea type A insns */
20+/* removal of imml 0 and imml -1 for bea type A insns.
21+if offset is 16 bit then imml instructions are redundant */
22 if (microblaze_arch_size == 64 && (streq (name, "brai") || streq (name, "braid")))
23 opc = str_microblaze_64;
24 else
25--
262.17.1
27
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0049-Patch-MicroBlaze-improper-address-mapping-of-PROVIDE.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0049-Patch-MicroBlaze-improper-address-mapping-of-PROVIDE.patch
new file mode 100644
index 00000000..b751f294
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0049-Patch-MicroBlaze-improper-address-mapping-of-PROVIDE.patch
@@ -0,0 +1,39 @@
1From ba660177916ffb8a0a9882c27246a201dbc218bd Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 17 Jun 2020 21:20:26 +0530
4Subject: [PATCH 49/49] [Patch,MicroBlaze] : improper address mapping of
5 PROVIDE directive symbols[DTOR_END] are causing runtime loops and we don't
6 need to override PROVIDE symbols if symbols are defined in libraries and
7 linker so I am disabling override for PROVIDE symbols.
8
9---
10 ld/ldlang.c | 12 +++++++++---
11 1 file changed, 9 insertions(+), 3 deletions(-)
12
13diff --git a/ld/ldlang.c b/ld/ldlang.c
14index 33f6bda292..a0b404c04d 100644
15--- a/ld/ldlang.c
16+++ b/ld/ldlang.c
17@@ -3559,10 +3559,16 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
18 plugin_insert = NULL;
19 #endif
20 break;
21+ /* This is from a --defsym on the command line. */
22 case lang_assignment_statement_enum:
23- if (s->assignment_statement.exp->type.node_class != etree_assert)
24- exp_fold_tree_no_dot (s->assignment_statement.exp);
25- break;
26+ if (s->assignment_statement.exp->type.node_class != etree_assert)
27+ {
28+ if(!(s->assignment_statement.exp->assign.defsym) && (s->assignment_statement.exp->type.node_class == etree_provide))
29+ ;
30+ else
31+ exp_fold_tree_no_dot (s->assignment_statement.exp);
32+ }
33+ break;
34 default:
35 break;
36 }
37--
382.17.1
39
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0050-Fix-i386-md_pseudo_table.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0050-Fix-i386-md_pseudo_table.patch
new file mode 100644
index 00000000..9469732e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0050-Fix-i386-md_pseudo_table.patch
@@ -0,0 +1,28 @@
1Fix a possible compilation issue on i386 when using microblaze patches
2
3Due to patch 0019, a later item may need to refer to this table.
4
5| ../../gas/config/tc-i386.c:1155:20: error: conflicting types for ‘md_pseudo_table’
6| const pseudo_typeS md_pseudo_table[] =
7| ^~~~~~~~~~~~~~~
8| In file included from ../../gas/as.h:565:0,
9| from ../../gas/config/tc-i386.c:28:
10| ../../gas/tc.h:25:21: note: previous declaration of ‘md_pseudo_table’ was here
11| extern pseudo_typeS md_pseudo_table[];
12| ^~~~~~~~~~~~~~~
13
14Signed-off-by: Mark Hatle <mark.hatle@xilinx.com>
15
16Index: git/gas/config/tc-i386.c
17===================================================================
18--- git.orig/gas/config/tc-i386.c
19+++ git/gas/config/tc-i386.c
20@@ -1152,7 +1152,7 @@ pe_lcomm (int needs_align)
21 }
22 #endif
23
24-const pseudo_typeS md_pseudo_table[] =
25+pseudo_typeS md_pseudo_table[] =
26 {
27 #if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO)
28 {"align", s_align_bytes, 0},
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils_%.bbappend b/meta-microblaze/recipes-devtools/binutils/binutils_%.bbappend
new file mode 100644
index 00000000..e439cae7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils_%.bbappend
@@ -0,0 +1,4 @@
1MICROBLAZEPATCHES = ""
2MICROBLAZEPATCHES_microblaze = "binutils-microblaze.inc"
3
4require ${MICROBLAZEPATCHES}